summaryrefslogtreecommitdiffstats
path: root/spec/unit
diff options
context:
space:
mode:
Diffstat (limited to 'spec/unit')
-rwxr-xr-xspec/unit/node/catalog.rb60
-rwxr-xr-xspec/unit/other/pgraph.rb34
-rwxr-xr-xspec/unit/parser/ast/definition.rb158
-rwxr-xr-xspec/unit/parser/ast/hostclass.rb131
-rwxr-xr-xspec/unit/parser/ast/node.rb127
-rwxr-xr-xspec/unit/parser/collector.rb60
-rwxr-xr-xspec/unit/parser/compile.rb281
-rwxr-xr-xspec/unit/parser/compiler.rb544
-rwxr-xr-xspec/unit/parser/interpreter.rb6
-rwxr-xr-xspec/unit/parser/resource.rb14
-rwxr-xr-xspec/unit/parser/resource/reference.rb8
-rwxr-xr-xspec/unit/ral/type.rb4
-rwxr-xr-xspec/unit/simple_graph.rb64
-rwxr-xr-xspec/unit/util/constant_inflector.rb70
-rwxr-xr-xspec/unit/util/tagging.rb9
15 files changed, 1162 insertions, 408 deletions
diff --git a/spec/unit/node/catalog.rb b/spec/unit/node/catalog.rb
index 3833890f7..aa49909e2 100755
--- a/spec/unit/node/catalog.rb
+++ b/spec/unit/node/catalog.rb
@@ -57,11 +57,11 @@ describe Puppet::Node::Catalog, " when extracting transobjects" do
def mkscope
@parser = Puppet::Parser::Parser.new :Code => ""
@node = Puppet::Node.new("mynode")
- @compile = Puppet::Parser::Compile.new(@node, @parser)
+ @compiler = Puppet::Parser::Compiler.new(@node, @parser)
# XXX This is ridiculous.
- @compile.send(:evaluate_main)
- @scope = @compile.topscope
+ @compiler.send(:evaluate_main)
+ @scope = @compiler.topscope
end
def mkresource(type, name)
@@ -75,7 +75,7 @@ describe Puppet::Node::Catalog, " when extracting transobjects" do
@source = mock 'source'
main = mkresource("class", :main)
- config.add_vertex!(main)
+ config.add_vertex(main)
bucket = mock 'bucket'
bucket.expects(:classes=).with(config.classes)
@@ -95,7 +95,7 @@ describe Puppet::Node::Catalog, " when extracting transobjects" do
defined = mkresource("class", :main)
builtin = mkresource("file", "/yay")
- config.add_edge!(defined, builtin)
+ config.add_edge(defined, builtin)
bucket = []
bucket.expects(:classes=).with(config.classes)
@@ -121,21 +121,21 @@ describe Puppet::Node::Catalog, " when extracting transobjects" do
top.expects(:to_trans).returns(topbucket)
topres = mkresource "file", "/top"
topres.expects(:to_trans).returns(:topres)
- config.add_edge! top, topres
+ config.add_edge top, topres
middle = mkresource "class", "middle"
middle.expects(:to_trans).returns([])
- config.add_edge! top, middle
+ config.add_edge top, middle
midres = mkresource "file", "/mid"
midres.expects(:to_trans).returns(:midres)
- config.add_edge! middle, midres
+ config.add_edge middle, midres
bottom = mkresource "class", "bottom"
bottom.expects(:to_trans).returns([])
- config.add_edge! middle, bottom
+ config.add_edge middle, bottom
botres = mkresource "file", "/bot"
botres.expects(:to_trans).returns(:botres)
- config.add_edge! bottom, botres
+ config.add_edge bottom, botres
toparray = config.extract_to_transportable
@@ -196,13 +196,13 @@ describe Puppet::Node::Catalog, " when converting to a transobject catalog" do
@resources = [@top, @topobject, @middle, @middleobject, @bottom, @bottomobject]
- @original.add_edge!(@top, @topobject)
- @original.add_edge!(@top, @virtual)
- @original.add_edge!(@virtual, @virtualobject)
- @original.add_edge!(@top, @middle)
- @original.add_edge!(@middle, @middleobject)
- @original.add_edge!(@middle, @bottom)
- @original.add_edge!(@bottom, @bottomobject)
+ @original.add_edge(@top, @topobject)
+ @original.add_edge(@top, @virtual)
+ @original.add_edge(@virtual, @virtualobject)
+ @original.add_edge(@top, @middle)
+ @original.add_edge(@middle, @middleobject)
+ @original.add_edge(@middle, @bottom)
+ @original.add_edge(@bottom, @bottomobject)
@catalog = @original.to_transportable
end
@@ -261,11 +261,11 @@ describe Puppet::Node::Catalog, " when converting to a RAL catalog" do
@original.add_resource(*@resources)
- @original.add_edge!(@top, @topobject)
- @original.add_edge!(@top, @middle)
- @original.add_edge!(@middle, @middleobject)
- @original.add_edge!(@middle, @bottom)
- @original.add_edge!(@bottom, @bottomobject)
+ @original.add_edge(@top, @topobject)
+ @original.add_edge(@top, @middle)
+ @original.add_edge(@middle, @middleobject)
+ @original.add_edge(@middle, @bottom)
+ @original.add_edge(@bottom, @bottomobject)
@catalog = @original.to_ral
end
@@ -300,7 +300,7 @@ describe Puppet::Node::Catalog, " when converting to a RAL catalog" do
config.add_resource(changer)
config.add_resource(@top)
- config.add_edge!(@top, changer)
+ config.add_edge(@top, changer)
resource = stub 'resource', :name => "changer2", :title => "changer2", :ref => "Test[changer2]", :catalog= => nil, :remove => nil
@@ -365,6 +365,12 @@ describe Puppet::Node::Catalog, " when functioning as a resource container" do
it "should not allow two resources with the same resource reference" do
@catalog.add_resource(@one)
+
+ # These are used to build the failure
+ @dupe.stubs(:file)
+ @dupe.stubs(:line)
+ @one.stubs(:file)
+ @one.stubs(:line)
proc { @catalog.add_resource(@dupe) }.should raise_error(ArgumentError)
end
@@ -591,8 +597,8 @@ describe Puppet::Node::Catalog, " when creating a relationship graph" do
@file = Puppet::Type.type(:file)
@one = @file.create :path => "/one"
@two = @file.create :path => "/two"
- @catalog.add_edge! @compone, @one
- @catalog.add_edge! @comptwo, @two
+ @catalog.add_edge @compone, @one
+ @catalog.add_edge @comptwo, @two
@three = @file.create :path => "/three"
@four = @file.create :path => "/four", :require => ["file", "/three"]
@@ -765,7 +771,7 @@ end
describe Puppet::Node::Catalog, " when converting to yaml" do
before do
@catalog = Puppet::Node::Catalog.new("me")
- @catalog.add_edge!("one", "two")
+ @catalog.add_edge("one", "two")
end
it "should be able to be dumped to yaml" do
@@ -776,7 +782,7 @@ end
describe Puppet::Node::Catalog, " when converting from yaml" do
before do
@catalog = Puppet::Node::Catalog.new("me")
- @catalog.add_edge!("one", "two")
+ @catalog.add_edge("one", "two")
text = YAML.dump(@catalog)
@newcatalog = YAML.load(text)
diff --git a/spec/unit/other/pgraph.rb b/spec/unit/other/pgraph.rb
index 252a807ec..7d66ae331 100755
--- a/spec/unit/other/pgraph.rb
+++ b/spec/unit/other/pgraph.rb
@@ -35,8 +35,8 @@ describe Puppet::PGraph do
end
it "should correctly clear vertices and edges when asked" do
- @graph.add_edge!("a", "b")
- @graph.add_vertex! "c"
+ @graph.add_edge("a", "b")
+ @graph.add_vertex "c"
@graph.clear
@graph.vertices.should be_empty
@graph.edges.should be_empty
@@ -52,7 +52,7 @@ describe Puppet::PGraph, " when matching edges" do
@edges = {}
@edges["a/b"] = Puppet::Relationship.new("a", "b", {:event => :yay, :callback => :refresh})
@edges["a/c"] = Puppet::Relationship.new("a", "c", {:event => :yay, :callback => :refresh})
- @graph.add_edge!(@edges["a/b"])
+ @graph.add_edge(@edges["a/b"])
end
it "should match edges whose source matches the source of the event" do
@@ -64,7 +64,7 @@ describe Puppet::PGraph, " when matching edges" do
end
it "should match multiple edges" do
- @graph.add_edge!(@edges["a/c"])
+ @graph.add_edge(@edges["a/c"])
edges = @graph.matching_edges([@event])
edges.should be_include(@edges["a/b"])
edges.should be_include(@edges["a/c"])
@@ -75,9 +75,9 @@ describe Puppet::PGraph, " when determining dependencies" do
before do
@graph = Puppet::PGraph.new
- @graph.add_edge!("a", "b")
- @graph.add_edge!("a", "c")
- @graph.add_edge!("b", "d")
+ @graph.add_edge("a", "b")
+ @graph.add_edge("a", "c")
+ @graph.add_edge("b", "d")
end
it "should find all dependents when they are on multiple levels" do
@@ -118,19 +118,19 @@ describe Puppet::PGraph, " when splicing the relationship graph" do
# We have to add the container to the main graph, else it won't
# be spliced in the dependency graph.
- @contgraph.add_vertex!(@empty)
+ @contgraph.add_vertex(@empty)
end
def dependency_graph
@depgraph = Puppet::PGraph.new
@contgraph.vertices.each do |v|
- @depgraph.add_vertex!(v)
+ @depgraph.add_vertex(v)
end
# We have to specify a relationship to our empty container, else it
# never makes it into the dep graph in the first place.
{@one => @two, "f" => "c", "h" => @middle, "c" => @empty}.each do |source, target|
- @depgraph.add_edge!(source, target, :callback => :refresh)
+ @depgraph.add_edge(source, target, :callback => :refresh)
end
end
@@ -176,13 +176,13 @@ describe Puppet::PGraph, " when splicing the relationship graph" do
end
it "should not add labels to edges that have none" do
- @depgraph.add_edge!(@two, @three)
+ @depgraph.add_edge(@two, @three)
splice
@depgraph.edge_label("c", "i").should == {}
end
it "should copy labels over edges that have none" do
- @depgraph.add_edge!("c", @three, {:callback => :refresh})
+ @depgraph.add_edge("c", @three, {:callback => :refresh})
splice
# And make sure the label got copied.
@depgraph.edge_label("c", "i").should == {:callback => :refresh}
@@ -190,18 +190,18 @@ describe Puppet::PGraph, " when splicing the relationship graph" do
it "should not replace a label with a nil label" do
# Lastly, add some new label-less edges and make sure the label stays.
- @depgraph.add_edge!(@middle, @three)
- @depgraph.add_edge!("c", @three, {:callback => :refresh})
+ @depgraph.add_edge(@middle, @three)
+ @depgraph.add_edge("c", @three, {:callback => :refresh})
splice
@depgraph.edge_label("c", "i").should == {:callback => :refresh}
end
it "should copy labels to all created edges" do
- @depgraph.add_edge!(@middle, @three)
- @depgraph.add_edge!("c", @three, {:callback => :refresh})
+ @depgraph.add_edge(@middle, @three)
+ @depgraph.add_edge("c", @three, {:callback => :refresh})
splice
@three.each do |child|
- edge = @depgraph.edge_class.new("c", child)
+ edge = Puppet::Relationship.new("c", child)
@depgraph.should be_edge(edge.source, edge.target)
@depgraph.edge_label(edge.source, edge.target).should == {:callback => :refresh}
end
diff --git a/spec/unit/parser/ast/definition.rb b/spec/unit/parser/ast/definition.rb
index a27fb4721..f236e23b7 100755
--- a/spec/unit/parser/ast/definition.rb
+++ b/spec/unit/parser/ast/definition.rb
@@ -12,8 +12,8 @@ describe Puppet::Parser::AST::Definition, "when evaluating" do
@source = @parser.newclass ""
@definition = @parser.newdefine "mydefine"
@node = Puppet::Node.new("yaynode")
- @compile = Puppet::Parser::Compile.new(@node, @parser)
- @scope = @compile.topscope
+ @compiler = Puppet::Parser::Compiler.new(@node, @parser)
+ @scope = @compiler.topscope
@resource = Puppet::Parser::Resource.new(:type => "mydefine", :title => "myresource", :scope => @scope, :source => @source)
end
@@ -21,12 +21,12 @@ describe Puppet::Parser::AST::Definition, "when evaluating" do
it "should create a new scope" do
scope = nil
code = mock 'code'
- code.expects(:safeevaluate).with do |options|
- options[:scope].object_id.should_not == @scope.object_id
+ code.expects(:safeevaluate).with do |scope|
+ scope.object_id.should_not == @scope.object_id
true
end
@definition.stubs(:code).returns(code)
- @definition.evaluate(:scope => @scope, :resource => @resource)
+ @definition.evaluate_code(@resource)
end
# it "should copy its namespace to the scope"
@@ -44,4 +44,152 @@ describe Puppet::Parser::AST::Definition, "when evaluating" do
# it "should not copy the resource's title as the name if 'name' is one of the resource parameters"
#
# it "should evaluate the associated code with the new scope"
+
+ def test_initialize
+ parser = mkparser
+
+ # Create a new definition
+ klass = parser.newdefine "yayness",
+ :arguments => [["owner", stringobj("nobody")], %w{mode}],
+ :code => AST::ASTArray.new(
+ :children => [resourcedef("file", "/tmp/$name",
+ "owner" => varref("owner"), "mode" => varref("mode"))]
+ )
+
+ # Test validattr? a couple different ways
+ [:owner, "owner", :schedule, "schedule"].each do |var|
+ assert(klass.validattr?(var), "%s was not considered valid" % var.inspect)
+ end
+
+ [:random, "random"].each do |var|
+ assert(! klass.validattr?(var), "%s was considered valid" % var.inspect)
+ end
+
+ end
+
+ def test_evaluate
+ parser = mkparser
+ config = mkcompiler
+ config.send(:evaluate_main)
+ scope = config.topscope
+ klass = parser.newdefine "yayness",
+ :arguments => [["owner", stringobj("nobody")], %w{mode}],
+ :code => AST::ASTArray.new(
+ :children => [resourcedef("file", "/tmp/$name",
+ "owner" => varref("owner"), "mode" => varref("mode"))]
+ )
+
+ resource = Puppet::Parser::Resource.new(
+ :title => "first",
+ :type => "yayness",
+ :exported => false,
+ :virtual => false,
+ :scope => scope,
+ :source => scope.source
+ )
+ resource.send(:set_parameter, "name", "first")
+ resource.send(:set_parameter, "mode", "755")
+
+ resource.stubs(:title)
+ assert_nothing_raised do
+ klass.evaluate_code(resource)
+ end
+
+ firstobj = config.findresource("File[/tmp/first]")
+ assert(firstobj, "Did not create /tmp/first obj")
+
+ assert_equal("File", firstobj.type)
+ assert_equal("/tmp/first", firstobj.title)
+ assert_equal("nobody", firstobj[:owner])
+ assert_equal("755", firstobj[:mode])
+
+ # Make sure we can't evaluate it with the same args
+ assert_raise(Puppet::ParseError) do
+ klass.evaluate_code(resource)
+ end
+
+ # Now create another with different args
+ resource2 = Puppet::Parser::Resource.new(
+ :title => "second",
+ :type => "yayness",
+ :exported => false,
+ :virtual => false,
+ :scope => scope,
+ :source => scope.source
+ )
+ resource2.send(:set_parameter, "name", "second")
+ resource2.send(:set_parameter, "mode", "755")
+ resource2.send(:set_parameter, "owner", "daemon")
+
+ assert_nothing_raised do
+ klass.evaluate_code(resource2)
+ end
+
+ secondobj = config.findresource("File[/tmp/second]")
+ assert(secondobj, "Did not create /tmp/second obj")
+
+ assert_equal("File", secondobj.type)
+ assert_equal("/tmp/second", secondobj.title)
+ assert_equal("daemon", secondobj[:owner])
+ assert_equal("755", secondobj[:mode])
+ end
+
+ # #539 - definitions should support both names and titles
+ def test_names_and_titles
+ parser = mkparser
+ scope = mkscope :parser => parser
+
+ [
+ {:name => "one", :title => "two"},
+ {:title => "mytitle"}
+ ].each_with_index do |hash, i|
+ # Create a definition that uses both name and title. Put this
+ # inside the loop so the subscope expectations work.
+ klass = parser.newdefine "yayness%s" % i
+
+ resource = Puppet::Parser::Resource.new(
+ :title => hash[:title],
+ :type => "yayness%s" % i,
+ :exported => false,
+ :virtual => false,
+ :scope => scope,
+ :source => scope.source
+ )
+
+ subscope = klass.subscope(scope, resource)
+
+ klass.expects(:subscope).returns(subscope)
+
+ if hash[:name]
+ resource.stubs(:to_hash).returns({:name => hash[:name]})
+ end
+
+ assert_nothing_raised("Could not evaluate definition with %s" % hash.inspect) do
+ klass.evaluate_code(resource)
+ end
+
+ name = hash[:name] || hash[:title]
+ title = hash[:title]
+
+ assert_equal(name, subscope.lookupvar("name"),
+ "Name did not get set correctly")
+ assert_equal(title, subscope.lookupvar("title"),
+ "title did not get set correctly")
+
+ [:name, :title].each do |param|
+ val = resource.send(param)
+ assert(subscope.tags.include?(val),
+ "Scope was not tagged with %s '%s'" % [param, val])
+ end
+ end
+ end
+
+ # Testing the root cause of #615. We should be using the fqname for the type, instead
+ # of just the short name.
+ def test_fully_qualified_types
+ parser = mkparser
+ klass = parser.newclass("one::two")
+
+ assert_equal("one::two", klass.classname, "Class did not get fully qualified class name")
+ end
end
diff --git a/spec/unit/parser/ast/hostclass.rb b/spec/unit/parser/ast/hostclass.rb
new file mode 100755
index 000000000..422861857
--- /dev/null
+++ b/spec/unit/parser/ast/hostclass.rb
@@ -0,0 +1,131 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+module HostClassTesting
+ def setup
+ @node = Puppet::Node.new "testnode"
+ @parser = Puppet::Parser::Parser.new :environment => "development"
+ @scope_resource = stub 'scope_resource', :builtin? => true
+ @compiler = Puppet::Parser::Compiler.new(@node, @parser)
+
+ @scope = @compiler.topscope
+ end
+end
+
+describe Puppet::Parser::AST::HostClass, "when evaluating" do
+ include HostClassTesting
+
+ before do
+ @top = @parser.newclass "top"
+ @middle = @parser.newclass "middle", :parent => "top"
+ end
+
+ it "should create a resource that references itself" do
+ @top.evaluate(@scope)
+
+ @compiler.catalog.resource(:class, "top").should be_instance_of(Puppet::Parser::Resource)
+ end
+
+ it "should evaluate the parent class if one exists" do
+ @middle.evaluate(@scope)
+
+ @compiler.catalog.resource(:class, "top").should be_instance_of(Puppet::Parser::Resource)
+ end
+
+ it "should fail to evaluate if a parent class is defined but cannot be found" do
+ othertop = @parser.newclass "something", :parent => "yay"
+ lambda { othertop.evaluate(@scope) }.should raise_error(Puppet::ParseError)
+ end
+
+ it "should not create a new resource if one already exists" do
+ @compiler.catalog.expects(:resource).with(:class, "top").returns("something")
+ @compiler.catalog.expects(:add_resource).never
+ @top.evaluate(@scope)
+ end
+
+ it "should not create a new parent resource if one already exists and it has a parent class" do
+ @top.evaluate(@scope)
+
+ top_resource = @compiler.catalog.resource(:class, "top")
+
+ @middle.evaluate(@scope)
+
+ @compiler.catalog.resource(:class, "top").should equal(top_resource)
+ end
+
+ # #795 - tag before evaluation.
+ it "should tag the catalog with the resource tags when it is evaluated" do
+ @middle.evaluate(@scope)
+
+ @compiler.catalog.should be_tagged("middle")
+ end
+
+ it "should tag the catalog with the parent class tags when it is evaluated" do
+ @middle.evaluate(@scope)
+
+ @compiler.catalog.should be_tagged("top")
+ end
+end
+
+describe Puppet::Parser::AST::HostClass, "when evaluating code" do
+ include HostClassTesting
+
+ before do
+ @top_resource = stub "top_resource"
+ @top = @parser.newclass "top", :code => @top_resource
+
+ @middle_resource = stub "middle_resource"
+ @middle = @parser.newclass "top::middle", :parent => "top", :code => @middle_resource
+ end
+
+ it "should set its namespace to its fully qualified name" do
+ @middle.namespace.should == "top::middle"
+ end
+
+ it "should evaluate the code referred to by the class" do
+ @top_resource.expects(:safeevaluate)
+
+ resource = @top.evaluate(@scope)
+
+ @top.evaluate_code(resource)
+ end
+
+ it "should evaluate the parent class's code if it has a parent" do
+ @top_resource.expects(:safeevaluate)
+ @middle_resource.expects(:safeevaluate)
+
+ resource = @middle.evaluate(@scope)
+
+ @middle.evaluate_code(resource)
+ end
+
+ it "should not evaluate the parent class's code if the parent has already been evaluated" do
+ @top_resource.stubs(:safeevaluate)
+ resource = @top.evaluate(@scope)
+ @top.evaluate_code(resource)
+
+ @top_resource.expects(:safeevaluate).never
+ @middle_resource.stubs(:safeevaluate)
+ resource = @middle.evaluate(@scope)
+ @middle.evaluate_code(resource)
+ end
+
+ it "should use the parent class's scope as its parent scope" do
+ @top_resource.stubs(:safeevaluate)
+ @middle_resource.stubs(:safeevaluate)
+ resource = @middle.evaluate(@scope)
+ @middle.evaluate_code(resource)
+
+ @compiler.class_scope(@middle).parent.should equal(@compiler.class_scope(@top))
+ end
+
+ it "should add the parent class's namespace to its namespace search path" do
+ @top_resource.stubs(:safeevaluate)
+ @middle_resource.stubs(:safeevaluate)
+ resource = @middle.evaluate(@scope)
+ @middle.evaluate_code(resource)
+
+ @compiler.class_scope(@middle).namespaces.should be_include(@top.namespace)
+ end
+end
diff --git a/spec/unit/parser/ast/node.rb b/spec/unit/parser/ast/node.rb
new file mode 100755
index 000000000..340630194
--- /dev/null
+++ b/spec/unit/parser/ast/node.rb
@@ -0,0 +1,127 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+module ASTNodeTesting
+ def setup
+ @node = Puppet::Node.new "testnode"
+ @parser = Puppet::Parser::Parser.new :environment => "development"
+ @scope_resource = stub 'scope_resource', :builtin? => true
+ @compiler = Puppet::Parser::Compiler.new(@node, @parser)
+
+ @scope = @compiler.topscope
+ end
+end
+
+describe Puppet::Parser::AST::Node, "when evaluating" do
+ include ASTNodeTesting
+
+ before do
+ @top = @parser.newnode("top").shift
+ @middle = @parser.newnode("middle", :parent => "top").shift
+ end
+
+ it "should create a resource that references itself" do
+ @top.evaluate(@scope)
+
+ @compiler.catalog.resource(:node, "top").should be_an_instance_of(Puppet::Parser::Resource)
+ end
+
+ it "should evaluate the parent class if one exists" do
+ @middle.evaluate(@scope)
+
+ @compiler.catalog.resource(:node, "top").should be_an_instance_of(Puppet::Parser::Resource)
+ end
+
+ it "should fail to evaluate if a parent class is defined but cannot be found" do
+ othertop = @parser.newnode("something", :parent => "yay").shift
+ lambda { othertop.evaluate(@scope) }.should raise_error(Puppet::ParseError)
+ end
+
+ it "should not create a new resource if one already exists" do
+ @compiler.catalog.expects(:resource).with(:node, "top").returns("something")
+ @compiler.catalog.expects(:add_resource).never
+ @top.evaluate(@scope)
+ end
+
+ it "should not create a new parent resource if one already exists and it has a parent class" do
+ @top.evaluate(@scope)
+
+ top_resource = @compiler.catalog.resource(:node, "top")
+
+ @middle.evaluate(@scope)
+
+ @compiler.catalog.resource(:node, "top").should equal(top_resource)
+ end
+
+ # #795 - tag before evaluation.
+ it "should tag the catalog with the resource tags when it is evaluated" do
+ @middle.evaluate(@scope)
+
+ @compiler.catalog.should be_tagged("middle")
+ end
+
+ it "should tag the catalog with the parent class tags when it is evaluated" do
+ @middle.evaluate(@scope)
+
+ @compiler.catalog.should be_tagged("top")
+ end
+end
+
+describe Puppet::Parser::AST::Node, "when evaluating code" do
+ include ASTNodeTesting
+
+ before do
+ @top_resource = stub "top_resource"
+ @top = @parser.newnode("top", :code => @top_resource).shift
+
+ @middle_resource = stub "middle_resource"
+ @middle = @parser.newnode("middle", :parent => "top", :code => @middle_resource).shift
+ end
+
+ it "should evaluate the code referred to by the class" do
+ @top_resource.expects(:safeevaluate)
+
+ resource = @top.evaluate(@scope)
+
+ @top.evaluate_code(resource)
+ end
+
+ it "should evaluate the parent class's code if it has a parent" do
+ @top_resource.expects(:safeevaluate)
+ @middle_resource.expects(:safeevaluate)
+
+ resource = @middle.evaluate(@scope)
+
+ @middle.evaluate_code(resource)
+ end
+
+ it "should not evaluate the parent class's code if the parent has already been evaluated" do
+ @top_resource.stubs(:safeevaluate)
+ resource = @top.evaluate(@scope)
+ @top.evaluate_code(resource)
+
+ @top_resource.expects(:safeevaluate).never
+ @middle_resource.stubs(:safeevaluate)
+ resource = @middle.evaluate(@scope)
+ @middle.evaluate_code(resource)
+ end
+
+ it "should use the parent class's scope as its parent scope" do
+ @top_resource.stubs(:safeevaluate)
+ @middle_resource.stubs(:safeevaluate)
+ resource = @middle.evaluate(@scope)
+ @middle.evaluate_code(resource)
+
+ @compiler.class_scope(@middle).parent.should equal(@compiler.class_scope(@top))
+ end
+
+ it "should add the parent class's namespace to its namespace search path" do
+ @top_resource.stubs(:safeevaluate)
+ @middle_resource.stubs(:safeevaluate)
+ resource = @middle.evaluate(@scope)
+ @middle.evaluate_code(resource)
+
+ @compiler.class_scope(@middle).namespaces.should be_include(@top.namespace)
+ end
+end
diff --git a/spec/unit/parser/collector.rb b/spec/unit/parser/collector.rb
index 9b5eab1f4..e1ceb23ed 100755
--- a/spec/unit/parser/collector.rb
+++ b/spec/unit/parser/collector.rb
@@ -79,8 +79,8 @@ describe Puppet::Parser::Collector, "when collecting specific virtual resources"
@collector.resources = ["File[virtual1]"]
one = mock 'one'
one.stubs(:virtual=)
- @compile.expects(:delete_collection).with(@collector)
- @scope.expects(:compile).returns(@compile)
+ @compiler.expects(:delete_collection).with(@collector)
+ @scope.expects(:compiler).returns(@compiler)
@scope.stubs(:findresource).with("File[virtual1]").returns(one)
@collector.evaluate
end
@@ -89,7 +89,7 @@ describe Puppet::Parser::Collector, "when collecting specific virtual resources"
@collector.resources = ["File[virtual1]"]
one = mock 'one'
one.stubs(:virtual=)
- @compile.expects(:delete_collection).never
+ @compiler.expects(:delete_collection).never
@scope.stubs(:findresource).with("File[virtual1]").returns(nil)
@collector.evaluate
end
@@ -98,8 +98,8 @@ end
describe Puppet::Parser::Collector, "when collecting virtual resources" do
before do
@scope = mock 'scope'
- @compile = mock 'compile'
- @scope.stubs(:compile).returns(@compile)
+ @compiler = mock 'compile'
+ @scope.stubs(:compiler).returns(@compiler)
@resource_type = "Mytype"
@vquery = proc { |res| true }
@@ -113,7 +113,7 @@ describe Puppet::Parser::Collector, "when collecting virtual resources" do
one.stubs(:virtual=)
two.stubs(:virtual=)
- @compile.expects(:resources).returns([one, two])
+ @compiler.expects(:resources).returns([one, two])
@collector.evaluate.should == [one, two]
end
@@ -123,7 +123,7 @@ describe Puppet::Parser::Collector, "when collecting virtual resources" do
one.expects(:virtual=).with(false)
- @compile.expects(:resources).returns([one])
+ @compiler.expects(:resources).returns([one])
@collector.evaluate
end
@@ -135,7 +135,7 @@ describe Puppet::Parser::Collector, "when collecting virtual resources" do
one.stubs(:virtual=)
two.stubs(:virtual=)
- @compile.expects(:resources).returns([one, two])
+ @compiler.expects(:resources).returns([one, two])
@collector.evaluate.should == [one, two]
end
@@ -147,7 +147,7 @@ describe Puppet::Parser::Collector, "when collecting virtual resources" do
one.expects(:virtual=).with(false)
two.expects(:virtual=).with(false)
- @compile.expects(:resources).returns([one, two])
+ @compiler.expects(:resources).returns([one, two])
@collector = Puppet::Parser::Collector.new(@scope, @resource_type, nil, nil, :virtual)
@@ -161,7 +161,7 @@ describe Puppet::Parser::Collector, "when collecting virtual resources" do
one.expects(:virtual=).with(false)
two.expects(:virtual=).never
- @compile.expects(:resources).returns([one, two])
+ @compiler.expects(:resources).returns([one, two])
@collector.evaluate.should == [one]
end
@@ -173,7 +173,7 @@ describe Puppet::Parser::Collector, "when collecting virtual resources" do
one.expects(:virtual=).never
two.expects(:virtual=).never
- @compile.expects(:resources).returns([one, two])
+ @compiler.expects(:resources).returns([one, two])
@collector.evaluate.should be_false
end
@@ -187,7 +187,7 @@ describe Puppet::Parser::Collector, "when collecting virtual resources" do
one.expects(:virtual=).with(false)
two.expects(:virtual=).never
- @compile.expects(:resources).returns([one, two])
+ @compiler.expects(:resources).returns([one, two])
@collector.evaluate.should == [one]
end
@@ -198,8 +198,8 @@ describe Puppet::Parser::Collector, "when collecting exported resources" do
before do
@scope = stub 'scope', :host => "myhost", :debug => nil
- @compile = mock 'compile'
- @scope.stubs(:compile).returns(@compile)
+ @compiler = mock 'compile'
+ @scope.stubs(:compiler).returns(@compiler)
@resource_type = "Mytype"
@equery = "test = true"
@vquery = proc { |r| true }
@@ -218,7 +218,7 @@ describe Puppet::Parser::Collector, "when collecting exported resources" do
end
it "should use initialize the Rails support if ActiveRecord is not connected" do
- @compile.stubs(:resources).returns([])
+ @compiler.stubs(:resources).returns([])
ActiveRecord::Base.expects(:connected?).returns(false)
Puppet::Rails.expects(:init)
Puppet::Rails::Host.stubs(:find_by_name).returns(nil)
@@ -238,7 +238,7 @@ describe Puppet::Parser::Collector, "when collecting exported resources" do
two.stubs(:exported=)
two.stubs(:virtual=)
- @compile.expects(:resources).returns([one, two])
+ @compiler.expects(:resources).returns([one, two])
@collector.evaluate.should == [one, two]
end
@@ -251,7 +251,7 @@ describe Puppet::Parser::Collector, "when collecting exported resources" do
one.stubs(:exported=)
one.expects(:virtual=).with(false)
- @compile.expects(:resources).returns([one])
+ @compiler.expects(:resources).returns([one])
@collector.evaluate.should == [one]
end
@@ -268,10 +268,10 @@ describe Puppet::Parser::Collector, "when collecting exported resources" do
resource.stubs(:exported=)
resource.stubs(:virtual=)
- @compile.stubs(:resources).returns([])
+ @compiler.stubs(:resources).returns([])
@scope.stubs(:findresource).returns(nil)
- @compile.stubs(:store_resource)
+ @compiler.stubs(:add_resource)
@collector.evaluate.should == [resource]
end
@@ -288,10 +288,10 @@ describe Puppet::Parser::Collector, "when collecting exported resources" do
resource.stubs(:exported=)
resource.stubs(:virtual=)
- @compile.stubs(:resources).returns([])
+ @compiler.stubs(:resources).returns([])
@scope.stubs(:findresource).returns(nil)
- @compile.expects(:store_resource).with(@scope, resource)
+ @compiler.expects(:add_resource).with(@scope, resource)
@collector.evaluate.should == [resource]
end
@@ -309,10 +309,10 @@ describe Puppet::Parser::Collector, "when collecting exported resources" do
resource.expects(:exported=).with(false)
resource.stubs(:virtual=)
- @compile.stubs(:resources).returns([])
+ @compiler.stubs(:resources).returns([])
@scope.stubs(:findresource).returns(nil)
- @compile.stubs(:store_resource)
+ @compiler.stubs(:add_resource)
@collector.evaluate
end
@@ -328,10 +328,10 @@ describe Puppet::Parser::Collector, "when collecting exported resources" do
resource = mock 'resource'
- @compile.stubs(:resources).returns([])
+ @compiler.stubs(:resources).returns([])
@scope.stubs(:findresource).returns(inmemory)
- @compile.stubs(:store_resource)
+ @compiler.stubs(:add_resource)
proc { @collector.evaluate }.should raise_error(Puppet::ParseError)
end
@@ -347,10 +347,10 @@ describe Puppet::Parser::Collector, "when collecting exported resources" do
resource = mock 'resource'
- @compile.stubs(:resources).returns([])
+ @compiler.stubs(:resources).returns([])
@scope.stubs(:findresource).returns(inmemory)
- @compile.stubs(:store_resource)
+ @compiler.stubs(:add_resource)
proc { @collector.evaluate }.should_not raise_error(Puppet::ParseError)
end
@@ -361,14 +361,14 @@ describe Puppet::Parser::Collector, "when building its ActiveRecord query for co
before do
@scope = stub 'scope', :host => "myhost", :debug => nil
- @compile = mock 'compile'
- @scope.stubs(:compile).returns(@compile)
+ @compiler = mock 'compile'
+ @scope.stubs(:compiler).returns(@compiler)
@resource_type = "Mytype"
@equery = nil
@vquery = proc { |r| true }
@collector = Puppet::Parser::Collector.new(@scope, @resource_type, @equery, @vquery, :exported)
- @compile.stubs(:resources).returns([])
+ @compiler.stubs(:resources).returns([])
ActiveRecord::Base.stubs(:connected?).returns(false)
diff --git a/spec/unit/parser/compile.rb b/spec/unit/parser/compile.rb
deleted file mode 100755
index 092bece0c..000000000
--- a/spec/unit/parser/compile.rb
+++ /dev/null
@@ -1,281 +0,0 @@
-#!/usr/bin/env ruby
-
-require File.dirname(__FILE__) + '/../../spec_helper'
-
-describe Puppet::Parser::Compile, " when compiling" do
- before do
- @node = stub 'node', :name => 'mynode'
- @parser = stub 'parser', :version => "1.0"
- @compile = Puppet::Parser::Compile.new(@node, @parser)
- end
-
- def compile_methods
- [:set_node_parameters, :evaluate_main, :evaluate_ast_node, :evaluate_node_classes, :evaluate_generators, :fail_on_unevaluated,
- :finish, :store, :extract]
- end
-
- # Stub all of the main compile methods except the ones we're specifically interested in.
- def compile_stub(*except)
- (compile_methods - except).each { |m| @compile.stubs(m) }
- end
-
- it "should set node parameters as variables in the top scope" do
- params = {"a" => "b", "c" => "d"}
- @node.stubs(:parameters).returns(params)
- compile_stub(:set_node_parameters)
- @compile.compile
- @compile.topscope.lookupvar("a").should == "b"
- @compile.topscope.lookupvar("c").should == "d"
- end
-
- it "should evaluate any existing classes named in the node" do
- classes = %w{one two three four}
- main = stub 'main'
- one = stub 'one', :classname => "one"
- three = stub 'three', :classname => "three"
- @node.stubs(:name).returns("whatever")
- @node.stubs(:classes).returns(classes)
-
- @compile.expects(:evaluate_classes).with(classes, @compile.topscope)
- @compile.send :evaluate_node_classes
- end
-
- it "should enable ast_nodes if the parser has any nodes" do
- @parser.expects(:nodes).returns(:one => :yay)
- @compile.ast_nodes?.should be_true
- end
-
- it "should disable ast_nodes if the parser has no nodes" do
- @parser.expects(:nodes).returns({})
- @compile.ast_nodes?.should be_false
- end
-end
-
-describe Puppet::Parser::Compile, " when evaluating classes" do
- before do
- @node = stub 'node', :name => 'mynode'
- @parser = stub 'parser', :version => "1.0"
- @scope = stub 'scope', :source => mock("source")
- @compile = Puppet::Parser::Compile.new(@node, @parser)
- end
-
- it "should fail if there's no source listed for the scope" do
- scope = stub 'scope', :source => nil
- proc { @compile.evaluate_classes(%w{one two}, scope) }.should raise_error(Puppet::DevError)
- end
-
- it "should tag the catalog with the name of each not-found class" do
- @compile.catalog.expects(:tag).with("notfound")
- @scope.expects(:findclass).with("notfound").returns(nil)
- @compile.evaluate_classes(%w{notfound}, @scope)
- end
-end
-
-describe Puppet::Parser::Compile, " when evaluating collections" do
- before do
- @node = stub 'node', :name => 'mynode'
- @parser = stub 'parser', :version => "1.0"
- @scope = stub 'scope', :source => mock("source")
- @compile = Puppet::Parser::Compile.new(@node, @parser)
- end
-
- it "should evaluate each collection" do
- 2.times { |i|
- coll = mock 'coll%s' % i
- @compile.add_collection(coll)
-
- # This is the hard part -- we have to emulate the fact that
- # collections delete themselves if they are done evaluating.
- coll.expects(:evaluate).with do
- @compile.delete_collection(coll)
- end
- }
-
- @compile.class.publicize_methods(:evaluate_collections) { @compile.evaluate_collections }
- end
-end
-
-
-describe Puppet::Parser::Compile, " when evaluating found classes" do
- before do
- @node = stub 'node', :name => 'mynode'
- @parser = stub 'parser', :version => "1.0"
- @scope = stub 'scope', :source => mock("source")
- @compile = Puppet::Parser::Compile.new(@node, @parser)
-
- @class = stub 'class', :classname => "my::class"
- @scope.stubs(:findclass).with("myclass").returns(@class)
-
- @resource = stub 'resource', :ref => 'Class[myclass]'
- end
-
- it "should create a resource for each found class" do
- @compile.catalog.stubs(:tag)
-
- @compile.stubs :store_resource
-
- Puppet::Parser::Resource.expects(:new).with(:scope => @scope, :source => @scope.source, :title => "my::class", :type => "class").returns(@resource)
- @compile.evaluate_classes(%w{myclass}, @scope)
- end
-
- it "should store each created resource in the compile" do
- @compile.catalog.stubs(:tag)
-
- @compile.expects(:store_resource).with(@scope, @resource)
-
- Puppet::Parser::Resource.stubs(:new).returns(@resource)
- @compile.evaluate_classes(%w{myclass}, @scope)
- end
-
- it "should tag the catalog with the fully-qualified name of each found class" do
- @compile.catalog.expects(:tag).with("my::class")
-
- @compile.stubs(:store_resource)
-
- Puppet::Parser::Resource.stubs(:new).returns(@resource)
- @compile.evaluate_classes(%w{myclass}, @scope)
- end
-
- it "should not evaluate the resources created for found classes unless asked" do
- @compile.catalog.stubs(:tag)
-
- @compile.stubs(:store_resource)
- @resource.expects(:evaluate).never
-
- Puppet::Parser::Resource.stubs(:new).returns(@resource)
- @compile.evaluate_classes(%w{myclass}, @scope)
- end
-
- it "should immediately evaluate the resources created for found classes when asked" do
- @compile.catalog.stubs(:tag)
-
- @compile.stubs(:store_resource)
- @resource.expects(:evaluate)
-
- Puppet::Parser::Resource.stubs(:new).returns(@resource)
- @compile.evaluate_classes(%w{myclass}, @scope, false)
- end
-
- it "should skip classes that have already been evaluated" do
- @compile.catalog.stubs(:tag)
-
- @compile.expects(:class_scope).with(@class).returns("something")
-
- @compile.expects(:store_resource).never
-
- @resource.expects(:evaluate).never
-
- Puppet::Parser::Resource.expects(:new).never
- @compile.evaluate_classes(%w{myclass}, @scope, false)
- end
-
- it "should return the list of found classes" do
- @compile.catalog.stubs(:tag)
-
- @compile.stubs(:store_resource)
- @scope.stubs(:findclass).with("notfound").returns(nil)
-
- Puppet::Parser::Resource.stubs(:new).returns(@resource)
- @compile.evaluate_classes(%w{myclass notfound}, @scope).should == %w{myclass}
- end
-end
-
-describe Puppet::Parser::Compile, " when evaluating AST nodes with no AST nodes present" do
- before do
- @node = stub 'node', :name => "foo"
- @parser = stub 'parser', :version => "1.0", :nodes => {}
- @compile = Puppet::Parser::Compile.new(@node, @parser)
- end
-
- it "should do nothing" do
- @compile.expects(:ast_nodes?).returns(false)
- @compile.parser.expects(:nodes).never
- Puppet::Parser::Resource.expects(:new).never
-
- @compile.send(:evaluate_ast_node)
- end
-end
-
-describe Puppet::Parser::Compile, " when evaluating AST nodes with AST nodes present" do
- before do
- @node = stub 'node', :name => "foo"
- @parser = stub 'parser', :version => "1.0", :nodes => {}
- @compile = Puppet::Parser::Compile.new(@node, @parser)
-
- @nodes = mock 'node_hash'
- @compile.stubs(:ast_nodes?).returns(true)
- @compile.parser.stubs(:nodes).returns(@nodes)
-
- # Set some names for our test
- @node.stubs(:names).returns(%w{a b c})
- @nodes.stubs(:[]).with("a").returns(nil)
- @nodes.stubs(:[]).with("b").returns(nil)
- @nodes.stubs(:[]).with("c").returns(nil)
-
- # It should check this last, of course.
- @nodes.stubs(:[]).with("default").returns(nil)
- end
-
- it "should fail if the named node cannot be found" do
- proc { @compile.send(:evaluate_ast_node) }.should raise_error(Puppet::ParseError)
- end
-
- it "should create a resource for the first node class matching the node name" do
- node_class = stub 'node', :classname => "c"
- @nodes.stubs(:[]).with("c").returns(node_class)
-
- node_resource = stub 'node resource', :ref => "Node[c]", :evaluate => nil
- Puppet::Parser::Resource.expects(:new).with { |args| args[:title] == "c" and args[:type] == "node" }.returns(node_resource)
-
- @compile.send(:evaluate_ast_node)
- end
-
- it "should match the default node if no matching node can be found" do
- node_class = stub 'node', :classname => "default"
- @nodes.stubs(:[]).with("default").returns(node_class)
-
- node_resource = stub 'node resource', :ref => "Node[default]", :evaluate => nil
- Puppet::Parser::Resource.expects(:new).with { |args| args[:title] == "default" and args[:type] == "node" }.returns(node_resource)
-
- @compile.send(:evaluate_ast_node)
- end
-
- it "should tag the catalog with the found node name" do
- node_class = stub 'node', :classname => "c"
- @nodes.stubs(:[]).with("c").returns(node_class)
-
- node_resource = stub 'node resource', :ref => "Node[c]", :evaluate => nil
- Puppet::Parser::Resource.stubs(:new).returns(node_resource)
-
- @compile.catalog.expects(:tag).with("c")
- @compile.send(:evaluate_ast_node)
- end
-
- it "should evaluate the node resource immediately rather than using lazy evaluation" do
- node_class = stub 'node', :classname => "c"
- @nodes.stubs(:[]).with("c").returns(node_class)
-
- node_resource = stub 'node resource', :ref => "Node[c]"
- Puppet::Parser::Resource.stubs(:new).returns(node_resource)
-
- node_resource.expects(:evaluate)
-
- @compile.send(:evaluate_ast_node)
- end
-
- it "should set the node's scope as the top scope" do
- node_class = stub 'node', :classname => "c"
- @nodes.stubs(:[]).with("c").returns(node_class)
-
- node_resource = stub 'node resource', :ref => "Node[c]"
- Puppet::Parser::Resource.stubs(:new).returns(node_resource)
-
- # The #evaluate method normally does this.
- @compile.class_set(node_class.classname, :my_node_scope)
- node_resource.stubs(:evaluate)
-
- @compile.send(:evaluate_ast_node)
-
- @compile.topscope.should == :my_node_scope
- end
-end
diff --git a/spec/unit/parser/compiler.rb b/spec/unit/parser/compiler.rb
new file mode 100755
index 000000000..6b821977d
--- /dev/null
+++ b/spec/unit/parser/compiler.rb
@@ -0,0 +1,544 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+module CompilerTesting
+ def setup
+ @node = Puppet::Node.new "testnode"
+ @parser = Puppet::Parser::Parser.new :environment => "development"
+
+ @scope_resource = stub 'scope_resource', :builtin? => true
+ @scope = stub 'scope', :resource => @scope_resource, :source => mock("source")
+ @compiler = Puppet::Parser::Compiler.new(@node, @parser)
+ end
+end
+
+describe Puppet::Parser::Compiler do
+ include CompilerTesting
+
+ it "should be able to store references to class scopes" do
+ lambda { @compiler.class_set "myname", "myscope" }.should_not raise_error
+ end
+
+ it "should be able to retrieve class scopes by name" do
+ @compiler.class_set "myname", "myscope"
+ @compiler.class_scope("myname").should == "myscope"
+ end
+
+ it "should be able to retrieve class scopes by object" do
+ klass = mock 'ast_class'
+ klass.expects(:classname).returns("myname")
+ @compiler.class_set "myname", "myscope"
+ @compiler.class_scope(klass).should == "myscope"
+ end
+
+ it "should be able to return a class list containing all set classes" do
+ @compiler.class_set "", "empty"
+ @compiler.class_set "one", "yep"
+ @compiler.class_set "two", "nope"
+
+ @compiler.classlist.sort.should == %w{one two}.sort
+ end
+end
+
+describe Puppet::Parser::Compiler, " when initializing" do
+ include CompilerTesting
+
+ it "should set its node attribute" do
+ @compiler.node.should equal(@node)
+ end
+
+ it "should set its parser attribute" do
+ @compiler.parser.should equal(@parser)
+ end
+
+ it "should detect when ast nodes are absent" do
+ @compiler.ast_nodes?.should be_false
+ end
+
+ it "should detect when ast nodes are present" do
+ @parser.nodes["testing"] = "yay"
+ @compiler.ast_nodes?.should be_true
+ end
+end
+
+describe Puppet::Parser::Compiler, "when managing scopes" do
+ include CompilerTesting
+
+ it "should create a top scope" do
+ @compiler.topscope.should be_instance_of(Puppet::Parser::Scope)
+ end
+
+ it "should be able to create new scopes" do
+ @compiler.newscope(@compiler.topscope).should be_instance_of(Puppet::Parser::Scope)
+ end
+
+ it "should correctly set the level of newly created scopes" do
+ @compiler.newscope(@compiler.topscope, :level => 5).level.should == 5
+ end
+
+ it "should set the parent scope of the new scope to be the passed-in parent" do
+ scope = mock 'scope'
+ newscope = @compiler.newscope(scope)
+
+ @compiler.parent(newscope).should equal(scope)
+ end
+end
+
+describe Puppet::Parser::Compiler, " when compiling" do
+ include CompilerTesting
+
+ def compile_methods
+ [:set_node_parameters, :evaluate_main, :evaluate_ast_node, :evaluate_node_classes, :evaluate_generators, :fail_on_unevaluated,
+ :finish, :store, :extract]
+ end
+
+ # Stub all of the main compile methods except the ones we're specifically interested in.
+ def compile_stub(*except)
+ (compile_methods - except).each { |m| @compiler.stubs(m) }
+ end
+
+ it "should set node parameters as variables in the top scope" do
+ params = {"a" => "b", "c" => "d"}
+ @node.stubs(:parameters).returns(params)
+ compile_stub(:set_node_parameters)
+ @compiler.compile
+ @compiler.topscope.lookupvar("a").should == "b"
+ @compiler.topscope.lookupvar("c").should == "d"
+ end
+
+ it "should evaluate any existing classes named in the node" do
+ classes = %w{one two three four}
+ main = stub 'main'
+ one = stub 'one', :classname => "one"
+ three = stub 'three', :classname => "three"
+ @node.stubs(:name).returns("whatever")
+ @node.stubs(:classes).returns(classes)
+
+ @compiler.expects(:evaluate_classes).with(classes, @compiler.topscope)
+ @compiler.class.publicize_methods(:evaluate_node_classes) { @compiler.evaluate_node_classes }
+ end
+
+ it "should enable ast_nodes if the parser has any nodes" do
+ @parser.expects(:nodes).returns(:one => :yay)
+ @compiler.ast_nodes?.should be_true
+ end
+
+ it "should disable ast_nodes if the parser has no nodes" do
+ @parser.expects(:nodes).returns({})
+ @compiler.ast_nodes?.should be_false
+ end
+
+ it "should evaluate the main class if it exists" do
+ compile_stub(:evaluate_main)
+ main_class = mock 'main_class'
+ main_class.expects(:evaluate_code).with { |r| r.is_a?(Puppet::Parser::Resource) }
+ @compiler.topscope.expects(:source=).with(main_class)
+ @parser.stubs(:findclass).with("", "").returns(main_class)
+
+ @compiler.compile
+ end
+
+ it "should evaluate any node classes" do
+ @node.stubs(:classes).returns(%w{one two three four})
+ @compiler.expects(:evaluate_classes).with(%w{one two three four}, @compiler.topscope)
+ @compiler.send(:evaluate_node_classes)
+ end
+
+ it "should evaluate all added collections" do
+ colls = []
+ # And when the collections fail to evaluate.
+ colls << mock("coll1-false")
+ colls << mock("coll2-false")
+ colls.each { |c| c.expects(:evaluate).returns(false) }
+
+ @compiler.add_collection(colls[0])
+ @compiler.add_collection(colls[1])
+
+ compile_stub(:evaluate_generators)
+ @compiler.compile
+ end
+
+ it "should ignore builtin resources" do
+ resource = stub 'builtin', :ref => "File[testing]", :builtin? => true
+
+ @compiler.add_resource(@scope, resource)
+ resource.expects(:evaluate).never
+
+ @compiler.compile
+ end
+
+ it "should evaluate unevaluated resources" do
+ resource = stub 'notevaluated', :ref => "File[testing]", :builtin? => false, :evaluated? => false, :virtual? => false
+ @compiler.add_resource(@scope, resource)
+
+ # We have to now mark the resource as evaluated
+ resource.expects(:evaluate).with { |*whatever| resource.stubs(:evaluated?).returns true }
+
+ @compiler.compile
+ end
+
+ it "should not evaluate already-evaluated resources" do
+ resource = stub 'already_evaluated', :ref => "File[testing]", :builtin? => false, :evaluated? => true, :virtual? => false
+ @compiler.add_resource(@scope, resource)
+ resource.expects(:evaluate).never
+
+ @compiler.compile
+ end
+
+ it "should evaluate unevaluated resources created by evaluating other resources" do
+ resource = stub 'notevaluated', :ref => "File[testing]", :builtin? => false, :evaluated? => false, :virtual? => false
+ @compiler.add_resource(@scope, resource)
+
+ resource2 = stub 'created', :ref => "File[other]", :builtin? => false, :evaluated? => false, :virtual? => false
+
+ # We have to now mark the resource as evaluated
+ resource.expects(:evaluate).with { |*whatever| resource.stubs(:evaluated?).returns(true); @compiler.add_resource(@scope, resource2) }
+ resource2.expects(:evaluate).with { |*whatever| resource2.stubs(:evaluated?).returns(true) }
+
+
+ @compiler.compile
+ end
+
+ it "should call finish() on all resources" do
+ # Add a resource that does respond to :finish
+ resource = Puppet::Parser::Resource.new :scope => @scope, :type => "file", :title => "finish"
+ resource.expects(:finish)
+
+ @compiler.add_resource(@scope, resource)
+
+ # And one that does not
+ dnf = stub "dnf", :ref => "File[dnf]"
+
+ @compiler.add_resource(@scope, dnf)
+
+ @compiler.send(:finish)
+ end
+
+ it "should add resources that do not conflict with existing resources" do
+ resource = stub "noconflict", :ref => "File[yay]"
+ @compiler.add_resource(@scope, resource)
+
+ @compiler.catalog.should be_vertex(resource)
+ end
+
+ it "should fail to add resources that conflict with existing resources" do
+ type = stub 'faketype', :isomorphic? => true, :name => "mytype"
+ Puppet::Type.stubs(:type).with("mytype").returns(type)
+
+ resource1 = stub "iso1conflict", :ref => "Mytype[yay]", :type => "mytype", :file => "eh", :line => 0
+ resource2 = stub "iso2conflict", :ref => "Mytype[yay]", :type => "mytype", :file => "eh", :line => 0
+
+ @compiler.add_resource(@scope, resource1)
+ lambda { @compiler.add_resource(@scope, resource2) }.should raise_error(ArgumentError)
+ end
+
+ it "should have a method for looking up resources" do
+ resource = stub 'resource', :ref => "Yay[foo]"
+ @compiler.add_resource(@scope, resource)
+ @compiler.findresource("Yay[foo]").should equal(resource)
+ end
+
+ it "should be able to look resources up by type and title" do
+ resource = stub 'resource', :ref => "Yay[foo]"
+ @compiler.add_resource(@scope, resource)
+ @compiler.findresource("Yay", "foo").should equal(resource)
+ end
+
+ it "should not evaluate virtual defined resources" do
+ resource = stub 'notevaluated', :ref => "File[testing]", :builtin? => false, :evaluated? => false, :virtual? => true
+ @compiler.add_resource(@scope, resource)
+
+ resource.expects(:evaluate).never
+
+ @compiler.compile
+ end
+end
+
+describe Puppet::Parser::Compiler, " when evaluating collections" do
+ include CompilerTesting
+
+ it "should evaluate each collection" do
+ 2.times { |i|
+ coll = mock 'coll%s' % i
+ @compiler.add_collection(coll)
+
+ # This is the hard part -- we have to emulate the fact that
+ # collections delete themselves if they are done evaluating.
+ coll.expects(:evaluate).with do
+ @compiler.delete_collection(coll)
+ end
+ }
+
+ @compiler.class.publicize_methods(:evaluate_collections) { @compiler.evaluate_collections }
+ end
+
+ it "should not fail when there are unevaluated resource collections that do not refer to specific resources" do
+ coll = stub 'coll', :evaluate => false
+ coll.expects(:resources).returns(nil)
+
+ @compiler.add_collection(coll)
+
+ lambda { @compiler.compile }.should_not raise_error
+ end
+
+ it "should fail when there are unevaluated resource collections that refer to a specific resource" do
+ coll = stub 'coll', :evaluate => false
+ coll.expects(:resources).returns(:something)
+
+ @compiler.add_collection(coll)
+
+ lambda { @compiler.compile }.should raise_error(Puppet::ParseError)
+ end
+
+ it "should fail when there are unevaluated resource collections that refer to multiple specific resources" do
+ coll = stub 'coll', :evaluate => false
+ coll.expects(:resources).returns([:one, :two])
+
+ @compiler.add_collection(coll)
+
+ lambda { @compiler.compile }.should raise_error(Puppet::ParseError)
+ end
+end
+
+describe Puppet::Parser::Compiler, "when told to evaluate missing classes" do
+ include CompilerTesting
+
+ it "should fail if there's no source listed for the scope" do
+ scope = stub 'scope', :source => nil
+ proc { @compiler.evaluate_classes(%w{one two}, scope) }.should raise_error(Puppet::DevError)
+ end
+
+ it "should tag the catalog with the name of each not-found class" do
+ @compiler.catalog.expects(:tag).with("notfound")
+ @scope.expects(:findclass).with("notfound").returns(nil)
+ @compiler.evaluate_classes(%w{notfound}, @scope)
+ end
+end
+
+describe Puppet::Parser::Compiler, " when evaluating found classes" do
+ include CompilerTesting
+
+ before do
+ @class = stub 'class', :classname => "my::class"
+ @scope.stubs(:findclass).with("myclass").returns(@class)
+
+ @resource = stub 'resource', :ref => "Class[myclass]"
+ end
+
+ it "should evaluate each class" do
+ @compiler.catalog.stubs(:tag)
+
+ @class.expects(:evaluate).with(@scope)
+
+ @compiler.evaluate_classes(%w{myclass}, @scope)
+ end
+
+ it "should not evaluate the resources created for found classes unless asked" do
+ @compiler.catalog.stubs(:tag)
+
+ @resource.expects(:evaluate).never
+
+ @class.expects(:evaluate).returns(@resource)
+
+ @compiler.evaluate_classes(%w{myclass}, @scope)
+ end
+
+ it "should immediately evaluate the resources created for found classes when asked" do
+ @compiler.catalog.stubs(:tag)
+
+ @resource.expects(:evaluate)
+ @class.expects(:evaluate).returns(@resource)
+
+ @compiler.evaluate_classes(%w{myclass}, @scope, false)
+ end
+
+ it "should skip classes that have already been evaluated" do
+ @compiler.catalog.stubs(:tag)
+
+ @compiler.expects(:class_scope).with(@class).returns("something")
+
+ @compiler.expects(:add_resource).never
+
+ @resource.expects(:evaluate).never
+
+ Puppet::Parser::Resource.expects(:new).never
+ @compiler.evaluate_classes(%w{myclass}, @scope, false)
+ end
+
+ it "should return the list of found classes" do
+ @compiler.catalog.stubs(:tag)
+
+ @compiler.stubs(:add_resource)
+ @scope.stubs(:findclass).with("notfound").returns(nil)
+
+ Puppet::Parser::Resource.stubs(:new).returns(@resource)
+ @class.stubs :evaluate
+ @compiler.evaluate_classes(%w{myclass notfound}, @scope).should == %w{myclass}
+ end
+end
+
+describe Puppet::Parser::Compiler, " when evaluating AST nodes with no AST nodes present" do
+ include CompilerTesting
+
+ it "should do nothing" do
+ @compiler.expects(:ast_nodes?).returns(false)
+ @compiler.parser.expects(:nodes).never
+ Puppet::Parser::Resource.expects(:new).never
+
+ @compiler.send(:evaluate_ast_node)
+ end
+end
+
+describe Puppet::Parser::Compiler, " when evaluating AST nodes with AST nodes present" do
+ include CompilerTesting
+
+ before do
+ @nodes = mock 'node_hash'
+ @compiler.stubs(:ast_nodes?).returns(true)
+ @compiler.parser.stubs(:nodes).returns(@nodes)
+
+ # Set some names for our test
+ @node.stubs(:names).returns(%w{a b c})
+ @nodes.stubs(:[]).with("a").returns(nil)
+ @nodes.stubs(:[]).with("b").returns(nil)
+ @nodes.stubs(:[]).with("c").returns(nil)
+
+ # It should check this last, of course.
+ @nodes.stubs(:[]).with("default").returns(nil)
+ end
+
+ it "should fail if the named node cannot be found" do
+ proc { @compiler.send(:evaluate_ast_node) }.should raise_error(Puppet::ParseError)
+ end
+
+ it "should evaluate the first node class matching the node name" do
+ node_class = stub 'node', :classname => "c", :evaluate_code => nil
+ @nodes.stubs(:[]).with("c").returns(node_class)
+
+ node_resource = stub 'node resource', :ref => "Node[c]", :evaluate => nil
+ node_class.expects(:evaluate).returns(node_resource)
+
+ @compiler.compile
+ end
+
+ it "should match the default node if no matching node can be found" do
+ node_class = stub 'node', :classname => "default", :evaluate_code => nil
+ @nodes.stubs(:[]).with("default").returns(node_class)
+
+ node_resource = stub 'node resource', :ref => "Node[default]", :evaluate => nil
+ node_class.expects(:evaluate).returns(node_resource)
+
+ @compiler.compile
+ end
+
+ it "should evaluate the node resource immediately rather than using lazy evaluation" do
+ node_class = stub 'node', :classname => "c"
+ @nodes.stubs(:[]).with("c").returns(node_class)
+
+ node_resource = stub 'node resource', :ref => "Node[c]"
+ node_class.expects(:evaluate).returns(node_resource)
+
+ node_resource.expects(:evaluate)
+
+ @compiler.send(:evaluate_ast_node)
+ end
+
+ it "should set the node's scope as the top scope" do
+ node_resource = stub 'node resource', :ref => "Node[c]", :evaluate => nil
+ node_class = stub 'node', :classname => "c", :evaluate => node_resource
+
+ @nodes.stubs(:[]).with("c").returns(node_class)
+
+ # The #evaluate method normally does this.
+ scope = stub 'scope', :source => "mysource"
+ @compiler.class_set(node_class.classname, scope)
+ node_resource.stubs(:evaluate)
+
+ @compiler.compile
+
+ @compiler.topscope.should equal(scope)
+ end
+end
+
+describe Puppet::Parser::Compiler, "when storing compiled resources" do
+ include CompilerTesting
+
+ it "should store the resources" do
+ Puppet.features.expects(:rails?).returns(true)
+ Puppet::Rails.expects(:connect)
+
+ @compiler.catalog.expects(:vertices).returns(:resources)
+
+ @compiler.expects(:store_to_active_record).with(@node, :resources)
+ @compiler.send(:store)
+ end
+
+ it "should store to active_record" do
+ @node.expects(:name).returns("myname")
+ Puppet::Rails::Host.stubs(:transaction).yields
+ Puppet::Rails::Host.expects(:store).with(@node, :resources)
+ @compiler.send(:store_to_active_record, @node, :resources)
+ end
+end
+
+describe Puppet::Parser::Compiler, "when managing resource overrides" do
+ include CompilerTesting
+
+ before do
+ @override = stub 'override', :ref => "My[ref]"
+ @resource = stub 'resource', :ref => "My[ref]", :builtin? => true
+ end
+
+ it "should be able to store overrides" do
+ lambda { @compiler.add_override(@override) }.should_not raise_error
+ end
+
+ it "should apply overrides to the appropriate resources" do
+ @compiler.add_resource(@scope, @resource)
+ @resource.expects(:merge).with(@override)
+
+ @compiler.add_override(@override)
+
+ @compiler.compile
+ end
+
+ it "should accept overrides before the related resource has been created" do
+ @resource.expects(:merge).with(@override)
+
+ # First store the override
+ @compiler.add_override(@override)
+
+ # Then the resource
+ @compiler.add_resource(@scope, @resource)
+
+ # And compile, so they get resolved
+ @compiler.compile
+ end
+
+ it "should fail if the compile is finished and resource overrides have not been applied" do
+ @compiler.add_override(@override)
+
+ lambda { @compiler.compile }.should raise_error(Puppet::ParseError)
+ end
+end
+
+# #620 - Nodes and classes should conflict, else classes don't get evaluated
+describe Puppet::Parser::Compiler, "when evaluating nodes and classes with the same name (#620)" do
+ include CompilerTesting
+
+ before do
+ @node = stub :nodescope? => true
+ @class = stub :nodescope? => false
+ end
+
+ it "should fail if a node already exists with the same name as the class being evaluated" do
+ @compiler.class_set("one", @node)
+ lambda { @compiler.class_set("one", @class) }.should raise_error(Puppet::ParseError)
+ end
+
+ it "should fail if a class already exists with the same name as the node being evaluated" do
+ @compiler.class_set("one", @class)
+ lambda { @compiler.class_set("one", @node) }.should raise_error(Puppet::ParseError)
+ end
+end
diff --git a/spec/unit/parser/interpreter.rb b/spec/unit/parser/interpreter.rb
index ed30ced93..7885f0542 100755
--- a/spec/unit/parser/interpreter.rb
+++ b/spec/unit/parser/interpreter.rb
@@ -115,14 +115,14 @@ describe Puppet::Parser::Interpreter, " when compiling catalog" do
before do
@interp = Puppet::Parser::Interpreter.new
@node = stub 'node', :environment => :myenv
- @compile = mock 'compile'
+ @compiler = mock 'compile'
@parser = mock 'parser'
end
it "should create a compile with the node and parser" do
- @compile.expects(:compile).returns(:config)
+ @compiler.expects(:compile).returns(:config)
@interp.expects(:parser).with(:myenv).returns(@parser)
- Puppet::Parser::Compile.expects(:new).with(@node, @parser).returns(@compile)
+ Puppet::Parser::Compiler.expects(:new).with(@node, @parser).returns(@compiler)
@interp.compile(@node)
end
diff --git a/spec/unit/parser/resource.rb b/spec/unit/parser/resource.rb
index 319d8f7d8..a5a49e2a6 100755
--- a/spec/unit/parser/resource.rb
+++ b/spec/unit/parser/resource.rb
@@ -15,26 +15,26 @@ describe Puppet::Parser::Resource, " when evaluating" do
@class = @parser.newclass "myclass"
@nodedef = @parser.newnode("mynode")[0]
@node = Puppet::Node.new("yaynode")
- @compile = Puppet::Parser::Compile.new(@node, @parser)
- @scope = @compile.topscope
+ @compiler = Puppet::Parser::Compiler.new(@node, @parser)
+ @scope = @compiler.topscope
end
it "should evaluate the associated AST definition" do
res = @type.new(:type => "mydefine", :title => "whatever", :scope => @scope, :source => @source)
- @definition.expects(:evaluate).with(:scope => @scope, :resource => res)
+ @definition.expects(:evaluate_code).with(res)
res.evaluate
end
it "should evaluate the associated AST class" do
res = @type.new(:type => "class", :title => "myclass", :scope => @scope, :source => @source)
- @class.expects(:evaluate).with(:scope => @scope, :resource => res)
+ @class.expects(:evaluate_code).with(res)
res.evaluate
end
it "should evaluate the associated AST node" do
res = @type.new(:type => "node", :title => "mynode", :scope => @scope, :source => @source)
- @nodedef.expects(:evaluate).with(:scope => @scope, :resource => res)
+ @nodedef.expects(:evaluate_code).with(res)
res.evaluate
end
end
@@ -47,8 +47,8 @@ describe Puppet::Parser::Resource, " when finishing" do
@class = @parser.newclass "myclass"
@nodedef = @parser.newnode("mynode")[0]
@node = Puppet::Node.new("yaynode")
- @compile = Puppet::Parser::Compile.new(@node, @parser)
- @scope = @compile.topscope
+ @compiler = Puppet::Parser::Compiler.new(@node, @parser)
+ @scope = @compiler.topscope
@resource = Puppet::Parser::Resource.new(:type => "mydefine", :title => "whatever", :scope => @scope, :source => @source)
end
diff --git a/spec/unit/parser/resource/reference.rb b/spec/unit/parser/resource/reference.rb
index e7385f796..147f772d1 100755
--- a/spec/unit/parser/resource/reference.rb
+++ b/spec/unit/parser/resource/reference.rb
@@ -52,23 +52,23 @@ describe Puppet::Parser::Resource::Reference, " when modeling defined types" do
@nodedef = @parser.newnode("mynode")[0]
@node = Puppet::Node.new("yaynode")
- @compile = Puppet::Parser::Compile.new(@node, @parser)
+ @compiler = Puppet::Parser::Compiler.new(@node, @parser)
end
it "should be able to find defined types" do
- ref = @type.new(:type => "mydefine", :title => "/tmp/yay", :scope => @compile.topscope)
+ ref = @type.new(:type => "mydefine", :title => "/tmp/yay", :scope => @compiler.topscope)
ref.builtin?.should be_false
ref.definedtype.should equal(@definition)
end
it "should be able to find classes" do
- ref = @type.new(:type => "class", :title => "myclass", :scope => @compile.topscope)
+ ref = @type.new(:type => "class", :title => "myclass", :scope => @compiler.topscope)
ref.builtin?.should be_false
ref.definedtype.should equal(@class)
end
it "should be able to find nodes" do
- ref = @type.new(:type => "node", :title => "mynode", :scope => @compile.topscope)
+ ref = @type.new(:type => "node", :title => "mynode", :scope => @compiler.topscope)
ref.builtin?.should be_false
ref.definedtype.object_id.should == @nodedef.object_id
end
diff --git a/spec/unit/ral/type.rb b/spec/unit/ral/type.rb
index 25f8cbaf1..5980167d6 100755
--- a/spec/unit/ral/type.rb
+++ b/spec/unit/ral/type.rb
@@ -11,8 +11,8 @@ describe Puppet::Type, " when in a configuration" do
@catalog.add_resource @container
@catalog.add_resource @one
@catalog.add_resource @two
- @catalog.add_edge! @container, @one
- @catalog.add_edge! @container, @two
+ @catalog.add_edge @container, @one
+ @catalog.add_edge @container, @two
end
it "should have no parent if there is no in edge" do
diff --git a/spec/unit/simple_graph.rb b/spec/unit/simple_graph.rb
index 061a07458..c8fe14cf3 100755
--- a/spec/unit/simple_graph.rb
+++ b/spec/unit/simple_graph.rb
@@ -9,8 +9,8 @@ require 'puppet/simple_graph'
describe Puppet::SimpleGraph do
it "should return the number of its vertices as its length" do
@graph = Puppet::SimpleGraph.new
- @graph.add_vertex!("one")
- @graph.add_vertex!("two")
+ @graph.add_vertex("one")
+ @graph.add_vertex("two")
@graph.size.should == 2
end
@@ -20,13 +20,13 @@ describe Puppet::SimpleGraph do
it "should provide a method for reversing the graph" do
@graph = Puppet::SimpleGraph.new
- @graph.add_edge!(:one, :two)
+ @graph.add_edge(:one, :two)
@graph.reversal.edge?(:two, :one).should be_true
end
it "should be able to produce a dot graph" do
@graph = Puppet::SimpleGraph.new
- @graph.add_edge!(:one, :two)
+ @graph.add_edge(:one, :two)
proc { @graph.to_dot_graph }.should_not raise_error
end
@@ -38,17 +38,17 @@ describe Puppet::SimpleGraph, " when managing vertices" do
end
it "should provide a method to add a vertex" do
- @graph.add_vertex!(:test)
+ @graph.add_vertex(:test)
@graph.vertex?(:test).should be_true
end
it "should ignore already-present vertices when asked to add a vertex" do
- @graph.add_vertex!(:test)
- proc { @graph.add_vertex!(:test) }.should_not raise_error
+ @graph.add_vertex(:test)
+ proc { @graph.add_vertex(:test) }.should_not raise_error
end
it "should return true when asked if a vertex is present" do
- @graph.add_vertex!(:test)
+ @graph.add_vertex(:test)
@graph.vertex?(:test).should be_true
end
@@ -57,15 +57,15 @@ describe Puppet::SimpleGraph, " when managing vertices" do
end
it "should return all set vertices when asked" do
- @graph.add_vertex!(:one)
- @graph.add_vertex!(:two)
+ @graph.add_vertex(:one)
+ @graph.add_vertex(:two)
@graph.vertices.length.should == 2
@graph.vertices.should include(:one)
@graph.vertices.should include(:two)
end
it "should remove a given vertex when asked" do
- @graph.add_vertex!(:one)
+ @graph.add_vertex(:one)
@graph.remove_vertex!(:one)
@graph.vertex?(:one).should be_false
end
@@ -86,49 +86,49 @@ describe Puppet::SimpleGraph, " when managing edges" do
it "should provide a method to add an edge as an instance of the edge class" do
edge = Puppet::Relationship.new(:one, :two)
- @graph.add_edge!(edge)
+ @graph.add_edge(edge)
@graph.edge?(:one, :two).should be_true
end
it "should provide a method to add an edge by specifying the two vertices" do
- @graph.add_edge!(:one, :two)
+ @graph.add_edge(:one, :two)
@graph.edge?(:one, :two).should be_true
end
it "should provide a method to add an edge by specifying the two vertices and a label" do
- @graph.add_edge!(:one, :two, :stuff => :awesome)
+ @graph.add_edge(:one, :two, :stuff => :awesome)
@graph.edge?(:one, :two).should be_true
end
it "should provide a method for retrieving an edge label" do
edge = Puppet::Relationship.new(:one, :two, :stuff => :awesome)
- @graph.add_edge!(edge)
+ @graph.add_edge(edge)
@graph.edge_label(:one, :two).should == {:stuff => :awesome}
end
it "should provide a method for retrieving an edge" do
edge = Puppet::Relationship.new(:one, :two)
- @graph.add_edge!(edge)
+ @graph.add_edge(edge)
@graph.edge(:one, :two).should equal(edge)
end
it "should add the edge source as a vertex if it is not already" do
edge = Puppet::Relationship.new(:one, :two)
- @graph.add_edge!(edge)
+ @graph.add_edge(edge)
@graph.vertex?(:one).should be_true
end
it "should add the edge target as a vertex if it is not already" do
edge = Puppet::Relationship.new(:one, :two)
- @graph.add_edge!(edge)
+ @graph.add_edge(edge)
@graph.vertex?(:two).should be_true
end
it "should return all edges as edge instances when asked" do
one = Puppet::Relationship.new(:one, :two)
two = Puppet::Relationship.new(:two, :three)
- @graph.add_edge!(one)
- @graph.add_edge!(two)
+ @graph.add_edge(one)
+ @graph.add_edge(two)
edges = @graph.edges
edges.length.should == 2
edges.should include(one)
@@ -137,7 +137,7 @@ describe Puppet::SimpleGraph, " when managing edges" do
it "should remove an edge when asked" do
edge = Puppet::Relationship.new(:one, :two)
- @graph.add_edge!(edge)
+ @graph.add_edge(edge)
@graph.remove_edge!(edge)
@graph.edge?(edge.source, edge.target).should be_false
end
@@ -145,8 +145,8 @@ describe Puppet::SimpleGraph, " when managing edges" do
it "should remove all related edges when a vertex is removed" do
one = Puppet::Relationship.new(:one, :two)
two = Puppet::Relationship.new(:two, :three)
- @graph.add_edge!(one)
- @graph.add_edge!(two)
+ @graph.add_edge(one)
+ @graph.add_edge(two)
@graph.remove_vertex!(:two)
@graph.edge?(:one, :two).should be_false
@graph.edge?(:two, :three).should be_false
@@ -160,9 +160,9 @@ describe Puppet::SimpleGraph, " when finding adjacent vertices" do
@one_two = Puppet::Relationship.new(:one, :two)
@two_three = Puppet::Relationship.new(:two, :three)
@one_three = Puppet::Relationship.new(:one, :three)
- @graph.add_edge!(@one_two)
- @graph.add_edge!(@one_three)
- @graph.add_edge!(@two_three)
+ @graph.add_edge(@one_two)
+ @graph.add_edge(@one_three)
+ @graph.add_edge(@two_three)
end
it "should return adjacent vertices" do
@@ -193,8 +193,8 @@ describe Puppet::SimpleGraph, " when clearing" do
@graph = Puppet::SimpleGraph.new
one = Puppet::Relationship.new(:one, :two)
two = Puppet::Relationship.new(:two, :three)
- @graph.add_edge!(one)
- @graph.add_edge!(two)
+ @graph.add_edge(one)
+ @graph.add_edge(two)
@graph.clear
end
@@ -214,18 +214,18 @@ describe Puppet::SimpleGraph, " when reversing graphs" do
end
it "should provide a method for reversing the graph" do
- @graph.add_edge!(:one, :two)
+ @graph.add_edge(:one, :two)
@graph.reversal.edge?(:two, :one).should be_true
end
it "should add all vertices to the reversed graph" do
- @graph.add_edge!(:one, :two)
+ @graph.add_edge(:one, :two)
@graph.vertex?(:one).should be_true
@graph.vertex?(:two).should be_true
end
it "should retain labels on edges" do
- @graph.add_edge!(:one, :two, :stuff => :awesome)
+ @graph.add_edge(:one, :two, :stuff => :awesome)
edge = @graph.reversal.edge(:two, :one)
edge.label.should == {:stuff => :awesome}
end
@@ -238,7 +238,7 @@ describe Puppet::SimpleGraph, " when sorting the graph" do
def add_edges(hash)
hash.each do |a,b|
- @graph.add_edge!(a, b)
+ @graph.add_edge(a, b)
end
end
diff --git a/spec/unit/util/constant_inflector.rb b/spec/unit/util/constant_inflector.rb
new file mode 100755
index 000000000..5112e730f
--- /dev/null
+++ b/spec/unit/util/constant_inflector.rb
@@ -0,0 +1,70 @@
+#!/usr/bin/env ruby
+#
+# Created by Luke Kanies on 2008-02-12.
+# Copyright (c) 2007. All rights reserved.
+
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+require 'puppet/util/constant_inflector'
+
+describe Puppet::Util::ConstantInflector, "when converting file names to constants" do
+ before do
+ @inflector = Object.new
+ @inflector.extend(Puppet::Util::ConstantInflector)
+ end
+
+ it "should capitalize terms" do
+ @inflector.file2constant("file").should == "File"
+ end
+
+ it "should switch all '/' characters to double colons" do
+ @inflector.file2constant("file/other").should == "File::Other"
+ end
+
+ it "should remove underscores and capitalize the proceeding letter" do
+ @inflector.file2constant("file_other").should == "FileOther"
+ end
+
+ it "should correctly replace as many underscores as exist in the file name" do
+ @inflector.file2constant("two_under_scores/with_some_more_underscores").should == "TwoUnderScores::WithSomeMoreUnderscores"
+ end
+
+ it "should collapse multiple underscores" do
+ @inflector.file2constant("many___scores").should == "ManyScores"
+ end
+
+ it "should correctly handle file names deeper than two directories" do
+ @inflector.file2constant("one_two/three_four/five_six").should == "OneTwo::ThreeFour::FiveSix"
+ end
+end
+
+describe Puppet::Util::ConstantInflector, "when converting constnats to file names" do
+ before do
+ @inflector = Object.new
+ @inflector.extend(Puppet::Util::ConstantInflector)
+ end
+
+ it "should convert them to a string if necessary" do
+ @inflector.constant2file(Puppet::Util::ConstantInflector).should be_instance_of(String)
+ end
+
+ it "should accept string inputs" do
+ @inflector.constant2file("Puppet::Util::ConstantInflector").should be_instance_of(String)
+ end
+
+ it "should downcase all terms" do
+ @inflector.constant2file("Puppet").should == "puppet"
+ end
+
+ it "should convert '::' to '/'" do
+ @inflector.constant2file("Puppet::Util::Constant").should == "puppet/util/constant"
+ end
+
+ it "should convert mid-word capitalization to an underscore" do
+ @inflector.constant2file("OneTwo::ThreeFour").should == "one_two/three_four"
+ end
+
+ it "should correctly handle constants with more than two parts" do
+ @inflector.constant2file("OneTwoThree::FourFiveSixSeven").should == "one_two_three/four_five_six_seven"
+ end
+end
diff --git a/spec/unit/util/tagging.rb b/spec/unit/util/tagging.rb
index 51b69a63c..91cbb213d 100755
--- a/spec/unit/util/tagging.rb
+++ b/spec/unit/util/tagging.rb
@@ -76,4 +76,13 @@ describe Puppet::Util::Tagging, "when adding tags" do
@tagger.tags.should be_include("two")
@tagger.tags.should be_include("three")
end
+
+ it "should indicate when the object is tagged with a provided tag" do
+ @tagger.tag("one")
+ @tagger.should be_tagged("one")
+ end
+
+ it "should indicate when the object is not tagged with a provided tag" do
+ @tagger.should_not be_tagged("one")
+ end
end