summaryrefslogtreecommitdiffstats
path: root/spec/unit/parser
diff options
context:
space:
mode:
Diffstat (limited to 'spec/unit/parser')
-rwxr-xr-xspec/unit/parser/ast/resource.rb29
-rwxr-xr-xspec/unit/parser/ast/resource_reference.rb51
-rwxr-xr-xspec/unit/parser/collector.rb3
-rwxr-xr-xspec/unit/parser/compiler.rb11
-rwxr-xr-xspec/unit/parser/functions/defined.rb50
-rwxr-xr-xspec/unit/parser/functions/require.rb2
-rwxr-xr-xspec/unit/parser/functions/tag.rb24
-rwxr-xr-xspec/unit/parser/parser.rb16
-rwxr-xr-xspec/unit/parser/resource.rb143
-rwxr-xr-xspec/unit/parser/resource/reference.rb134
-rwxr-xr-xspec/unit/parser/scope.rb157
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