summaryrefslogtreecommitdiffstats
path: root/spec/unit/parser
diff options
context:
space:
mode:
authorDominic Cleal <dcleal@redhat.com>2010-11-27 13:36:04 +0000
committerDominic Cleal <dcleal@redhat.com>2010-11-27 13:36:04 +0000
commitafe2d014feb2210a8666c93465d11e9c9d555f8b (patch)
tree208f5ac82b2c29610d2021821c8fca9b079e638b /spec/unit/parser
parent143fc744a839affd328234fca26246d49d15d3d8 (diff)
parent4b35402ba85d8842d757becec5c8a7bf4d6f6654 (diff)
Merge branch 'master' of github.com:domcleal/puppet into master-old
Diffstat (limited to 'spec/unit/parser')
-rwxr-xr-xspec/unit/parser/ast/astarray_spec.rb49
-rwxr-xr-xspec/unit/parser/ast/collection_spec.rb4
-rw-r--r--spec/unit/parser/ast/definition_spec.rb22
-rw-r--r--spec/unit/parser/ast/function_spec.rb18
-rw-r--r--spec/unit/parser/ast/hostclass_spec.rb73
-rwxr-xr-xspec/unit/parser/ast/leaf_spec.rb46
-rw-r--r--spec/unit/parser/ast/node_spec.rb31
-rwxr-xr-xspec/unit/parser/ast/resource_reference_spec.rb5
-rwxr-xr-xspec/unit/parser/ast/resource_spec.rb226
-rwxr-xr-xspec/unit/parser/collector_spec.rb1
-rwxr-xr-xspec/unit/parser/compiler_spec.rb29
-rw-r--r--spec/unit/parser/files_spec.rb6
-rwxr-xr-xspec/unit/parser/functions/extlookup_spec.rb95
-rw-r--r--spec/unit/parser/functions/include_spec.rb33
-rwxr-xr-xspec/unit/parser/functions/require_spec.rb2
-rwxr-xr-xspec/unit/parser/functions/tag_spec.rb1
-rwxr-xr-xspec/unit/parser/lexer_spec.rb20
-rwxr-xr-xspec/unit/parser/parser_spec.rb145
-rwxr-xr-xspec/unit/parser/resource_spec.rb12
-rwxr-xr-xspec/unit/parser/scope_spec.rb3
-rwxr-xr-xspec/unit/parser/templatewrapper_spec.rb1
-rw-r--r--spec/unit/parser/type_loader_spec.rb113
22 files changed, 628 insertions, 307 deletions
diff --git a/spec/unit/parser/ast/astarray_spec.rb b/spec/unit/parser/ast/astarray_spec.rb
index f79d6c533..8794848b6 100755
--- a/spec/unit/parser/ast/astarray_spec.rb
+++ b/spec/unit/parser/ast/astarray_spec.rb
@@ -23,43 +23,26 @@ describe Puppet::Parser::AST::ASTArray do
operator.evaluate(@scope)
end
- it "should evaluate childrens of type ASTArray" do
- item1 = stub "item1", :is_a? => true
- item2 = stub "item2"
- item2.stubs(:is_a?).with(Puppet::Parser::AST).returns(true)
- item2.stubs(:instance_of?).with(Puppet::Parser::AST::ASTArray).returns(true)
- item2.stubs(:each).yields(item1)
-
- item1.expects(:safeevaluate).with(@scope).returns(123)
-
- operator = Puppet::Parser::AST::ASTArray.new :children => [item2]
- operator.evaluate(@scope).should == [123]
- end
-
- it "should flatten children coming from children ASTArray" do
- item1 = stub "item1", :is_a? => true
- item2 = stub "item2"
- item2.stubs(:is_a?).with(Puppet::Parser::AST).returns(true)
- item2.stubs(:instance_of?).with(Puppet::Parser::AST::ASTArray).returns(true)
- item2.stubs(:each).yields([item1])
-
- item1.expects(:safeevaluate).with(@scope).returns(123)
-
- operator = Puppet::Parser::AST::ASTArray.new :children => [item2]
- operator.evaluate(@scope).should == [123]
+ it "should not flatten children coming from children ASTArray" do
+ item = Puppet::Parser::AST::String.new :value => 'foo'
+ inner_array = Puppet::Parser::AST::ASTArray.new :children => [item, item]
+ operator = Puppet::Parser::AST::ASTArray.new :children => [inner_array, inner_array]
+ operator.evaluate(@scope).should == [['foo', 'foo'], ['foo', 'foo']]
end
it "should not flatten the results of children evaluation" do
- item1 = stub "item1", :is_a? => true
- item2 = stub "item2"
- item2.stubs(:is_a?).with(Puppet::Parser::AST).returns(true)
- item2.stubs(:instance_of?).with(Puppet::Parser::AST::ASTArray).returns(true)
- item2.stubs(:each).yields([item1])
-
- item1.expects(:safeevaluate).with(@scope).returns([123])
+ item = Puppet::Parser::AST::String.new :value => 'foo'
+ item.stubs(:evaluate).returns(['foo'])
+ operator = Puppet::Parser::AST::ASTArray.new :children => [item, item]
+ operator.evaluate(@scope).should == [['foo'], ['foo']]
+ end
- operator = Puppet::Parser::AST::ASTArray.new :children => [item2]
- operator.evaluate(@scope).should == [[123]]
+ it "should discard nil results from children evaluation" do
+ item1 = Puppet::Parser::AST::String.new :value => 'foo'
+ item2 = Puppet::Parser::AST::String.new :value => 'foo'
+ item2.stubs(:evaluate).returns(nil)
+ operator = Puppet::Parser::AST::ASTArray.new :children => [item1, item2]
+ operator.evaluate(@scope).should == ['foo']
end
it "should return a valid string with to_s" do
diff --git a/spec/unit/parser/ast/collection_spec.rb b/spec/unit/parser/ast/collection_spec.rb
index 3f7878a99..392a2c0f0 100755
--- a/spec/unit/parser/ast/collection_spec.rb
+++ b/spec/unit/parser/ast/collection_spec.rb
@@ -5,6 +5,8 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
describe Puppet::Parser::AST::Collection do
before :each do
@scope = stub_everything 'scope'
+ @mytype = stub_everything('mytype')
+ @scope.stubs(:find_resource_type).returns @mytype
@compiler = stub_everything 'compile'
@scope.stubs(:compiler).returns(@compiler)
@@ -24,6 +26,8 @@ describe Puppet::Parser::AST::Collection do
it "should instantiate a Collector for this type" do
collection = Puppet::Parser::AST::Collection.new :form => :virtual, :type => "test"
+ @test_type = stub 'type', :name => 'test'
+ @scope.expects(:find_resource_type).with('test').returns @test_type
Puppet::Parser::Collector.expects(:new).with(@scope, "test", nil, nil, :virtual)
diff --git a/spec/unit/parser/ast/definition_spec.rb b/spec/unit/parser/ast/definition_spec.rb
new file mode 100644
index 000000000..b7b2c851c
--- /dev/null
+++ b/spec/unit/parser/ast/definition_spec.rb
@@ -0,0 +1,22 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+describe Puppet::Parser::AST::Definition do
+ it "should make its context available through an accessor" do
+ definition = Puppet::Parser::AST::Definition.new('foo', :line => 5)
+ definition.context.should == {:line => 5}
+ end
+
+ describe "when instantiated" do
+ it "should create a definition with the proper type, name, context, and module name" do
+ definition = Puppet::Parser::AST::Definition.new('foo', :line => 5)
+ instantiated_definitions = definition.instantiate('modname')
+ instantiated_definitions.length.should == 1
+ instantiated_definitions[0].type.should == :definition
+ instantiated_definitions[0].name.should == 'foo'
+ instantiated_definitions[0].line.should == 5
+ instantiated_definitions[0].module_name.should == 'modname'
+ end
+ end
+end
diff --git a/spec/unit/parser/ast/function_spec.rb b/spec/unit/parser/ast/function_spec.rb
index c57c7f098..38e344157 100644
--- a/spec/unit/parser/ast/function_spec.rb
+++ b/spec/unit/parser/ast/function_spec.rb
@@ -61,20 +61,30 @@ describe Puppet::Parser::AST::Function do
end
it "should call the underlying ruby function" do
- argument = stub 'arg', :safeevaluate => "nothing"
+ argument = stub 'arg', :safeevaluate => ["nothing"]
Puppet::Parser::Functions.stubs(:function).with("exist").returns(true)
func = Puppet::Parser::AST::Function.new :name => "exist", :ftype => :statement, :arguments => argument
- @scope.expects(:function_exist).with("nothing")
+ @scope.expects(:function_exist).with(["nothing"])
+
+ func.evaluate(@scope)
+ end
+
+ it "should convert :undef to '' in arguments" do
+ argument = stub 'arg', :safeevaluate => ["foo", :undef, "bar"]
+ Puppet::Parser::Functions.stubs(:function).with("exist").returns(true)
+ func = Puppet::Parser::AST::Function.new :name => "exist", :ftype => :statement, :arguments => argument
+
+ @scope.expects(:function_exist).with(["foo", "", "bar"])
func.evaluate(@scope)
end
it "should return the ruby function return for rvalue functions" do
- argument = stub 'arg', :safeevaluate => "nothing"
+ argument = stub 'arg', :safeevaluate => ["nothing"]
Puppet::Parser::Functions.stubs(:function).with("exist").returns(true)
func = Puppet::Parser::AST::Function.new :name => "exist", :ftype => :statement, :arguments => argument
- @scope.stubs(:function_exist).with("nothing").returns("returning")
+ @scope.stubs(:function_exist).with(["nothing"]).returns("returning")
func.evaluate(@scope).should == "returning"
end
diff --git a/spec/unit/parser/ast/hostclass_spec.rb b/spec/unit/parser/ast/hostclass_spec.rb
new file mode 100644
index 000000000..b22eba98b
--- /dev/null
+++ b/spec/unit/parser/ast/hostclass_spec.rb
@@ -0,0 +1,73 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+describe Puppet::Parser::AST::Hostclass do
+ def ast
+ Puppet::Parser::AST
+ end
+
+ def newarray(*elems)
+ ast::ASTArray.new({}).push(*elems)
+ end
+
+ it "should make its name and context available through accessors" do
+ hostclass = ast::Hostclass.new('foo', :line => 5)
+ hostclass.name.should == 'foo'
+ hostclass.context.should == {:line => 5}
+ end
+
+ it "should make its code available through an accessor" do
+ code = newarray
+ hostclass = ast::Hostclass.new('foo', :code => code)
+ hostclass.code.should be_equal(code)
+ end
+
+ describe "when instantiated" do
+ it "should create a class with the proper type, code, name, context, and module name" do
+ code = newarray
+ hostclass = ast::Hostclass.new('foo', :code => code, :line => 5)
+ instantiated_class = hostclass.instantiate('modname')[0]
+ instantiated_class.type.should == :hostclass
+ instantiated_class.name.should == 'foo'
+ instantiated_class.code.should be_equal(code)
+ instantiated_class.line.should == 5
+ instantiated_class.module_name.should == 'modname'
+ end
+
+ it "should instantiate all nested classes, defines, and nodes with the same module name." do
+ nested_objects = newarray(ast::Hostclass.new('foo::child1'),
+ ast::Definition.new('foo::child2'),
+ ast::Definition.new('child3'))
+ hostclass = ast::Hostclass.new('foo', :code => nested_objects)
+ instantiated_classes = hostclass.instantiate('modname')
+ instantiated_classes.length.should == 4
+ instantiated_classes[0].name.should == 'foo'
+ instantiated_classes[1].name.should == 'foo::child1'
+ instantiated_classes[2].name.should == 'foo::child2'
+ instantiated_classes[3].name.should == 'child3'
+ instantiated_classes.each { |cls| cls.module_name.should == 'modname' }
+ end
+
+ it "should handle a nested class that contains its own nested classes." do
+ foo_bar_baz = ast::Hostclass.new('foo::bar::baz')
+ foo_bar = ast::Hostclass.new('foo::bar', :code => newarray(foo_bar_baz))
+ foo = ast::Hostclass.new('foo', :code => newarray(foo_bar))
+ instantiated_classes = foo.instantiate('')
+ instantiated_classes.length.should == 3
+ instantiated_classes[0].name.should == 'foo'
+ instantiated_classes[1].name.should == 'foo::bar'
+ instantiated_classes[2].name.should == 'foo::bar::baz'
+ end
+
+ it "should skip nested elements that are not classes, definitions, or nodes." do
+ func = ast::Function.new(:name => 'biz', :arguments => newarray(ast::Name.new(:value => 'baz')))
+ foo = ast::Hostclass.new('foo', :code => newarray(func))
+ instantiated_classes = foo.instantiate('')
+ instantiated_classes.length.should == 1
+ instantiated_classes[0].should be_a(Puppet::Resource::Type)
+ instantiated_classes[0].name.should == 'foo'
+ end
+ end
+end
+
diff --git a/spec/unit/parser/ast/leaf_spec.rb b/spec/unit/parser/ast/leaf_spec.rb
index 5bdca67fa..a19c24115 100755
--- a/spec/unit/parser/ast/leaf_spec.rb
+++ b/spec/unit/parser/ast/leaf_spec.rb
@@ -47,6 +47,10 @@ describe Puppet::Parser::AST::String do
value = stub 'value', :is_a? => true, :to_s => "ab"
Puppet::Parser::AST::String.new( :value => value ).to_s.should == "\"ab\""
end
+ it "should return a dup of its value" do
+ value = ""
+ Puppet::Parser::AST::String.new( :value => value ).evaluate(stub('scope')).should_not be_equal(value)
+ end
end
end
@@ -132,6 +136,22 @@ describe Puppet::Parser::AST::HashOrArrayAccess do
access.evaluate(@scope).should == "val2"
end
+ it "should be able to return an array member when index is a stringified number" do
+ @scope.stubs(:lookupvar).with("a").returns(["val1", "val2", "val3"])
+
+ access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "1" )
+
+ access.evaluate(@scope).should == "val2"
+ end
+
+ it "should raise an error when accessing an array with a key" do
+ @scope.stubs(:lookupvar).with("a").returns(["val1", "val2", "val3"])
+
+ access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "get_me_the_second_element_please" )
+
+ lambda { access.evaluate(@scope) }.should raise_error
+ end
+
it "should be able to return an hash value" do
@scope.stubs(:lookupvar).with("a").returns({ "key1" => "val1", "key2" => "val2", "key3" => "val3" })
@@ -140,6 +160,14 @@ describe Puppet::Parser::AST::HashOrArrayAccess do
access.evaluate(@scope).should == "val2"
end
+ it "should be able to return an hash value with a numerical key" do
+ @scope.stubs(:lookupvar).with("a").returns({ "key1" => "val1", "key2" => "val2", "45" => "45", "key3" => "val3" })
+
+ access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "45" )
+
+ access.evaluate(@scope).should == "45"
+ end
+
it "should raise an error if the variable lookup didn't return an hash or an array" do
@scope.stubs(:lookupvar).with("a").returns("I'm a string")
@@ -191,6 +219,24 @@ describe Puppet::Parser::AST::HashOrArrayAccess do
scope.lookupvar("a").should be_include("b")
end
+ it "should raise an error when assigning an array element with a key" do
+ @scope.stubs(:lookupvar).with("a").returns([])
+
+ access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "get_me_the_second_element_please" )
+
+ lambda { access.assign(@scope, "test") }.should raise_error
+ end
+
+ it "should be able to return an array member when index is a stringified number" do
+ scope = Puppet::Parser::Scope.new
+ scope.setvar("a", [])
+
+ access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "0" )
+
+ access.assign(scope, "val2")
+ scope.lookupvar("a").should == ["val2"]
+ end
+
it "should raise an error when trying to overwrite an hash value" do
@scope.stubs(:lookupvar).with("a").returns({ "key" => [ "a" , "b" ]})
access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "key")
diff --git a/spec/unit/parser/ast/node_spec.rb b/spec/unit/parser/ast/node_spec.rb
new file mode 100644
index 000000000..3e8017de0
--- /dev/null
+++ b/spec/unit/parser/ast/node_spec.rb
@@ -0,0 +1,31 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+describe Puppet::Parser::AST::Node do
+ describe "when instantiated" do
+ it "should make its names and context available through accessors" do
+ node = Puppet::Parser::AST::Node.new(['foo', 'bar'], :line => 5)
+ node.names.should == ['foo', 'bar']
+ node.context.should == {:line => 5}
+ end
+
+ it "should create a node with the proper type, name, context, and module name" do
+ node = Puppet::Parser::AST::Node.new(['foo'], :line => 5)
+ instantiated_nodes = node.instantiate('modname')
+ instantiated_nodes.length.should == 1
+ instantiated_nodes[0].type.should == :node
+ instantiated_nodes[0].name.should == 'foo'
+ instantiated_nodes[0].line.should == 5
+ instantiated_nodes[0].module_name.should == 'modname'
+ end
+
+ it "should handle multiple names" do
+ node = Puppet::Parser::AST::Node.new(['foo', 'bar'])
+ instantiated_nodes = node.instantiate('modname')
+ instantiated_nodes.length.should == 2
+ instantiated_nodes[0].name.should == 'foo'
+ instantiated_nodes[1].name.should == 'bar'
+ end
+ end
+end
diff --git a/spec/unit/parser/ast/resource_reference_spec.rb b/spec/unit/parser/ast/resource_reference_spec.rb
index 7b48119f4..93419d963 100755
--- a/spec/unit/parser/ast/resource_reference_spec.rb
+++ b/spec/unit/parser/ast/resource_reference_spec.rb
@@ -32,11 +32,6 @@ describe Puppet::Parser::AST::ResourceReference do
]
end
- 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
type = stub 'type', :is_a? => true, :to_s => "file"
title = stub 'title', :is_a? => true, :to_s => "[/tmp/a, /tmp/b]"
diff --git a/spec/unit/parser/ast/resource_spec.rb b/spec/unit/parser/ast/resource_spec.rb
index 58ffae925..3f7fa229a 100755
--- a/spec/unit/parser/ast/resource_spec.rb
+++ b/spec/unit/parser/ast/resource_spec.rb
@@ -5,116 +5,180 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
describe Puppet::Parser::AST::Resource do
ast = Puppet::Parser::AST
- before :each do
- @title = Puppet::Parser::AST::String.new(:value => "mytitle")
- @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("mynode"))
- @scope = Puppet::Parser::Scope.new(:compiler => @compiler)
- @scope.stubs(:resource).returns(stub_everything)
- @resource = ast::Resource.new(:title => @title, :type => "file", :parameters => ast::ASTArray.new(:children => []) )
- @resource.stubs(:qualified_type).returns("Resource")
- end
+ describe "for builtin types" do
+ before :each do
+ @title = Puppet::Parser::AST::String.new(:value => "mytitle")
+ @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("mynode"))
+ @scope = Puppet::Parser::Scope.new(:compiler => @compiler)
+ @scope.stubs(:resource).returns(stub_everything)
+ @instance = ast::ResourceInstance.new(:title => @title, :parameters => ast::ASTArray.new(:children => []))
+ @resource = ast::Resource.new(:type => "file", :instances => ast::ASTArray.new(:children => [@instance]))
+ @resource.stubs(:qualified_type).returns("Resource")
+ end
- it "should evaluate all its parameters" do
- param = stub 'param'
- param.expects(:safeevaluate).with(@scope).returns Puppet::Parser::Resource::Param.new(:name => "myparam", :value => "myvalue", :source => stub("source"))
- @resource.stubs(:parameters).returns [param]
+ it "should evaluate all its parameters" do
+ param = stub 'param'
+ param.expects(:safeevaluate).with(@scope).returns Puppet::Parser::Resource::Param.new(:name => "myparam", :value => "myvalue", :source => stub("source"))
+ @instance.stubs(:parameters).returns [param]
- @resource.evaluate(@scope)
- end
-
- it "should evaluate its title" do
- @resource.evaluate(@scope)[0].title.should == "mytitle"
- end
+ @resource.evaluate(@scope)
+ end
- it "should flatten the titles array" do
- titles = []
- %w{one two}.each do |title|
- titles << Puppet::Parser::AST::String.new(:value => title)
+ it "should evaluate its title" do
+ @resource.evaluate(@scope)[0].title.should == "mytitle"
end
- array = Puppet::Parser::AST::ASTArray.new(:children => titles)
+ it "should flatten the titles array" do
+ titles = []
+ %w{one two}.each do |title|
+ titles << Puppet::Parser::AST::String.new(:value => title)
+ end
- @resource.title = array
- result = @resource.evaluate(@scope).collect { |r| r.title }
- result.should be_include("one")
- result.should be_include("two")
- end
+ array = Puppet::Parser::AST::ASTArray.new(:children => titles)
- it "should create and return one resource objects per title" do
- titles = []
- %w{one two}.each do |title|
- titles << Puppet::Parser::AST::String.new(:value => title)
+ @instance.title = array
+ result = @resource.evaluate(@scope).collect { |r| r.title }
+ result.should be_include("one")
+ result.should be_include("two")
end
- array = Puppet::Parser::AST::ASTArray.new(:children => titles)
+ it "should create and return one resource objects per title" do
+ titles = []
+ %w{one two}.each do |title|
+ titles << Puppet::Parser::AST::String.new(:value => title)
+ end
- @resource.title = array
- result = @resource.evaluate(@scope).collect { |r| r.title }
- result.should be_include("one")
- result.should be_include("two")
- end
+ array = Puppet::Parser::AST::ASTArray.new(:children => titles)
- it "should handover resources to the compiler" do
- titles = []
- %w{one two}.each do |title|
- titles << Puppet::Parser::AST::String.new(:value => title)
+ @instance.title = array
+ result = @resource.evaluate(@scope).collect { |r| r.title }
+ result.should be_include("one")
+ result.should be_include("two")
end
- array = Puppet::Parser::AST::ASTArray.new(:children => titles)
+ it "should implicitly iterate over instances" do
+ new_title = Puppet::Parser::AST::String.new(:value => "other_title")
+ new_instance = ast::ResourceInstance.new(:title => new_title, :parameters => ast::ASTArray.new(:children => []))
+ @resource.instances.push(new_instance)
+ @resource.evaluate(@scope).collect { |r| r.title }.should == ["mytitle", "other_title"]
+ end
- @resource.title = array
- result = @resource.evaluate(@scope)
+ it "should handover resources to the compiler" do
+ titles = []
+ %w{one two}.each do |title|
+ titles << Puppet::Parser::AST::String.new(:value => title)
+ end
- result.each do |res|
- @compiler.catalog.resource(res.ref).should be_instance_of(Puppet::Parser::Resource)
- end
- end
- it "should generate virtual resources if it is virtual" do
- @resource.virtual = true
+ array = Puppet::Parser::AST::ASTArray.new(:children => titles)
- result = @resource.evaluate(@scope)
- result[0].should be_virtual
- end
+ @instance.title = array
+ result = @resource.evaluate(@scope)
- it "should generate virtual and exported resources if it is exported" do
- @resource.exported = true
+ result.each do |res|
+ @compiler.catalog.resource(res.ref).should be_instance_of(Puppet::Parser::Resource)
+ end
+ end
- result = @resource.evaluate(@scope)
- result[0].should be_virtual
- result[0].should be_exported
- end
+ it "should generate virtual resources if it is virtual" do
+ @resource.virtual = true
- # Related to #806, make sure resources always look up the full path to the resource.
- describe "when generating qualified resources" do
- before do
- @scope = Puppet::Parser::Scope.new :compiler => Puppet::Parser::Compiler.new(Puppet::Node.new("mynode"))
- @parser = Puppet::Parser::Parser.new(Puppet::Node::Environment.new)
- @parser.newdefine "one"
- @parser.newdefine "one::two"
- @parser.newdefine "three"
- @twoscope = @scope.newscope(:namespace => "one")
- @twoscope.resource = @scope.resource
+ result = @resource.evaluate(@scope)
+ result[0].should be_virtual
end
- def resource(type, params = nil)
- params ||= Puppet::Parser::AST::ASTArray.new(:children => [])
- Puppet::Parser::AST::Resource.new(:type => type, :title => Puppet::Parser::AST::String.new(:value => "myresource"), :parameters => params)
+ it "should generate virtual and exported resources if it is exported" do
+ @resource.exported = true
+
+ result = @resource.evaluate(@scope)
+ result[0].should be_virtual
+ result[0].should be_exported
end
- it "should be able to generate resources with fully qualified type information" do
- resource("two").evaluate(@twoscope)[0].type.should == "One::Two"
+ # Related to #806, make sure resources always look up the full path to the resource.
+ describe "when generating qualified resources" do
+ before do
+ @scope = Puppet::Parser::Scope.new :compiler => Puppet::Parser::Compiler.new(Puppet::Node.new("mynode"))
+ @parser = Puppet::Parser::Parser.new(Puppet::Node::Environment.new)
+ ["one", "one::two", "three"].each do |name|
+ @parser.environment.known_resource_types.add(Puppet::Resource::Type.new(:definition, name, {}))
+ end
+ @twoscope = @scope.newscope(:namespace => "one")
+ @twoscope.resource = @scope.resource
+ end
+
+ def resource(type, params = nil)
+ params ||= Puppet::Parser::AST::ASTArray.new(:children => [])
+ instance = Puppet::Parser::AST::ResourceInstance.new(
+ :title => Puppet::Parser::AST::String.new(:value => "myresource"), :parameters => params)
+ Puppet::Parser::AST::Resource.new(:type => type,
+ :instances => Puppet::Parser::AST::ASTArray.new(:children => [instance]))
+ end
+
+ it "should be able to generate resources with fully qualified type information" do
+ resource("two").evaluate(@twoscope)[0].type.should == "One::Two"
+ end
+
+ it "should be able to generate resources with unqualified type information" do
+ resource("one").evaluate(@twoscope)[0].type.should == "One"
+ end
+
+ it "should correctly generate resources that can look up builtin types" do
+ resource("file").evaluate(@twoscope)[0].type.should == "File"
+ end
+
+ it "should correctly generate resources that can look up defined classes by title" do
+ @scope.known_resource_types.add_hostclass Puppet::Resource::Type.new(:hostclass, "Myresource", {})
+ @scope.compiler.stubs(:evaluate_classes)
+ res = resource("class").evaluate(@twoscope)[0]
+ res.type.should == "Class"
+ res.title.should == "Myresource"
+ end
+
+ it "should evaluate parameterized classes when they are instantiated" do
+ @scope.known_resource_types.add_hostclass Puppet::Resource::Type.new(:hostclass, "Myresource", {})
+ @scope.compiler.expects(:evaluate_classes).with(['myresource'],@twoscope,false)
+ resource("class").evaluate(@twoscope)[0]
+ end
+
+ it "should fail for resource types that do not exist" do
+ lambda { resource("nosuchtype").evaluate(@twoscope) }.should raise_error(Puppet::ParseError)
+ end
end
+ end
- it "should be able to generate resources with unqualified type information" do
- resource("one").evaluate(@twoscope)[0].type.should == "One"
+ describe "for class resources" do
+ before do
+ @title = Puppet::Parser::AST::String.new(:value => "classname")
+ @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("mynode"))
+ @scope = Puppet::Parser::Scope.new(:compiler => @compiler)
+ @scope.stubs(:resource).returns(stub_everything)
+ @instance = ast::ResourceInstance.new(:title => @title, :parameters => ast::ASTArray.new(:children => []))
+ @resource = ast::Resource.new(:type => "Class", :instances => ast::ASTArray.new(:children => [@instance]))
+ @resource.stubs(:qualified_type).returns("Resource")
+ @type = Puppet::Resource::Type.new(:hostclass, "classname")
+ @compiler.known_resource_types.add(@type)
end
- it "should correctly generate resources that can look up builtin types" do
- resource("file").evaluate(@twoscope)[0].type.should == "File"
+ it "should instantiate the class" do
+ @compiler.stubs(:evaluate_classes)
+ result = @resource.evaluate(@scope)
+ result.length.should == 1
+ result.first.ref.should == "Class[Classname]"
+ @compiler.catalog.resource("Class[Classname]").should equal(result.first)
end
- it "should fail for resource types that do not exist" do
- lambda { resource("nosuchtype").evaluate(@twoscope) }.should raise_error(Puppet::ParseError)
+ it "should cause its parent to be evaluated" do
+ parent_type = Puppet::Resource::Type.new(:hostclass, "parentname")
+ @compiler.stubs(:evaluate_classes)
+ @compiler.known_resource_types.add(parent_type)
+ @type.parent = "parentname"
+ result = @resource.evaluate(@scope)
+ result.length.should == 1
+ result.first.ref.should == "Class[Classname]"
+ @compiler.catalog.resource("Class[Classname]").should equal(result.first)
+ @compiler.catalog.resource("Class[Parentname]").should be_instance_of(Puppet::Parser::Resource)
end
+
end
+
end
diff --git a/spec/unit/parser/collector_spec.rb b/spec/unit/parser/collector_spec.rb
index 15808d6ff..908cda63a 100755
--- a/spec/unit/parser/collector_spec.rb
+++ b/spec/unit/parser/collector_spec.rb
@@ -2,6 +2,7 @@
require File.dirname(__FILE__) + '/../../spec_helper'
+require 'puppet/rails'
require 'puppet/parser/collector'
describe Puppet::Parser::Collector, "when initializing" do
diff --git a/spec/unit/parser/compiler_spec.rb b/spec/unit/parser/compiler_spec.rb
index e8c06dd0b..95f3853e2 100755
--- a/spec/unit/parser/compiler_spec.rb
+++ b/spec/unit/parser/compiler_spec.rb
@@ -430,7 +430,18 @@ describe Puppet::Parser::Compiler do
lambda { @compiler.add_resource(@scope, resource) }.should raise_error(ArgumentError)
end
- it "should add edges from the class resources to the main stage if no stage is specified" do
+ it "should add edges from the class resources to the parent's stage if no stage is specified" do
+ main = @compiler.catalog.resource(:stage, :main)
+ foo_stage = resource(:stage, :foo_stage)
+ @compiler.add_resource(@scope, foo_stage)
+ resource = resource(:class, "foo")
+ @scope.stubs(:resource).returns(:stage => :foo_stage)
+ @compiler.add_resource(@scope, resource)
+
+ @compiler.catalog.should be_edge(foo_stage, resource)
+ end
+
+ it "should add edges from top-level class resources to the main stage if no stage is specified" do
main = @compiler.catalog.resource(:stage, :main)
resource = resource(:class, "foo")
@compiler.add_resource(@scope, resource)
@@ -569,7 +580,7 @@ describe Puppet::Parser::Compiler do
it "should evaluate each class" do
@compiler.catalog.stubs(:tag)
- @class.expects(:mk_plain_resource).with(@scope)
+ @class.expects(:ensure_in_catalog).with(@scope)
@scope.stubs(:class_scope).with(@class)
@compiler.evaluate_classes(%w{myclass}, @scope)
@@ -580,7 +591,7 @@ describe Puppet::Parser::Compiler do
@resource.expects(:evaluate).never
- @class.expects(:mk_plain_resource).returns(@resource)
+ @class.expects(:ensure_in_catalog).returns(@resource)
@scope.stubs(:class_scope).with(@class)
@compiler.evaluate_classes(%w{myclass}, @scope)
@@ -590,7 +601,7 @@ describe Puppet::Parser::Compiler do
@compiler.catalog.stubs(:tag)
@resource.expects(:evaluate)
- @class.expects(:mk_plain_resource).returns(@resource)
+ @class.expects(:ensure_in_catalog).returns(@resource)
@scope.stubs(:class_scope).with(@class)
@compiler.evaluate_classes(%w{myclass}, @scope, false)
@@ -627,7 +638,7 @@ describe Puppet::Parser::Compiler do
@scope.stubs(:class_scope).with(@class)
Puppet::Parser::Resource.stubs(:new).returns(@resource)
- @class.stubs :mk_plain_resource
+ @class.stubs :ensure_in_catalog
@compiler.evaluate_classes(%w{myclass notfound}, @scope).should == %w{myclass}
end
end
@@ -667,7 +678,7 @@ describe Puppet::Parser::Compiler do
@compiler.known_resource_types.stubs(:node).with("c").returns(node_class)
node_resource = stub 'node resource', :ref => "Node[c]", :evaluate => nil, :type => "node"
- node_class.expects(:mk_plain_resource).returns(node_resource)
+ node_class.expects(:ensure_in_catalog).returns(node_resource)
@compiler.compile
end
@@ -677,7 +688,7 @@ describe Puppet::Parser::Compiler do
@compiler.known_resource_types.stubs(:node).with("default").returns(node_class)
node_resource = stub 'node resource', :ref => "Node[default]", :evaluate => nil, :type => "node"
- node_class.expects(:mk_plain_resource).returns(node_resource)
+ node_class.expects(:ensure_in_catalog).returns(node_resource)
@compiler.compile
end
@@ -687,7 +698,7 @@ describe Puppet::Parser::Compiler do
@compiler.known_resource_types.stubs(:node).with("c").returns(node_class)
node_resource = stub 'node resource', :ref => "Node[c]", :type => "node"
- node_class.expects(:mk_plain_resource).returns(node_resource)
+ node_class.expects(:ensure_in_catalog).returns(node_resource)
node_resource.expects(:evaluate)
@@ -696,7 +707,7 @@ describe Puppet::Parser::Compiler do
it "should set the node's scope as the top scope" do
node_resource = stub 'node resource', :ref => "Node[c]", :evaluate => nil, :type => "node"
- node_class = stub 'node', :name => "c", :mk_plain_resource => node_resource
+ node_class = stub 'node', :name => "c", :ensure_in_catalog => node_resource
@compiler.known_resource_types.stubs(:node).with("c").returns(node_class)
diff --git a/spec/unit/parser/files_spec.rb b/spec/unit/parser/files_spec.rb
index fcfbfa613..3eb0db07e 100644
--- a/spec/unit/parser/files_spec.rb
+++ b/spec/unit/parser/files_spec.rb
@@ -154,7 +154,7 @@ describe Puppet::Parser::Files do
it "should match against provided fully qualified patterns" do
pattern = @basepath + "/fully/qualified/pattern/*"
- Dir.expects(:glob).with(pattern+'{,.pp,.rb}').returns(%w{my file list})
+ Dir.expects(:glob).with(pattern+'{.pp,.rb}').returns(%w{my file list})
Puppet::Parser::Files.find_manifests(pattern)[1].should == %w{my file list}
end
@@ -168,7 +168,7 @@ describe Puppet::Parser::Files do
pattern = @basepath + "/fully/qualified/pattern/*"
file = @basepath + "/my/file"
dir = @basepath + "/my/directory"
- Dir.expects(:glob).with(pattern+'{,.pp,.rb}').returns([file, dir])
+ Dir.expects(:glob).with(pattern+'{.pp,.rb}').returns([file, dir])
FileTest.expects(:directory?).with(file).returns(false)
FileTest.expects(:directory?).with(dir).returns(true)
Puppet::Parser::Files.find_manifests(pattern)[1].should == [file]
@@ -176,7 +176,7 @@ describe Puppet::Parser::Files do
it "should return files once only" do
pattern = @basepath + "/fully/qualified/pattern/*"
- Dir.expects(:glob).with(pattern+'{,.pp,.rb}').returns(%w{one two one})
+ Dir.expects(:glob).with(pattern+'{.pp,.rb}').returns(%w{one two one})
Puppet::Parser::Files.find_manifests(pattern)[1].should == %w{one two}
end
end
diff --git a/spec/unit/parser/functions/extlookup_spec.rb b/spec/unit/parser/functions/extlookup_spec.rb
new file mode 100755
index 000000000..a3dcaa742
--- /dev/null
+++ b/spec/unit/parser/functions/extlookup_spec.rb
@@ -0,0 +1,95 @@
+#! /usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+require 'tempfile'
+
+describe "the extlookup function" do
+
+ before :each do
+ @scope = Puppet::Parser::Scope.new
+
+ @scope.stubs(:environment).returns(Puppet::Node::Environment.new('production'))
+ Puppet::Parser::Functions.function("extlookup")
+ end
+
+ it "should exist" do
+ Puppet::Parser::Functions.function("extlookup").should == "function_extlookup"
+ end
+
+ it "should raise a ParseError if there is less than 1 arguments" do
+ lambda { @scope.function_extlookup([]) }.should( raise_error(Puppet::ParseError))
+ end
+
+ it "should raise a ParseError if there is more than 3 arguments" do
+ lambda { @scope.function_extlookup(["foo", "bar", "baz", "gazonk"]) }.should( raise_error(Puppet::ParseError))
+ end
+
+ it "should return the default" do
+ result = @scope.function_extlookup([ "key", "default"])
+ result.should == "default"
+ end
+
+ it "should lookup the key in a supplied datafile" do
+ t = Tempfile.new('extlookup.csv') do
+ t.puts 'key,value'
+ t.puts 'nonkey,nonvalue'
+ t.close
+
+ result = @scope.function_extlookup([ "key", "default", t.path])
+ result.should == "value"
+ end
+ end
+
+ it "should return an array if the datafile contains more than two columns" do
+ t = Tempfile.new('extlookup.csv') do
+ t.puts 'key,value1,value2'
+ t.puts 'nonkey,nonvalue,nonvalue'
+ t.close
+
+ result = @scope.function_extlookup([ "key", "default", t.path])
+ result.should == ["value1", "value2"]
+ end
+ end
+
+ it "should raise an error if there's no matching key and no default" do
+ t = Tempfile.new('extlookup.csv') do
+ t.puts 'key,value'
+ t.puts 'nonkey,nonvalue'
+ t.close
+
+ result = @scope.function_extlookup([ "key", nil, t.path])
+ result.should == "value"
+ end
+ end
+
+ describe "should look in $extlookup_datadir for data files listed by $extlookup_precedence" do
+ before do
+ @scope.stubs(:lookupvar).with('extlookup_datadir').returns("/tmp")
+ File.open("/tmp/one.csv","w"){|one| one.puts "key,value1" }
+ File.open("/tmp/two.csv","w") do |two|
+ two.puts "key,value2"
+ two.puts "key2,value_two"
+ end
+ end
+
+ it "when the key is in the first file" do
+ @scope.stubs(:lookupvar).with('extlookup_precedence').returns(["one","two"])
+ result = @scope.function_extlookup([ "key" ])
+ result.should == "value1"
+ end
+
+ it "when the key is in the second file" do
+ @scope.stubs(:lookupvar).with('extlookup_precedence').returns(["one","two"])
+ result = @scope.function_extlookup([ "key2" ])
+ result.should == "value_two"
+ end
+
+ it "should not modify extlookup_precedence data" do
+ variable = '%{fqdn}'
+ @scope.stubs(:lookupvar).with('extlookup_precedence').returns([variable,"one"])
+ @scope.stubs(:lookupvar).with('fqdn').returns('myfqdn')
+ result = @scope.function_extlookup([ "key" ])
+ variable.should == '%{fqdn}'
+ end
+ end
+end
diff --git a/spec/unit/parser/functions/include_spec.rb b/spec/unit/parser/functions/include_spec.rb
new file mode 100644
index 000000000..4f609b055
--- /dev/null
+++ b/spec/unit/parser/functions/include_spec.rb
@@ -0,0 +1,33 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+describe "the 'include' function" do
+
+ before :each do
+ Puppet::Node::Environment.stubs(:current).returns(nil)
+ @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("foo"))
+ @scope = Puppet::Parser::Scope.new(:compiler => @compiler)
+ end
+
+ it "should exist" do
+ Puppet::Parser::Functions.function("include").should == "function_include"
+ end
+
+ it "should include a single class" do
+ inc = "foo"
+ @compiler.expects(:evaluate_classes).with {|klasses,parser,lazy| klasses == [inc]}.returns([inc])
+ @scope.function_include("foo")
+ end
+
+ it "should include multiple classes" do
+ inc = ["foo","bar"]
+ @compiler.expects(:evaluate_classes).with {|klasses,parser,lazy| klasses == inc}.returns(inc)
+ @scope.function_include(["foo","bar"])
+ end
+
+ it "should not lazily evaluate the included class" do
+ @compiler.expects(:evaluate_classes).with {|klasses,parser,lazy| lazy == false}.returns("foo")
+ @scope.function_include("foo")
+ end
+end
diff --git a/spec/unit/parser/functions/require_spec.rb b/spec/unit/parser/functions/require_spec.rb
index bd42fa579..49c4bbf74 100755
--- a/spec/unit/parser/functions/require_spec.rb
+++ b/spec/unit/parser/functions/require_spec.rb
@@ -6,7 +6,7 @@ describe "the require function" do
before :each do
@catalog = stub 'catalog'
- @compiler = stub 'compiler', :catalog => @catalog
+ @compiler = stub 'compiler', :catalog => @catalog, :environment => nil
@scope = Puppet::Parser::Scope.new
@scope.stubs(:findresource)
diff --git a/spec/unit/parser/functions/tag_spec.rb b/spec/unit/parser/functions/tag_spec.rb
index ff37badbb..dac134134 100755
--- a/spec/unit/parser/functions/tag_spec.rb
+++ b/spec/unit/parser/functions/tag_spec.rb
@@ -6,6 +6,7 @@ describe "the 'tag' function" do
before :each do
@scope = Puppet::Parser::Scope.new
+ @scope.stubs(:environment).returns(nil)
end
it "should exist" do
diff --git a/spec/unit/parser/lexer_spec.rb b/spec/unit/parser/lexer_spec.rb
index d3d2a0a31..d52add399 100755
--- a/spec/unit/parser/lexer_spec.rb
+++ b/spec/unit/parser/lexer_spec.rb
@@ -30,6 +30,14 @@ describe Puppet::Parser::Lexer do
@lexer.line.should == 10
end
+
+ it "should not think the terminator is escaped, when preceeded by an even number of backslashes" do
+ @lexer.line = 10
+ @lexer.string = "here\nis\nthe\nstring\\\\'with\nextra\njunk"
+ @lexer.slurpstring("'")
+
+ @lexer.line.should == 13
+ end
end
end
@@ -410,8 +418,13 @@ describe Puppet::Parser::Lexer,"when lexing strings" do
%q{'single quoted string')} => [[:STRING,'single quoted string']],
%q{"double quoted string"} => [[:STRING,'double quoted string']],
%q{'single quoted string with an escaped "\\'"'} => [[:STRING,'single quoted string with an escaped "\'"']],
+ %q{'single quoted string with an escaped "\$"'} => [[:STRING,'single quoted string with an escaped "\$"']],
+ %q{'single quoted string with an escaped "\."'} => [[:STRING,'single quoted string with an escaped "\."']],
+ %q{'single quoted string with an escaped "\n"'} => [[:STRING,'single quoted string with an escaped "\n"']],
+ %q{'single quoted string with an escaped "\\\\"'} => [[:STRING,'single quoted string with an escaped "\\\\"']],
%q{"string with an escaped '\\"'"} => [[:STRING,"string with an escaped '\"'"]],
%q{"string with an escaped '\\$'"} => [[:STRING,"string with an escaped '$'"]],
+ %Q{"string with a line ending with a backslash: \\\nfoo"} => [[:STRING,"string with a line ending with a backslash: foo"]],
%q{"string with $v (but no braces)"} => [[:DQPRE,"string with "],[:VARIABLE,'v'],[:DQPOST,' (but no braces)']],
%q["string with ${v} in braces"] => [[:DQPRE,"string with "],[:VARIABLE,'v'],[:DQPOST,' in braces']],
%q["string with ${qualified::var} in braces"] => [[:DQPRE,"string with "],[:VARIABLE,'qualified::var'],[:DQPOST,' in braces']],
@@ -616,6 +629,12 @@ describe "Puppet::Parser::Lexer in the old tests" do
@lexer.namespace.should == "base::sub"
end
+ it "should not put class instantiation on the namespace" do
+ @lexer.string = "class base { class sub { class { mode"
+ @lexer.fullscan
+ @lexer.namespace.should == "base::sub"
+ end
+
it "should correctly handle fully qualified names" do
@lexer.string = "class base { class sub::more {"
@lexer.fullscan
@@ -634,7 +653,6 @@ end
require 'puppettest/support/utils'
describe "Puppet::Parser::Lexer in the old tests when lexing example files" do
- extend PuppetTest
extend PuppetTest::Support::Utils
textfiles do |file|
it "should correctly lex #{file}" do
diff --git a/spec/unit/parser/parser_spec.rb b/spec/unit/parser/parser_spec.rb
index 0657ab37a..ab43194e9 100755
--- a/spec/unit/parser/parser_spec.rb
+++ b/spec/unit/parser/parser_spec.rb
@@ -4,7 +4,7 @@ require File.dirname(__FILE__) + '/../../spec_helper'
describe Puppet::Parser do
- ast = Puppet::Parser::AST
+ Puppet::Parser::AST
before :each do
@known_resource_types = Puppet::Resource::TypeCollection.new("development")
@@ -52,15 +52,6 @@ describe Puppet::Parser do
@parser.file = "/my/file.rb"
@parser.parse
end
-
- describe "in ruby" do
- it "should use the ruby interpreter to load the file" do
- @parser.file = "/my/file.rb"
- @parser.expects(:require).with "/my/file.rb"
-
- @parser.parse_ruby_file
- end
- end
end
describe "when parsing append operator" do
@@ -73,35 +64,37 @@ describe Puppet::Parser do
lambda { @parser.parse("$var += ") }.should raise_error
end
- it "should call ast::VarDef with append=true" do
- ast::VarDef.expects(:new).with { |h| h[:append] == true }
- @parser.parse("$var += 2")
+ it "should create ast::VarDef with append=true" do
+ vardef = @parser.parse("$var += 2").code[0]
+ vardef.should be_a(Puppet::Parser::AST::VarDef)
+ vardef.append.should == true
end
it "should work with arrays too" do
- ast::VarDef.expects(:new).with { |h| h[:append] == true }
- @parser.parse("$var += ['test']")
+ vardef = @parser.parse("$var += ['test']").code[0]
+ vardef.should be_a(Puppet::Parser::AST::VarDef)
+ vardef.append.should == true
end
end
describe "when parsing 'if'" do
it "not, it should create the correct ast objects" do
- ast::Not.expects(:new).with { |h| h[:value].is_a?(ast::Boolean) }
+ Puppet::Parser::AST::Not.expects(:new).with { |h| h[:value].is_a?(Puppet::Parser::AST::Boolean) }
@parser.parse("if ! true { $var = 1 }")
end
it "boolean operation, it should create the correct ast objects" do
- ast::BooleanOperator.expects(:new).with {
- |h| h[:rval].is_a?(ast::Boolean) and h[:lval].is_a?(ast::Boolean) and h[:operator]=="or"
+ Puppet::Parser::AST::BooleanOperator.expects(:new).with {
+ |h| h[:rval].is_a?(Puppet::Parser::AST::Boolean) and h[:lval].is_a?(Puppet::Parser::AST::Boolean) and h[:operator]=="or"
}
@parser.parse("if true or true { $var = 1 }")
end
it "comparison operation, it should create the correct ast objects" do
- ast::ComparisonOperator.expects(:new).with {
- |h| h[:lval].is_a?(ast::Name) and h[:rval].is_a?(ast::Name) and h[:operator]=="<"
+ Puppet::Parser::AST::ComparisonOperator.expects(:new).with {
+ |h| h[:lval].is_a?(Puppet::Parser::AST::Name) and h[:rval].is_a?(Puppet::Parser::AST::Name) and h[:operator]=="<"
}
@parser.parse("if 1 < 2 { $var = 1 }")
@@ -112,13 +105,13 @@ describe Puppet::Parser do
describe "when parsing if complex expressions" do
it "should create a correct ast tree" do
aststub = stub_everything 'ast'
- ast::ComparisonOperator.expects(:new).with {
- |h| h[:rval].is_a?(ast::Name) and h[:lval].is_a?(ast::Name) and h[:operator]==">"
+ Puppet::Parser::AST::ComparisonOperator.expects(:new).with {
+ |h| h[:rval].is_a?(Puppet::Parser::AST::Name) and h[:lval].is_a?(Puppet::Parser::AST::Name) and h[:operator]==">"
}.returns(aststub)
- ast::ComparisonOperator.expects(:new).with {
- |h| h[:rval].is_a?(ast::Name) and h[:lval].is_a?(ast::Name) and h[:operator]=="=="
+ Puppet::Parser::AST::ComparisonOperator.expects(:new).with {
+ |h| h[:rval].is_a?(Puppet::Parser::AST::Name) and h[:lval].is_a?(Puppet::Parser::AST::Name) and h[:operator]=="=="
}.returns(aststub)
- ast::BooleanOperator.expects(:new).with {
+ Puppet::Parser::AST::BooleanOperator.expects(:new).with {
|h| h[:rval]==aststub and h[:lval]==aststub and h[:operator]=="and"
}
@parser.parse("if (1 > 2) and (1 == 2) { $var = 1 }")
@@ -141,9 +134,8 @@ describe Puppet::Parser do
end
it "should create an ast::ResourceReference" do
- ast::Resource.stubs(:new)
- ast::ResourceReference.expects(:new).with { |arg|
- arg[:line]==1 and arg[:type]=="File" and arg[:title].is_a?(ast::ASTArray)
+ Puppet::Parser::AST::ResourceReference.expects(:new).with { |arg|
+ arg[:line]==1 and arg[:type]=="File" and arg[:title].is_a?(Puppet::Parser::AST::ASTArray)
}
@parser.parse('exec { test: command => File["a","b"] }')
end
@@ -160,10 +152,14 @@ describe Puppet::Parser do
end
it "should create an ast::ResourceOverride" do
- ast::ResourceOverride.expects(:new).with { |arg|
- arg[:line]==1 and arg[:object].is_a?(ast::ResourceReference) and arg[:parameters].is_a?(ast::ResourceParam)
- }
- @parser.parse('Resource["title1","title2"] { param => value }')
+ #Puppet::Parser::AST::ResourceOverride.expects(:new).with { |arg|
+ # arg[:line]==1 and arg[:object].is_a?(Puppet::Parser::AST::ResourceReference) and arg[:parameters].is_a?(Puppet::Parser::AST::ResourceParam)
+ #}
+ ro = @parser.parse('Resource["title1","title2"] { param => value }').code[0]
+ ro.should be_a(Puppet::Parser::AST::ResourceOverride)
+ ro.line.should == 1
+ ro.object.should be_a(Puppet::Parser::AST::ResourceReference)
+ ro.parameters[0].should be_a(Puppet::Parser::AST::ResourceParam)
end
end
@@ -183,17 +179,17 @@ describe Puppet::Parser do
end
it "should create a nop node for empty branch" do
- ast::Nop.expects(:new)
+ Puppet::Parser::AST::Nop.expects(:new)
@parser.parse("if true { }")
end
it "should create a nop node for empty else branch" do
- ast::Nop.expects(:new)
+ Puppet::Parser::AST::Nop.expects(:new)
@parser.parse("if true { notice('test') } else { }")
end
it "should build a chain of 'ifs' if there's an 'elsif'" do
- ast = @parser.parse(<<-PP)
+ lambda { @parser.parse(<<-PP) }.should_not raise_error
if true { notice('test') } elsif true {} else { }
PP
end
@@ -278,33 +274,22 @@ describe Puppet::Parser do
it "should prefer provided options over AST context" do
@class.expects(:new).with { |opts| opts[:file] == "/bar" }
- @parser.expects(:ast_context).returns :file => "/foo"
+ @lexer.expects(:file).returns "/foo"
@parser.ast(@class, :file => "/bar")
end
it "should include docs when the AST class uses them" do
@class.expects(:use_docs).returns true
@class.stubs(:new)
- @parser.expects(:ast_context).with(true).returns({})
+ @parser.expects(:ast_context).with{ |a| a[0] == true }.returns({})
@parser.ast(@class, :file => "/bar")
end
- end
-
- describe "when creating a node" do
- before :each do
- @lexer = stub 'lexer'
- @lexer.stubs(:getcomment)
- @parser.stubs(:lexer).returns(@lexer)
- @node = stub_everything 'node'
- @parser.stubs(:ast_context).returns({})
- @parser.stubs(:node).returns(nil)
-
- @nodename = stub 'nodename', :is_a? => false, :value => "foo"
- @nodename.stubs(:is_a?).with(Puppet::Parser::AST::HostName).returns(true)
- end
- it "should return an array of nodes" do
- @parser.newnode(@nodename).should be_instance_of(Array)
+ it "should get docs from lexer using the correct AST line number" do
+ @class.expects(:use_docs).returns true
+ @class.stubs(:new).with{ |a| a[:doc] == "doc" }
+ @lexer.expects(:getcomment).with(12).returns "doc"
+ @parser.ast(@class, :file => "/bar", :line => 12)
end
end
@@ -360,30 +345,28 @@ describe Puppet::Parser do
@parser.stubs(:known_resource_types).returns @krt
end
- it "should create new classes" do
- @parser.parse("class foobar {}")
- @krt.hostclass("foobar").should be_instance_of(Puppet::Resource::Type)
+ it "should not create new classes" do
+ @parser.parse("class foobar {}").code[0].should be_a(Puppet::Parser::AST::Hostclass)
+ @krt.hostclass("foobar").should be_nil
end
it "should correctly set the parent class when one is provided" do
- @parser.parse("class foobar inherits yayness {}")
- @krt.hostclass("foobar").parent.should == "yayness"
+ @parser.parse("class foobar inherits yayness {}").code[0].instantiate('')[0].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"
+ statements = @parser.parse("class foobar inherits yayness {}\nclass boo inherits bar {}").code
+ statements[0].instantiate('')[0].parent.should == "yayness"
+ statements[1].instantiate('')[0].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
+ @parser.parse("class foobar { $var = val }").code[0].code.should_not be_nil
end
it "should define parameters when provided" do
- @parser.parse("class foobar($biz,$baz) {}")
- @krt.hostclass("foobar").arguments.should == {"biz" => nil, "baz" => nil}
+ foobar = @parser.parse("class foobar($biz,$baz) {}").code[0].instantiate('')[0]
+ foobar.arguments.should == {"biz" => nil, "baz" => nil}
end
end
@@ -400,13 +383,37 @@ describe Puppet::Parser do
end
it "should correctly mark exported resources as exported" do
- @parser.parse("@@file { '/file': }")
- @krt.hostclass("").code[0].exported.should be_true
+ @parser.parse("@@file { '/file': }").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
+ @parser.parse("@file { '/file': }").code[0].virtual.should be_true
+ end
+ end
+
+ describe "when parsing nodes" do
+ it "should be able to parse a node with a single name" do
+ node = @parser.parse("node foo { }").code[0]
+ node.should be_a Puppet::Parser::AST::Node
+ node.names.length.should == 1
+ node.names[0].value.should == "foo"
+ end
+
+ it "should be able to parse a node with two names" do
+ node = @parser.parse("node foo, bar { }").code[0]
+ node.should be_a Puppet::Parser::AST::Node
+ node.names.length.should == 2
+ node.names[0].value.should == "foo"
+ node.names[1].value.should == "bar"
+ end
+
+ it "should be able to parse a node with three names" do
+ node = @parser.parse("node foo, bar, baz { }").code[0]
+ node.should be_a Puppet::Parser::AST::Node
+ node.names.length.should == 3
+ node.names[0].value.should == "foo"
+ node.names[1].value.should == "bar"
+ node.names[2].value.should == "baz"
end
end
end
diff --git a/spec/unit/parser/resource_spec.rb b/spec/unit/parser/resource_spec.rb
index da49940b0..dae22fcaa 100755
--- a/spec/unit/parser/resource_spec.rb
+++ b/spec/unit/parser/resource_spec.rb
@@ -58,23 +58,17 @@ describe Puppet::Parser::Resource do
end
it "should get its environment from its scope" do
- scope = stub 'scope', :source => stub("source")
- scope.expects(:environment).returns "foo"
+ scope = stub 'scope', :source => stub("source"), :namespaces => nil
+ scope.expects(:environment).returns("foo").at_least_once
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 use the resource type collection helper module" do
Puppet::Parser::Resource.ancestors.should be_include(Puppet::Resource::TypeCollectionHelper)
end
it "should use the scope's environment as its environment" do
- @scope.expects(:environment).returns "myenv"
+ @scope.expects(:environment).returns("myenv").at_least_once
Puppet::Parser::Resource.new("file", "whatever", :scope => @scope).environment.should == "myenv"
end
diff --git a/spec/unit/parser/scope_spec.rb b/spec/unit/parser/scope_spec.rb
index 9895f446b..2e390a53b 100755
--- a/spec/unit/parser/scope_spec.rb
+++ b/spec/unit/parser/scope_spec.rb
@@ -29,8 +29,7 @@ describe Puppet::Parser::Scope do
end
it "should be able to retrieve its parent module name from the source of its parent type" do
- @topscope.source = Puppet::Resource::Type.new(:hostclass, :foo)
- @topscope.source.module_name = "foo"
+ @topscope.source = Puppet::Resource::Type.new(:hostclass, :foo, :module_name => "foo")
@scope.parent_module_name.should == "foo"
end
diff --git a/spec/unit/parser/templatewrapper_spec.rb b/spec/unit/parser/templatewrapper_spec.rb
index d4d1d1b8e..68d90a1cc 100755
--- a/spec/unit/parser/templatewrapper_spec.rb
+++ b/spec/unit/parser/templatewrapper_spec.rb
@@ -1,6 +1,7 @@
#!/usr/bin/env ruby
require File.dirname(__FILE__) + '/../../spec_helper'
+require 'puppet/parser/templatewrapper'
describe Puppet::Parser::TemplateWrapper do
before(:each) do
diff --git a/spec/unit/parser/type_loader_spec.rb b/spec/unit/parser/type_loader_spec.rb
index 8f005d551..cfa68871d 100644
--- a/spec/unit/parser/type_loader_spec.rb
+++ b/spec/unit/parser/type_loader_spec.rb
@@ -28,92 +28,21 @@ describe Puppet::Parser::TypeLoader do
describe "when loading names from namespaces" do
it "should do nothing if the name to import is an empty string" do
@loader.expects(:name2files).never
- @loader.load_until(["foo"], "") { |f| false }.should be_nil
- end
-
- it "should turn the provided namespaces and name into a list of files" do
- @loader.expects(:name2files).with(["foo"], "bar").returns []
- @loader.load_until(["foo"], "bar") { |f| false }
+ @loader.try_load_fqname(:hostclass, "") { |filename, modname| raise :should_not_occur }.should be_nil
end
it "should attempt to import each generated name" do
- @loader.expects(:name2files).returns %w{foo bar}
- @loader.expects(:import).with("foo",nil)
- @loader.expects(:import).with("bar",nil)
- @loader.load_until(["foo"], "bar") { |f| false }
- end
-
- it "should yield after each import" do
- yielded = []
- @loader.expects(:name2files).returns %w{foo bar}
- @loader.expects(:import).with("foo",nil)
- @loader.expects(:import).with("bar",nil)
- @loader.load_until(["foo"], "bar") { |f| yielded << f; false }
- yielded.should == %w{foo bar}
- end
-
- it "should stop importing when the yielded block returns true" do
- yielded = []
- @loader.expects(:name2files).returns %w{foo bar baz}
- @loader.expects(:import).with("foo",nil)
- @loader.expects(:import).with("bar",nil)
- @loader.expects(:import).with("baz",nil).never
- @loader.load_until(["foo"], "bar") { |f| true if f == "bar" }
- end
-
- it "should return the result of the block" do
- yielded = []
- @loader.expects(:name2files).returns %w{foo bar baz}
- @loader.expects(:import).with("foo",nil)
- @loader.expects(:import).with("bar",nil)
- @loader.expects(:import).with("baz",nil).never
- @loader.load_until(["foo"], "bar") { |f| 10 if f == "bar" }.should == 10
- end
-
- it "should return nil if the block never returns true" do
- @loader.expects(:name2files).returns %w{foo bar}
- @loader.expects(:import).with("foo",nil)
- @loader.expects(:import).with("bar",nil)
- @loader.load_until(["foo"], "bar") { |f| false }.should be_nil
- end
-
- it "should know when a given name has been loaded" do
- @loader.expects(:name2files).returns %w{file}
- @loader.expects(:import).with("file",nil)
- @loader.load_until(["foo"], "bar") { |f| true }
- @loader.should be_loaded("file")
- end
-
- it "should set the module name on any created resource types" do
- type = Puppet::Resource::Type.new(:hostclass, "mytype")
-
- Puppet::Parser::Files.expects(:find_manifests).returns ["modname", %w{one}]
- @loader.stubs(:parse_file)
- @loader.load_until(["foo"], "one") { |f| type }
-
- type.module_name.should == "modname"
- end
- end
-
- describe "when mapping names to files" do
- {
- [["foo"], "::bar::baz"] => %w{bar/baz},
- [[""], "foo::bar"] => %w{foo foo/bar},
- [%w{foo}, "bar"] => %w{foo foo/bar bar},
- [%w{a b}, "bar"] => %w{a a/bar b b/bar bar},
- [%w{a::b::c}, "bar"] => %w{a a/b/c/bar bar},
- [%w{a::b}, "foo::bar"] => %w{a a/b/foo/bar foo/bar}
- }.each do |inputs, outputs|
- it "should produce #{outputs.inspect} from the #{inputs[0].inspect} namespace and #{inputs[1]} name" do
- @loader.name2files(*inputs).should == outputs
- end
+ @loader.expects(:import).with("foo/bar",nil).returns([])
+ @loader.expects(:import).with("foo",nil).returns([])
+ @loader.try_load_fqname(:hostclass, "foo::bar") { |f| false }
end
end
describe "when importing" do
before do
Puppet::Parser::Files.stubs(:find_manifests).returns ["modname", %w{file}]
- @loader.stubs(:parse_file)
+ Puppet::Parser::Parser.any_instance.stubs(:parse).returns(Puppet::Parser::AST::Hostclass.new(''))
+ Puppet::Parser::Parser.any_instance.stubs(:file=)
end
it "should return immediately when imports are being ignored" do
@@ -144,26 +73,19 @@ describe Puppet::Parser::TypeLoader do
it "should parse each found file" do
Puppet::Parser::Files.expects(:find_manifests).returns ["modname", %w{/one}]
- @loader.expects(:parse_file).with("/one")
+ @loader.expects(:parse_file).with("/one").returns(Puppet::Parser::AST::Hostclass.new(''))
@loader.import("myfile")
end
it "should make each file qualified before attempting to parse it" do
Puppet::Parser::Files.expects(:find_manifests).returns ["modname", %w{one}]
- @loader.expects(:parse_file).with("/current/one")
+ @loader.expects(:parse_file).with("/current/one").returns(Puppet::Parser::AST::Hostclass.new(''))
@loader.import("myfile", "/current/file")
end
- it "should know when a given file has been imported" do
- Puppet::Parser::Files.expects(:find_manifests).returns ["modname", %w{/one}]
- @loader.import("myfile")
-
- @loader.should be_imported("/one")
- end
-
it "should not attempt to import files that have already been imported" do
Puppet::Parser::Files.expects(:find_manifests).returns ["modname", %w{/one}]
- @loader.expects(:parse_file).once
+ Puppet::Parser::Parser.any_instance.expects(:parse).once.returns(Puppet::Parser::AST::Hostclass.new(''))
@loader.import("myfile")
# This will fail if it tries to reimport the file.
@@ -174,7 +96,7 @@ describe Puppet::Parser::TypeLoader do
describe "when parsing a file" do
before do
@parser = Puppet::Parser::Parser.new(@loader.environment)
- @parser.stubs(:parse)
+ @parser.stubs(:parse).returns(Puppet::Parser::AST::Hostclass.new(''))
@parser.stubs(:file=)
Puppet::Parser::Parser.stubs(:new).with(@loader.environment).returns @parser
end
@@ -186,16 +108,27 @@ describe Puppet::Parser::TypeLoader do
it "should assign the parser its file and parse" do
@parser.expects(:file=).with("/my/file")
- @parser.expects(:parse)
+ @parser.expects(:parse).returns(Puppet::Parser::AST::Hostclass.new(''))
@loader.parse_file("/my/file")
end
end
it "should be able to add classes to the current resource type collection" do
- file = tmpfile("simple_file")
+ file = tmpfile("simple_file.pp")
File.open(file, "w") { |f| f.puts "class foo {}" }
@loader.import(file)
@loader.known_resource_types.hostclass("foo").should be_instance_of(Puppet::Resource::Type)
end
+
+ describe "when deciding where to look for files" do
+ { 'foo' => ['foo'],
+ 'foo::bar' => ['foo/bar', 'foo'],
+ 'foo::bar::baz' => ['foo/bar/baz', 'foo/bar', 'foo']
+ }.each do |fqname, expected_paths|
+ it "should look for #{fqname.inspect} in #{expected_paths.inspect}" do
+ @loader.instance_eval { name2files(fqname) }.should == expected_paths
+ end
+ end
+ end
end