diff options
Diffstat (limited to 'spec/unit/parser')
| -rwxr-xr-x | spec/unit/parser/ast/resource.rb | 29 | ||||
| -rwxr-xr-x | spec/unit/parser/ast/resource_reference.rb | 51 | ||||
| -rwxr-xr-x | spec/unit/parser/collector.rb | 3 | ||||
| -rwxr-xr-x | spec/unit/parser/compiler.rb | 11 | ||||
| -rwxr-xr-x | spec/unit/parser/functions/defined.rb | 50 | ||||
| -rwxr-xr-x | spec/unit/parser/functions/require.rb | 2 | ||||
| -rwxr-xr-x | spec/unit/parser/functions/tag.rb | 24 | ||||
| -rwxr-xr-x | spec/unit/parser/parser.rb | 16 | ||||
| -rwxr-xr-x | spec/unit/parser/resource.rb | 143 | ||||
| -rwxr-xr-x | spec/unit/parser/resource/reference.rb | 134 | ||||
| -rwxr-xr-x | spec/unit/parser/scope.rb | 157 |
11 files changed, 378 insertions, 242 deletions
diff --git a/spec/unit/parser/ast/resource.rb b/spec/unit/parser/ast/resource.rb index b257cb116..391f4c770 100755 --- a/spec/unit/parser/ast/resource.rb +++ b/spec/unit/parser/ast/resource.rb @@ -9,16 +9,15 @@ describe Puppet::Parser::AST::Resource do @title = stub_everything 'title' @compiler = stub_everything 'compiler' @scope = Puppet::Parser::Scope.new(:compiler => @compiler) - @param1 = stub_everything 'parameter', :is_a? => true @scope.stubs(:resource).returns(stub_everything) - @params = ast::ASTArray.new( :children => [@param1]) - @resource = ast::Resource.new(:title => @title, :type => "Resource", :params => @params ) + @resource = ast::Resource.new(:title => @title, :type => "Resource", :params => ast::ASTArray.new(:children => []) ) @resource.stubs(:qualified_type).returns("Resource") - Puppet::Parser::Resource.stubs(:new).returns(stub_everything) end it "should evaluate all its parameters" do - @param1.expects(:safeevaluate).with(@scope) + param = stub 'param' + param.expects(:safeevaluate).with(@scope).returns Puppet::Parser::Resource::Param.new(:name => "myparam", :value => "myvalue", :source => stub("source")) + @resource.stubs(:params).returns [param] @resource.evaluate(@scope) end @@ -49,10 +48,10 @@ describe Puppet::Parser::AST::Resource do title_array.stubs(:flatten).returns([@title]) titles.stubs(:safeevaluate).with(@scope).returns(title_array) - Puppet::Parser::Resource.expects(:new).with { |hash| hash[:title] == @title } - @resource.title = titles - @resource.evaluate(@scope) + result = @resource.evaluate(@scope) + result[0].should be_instance_of(Puppet::Parser::Resource) + result[0].title.should == @title end it "should handover resources to the compiler" do @@ -77,18 +76,18 @@ describe Puppet::Parser::AST::Resource do title_array.stubs(:flatten).returns([@title]) titles.stubs(:safeevaluate).with(@scope).returns(title_array) - Puppet::Parser::Resource.stubs(:new).returns(resource) - @compiler.stubs(:add_resource).with(resource) + @compiler.stubs(:add_resource) @resource.title = titles - @resource.evaluate(@scope).should == [resource] + @resource.evaluate(@scope)[0].should be_instance_of(Puppet::Parser::Resource) end it "should generate virtual resources if it is virtual" do @resource.virtual = true - Puppet::Parser::Resource.expects(:new).with { |hash| hash[:virtual] == true } + result = @resource.evaluate(@scope) + result[0].should be_virtual @resource.evaluate(@scope) end @@ -96,8 +95,8 @@ describe Puppet::Parser::AST::Resource do it "should generate virtual and exported resources if it is exported" do @resource.exported = true - Puppet::Parser::Resource.expects(:new).with { |hash| hash[:virtual] == true and hash[:exported] == true } - - @resource.evaluate(@scope) + result = @resource.evaluate(@scope) + result[0].should be_virtual + result[0].should be_exported end end diff --git a/spec/unit/parser/ast/resource_reference.rb b/spec/unit/parser/ast/resource_reference.rb index 10d9678c3..ee42694b9 100755 --- a/spec/unit/parser/ast/resource_reference.rb +++ b/spec/unit/parser/ast/resource_reference.rb @@ -10,54 +10,31 @@ describe Puppet::Parser::AST::ResourceReference do @scope = Puppet::Parser::Scope.new() end - def newref(title, type) + def newref(type, title) title = stub 'title', :safeevaluate => title ref = Puppet::Parser::AST::ResourceReference.new(:type => type, :title => title) end - it "should evaluate correctly reference to builtin types" do - newref("/tmp/yay", "File").evaluate(@scope).to_s.should == "File[/tmp/yay]" + it "should correctly produce reference strings" do + newref("File", "/tmp/yay").evaluate(@scope).to_s.should == "File[/tmp/yay]" end - %{ "one::two" "one-two"}.each do |type| - it "should evaluate correctly reference to define" do - klass = stub 'klass', :title => "three", :name => type - @scope.stubs(:find_definition).returns(klass) - - newref("three", type).evaluate(@scope).to_ref.should == Puppet::Parser::Resource::Reference.new( :type => type, :title => "three" ).to_ref - end + it "should produce a single resource when the title evaluates to a string" do + newref("File", "/tmp/yay").evaluate(@scope).should == Puppet::Resource.new("file", "/tmp/yay") end - it "should be able to call qualified_class" do - klass = stub 'klass', :title => "three", :name => "one" - @scope.expects(:find_hostclass).with("one").returns(klass) - newref("three","class").qualified_class(@scope,"one").should == "one" - end - - it "should be able to find qualified classes when evaluating" do - klass = stub 'klass', :title => "one", :name => "one" - @scope.stubs(:find_hostclass).returns(klass) - - evaled = newref("one", "class").evaluate(@scope) - evaled.type.should == "Class" - evaled.title.should == "one" - end - - it "should return an array of reference if given an array of titles" do + it "should return an array of resources if given an array of titles" do titles = mock 'titles', :safeevaluate => ["title1","title2"] - ref = ast::ResourceReference.new( :title => titles, :type => "Resource" ) - ref.stubs(:qualified_type).with(@scope).returns("Resource") - - ref.evaluate(@scope).should have(2).elements + ref = ast::ResourceReference.new( :title => titles, :type => "File" ) + ref.evaluate(@scope).should == [ + Puppet::Resource.new("file", "title1"), + Puppet::Resource.new("file", "title2") + ] end - it "should qualify class of all titles for Class resource references" do - titles = mock 'titles', :safeevaluate => ["title1","title2"] - ref = ast::ResourceReference.new( :title => titles, :type => "Class" ) - ref.expects(:qualified_class).with(@scope,"title1").returns("class") - ref.expects(:qualified_class).with(@scope,"title2").returns("class") - - ref.evaluate(@scope) + it "should pass its scope's namespaces to all created resource references" do + @scope.add_namespace "foo" + newref("File", "/tmp/yay").evaluate(@scope).namespaces.should == ["foo"] end it "should return a correct representation when converting to string" do diff --git a/spec/unit/parser/collector.rb b/spec/unit/parser/collector.rb index 7f88bf754..9c2d722e5 100755 --- a/spec/unit/parser/collector.rb +++ b/spec/unit/parser/collector.rb @@ -52,11 +52,10 @@ end describe Puppet::Parser::Collector, "when collecting specific virtual resources" do before do @scope = mock 'scope' - @resource_type = mock 'resource_type' @vquery = mock 'vquery' @equery = mock 'equery' - @collector = Puppet::Parser::Collector.new(@scope, @resource_type, @equery, @vquery, :virtual) + @collector = Puppet::Parser::Collector.new(@scope, "resource_type", @equery, @vquery, :virtual) end it "should not fail when it does not find any resources to collect" do diff --git a/spec/unit/parser/compiler.rb b/spec/unit/parser/compiler.rb index 333046c77..6fd4d1fb5 100755 --- a/spec/unit/parser/compiler.rb +++ b/spec/unit/parser/compiler.rb @@ -174,10 +174,9 @@ describe Puppet::Parser::Compiler do it "should evaluate the main class if it exists" do compile_stub(:evaluate_main) - main_class = mock 'main_class' + main_class = @known_resource_types.add Puppet::Resource::Type.new(:hostclass, "") main_class.expects(:evaluate_code).with { |r| r.is_a?(Puppet::Parser::Resource) } @compiler.topscope.expects(:source=).with(main_class) - @known_resource_types.stubs(:find_hostclass).with("", "").returns(main_class) @compiler.compile end @@ -185,7 +184,7 @@ describe Puppet::Parser::Compiler do it "should create a new, empty 'main' if no main class exists" do compile_stub(:evaluate_main) @compiler.compile - @known_resource_types.find_hostclass("", "").should be_instance_of(Puppet::Resource::Type) + @known_resource_types.find_hostclass([""], "").should be_instance_of(Puppet::Resource::Type) end it "should evaluate any node classes" do @@ -252,7 +251,7 @@ describe Puppet::Parser::Compiler do 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 = Puppet::Parser::Resource.new "file", "finish", :scope => @scope resource.expects(:finish) @compiler.add_resource(@scope, resource) @@ -268,12 +267,12 @@ describe Puppet::Parser::Compiler do it "should call finish() in add_resource order" do resources = sequence('resources') - resource1 = Puppet::Parser::Resource.new :scope => @scope, :type => "file", :title => "finish1" + resource1 = Puppet::Parser::Resource.new "file", "finish1", :scope => @scope resource1.expects(:finish).in_sequence(resources) @compiler.add_resource(@scope, resource1) - resource2 = Puppet::Parser::Resource.new :scope => @scope, :type => "file", :title => "finish2" + resource2 = Puppet::Parser::Resource.new "file", "finish2", :scope => @scope resource2.expects(:finish).in_sequence(resources) @compiler.add_resource(@scope, resource2) diff --git a/spec/unit/parser/functions/defined.rb b/spec/unit/parser/functions/defined.rb new file mode 100755 index 000000000..0da8c4a31 --- /dev/null +++ b/spec/unit/parser/functions/defined.rb @@ -0,0 +1,50 @@ +#!/usr/bin/env ruby + +require File.dirname(__FILE__) + '/../../../spec_helper' + +describe "the 'defined' function" do + + before :each do + @scope = Puppet::Parser::Scope.new() + @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("foo")) + @scope.compiler = @compiler + end + + it "should exist" do + Puppet::Parser::Functions.function("defined").should == "function_defined" + end + + it "should be true when the name is defined as a class" do + @scope.known_resource_types.add Puppet::Resource::Type.new(:hostclass, "yayness") + @scope.function_defined("yayness").should be_true + end + + it "should be true when the name is defined as a definition" do + @scope.known_resource_types.add Puppet::Resource::Type.new(:definition, "yayness") + @scope.function_defined("yayness").should be_true + end + + it "should be true when the name is defined as a builtin type" do + @scope.function_defined("file").should be_true + end + + + it "should be true when any of the provided names are defined" do + @scope.known_resource_types.add Puppet::Resource::Type.new(:definition, "yayness") + @scope.function_defined(["meh", "yayness", "booness"]).should be_true + end + + it "should be false when a single given name is not defined" do + @scope.function_defined("meh").should be_false + end + + it "should be false when none of the names are defined" do + @scope.function_defined(["meh", "yayness", "booness"]).should be_false + end + + it "should be true when a resource reference is provided and the resource is in the catalog" do + resource = Puppet::Resource.new("file", "/my/file") + @compiler.add_resource(@scope, resource) + @scope.function_defined(resource).should be_true + end +end diff --git a/spec/unit/parser/functions/require.rb b/spec/unit/parser/functions/require.rb index 924990a5d..1d9ce931c 100755 --- a/spec/unit/parser/functions/require.rb +++ b/spec/unit/parser/functions/require.rb @@ -28,7 +28,7 @@ describe "the require function" do end it "should set the 'require' prarameter on the resource to a resource reference" do - @resource.expects(:set_parameter).with { |name, value| name == :require and value[0].is_a?(Puppet::Parser::Resource::Reference) } + @resource.expects(:set_parameter).with { |name, value| name == :require and value[0].is_a?(Puppet::Resource) } @scope.stubs(:function_include) @scope.function_require("myclass") end diff --git a/spec/unit/parser/functions/tag.rb b/spec/unit/parser/functions/tag.rb new file mode 100755 index 000000000..5fb467e59 --- /dev/null +++ b/spec/unit/parser/functions/tag.rb @@ -0,0 +1,24 @@ +#! /usr/bin/env ruby + +require File.dirname(__FILE__) + '/../../../spec_helper' + +describe "the 'tag' function" do + + before :each do + @scope = Puppet::Parser::Scope.new() + end + + it "should exist" do + Puppet::Parser::Functions.function(:tag).should == "function_tag" + end + + it "should tag the resource with any provided tags" do + resource = Puppet::Parser::Resource.new(:file, "/file", :scope => @scope) + @scope.expects(:resource).returns resource + + @scope.function_tag ["one", "two"] + + resource.should be_tagged("one") + resource.should be_tagged("two") + end +end diff --git a/spec/unit/parser/parser.rb b/spec/unit/parser/parser.rb index 84749c3fb..8cc29c9b8 100755 --- a/spec/unit/parser/parser.rb +++ b/spec/unit/parser/parser.rb @@ -429,6 +429,12 @@ describe Puppet::Parser do @krt.hostclass("foobar").parent.should == "yayness" end + it "should correctly set the parent class for multiple classes at a time" do + @parser.parse("class foobar inherits yayness {}\nclass boo inherits bar {}") + @krt.hostclass("foobar").parent.should == "yayness" + @krt.hostclass("boo").parent.should == "bar" + end + it "should define the code when some is provided" do @parser.parse("class foobar { $var = val }") @krt.hostclass("foobar").code.should_not be_nil @@ -451,5 +457,15 @@ describe Puppet::Parser do @krt.add(Puppet::Resource::Type.new(:hostclass, "foobar", :arguments => {"biz" => nil})) lambda { @parser.parse("class { foobar: biz => stuff }") }.should_not raise_error end + + it "should correctly mark exported resources as exported" do + @parser.parse("@@file { '/file': }") + @krt.hostclass("").code[0].exported.should be_true + end + + it "should correctly mark virtual resources as virtual" do + @parser.parse("@file { '/file': }") + @krt.hostclass("").code[0].virtual.should be_true + end end end diff --git a/spec/unit/parser/resource.rb b/spec/unit/parser/resource.rb index bb3001c8e..0c70c817e 100755 --- a/spec/unit/parser/resource.rb +++ b/spec/unit/parser/resource.rb @@ -19,7 +19,7 @@ describe Puppet::Parser::Resource do args[:source] ||= "source" args[:scope] ||= stub('scope', :source => mock('source')) - {:type => "resource", :title => "testing", :source => "source", :scope => "scope"}.each do |param, value| + {:source => "source", :scope => "scope"}.each do |param, value| args[param] ||= value end @@ -30,7 +30,7 @@ describe Puppet::Parser::Resource do args[:params] = paramify(args[:source], params) end - Puppet::Parser::Resource.new(args) + Puppet::Parser::Resource.new("resource", "testing", args) end def param(name, value, source) @@ -61,19 +61,31 @@ describe Puppet::Parser::Resource do Puppet::Parser::Resource.ancestors.should be_include(Puppet::FileCollection::Lookup) end + it "should get its environment from its scope" do + scope = stub 'scope', :source => stub("source") + scope.expects(:environment).returns "foo" + Puppet::Parser::Resource.new("file", "whatever", :scope => scope).environment.should == "foo" + end + + it "should get its namespaces from its scope" do + scope = stub 'scope', :source => stub("source") + scope.expects(:namespaces).returns %w{one two} + Puppet::Parser::Resource.new("file", "whatever", :scope => scope).namespaces.should == %w{one two} + end + it "should be isomorphic if it is builtin and models an isomorphic type" do Puppet::Type.type(:file).expects(:isomorphic?).returns(true) - @resource = Puppet::Parser::Resource.new(:type => "file", :title => "whatever", :scope => @scope, :source => @source).isomorphic?.should be_true + @resource = Puppet::Parser::Resource.new("file", "whatever", :scope => @scope, :source => @source).isomorphic?.should be_true end it "should not be isomorphic if it is builtin and models a non-isomorphic type" do Puppet::Type.type(:file).expects(:isomorphic?).returns(false) - @resource = Puppet::Parser::Resource.new(:type => "file", :title => "whatever", :scope => @scope, :source => @source).isomorphic?.should be_false + @resource = Puppet::Parser::Resource.new("file", "whatever", :scope => @scope, :source => @source).isomorphic?.should be_false end it "should be isomorphic if it is not builtin" do newdefine "whatever" - @resource = Puppet::Parser::Resource.new(:type => "whatever", :title => "whatever", :scope => @scope, :source => @source).isomorphic?.should be_true + @resource = Puppet::Parser::Resource.new("whatever", "whatever", :scope => @scope, :source => @source).isomorphic?.should be_true end it "should have a array-indexing method for retrieving parameter values" do @@ -89,77 +101,68 @@ describe Puppet::Parser::Resource do end it "should be able to use the indexing operator to access parameters" do - resource = Puppet::Parser::Resource.new(:type => "resource", :title => "testing", :source => "source", :scope => "scope") + resource = Puppet::Parser::Resource.new("resource", "testing", :source => "source", :scope => "scope") resource["foo"] = "bar" resource["foo"].should == "bar" end it "should return the title when asked for a parameter named 'title'" do - Puppet::Parser::Resource.new(:type => "resource", :title => "testing", :source => "source", :scope => "scope")[:title].should == "testing" + Puppet::Parser::Resource.new("resource", "testing", :source => "source", :scope => "scope")[:title].should == "testing" end describe "when initializing" do before do - @arguments = {:type => "resource", :title => "testing", :scope => stub('scope', :source => mock('source'))} + @arguments = {:scope => stub('scope', :source => mock('source'))} end - [:type, :title, :scope].each do |name| - it "should fail unless #{name.to_s} is specified" do - try = @arguments.dup - try.delete(name) - lambda { Puppet::Parser::Resource.new(try) }.should raise_error(ArgumentError) - end + it "should fail unless #{name.to_s} is specified" do + lambda { Puppet::Parser::Resource.new('file', '/my/file') }.should raise_error(ArgumentError) end it "should set the reference correctly" do - res = Puppet::Parser::Resource.new(@arguments) + res = Puppet::Parser::Resource.new("resource", "testing", @arguments) res.ref.should == "Resource[testing]" end it "should be tagged with user tags" do tags = [ "tag1", "tag2" ] @arguments[:params] = [ param(:tag, tags , :source) ] - res = Puppet::Parser::Resource.new(@arguments) + res = Puppet::Parser::Resource.new("resource", "testing", @arguments) (res.tags & tags).should == tags end end describe "when refering to a resource with name canonicalization" do before do - @arguments = {:type => "file", :title => "/path/", :scope => stub('scope', :source => mock('source'))} + @arguments = {:scope => stub('scope', :source => mock('source'))} end it "should canonicalize its own name" do - res = Puppet::Parser::Resource.new(@arguments) + res = Puppet::Parser::Resource.new("file", "/path/", @arguments) res.ref.should == "File[/path]" end end describe "when evaluating" do - before do - @type = Puppet::Parser::Resource - - @definition = newdefine "mydefine" - @class = newclass "myclass" - @nodedef = newnode("mynode") - end - it "should evaluate the associated AST definition" do - res = @type.new(:type => "mydefine", :title => "whatever", :scope => @scope, :source => @source) - @definition.expects(:evaluate_code).with(res) + definition = newdefine "mydefine" + res = Puppet::Parser::Resource.new("mydefine", "whatever", :scope => @scope, :source => @source) + 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 = newclass "myclass" + res = Puppet::Parser::Resource.new("class", "myclass", :scope => @scope, :source => @source) @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_code).with(res) + nodedef = newnode("mynode") + res = Puppet::Parser::Resource.new("node", "mynode", :scope => @scope, :source => @source) + nodedef.expects(:evaluate_code).with(res) res.evaluate end end @@ -169,7 +172,7 @@ describe Puppet::Parser::Resource do @class = newclass "myclass" @nodedef = newnode("mynode") - @resource = Puppet::Parser::Resource.new(:type => "file", :title => "whatever", :scope => @scope, :source => @source) + @resource = Puppet::Parser::Resource.new("file", "whatever", :scope => @scope, :source => @source) end it "should do nothing if it has already been finished" do @@ -292,7 +295,7 @@ describe Puppet::Parser::Resource do before do @scope_resource = stub 'scope_resource', :tags => %w{srone srtwo} @scope = stub 'scope', :resource => @scope_resource - @resource = Puppet::Parser::Resource.new(:type => "file", :title => "yay", :scope => @scope, :source => mock('source')) + @resource = Puppet::Parser::Resource.new("file", "yay", :scope => @scope, :source => mock('source')) end it "should get tagged with the resource type" do @@ -304,19 +307,19 @@ describe Puppet::Parser::Resource do end it "should get tagged with each name in the title if the title is a qualified class name" do - resource = Puppet::Parser::Resource.new(:type => "file", :title => "one::two", :scope => @scope, :source => mock('source')) + resource = Puppet::Parser::Resource.new("file", "one::two", :scope => @scope, :source => mock('source')) resource.tags.should be_include("one") resource.tags.should be_include("two") end it "should get tagged with each name in the type if the type is a qualified class name" do - resource = Puppet::Parser::Resource.new(:type => "one::two", :title => "whatever", :scope => @scope, :source => mock('source')) + resource = Puppet::Parser::Resource.new("one::two", "whatever", :scope => @scope, :source => mock('source')) resource.tags.should be_include("one") resource.tags.should be_include("two") end it "should not get tagged with non-alphanumeric titles" do - resource = Puppet::Parser::Resource.new(:type => "file", :title => "this is a test", :scope => @scope, :source => mock('source')) + resource = Puppet::Parser::Resource.new("file", "this is a test", :scope => @scope, :source => mock('source')) resource.tags.should_not be_include("this is a test") end @@ -496,26 +499,26 @@ describe Puppet::Parser::Resource do @parser_resource.to_resource.virtual.should be_true end - it "should convert any parser resource references to Puppet::Resource::Reference instances" do - ref = Puppet::Parser::Resource::Reference.new(:title => "/my/file", :type => "file") + it "should convert any parser resource references to Puppet::Resource instances" do + ref = Puppet::Resource.new("file", "/my/file") @parser_resource = mkresource :source => @source, :params => {:foo => "bar", :fee => ref} result = @parser_resource.to_resource - result[:fee].should == Puppet::Resource::Reference.new(:file, "/my/file") + result[:fee].should == Puppet::Resource.new(:file, "/my/file") end - it "should convert any parser resource references to Puppet::Resource::Reference instances even if they are in an array" do - ref = Puppet::Parser::Resource::Reference.new(:title => "/my/file", :type => "file") + it "should convert any parser resource references to Puppet::Resource instances even if they are in an array" do + ref = Puppet::Resource.new("file", "/my/file") @parser_resource = mkresource :source => @source, :params => {:foo => "bar", :fee => ["a", ref]} result = @parser_resource.to_resource - result[:fee].should == ["a", Puppet::Resource::Reference.new(:file, "/my/file")] + result[:fee].should == ["a", Puppet::Resource.new(:file, "/my/file")] end - it "should convert any parser resource references to Puppet::Resource::Reference instances even if they are in an array of array, and even deeper" do - ref1 = Puppet::Parser::Resource::Reference.new(:title => "/my/file1", :type => "file") - ref2 = Puppet::Parser::Resource::Reference.new(:title => "/my/file2", :type => "file") + it "should convert any parser resource references to Puppet::Resource instances even if they are in an array of array, and even deeper" do + ref1 = Puppet::Resource.new("file", "/my/file1") + ref2 = Puppet::Resource.new("file", "/my/file2") @parser_resource = mkresource :source => @source, :params => {:foo => "bar", :fee => ["a", [ref1,ref2]]} result = @parser_resource.to_resource - result[:fee].should == ["a", Puppet::Resource::Reference.new(:file, "/my/file1"), Puppet::Resource::Reference.new(:file, "/my/file2")] + result[:fee].should == ["a", Puppet::Resource.new(:file, "/my/file1"), Puppet::Resource.new(:file, "/my/file2")] end it "should fail if the same param is declared twice" do @@ -531,4 +534,52 @@ describe Puppet::Parser::Resource do end.should raise_error(Puppet::ParseError) end end + + describe "when validating" do + it "should check each parameter" do + resource = Puppet::Parser::Resource.new :foo, "bar", :scope => stub("scope"), :source => stub("source") + resource[:one] = :two + resource[:three] = :four + resource.expects(:validate_parameter).with(:one) + resource.expects(:validate_parameter).with(:three) + resource.send(:validate) + end + + it "should raise a parse error when there's a failure" do + resource = Puppet::Parser::Resource.new :foo, "bar", :scope => stub("scope"), :source => stub("source") + resource[:one] = :two + resource.expects(:validate_parameter).with(:one).raises ArgumentError + lambda { resource.send(:validate) }.should raise_error(Puppet::ParseError) + end + end + + describe "when setting parameters" do + before do + @source = newclass "foobar" + @resource = Puppet::Parser::Resource.new :foo, "bar", :scope => stub("scope"), :source => @source + end + + it "should accept Param instances and add them to the parameter list" do + param = Puppet::Parser::Resource::Param.new :name => "foo", :value => "bar", :source => @source + @resource.set_parameter(param) + @resource["foo"].should == "bar" + end + + it "should fail when provided a parameter name but no value" do + lambda { @resource.set_parameter("myparam") }.should raise_error(ArgumentError) + end + + it "should use its source when provided a parameter name and value" do + @resource.set_parameter("myparam", "myvalue") + @resource["myparam"].should == "myvalue" + end + end + + # part of #629 -- the undef keyword. Make sure 'undef' params get skipped. + it "should not include 'undef' parameters when converting itself to a hash" do + resource = Puppet::Parser::Resource.new "file", "/tmp/testing", :source => mock("source"), :scope => mock("scope") + resource[:owner] = :undef + resource[:mode] = "755" + resource.to_hash[:owner].should be_nil + end end diff --git a/spec/unit/parser/resource/reference.rb b/spec/unit/parser/resource/reference.rb deleted file mode 100755 index a38604226..000000000 --- a/spec/unit/parser/resource/reference.rb +++ /dev/null @@ -1,134 +0,0 @@ -#!/usr/bin/env ruby - -require File.dirname(__FILE__) + '/../../../spec_helper' - -describe Puppet::Parser::Resource::Reference do - before do - @type = Puppet::Parser::Resource::Reference - end - - it "should get its environment from its scope" do - env = stub 'environment' - scope = stub 'scope', :environment => env - @type.new(:title => "foo", :type => "bar", :scope => scope).environment.should equal(env) - end - - it "should use the resource type collection helper to find its known resource types" do - Puppet::Parser::Resource::Reference.ancestors.should include(Puppet::Resource::TypeCollectionHelper) - end - - it "should use the file lookup module" do - Puppet::Parser::Resource::Reference.ancestors.should be_include(Puppet::FileCollection::Lookup) - end - - it "should require a type" do - proc { @type.new(:title => "yay") }.should raise_error(Puppet::DevError) - end - - it "should require a title" do - proc { @type.new(:type => "file") }.should raise_error(Puppet::DevError) - end - - it "should know when it refers to a builtin type" do - ref = @type.new(:type => "file", :title => "/tmp/yay") - ref.builtin?.should be_true - ref.builtintype.should equal(Puppet::Type.type(:file)) - end - - it "should return a downcased relationship-style resource reference for defined types" do - ref = @type.new(:type => "file", :title => "/tmp/yay") - ref.to_ref.should == ["file", "/tmp/yay"] - end - - it "should return a capitalized relationship-style resource reference for defined types" do - ref = @type.new(:type => "whatever", :title => "/tmp/yay") - ref.to_ref.should == ["Whatever", "/tmp/yay"] - end - - it "should return a resource reference string when asked" do - ref = @type.new(:type => "file", :title => "/tmp/yay") - ref.to_s.should == "File[/tmp/yay]" - end - - it "should canonize resource reference types" do - ref = @type.new(:type => "foo::bar", :title => "/tmp/yay") - ref.to_s.should == "Foo::Bar[/tmp/yay]" - end - - it "should canonize resource reference values" do - ref = @type.new(:type => "file", :title => "/tmp/yay/") - ref.to_s.should == "File[/tmp/yay]" - end - - it "should canonize resource reference values without order dependencies" do - args = [[:title, "/tmp/yay/"], [:type, "file"]] - ref = @type.new(args) - ref.to_s.should == "File[/tmp/yay]" - end - -end - -describe Puppet::Parser::Resource::Reference, " when modeling defined types" do - def newclass(name) - @known_resource_types.add Puppet::Resource::Type.new(:hostclass, name) - end - - def newdefine(name) - @known_resource_types.add Puppet::Resource::Type.new(:definition, name) - end - - def newnode(name) - @known_resource_types.add Puppet::Resource::Type.new(:node, name) - end - - before do - @type = Puppet::Parser::Resource::Reference - - @known_resource_types = Puppet::Resource::TypeCollection.new("myenv") - @definition = newdefine("mydefine") - @class = newclass("myclass") - @nodedef = newnode("mynode") - @node = Puppet::Node.new("yaynode") - - @compiler = Puppet::Parser::Compiler.new(@node) - @compiler.environment.stubs(:known_resource_types).returns @known_resource_types - end - - it "should be able to find defined types" do - 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 => @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 => @compiler.topscope) - ref.builtin?.should be_false - ref.definedtype.object_id.should == @nodedef.object_id - end - - it "should only look for fully qualified classes" do - top = newclass "top" - sub = newclass "other::top" - - scope = @compiler.topscope.class.new(:parent => @compiler.topscope, :namespace => "other", :compiler => @compiler) - - ref = @type.new(:type => "class", :title => "top", :scope => scope) - ref.definedtype.name.should equal(top.name) - end - - it "should only look for fully qualified definitions" do - top = newdefine "top" - sub = newdefine "other::top" - - scope = @compiler.topscope.class.new(:parent => @compiler.topscope, :namespace => "other", :compiler => @compiler) - - ref = @type.new(:type => "top", :title => "foo", :scope => scope) - ref.definedtype.name.should equal(top.name) - end -end diff --git a/spec/unit/parser/scope.rb b/spec/unit/parser/scope.rb index 799d05766..3d648fedf 100755 --- a/spec/unit/parser/scope.rb +++ b/spec/unit/parser/scope.rb @@ -8,6 +8,7 @@ describe Puppet::Parser::Scope do # This is necessary so we don't try to use the compiler to discover our parent. @topscope.parent = nil @scope = Puppet::Parser::Scope.new() + @scope.compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("foo")) @scope.parent = @topscope end @@ -104,7 +105,7 @@ describe Puppet::Parser::Scope do def create_class_scope(name) klass = newclass(name) - Puppet::Parser::Resource.new(:type => "class", :title => name, :scope => @scope, :source => mock('source')).evaluate + Puppet::Parser::Resource.new("class", name, :scope => @scope, :source => mock('source')).evaluate return @scope.class_scope(klass) end @@ -315,6 +316,114 @@ describe Puppet::Parser::Scope do @scope.strinterp('==${10}==').should == "==value==" end + + describe "with qualified variables" do + before do + @scopes = {} + klass = @scope.known_resource_types.add(Puppet::Resource::Type.new(:hostclass, "")) + Puppet::Parser::Resource.new("class", :main, :scope => @scope, :source => mock('source')).evaluate + @scopes[""] = @scope.compiler.class_scope(klass) + @scopes[""].setvar("test", "value") + + %w{one one::two one::two::three}.each do |name| + klass = @scope.known_resource_types.add(Puppet::Resource::Type.new(:hostclass, name)) + Puppet::Parser::Resource.new("class", name, :scope => @scope, :source => mock('source')).evaluate + @scopes[name] = @scope.compiler.class_scope(klass) + @scopes[name].setvar("test", "value-#{name.sub(/.+::/,'')}") + end + end + { + "===${one::two::three::test}===" => "===value-three===", + "===$one::two::three::test===" => "===value-three===", + "===${one::two::test}===" => "===value-two===", + "===$one::two::test===" => "===value-two===", + "===${one::test}===" => "===value-one===", + "===$one::test===" => "===value-one===", + "===${::test}===" => "===value===", + "===$::test===" => "===value===" + }.each do |input, output| + it "should parse '#{input}' correctly" do + @scope.strinterp(input).should == output + end + end + end + + tests = { + "===${test}===" => "===value===", + "===${test} ${test} ${test}===" => "===value value value===", + "===$test ${test} $test===" => "===value value value===", + "===\\$test===" => "===$test===", + '===\\$test string===' => "===$test string===", + '===$test string===' => "===value string===", + '===a testing $===' => "===a testing $===", + '===a testing \$===' => "===a testing $===", + "===an escaped \\\n carriage return===" => "===an escaped carriage return===", + '\$' => "$", + '\s' => "\s", + '\t' => "\t", + '\n' => "\n" + } + + tests.each do |input, output| + it "should parse '#{input}' correctly" do + @scope.setvar("test", "value") + @scope.strinterp(input).should == output + end + end + + # #523 + %w{d f h l w z}.each do |l| + it "should parse '#{l}' when escaped" do + string = "\\" + l + @scope.strinterp(string).should == string + end + end + end + + def test_strinterp + # Make and evaluate our classes so the qualified lookups work + parser = mkparser + klass = parser.newclass("") + scope = mkscope(:parser => parser) + Puppet::Parser::Resource.new(:type => "class", :title => :main, :scope => scope, :source => mock('source')).evaluate + + assert_nothing_raised { + scope.setvar("test","value") + } + + scopes = {"" => scope} + + %w{one one::two one::two::three}.each do |name| + klass = parser.newclass(name) + Puppet::Parser::Resource.new(:type => "class", :title => name, :scope => scope, :source => mock('source')).evaluate + scopes[name] = scope.compiler.class_scope(klass) + scopes[name].setvar("test", "value-%s" % name.sub(/.+::/,'')) + end + + assert_equal("value", scope.lookupvar("::test"), "did not look up qualified value correctly") + tests.each do |input, output| + assert_nothing_raised("Failed to scan %s" % input.inspect) do + assert_equal(output, scope.strinterp(input), + 'did not parserret %s correctly' % input.inspect) + end + end + + logs = [] + Puppet::Util::Log.close + Puppet::Util::Log.newdestination(logs) + + # #523 + %w{d f h l w z}.each do |l| + string = "\\" + l + assert_nothing_raised do + assert_equal(string, scope.strinterp(string), + 'did not parserret %s correctly' % string) + end + + assert(logs.detect { |m| m.message =~ /Unrecognised escape/ }, + "Did not get warning about escape sequence with %s" % string) + logs.clear + end end describe "when setting ephemeral vars from matches" do @@ -357,4 +466,50 @@ describe Puppet::Parser::Scope do @scope.lookupvar("foo").should == "" end end + + it "should use its namespaces to find hostclasses" do + klass = @scope.known_resource_types.add Puppet::Resource::Type.new(:hostclass, "a::b::c") + @scope.add_namespace "a::b" + @scope.find_hostclass("c").should equal(klass) + end + + it "should use its namespaces to find definitions" do + define = @scope.known_resource_types.add Puppet::Resource::Type.new(:definition, "a::b::c") + @scope.add_namespace "a::b" + @scope.find_definition("c").should equal(define) + end + + describe "when managing defaults" do + it "should be able to set and lookup defaults" do + param = Puppet::Parser::Resource::Param.new(:name => :myparam, :value => "myvalue", :source => stub("source")) + @scope.setdefaults(:mytype, param) + @scope.lookupdefaults(:mytype).should == {:myparam => param} + end + + it "should fail if a default is already defined and a new default is being defined" do + param = Puppet::Parser::Resource::Param.new(:name => :myparam, :value => "myvalue", :source => stub("source")) + @scope.setdefaults(:mytype, param) + lambda { @scope.setdefaults(:mytype, param) }.should raise_error(Puppet::ParseError) + end + + it "should return multiple defaults at once" do + param1 = Puppet::Parser::Resource::Param.new(:name => :myparam, :value => "myvalue", :source => stub("source")) + @scope.setdefaults(:mytype, param1) + param2 = Puppet::Parser::Resource::Param.new(:name => :other, :value => "myvalue", :source => stub("source")) + @scope.setdefaults(:mytype, param2) + + @scope.lookupdefaults(:mytype).should == {:myparam => param1, :other => param2} + end + + it "should look up defaults defined in parent scopes" do + param1 = Puppet::Parser::Resource::Param.new(:name => :myparam, :value => "myvalue", :source => stub("source")) + @scope.setdefaults(:mytype, param1) + + child_scope = @scope.newscope + param2 = Puppet::Parser::Resource::Param.new(:name => :other, :value => "myvalue", :source => stub("source")) + child_scope.setdefaults(:mytype, param2) + + child_scope.lookupdefaults(:mytype).should == {:myparam => param1, :other => param2} + end + end end |
