diff options
| author | Markus Roberts <Markus@reality.com> | 2010-07-09 18:12:17 -0700 |
|---|---|---|
| committer | Markus Roberts <Markus@reality.com> | 2010-07-09 18:12:17 -0700 |
| commit | 3180b9d9b2c844dade1d361326600f7001ec66dd (patch) | |
| tree | 98fe7c5ac7eb942aac9c39f019a17b0b3f5a57f4 /spec/unit/parser | |
| parent | 543225970225de5697734bfaf0a6eee996802c04 (diff) | |
| download | puppet-3180b9d9b2c844dade1d361326600f7001ec66dd.tar.gz puppet-3180b9d9b2c844dade1d361326600f7001ec66dd.tar.xz puppet-3180b9d9b2c844dade1d361326600f7001ec66dd.zip | |
Code smell: Two space indentation
Replaced 106806 occurances of ^( +)(.*$) with
The ruby community almost universally (i.e. everyone but Luke, Markus, and the other eleven people
who learned ruby in the 1900s) uses two-space indentation.
3 Examples:
The code:
end
# Tell getopt which arguments are valid
def test_get_getopt_args
element = Setting.new :name => "foo", :desc => "anything", :settings => Puppet::Util::Settings.new
assert_equal([["--foo", GetoptLong::REQUIRED_ARGUMENT]], element.getopt_args, "Did not produce appropriate getopt args")
becomes:
end
# Tell getopt which arguments are valid
def test_get_getopt_args
element = Setting.new :name => "foo", :desc => "anything", :settings => Puppet::Util::Settings.new
assert_equal([["--foo", GetoptLong::REQUIRED_ARGUMENT]], element.getopt_args, "Did not produce appropriate getopt args")
The code:
assert_equal(str, val)
assert_instance_of(Float, result)
end
# Now test it with a passed object
becomes:
assert_equal(str, val)
assert_instance_of(Float, result)
end
# Now test it with a passed object
The code:
end
assert_nothing_raised do
klass[:Yay] = "boo"
klass["Cool"] = :yayness
end
becomes:
end
assert_nothing_raised do
klass[:Yay] = "boo"
klass["Cool"] = :yayness
end
Diffstat (limited to 'spec/unit/parser')
48 files changed, 5459 insertions, 5459 deletions
diff --git a/spec/unit/parser/ast/arithmetic_operator_spec.rb b/spec/unit/parser/ast/arithmetic_operator_spec.rb index 3ebd2691e..093cf94f1 100755 --- a/spec/unit/parser/ast/arithmetic_operator_spec.rb +++ b/spec/unit/parser/ast/arithmetic_operator_spec.rb @@ -4,70 +4,70 @@ require File.dirname(__FILE__) + '/../../../spec_helper' describe Puppet::Parser::AST::ArithmeticOperator do - ast = Puppet::Parser::AST - - before :each do - @scope = Puppet::Parser::Scope.new - @one = stub 'lval', :safeevaluate => 1 - @two = stub 'rval', :safeevaluate => 2 - end - - it "should evaluate both branches" do - lval = stub "lval" - lval.expects(:safeevaluate).with(@scope).returns(1) - rval = stub "rval" - rval.expects(:safeevaluate).with(@scope).returns(2) - - operator = ast::ArithmeticOperator.new :rval => rval, :operator => "+", :lval => lval - operator.evaluate(@scope) - end - - it "should fail for an unknown operator" do - lambda { operator = ast::ArithmeticOperator.new :lval => @one, :operator => "%", :rval => @two }.should raise_error - end - - it "should call Puppet::Parser::Scope.number?" do - Puppet::Parser::Scope.expects(:number?).with(1).returns(1) - Puppet::Parser::Scope.expects(:number?).with(2).returns(2) - - ast::ArithmeticOperator.new(:lval => @one, :operator => "+", :rval => @two).evaluate(@scope) - end - - - %w{ + - * / << >>}.each do |op| - it "should call ruby Numeric '#{op}'" do - one = stub 'one' - two = stub 'two' - operator = ast::ArithmeticOperator.new :lval => @one, :operator => op, :rval => @two - Puppet::Parser::Scope.stubs(:number?).with(1).returns(one) - Puppet::Parser::Scope.stubs(:number?).with(2).returns(two) - one.expects(:send).with(op,two) - operator.evaluate(@scope) - end - end - - it "should work even with numbers embedded in strings" do - two = stub 'two', :safeevaluate => "2" - one = stub 'one', :safeevaluate => "1" - operator = ast::ArithmeticOperator.new :lval => two, :operator => "+", :rval => one - operator.evaluate(@scope).should == 3 - end - - it "should work even with floats" do - two = stub 'two', :safeevaluate => 2.53 - one = stub 'one', :safeevaluate => 1.80 - operator = ast::ArithmeticOperator.new :lval => two, :operator => "+", :rval => one - operator.evaluate(@scope).should == 4.33 - end - - it "should work for variables too" do - @scope.expects(:lookupvar).with("one", false).returns(1) - @scope.expects(:lookupvar).with("two", false).returns(2) - one = ast::Variable.new( :value => "one" ) - two = ast::Variable.new( :value => "two" ) - - operator = ast::ArithmeticOperator.new :lval => one, :operator => "+", :rval => two - operator.evaluate(@scope).should == 3 + ast = Puppet::Parser::AST + + before :each do + @scope = Puppet::Parser::Scope.new + @one = stub 'lval', :safeevaluate => 1 + @two = stub 'rval', :safeevaluate => 2 + end + + it "should evaluate both branches" do + lval = stub "lval" + lval.expects(:safeevaluate).with(@scope).returns(1) + rval = stub "rval" + rval.expects(:safeevaluate).with(@scope).returns(2) + + operator = ast::ArithmeticOperator.new :rval => rval, :operator => "+", :lval => lval + operator.evaluate(@scope) + end + + it "should fail for an unknown operator" do + lambda { operator = ast::ArithmeticOperator.new :lval => @one, :operator => "%", :rval => @two }.should raise_error + end + + it "should call Puppet::Parser::Scope.number?" do + Puppet::Parser::Scope.expects(:number?).with(1).returns(1) + Puppet::Parser::Scope.expects(:number?).with(2).returns(2) + + ast::ArithmeticOperator.new(:lval => @one, :operator => "+", :rval => @two).evaluate(@scope) + end + + + %w{ + - * / << >>}.each do |op| + it "should call ruby Numeric '#{op}'" do + one = stub 'one' + two = stub 'two' + operator = ast::ArithmeticOperator.new :lval => @one, :operator => op, :rval => @two + Puppet::Parser::Scope.stubs(:number?).with(1).returns(one) + Puppet::Parser::Scope.stubs(:number?).with(2).returns(two) + one.expects(:send).with(op,two) + operator.evaluate(@scope) end + end + + it "should work even with numbers embedded in strings" do + two = stub 'two', :safeevaluate => "2" + one = stub 'one', :safeevaluate => "1" + operator = ast::ArithmeticOperator.new :lval => two, :operator => "+", :rval => one + operator.evaluate(@scope).should == 3 + end + + it "should work even with floats" do + two = stub 'two', :safeevaluate => 2.53 + one = stub 'one', :safeevaluate => 1.80 + operator = ast::ArithmeticOperator.new :lval => two, :operator => "+", :rval => one + operator.evaluate(@scope).should == 4.33 + end + + it "should work for variables too" do + @scope.expects(:lookupvar).with("one", false).returns(1) + @scope.expects(:lookupvar).with("two", false).returns(2) + one = ast::Variable.new( :value => "one" ) + two = ast::Variable.new( :value => "two" ) + + operator = ast::ArithmeticOperator.new :lval => one, :operator => "+", :rval => two + operator.evaluate(@scope).should == 3 + end end diff --git a/spec/unit/parser/ast/astarray_spec.rb b/spec/unit/parser/ast/astarray_spec.rb index b9453c967..f79d6c533 100755 --- a/spec/unit/parser/ast/astarray_spec.rb +++ b/spec/unit/parser/ast/astarray_spec.rb @@ -3,70 +3,70 @@ require File.dirname(__FILE__) + '/../../../spec_helper' describe Puppet::Parser::AST::ASTArray do - before :each do - @scope = Puppet::Parser::Scope.new - end - - it "should have a [] accessor" do - array = Puppet::Parser::AST::ASTArray.new :children => [] - array.should respond_to(:[]) - end - - it "should evaluate all its children" do - item1 = stub "item1", :is_a? => true - item2 = stub "item2", :is_a? => true - - item1.expects(:safeevaluate).with(@scope).returns(123) - item2.expects(:safeevaluate).with(@scope).returns(246) - - operator = Puppet::Parser::AST::ASTArray.new :children => [item1,item2] - 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] - 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]) - - operator = Puppet::Parser::AST::ASTArray.new :children => [item2] - operator.evaluate(@scope).should == [[123]] - end - - it "should return a valid string with to_s" do - a = stub 'a', :is_a? => true, :to_s => "a" - b = stub 'b', :is_a? => true, :to_s => "b" - array = Puppet::Parser::AST::ASTArray.new :children => [a,b] - - array.to_s.should == "[a, b]" - end + before :each do + @scope = Puppet::Parser::Scope.new + end + + it "should have a [] accessor" do + array = Puppet::Parser::AST::ASTArray.new :children => [] + array.should respond_to(:[]) + end + + it "should evaluate all its children" do + item1 = stub "item1", :is_a? => true + item2 = stub "item2", :is_a? => true + + item1.expects(:safeevaluate).with(@scope).returns(123) + item2.expects(:safeevaluate).with(@scope).returns(246) + + operator = Puppet::Parser::AST::ASTArray.new :children => [item1,item2] + 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] + 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]) + + operator = Puppet::Parser::AST::ASTArray.new :children => [item2] + operator.evaluate(@scope).should == [[123]] + end + + it "should return a valid string with to_s" do + a = stub 'a', :is_a? => true, :to_s => "a" + b = stub 'b', :is_a? => true, :to_s => "b" + array = Puppet::Parser::AST::ASTArray.new :children => [a,b] + + array.to_s.should == "[a, b]" + end end diff --git a/spec/unit/parser/ast/asthash_spec.rb b/spec/unit/parser/ast/asthash_spec.rb index be3199b8a..c70553c56 100644 --- a/spec/unit/parser/ast/asthash_spec.rb +++ b/spec/unit/parser/ast/asthash_spec.rb @@ -3,96 +3,96 @@ require File.dirname(__FILE__) + '/../../../spec_helper' describe Puppet::Parser::AST::ASTHash do - before :each do - @scope = Puppet::Parser::Scope.new + before :each do + @scope = Puppet::Parser::Scope.new + end + + it "should have a merge functionality" do + hash = Puppet::Parser::AST::ASTHash.new(:value => {}) + hash.should respond_to(:merge) + end + + it "should be able to merge 2 AST hashes" do + hash = Puppet::Parser::AST::ASTHash.new(:value => { "a" => "b" }) + + hash.merge(Puppet::Parser::AST::ASTHash.new(:value => {"c" => "d"})) + + hash.value.should == { "a" => "b", "c" => "d" } + end + + it "should be able to merge with a ruby Hash" do + hash = Puppet::Parser::AST::ASTHash.new(:value => { "a" => "b" }) + + hash.merge({"c" => "d"}) + + hash.value.should == { "a" => "b", "c" => "d" } + end + + it "should evaluate each hash value" do + key1 = stub "key1" + value1 = stub "value1" + key2 = stub "key2" + value2 = stub "value2" + + value1.expects(:safeevaluate).with(@scope).returns("b") + value2.expects(:safeevaluate).with(@scope).returns("d") + + operator = Puppet::Parser::AST::ASTHash.new(:value => { key1 => value1, key2 => value2}) + operator.evaluate(@scope) + end + + it "should evaluate the hash keys if they are AST instances" do + key1 = stub "key1" + value1 = stub "value1", :safeevaluate => "one" + key2 = stub "key2" + value2 = stub "value2", :safeevaluate => "two" + + key1.expects(:safeevaluate).with(@scope).returns("1") + key2.expects(:safeevaluate).with(@scope).returns("2") + + operator = Puppet::Parser::AST::ASTHash.new(:value => { key1 => value1, key2 => value2}) + hash = operator.evaluate(@scope) + hash["1"].should == "one" + hash["2"].should == "two" + end + + it "should evaluate the hash keys if they are not AST instances" do + key1 = "1" + value1 = stub "value1", :safeevaluate => "one" + key2 = "2" + value2 = stub "value2", :safeevaluate => "two" + + operator = Puppet::Parser::AST::ASTHash.new(:value => { key1 => value1, key2 => value2}) + hash = operator.evaluate(@scope) + hash["1"].should == "one" + hash["2"].should == "two" + end + + it "should return an evaluated hash" do + key1 = stub "key1" + value1 = stub "value1", :safeevaluate => "b" + key2 = stub "key2" + value2 = stub "value2", :safeevaluate => "d" + + operator = Puppet::Parser::AST::ASTHash.new(:value => { key1 => value1, key2 => value2}) + operator.evaluate(@scope).should == { key1 => "b", key2 => "d" } + end + + describe "when being initialized without arguments" do + it "should evaluate to an empty hash" do + hash = Puppet::Parser::AST::ASTHash.new({}) + hash.evaluate(@scope).should == {} end - it "should have a merge functionality" do - hash = Puppet::Parser::AST::ASTHash.new(:value => {}) - hash.should respond_to(:merge) + it "should support merging" do + hash = Puppet::Parser::AST::ASTHash.new({}) + hash.merge({"a" => "b"}).should == {"a" => "b"} end + end - it "should be able to merge 2 AST hashes" do - hash = Puppet::Parser::AST::ASTHash.new(:value => { "a" => "b" }) + it "should return a valid string with to_s" do + hash = Puppet::Parser::AST::ASTHash.new(:value => { "a" => "b", "c" => "d" }) - hash.merge(Puppet::Parser::AST::ASTHash.new(:value => {"c" => "d"})) - - hash.value.should == { "a" => "b", "c" => "d" } - end - - it "should be able to merge with a ruby Hash" do - hash = Puppet::Parser::AST::ASTHash.new(:value => { "a" => "b" }) - - hash.merge({"c" => "d"}) - - hash.value.should == { "a" => "b", "c" => "d" } - end - - it "should evaluate each hash value" do - key1 = stub "key1" - value1 = stub "value1" - key2 = stub "key2" - value2 = stub "value2" - - value1.expects(:safeevaluate).with(@scope).returns("b") - value2.expects(:safeevaluate).with(@scope).returns("d") - - operator = Puppet::Parser::AST::ASTHash.new(:value => { key1 => value1, key2 => value2}) - operator.evaluate(@scope) - end - - it "should evaluate the hash keys if they are AST instances" do - key1 = stub "key1" - value1 = stub "value1", :safeevaluate => "one" - key2 = stub "key2" - value2 = stub "value2", :safeevaluate => "two" - - key1.expects(:safeevaluate).with(@scope).returns("1") - key2.expects(:safeevaluate).with(@scope).returns("2") - - operator = Puppet::Parser::AST::ASTHash.new(:value => { key1 => value1, key2 => value2}) - hash = operator.evaluate(@scope) - hash["1"].should == "one" - hash["2"].should == "two" - end - - it "should evaluate the hash keys if they are not AST instances" do - key1 = "1" - value1 = stub "value1", :safeevaluate => "one" - key2 = "2" - value2 = stub "value2", :safeevaluate => "two" - - operator = Puppet::Parser::AST::ASTHash.new(:value => { key1 => value1, key2 => value2}) - hash = operator.evaluate(@scope) - hash["1"].should == "one" - hash["2"].should == "two" - end - - it "should return an evaluated hash" do - key1 = stub "key1" - value1 = stub "value1", :safeevaluate => "b" - key2 = stub "key2" - value2 = stub "value2", :safeevaluate => "d" - - operator = Puppet::Parser::AST::ASTHash.new(:value => { key1 => value1, key2 => value2}) - operator.evaluate(@scope).should == { key1 => "b", key2 => "d" } - end - - describe "when being initialized without arguments" do - it "should evaluate to an empty hash" do - hash = Puppet::Parser::AST::ASTHash.new({}) - hash.evaluate(@scope).should == {} - end - - it "should support merging" do - hash = Puppet::Parser::AST::ASTHash.new({}) - hash.merge({"a" => "b"}).should == {"a" => "b"} - end - end - - it "should return a valid string with to_s" do - hash = Puppet::Parser::AST::ASTHash.new(:value => { "a" => "b", "c" => "d" }) - - hash.to_s.should == '{a => b, c => d}' - end + hash.to_s.should == '{a => b, c => d}' + end end diff --git a/spec/unit/parser/ast/boolean_operator_spec.rb b/spec/unit/parser/ast/boolean_operator_spec.rb index 23073159a..10e987e31 100755 --- a/spec/unit/parser/ast/boolean_operator_spec.rb +++ b/spec/unit/parser/ast/boolean_operator_spec.rb @@ -4,50 +4,50 @@ require File.dirname(__FILE__) + '/../../../spec_helper' describe Puppet::Parser::AST::BooleanOperator do - ast = Puppet::Parser::AST - - before :each do - @scope = Puppet::Parser::Scope.new - @true_ast = ast::Boolean.new( :value => true) - @false_ast = ast::Boolean.new( :value => false) - end - - it "should evaluate left operand inconditionally" do - lval = stub "lval" - lval.expects(:safeevaluate).with(@scope).returns("true") - rval = stub "rval", :safeevaluate => false - rval.expects(:safeevaluate).never - - operator = ast::BooleanOperator.new :rval => rval, :operator => "or", :lval => lval - operator.evaluate(@scope) - end - - it "should evaluate right 'and' operand only if left operand is true" do - lval = stub "lval", :safeevaluate => true - rval = stub "rval", :safeevaluate => false - rval.expects(:safeevaluate).with(@scope).returns(false) - operator = ast::BooleanOperator.new :rval => rval, :operator => "and", :lval => lval - operator.evaluate(@scope) - end - - it "should evaluate right 'or' operand only if left operand is false" do - lval = stub "lval", :safeevaluate => false - rval = stub "rval", :safeevaluate => false - rval.expects(:safeevaluate).with(@scope).returns(false) - operator = ast::BooleanOperator.new :rval => rval, :operator => "or", :lval => lval - operator.evaluate(@scope) - end - - it "should return true for false OR true" do - ast::BooleanOperator.new(:rval => @true_ast, :operator => "or", :lval => @false_ast).evaluate(@scope).should be_true - end - - it "should return false for true AND false" do - ast::BooleanOperator.new(:rval => @true_ast, :operator => "and", :lval => @false_ast ).evaluate(@scope).should be_false - end - - it "should return true for true AND true" do - ast::BooleanOperator.new(:rval => @true_ast, :operator => "and", :lval => @true_ast ).evaluate(@scope).should be_true - end + ast = Puppet::Parser::AST + + before :each do + @scope = Puppet::Parser::Scope.new + @true_ast = ast::Boolean.new( :value => true) + @false_ast = ast::Boolean.new( :value => false) + end + + it "should evaluate left operand inconditionally" do + lval = stub "lval" + lval.expects(:safeevaluate).with(@scope).returns("true") + rval = stub "rval", :safeevaluate => false + rval.expects(:safeevaluate).never + + operator = ast::BooleanOperator.new :rval => rval, :operator => "or", :lval => lval + operator.evaluate(@scope) + end + + it "should evaluate right 'and' operand only if left operand is true" do + lval = stub "lval", :safeevaluate => true + rval = stub "rval", :safeevaluate => false + rval.expects(:safeevaluate).with(@scope).returns(false) + operator = ast::BooleanOperator.new :rval => rval, :operator => "and", :lval => lval + operator.evaluate(@scope) + end + + it "should evaluate right 'or' operand only if left operand is false" do + lval = stub "lval", :safeevaluate => false + rval = stub "rval", :safeevaluate => false + rval.expects(:safeevaluate).with(@scope).returns(false) + operator = ast::BooleanOperator.new :rval => rval, :operator => "or", :lval => lval + operator.evaluate(@scope) + end + + it "should return true for false OR true" do + ast::BooleanOperator.new(:rval => @true_ast, :operator => "or", :lval => @false_ast).evaluate(@scope).should be_true + end + + it "should return false for true AND false" do + ast::BooleanOperator.new(:rval => @true_ast, :operator => "and", :lval => @false_ast ).evaluate(@scope).should be_false + end + + it "should return true for true AND true" do + ast::BooleanOperator.new(:rval => @true_ast, :operator => "and", :lval => @true_ast ).evaluate(@scope).should be_true + end end diff --git a/spec/unit/parser/ast/casestatement_spec.rb b/spec/unit/parser/ast/casestatement_spec.rb index dca8e5adb..4d79e54cb 100755 --- a/spec/unit/parser/ast/casestatement_spec.rb +++ b/spec/unit/parser/ast/casestatement_spec.rb @@ -3,159 +3,159 @@ require File.dirname(__FILE__) + '/../../../spec_helper' describe Puppet::Parser::AST::CaseStatement do + before :each do + @scope = Puppet::Parser::Scope.new + end + + describe "when evaluating" do + before :each do - @scope = Puppet::Parser::Scope.new - end + @test = stub 'test' + @test.stubs(:safeevaluate).with(@scope).returns("value") + + @option1 = stub 'option1', :eachopt => nil, :default? => false + @option2 = stub 'option2', :eachopt => nil, :default? => false - describe "when evaluating" do + @options = stub 'options' + @options.stubs(:each).multiple_yields(@option1, @option2) - before :each do - @test = stub 'test' - @test.stubs(:safeevaluate).with(@scope).returns("value") + @casestmt = Puppet::Parser::AST::CaseStatement.new :test => @test, :options => @options + end - @option1 = stub 'option1', :eachopt => nil, :default? => false - @option2 = stub 'option2', :eachopt => nil, :default? => false + it "should evaluate test" do + @test.expects(:safeevaluate).with(@scope) - @options = stub 'options' - @options.stubs(:each).multiple_yields(@option1, @option2) + @casestmt.evaluate(@scope) + end - @casestmt = Puppet::Parser::AST::CaseStatement.new :test => @test, :options => @options - end + it "should scan each option" do + @options.expects(:each).multiple_yields(@option1, @option2) - it "should evaluate test" do - @test.expects(:safeevaluate).with(@scope) + @casestmt.evaluate(@scope) + end - @casestmt.evaluate(@scope) - end + describe "when scanning options" do + before :each do + @opval1 = stub_everything 'opval1' + @option1.stubs(:eachopt).yields(@opval1) - it "should scan each option" do - @options.expects(:each).multiple_yields(@option1, @option2) + @opval2 = stub_everything 'opval2' + @option2.stubs(:eachopt).yields(@opval2) + end - @casestmt.evaluate(@scope) - end + it "should evaluate each sub-option" do + @option1.expects(:eachopt) + @option2.expects(:eachopt) - describe "when scanning options" do - before :each do - @opval1 = stub_everything 'opval1' - @option1.stubs(:eachopt).yields(@opval1) + @casestmt.evaluate(@scope) + end - @opval2 = stub_everything 'opval2' - @option2.stubs(:eachopt).yields(@opval2) - end + it "should evaluate first matching option" do + @opval2.stubs(:evaluate_match).with { |*arg| arg[0] == "value" }.returns(true) + @option2.expects(:safeevaluate).with(@scope) - it "should evaluate each sub-option" do - @option1.expects(:eachopt) - @option2.expects(:eachopt) + @casestmt.evaluate(@scope) + end - @casestmt.evaluate(@scope) - end + it "should return the first matching evaluated option" do + @opval2.stubs(:evaluate_match).with { |*arg| arg[0] == "value" }.returns(true) + @option2.stubs(:safeevaluate).with(@scope).returns(:result) - it "should evaluate first matching option" do - @opval2.stubs(:evaluate_match).with { |*arg| arg[0] == "value" }.returns(true) - @option2.expects(:safeevaluate).with(@scope) + @casestmt.evaluate(@scope).should == :result + end - @casestmt.evaluate(@scope) - end + it "should evaluate the default option if none matched" do + @option1.stubs(:default?).returns(true) + @option1.expects(:safeevaluate).with(@scope) - it "should return the first matching evaluated option" do - @opval2.stubs(:evaluate_match).with { |*arg| arg[0] == "value" }.returns(true) - @option2.stubs(:safeevaluate).with(@scope).returns(:result) + @casestmt.evaluate(@scope) + end - @casestmt.evaluate(@scope).should == :result - end + it "should return the default evaluated option if none matched" do + @option1.stubs(:default?).returns(true) + @option1.stubs(:safeevaluate).with(@scope).returns(:result) - it "should evaluate the default option if none matched" do - @option1.stubs(:default?).returns(true) - @option1.expects(:safeevaluate).with(@scope) + @casestmt.evaluate(@scope).should == :result + end - @casestmt.evaluate(@scope) - end + it "should return nil if nothing matched" do + @casestmt.evaluate(@scope).should be_nil + end - it "should return the default evaluated option if none matched" do - @option1.stubs(:default?).returns(true) - @option1.stubs(:safeevaluate).with(@scope).returns(:result) + it "should match and set scope ephemeral variables" do + @opval1.expects(:evaluate_match).with { |*arg| arg[0] == "value" and arg[1] == @scope } - @casestmt.evaluate(@scope).should == :result - end + @casestmt.evaluate(@scope) + end - it "should return nil if nothing matched" do - @casestmt.evaluate(@scope).should be_nil - end + it "should evaluate this regex option if it matches" do + @opval1.stubs(:evaluate_match).with { |*arg| arg[0] == "value" and arg[1] == @scope }.returns(true) - it "should match and set scope ephemeral variables" do - @opval1.expects(:evaluate_match).with { |*arg| arg[0] == "value" and arg[1] == @scope } + @option1.expects(:safeevaluate).with(@scope) - @casestmt.evaluate(@scope) - end + @casestmt.evaluate(@scope) + end - it "should evaluate this regex option if it matches" do - @opval1.stubs(:evaluate_match).with { |*arg| arg[0] == "value" and arg[1] == @scope }.returns(true) + it "should return this evaluated regex option if it matches" do + @opval1.stubs(:evaluate_match).with { |*arg| arg[0] == "value" and arg[1] == @scope }.returns(true) + @option1.stubs(:safeevaluate).with(@scope).returns(:result) - @option1.expects(:safeevaluate).with(@scope) + @casestmt.evaluate(@scope).should == :result + end - @casestmt.evaluate(@scope) - end + it "should unset scope ephemeral variables after option evaluation" do + @scope.stubs(:ephemeral_level).returns(:level) + @opval1.stubs(:evaluate_match).with { |*arg| arg[0] == "value" and arg[1] == @scope }.returns(true) + @option1.stubs(:safeevaluate).with(@scope).returns(:result) - it "should return this evaluated regex option if it matches" do - @opval1.stubs(:evaluate_match).with { |*arg| arg[0] == "value" and arg[1] == @scope }.returns(true) - @option1.stubs(:safeevaluate).with(@scope).returns(:result) + @scope.expects(:unset_ephemeral_var).with(:level) - @casestmt.evaluate(@scope).should == :result - end + @casestmt.evaluate(@scope) + end - it "should unset scope ephemeral variables after option evaluation" do - @scope.stubs(:ephemeral_level).returns(:level) - @opval1.stubs(:evaluate_match).with { |*arg| arg[0] == "value" and arg[1] == @scope }.returns(true) - @option1.stubs(:safeevaluate).with(@scope).returns(:result) + it "should not leak ephemeral variables even if evaluation fails" do + @scope.stubs(:ephemeral_level).returns(:level) + @opval1.stubs(:evaluate_match).with { |*arg| arg[0] == "value" and arg[1] == @scope }.returns(true) + @option1.stubs(:safeevaluate).with(@scope).raises - @scope.expects(:unset_ephemeral_var).with(:level) + @scope.expects(:unset_ephemeral_var).with(:level) - @casestmt.evaluate(@scope) - end + lambda { @casestmt.evaluate(@scope) }.should raise_error + end + end - it "should not leak ephemeral variables even if evaluation fails" do - @scope.stubs(:ephemeral_level).returns(:level) - @opval1.stubs(:evaluate_match).with { |*arg| arg[0] == "value" and arg[1] == @scope }.returns(true) - @option1.stubs(:safeevaluate).with(@scope).raises + end - @scope.expects(:unset_ephemeral_var).with(:level) + it "should match if any of the provided options evaluate as true" do + ast = nil + AST = Puppet::Parser::AST - lambda { @casestmt.evaluate(@scope) }.should raise_error - end - end + tests = { + "one" => %w{a b c}, + "two" => %w{e f g} + } + options = tests.collect do |result, values| + values = values.collect { |v| AST::Leaf.new :value => v } + AST::CaseOpt.new( + :value => AST::ASTArray.new(:children => values), + + :statements => AST::Leaf.new(:value => result)) end + options << AST::CaseOpt.new(:value => AST::Default.new(:value => "default"), :statements => AST::Leaf.new(:value => "default")) - it "should match if any of the provided options evaluate as true" do - ast = nil - AST = Puppet::Parser::AST + ast = nil + param = AST::Variable.new(:value => "testparam") + ast = AST::CaseStatement.new(:test => param, :options => options) - tests = { - "one" => %w{a b c}, - "two" => %w{e f g} - } - options = tests.collect do |result, values| - values = values.collect { |v| AST::Leaf.new :value => v } + tests.each do |should, values| + values.each do |value| + @scope = Puppet::Parser::Scope.new + @scope.setvar("testparam", value) + result = ast.evaluate(@scope) - AST::CaseOpt.new( - :value => AST::ASTArray.new(:children => values), - - :statements => AST::Leaf.new(:value => result)) - end - options << AST::CaseOpt.new(:value => AST::Default.new(:value => "default"), :statements => AST::Leaf.new(:value => "default")) - - ast = nil - param = AST::Variable.new(:value => "testparam") - ast = AST::CaseStatement.new(:test => param, :options => options) - - tests.each do |should, values| - values.each do |value| - @scope = Puppet::Parser::Scope.new - @scope.setvar("testparam", value) - result = ast.evaluate(@scope) - - result.should == should - end - end + result.should == should + end end + end end diff --git a/spec/unit/parser/ast/collection_spec.rb b/spec/unit/parser/ast/collection_spec.rb index c141bd708..3f7878a99 100755 --- a/spec/unit/parser/ast/collection_spec.rb +++ b/spec/unit/parser/ast/collection_spec.rb @@ -3,61 +3,61 @@ require File.dirname(__FILE__) + '/../../../spec_helper' describe Puppet::Parser::AST::Collection do - before :each do - @scope = stub_everything 'scope' - @compiler = stub_everything 'compile' - @scope.stubs(:compiler).returns(@compiler) + before :each do + @scope = stub_everything 'scope' + @compiler = stub_everything 'compile' + @scope.stubs(:compiler).returns(@compiler) - @overrides = stub_everything 'overrides' - @overrides.stubs(:is_a?).with(Puppet::Parser::AST).returns(true) + @overrides = stub_everything 'overrides' + @overrides.stubs(:is_a?).with(Puppet::Parser::AST).returns(true) - end + end - it "should evaluate its query" do - query = mock 'query' - collection = Puppet::Parser::AST::Collection.new :query => query, :form => :virtual + it "should evaluate its query" do + query = mock 'query' + collection = Puppet::Parser::AST::Collection.new :query => query, :form => :virtual - query.expects(:safeevaluate).with(@scope) + query.expects(:safeevaluate).with(@scope) - collection.evaluate(@scope) - end + collection.evaluate(@scope) + end - it "should instantiate a Collector for this type" do - collection = Puppet::Parser::AST::Collection.new :form => :virtual, :type => "test" + it "should instantiate a Collector for this type" do + collection = Puppet::Parser::AST::Collection.new :form => :virtual, :type => "test" - Puppet::Parser::Collector.expects(:new).with(@scope, "test", nil, nil, :virtual) + Puppet::Parser::Collector.expects(:new).with(@scope, "test", nil, nil, :virtual) - collection.evaluate(@scope) - end + collection.evaluate(@scope) + end - it "should tell the compiler about this collector" do - collection = Puppet::Parser::AST::Collection.new :form => :virtual, :type => "test" - Puppet::Parser::Collector.stubs(:new).returns("whatever") + it "should tell the compiler about this collector" do + collection = Puppet::Parser::AST::Collection.new :form => :virtual, :type => "test" + Puppet::Parser::Collector.stubs(:new).returns("whatever") - @compiler.expects(:add_collection).with("whatever") + @compiler.expects(:add_collection).with("whatever") - collection.evaluate(@scope) - end + collection.evaluate(@scope) + end - it "should evaluate overriden paramaters" do - collector = stub_everything 'collector' - collection = Puppet::Parser::AST::Collection.new :form => :virtual, :type => "test", :override => @overrides - Puppet::Parser::Collector.stubs(:new).returns(collector) + it "should evaluate overriden paramaters" do + collector = stub_everything 'collector' + collection = Puppet::Parser::AST::Collection.new :form => :virtual, :type => "test", :override => @overrides + Puppet::Parser::Collector.stubs(:new).returns(collector) - @overrides.expects(:safeevaluate).with(@scope) + @overrides.expects(:safeevaluate).with(@scope) - collection.evaluate(@scope) - end + collection.evaluate(@scope) + end - it "should tell the collector about overrides" do - collector = mock 'collector' - collection = Puppet::Parser::AST::Collection.new :form => :virtual, :type => "test", :override => @overrides - Puppet::Parser::Collector.stubs(:new).returns(collector) + it "should tell the collector about overrides" do + collector = mock 'collector' + collection = Puppet::Parser::AST::Collection.new :form => :virtual, :type => "test", :override => @overrides + Puppet::Parser::Collector.stubs(:new).returns(collector) - collector.expects(:add_override) + collector.expects(:add_override) - collection.evaluate(@scope) - end + collection.evaluate(@scope) + end end diff --git a/spec/unit/parser/ast/collexpr_spec.rb b/spec/unit/parser/ast/collexpr_spec.rb index 2aefe2f9d..01276dfb3 100755 --- a/spec/unit/parser/ast/collexpr_spec.rb +++ b/spec/unit/parser/ast/collexpr_spec.rb @@ -4,112 +4,112 @@ require File.dirname(__FILE__) + '/../../../spec_helper' describe Puppet::Parser::AST::CollExpr do - ast = Puppet::Parser::AST + ast = Puppet::Parser::AST + before :each do + @scope = Puppet::Parser::Scope.new + end + + describe "when evaluating with two operands" do before :each do - @scope = Puppet::Parser::Scope.new + @test1 = mock 'test1' + @test1.expects(:safeevaluate).with(@scope).returns("test1") + @test2 = mock 'test2' + @test2.expects(:safeevaluate).with(@scope).returns("test2") + end + + it "should evaluate both" do + collexpr = ast::CollExpr.new(:test1 => @test1, :test2 => @test2, :oper=>"==") + collexpr.evaluate(@scope) end - describe "when evaluating with two operands" do - before :each do - @test1 = mock 'test1' - @test1.expects(:safeevaluate).with(@scope).returns("test1") - @test2 = mock 'test2' - @test2.expects(:safeevaluate).with(@scope).returns("test2") - end - - it "should evaluate both" do - collexpr = ast::CollExpr.new(:test1 => @test1, :test2 => @test2, :oper=>"==") - collexpr.evaluate(@scope) - end - - it "should produce a textual representation and code of the expression" do - collexpr = ast::CollExpr.new(:test1 => @test1, :test2 => @test2, :oper=>"==") - result = collexpr.evaluate(@scope) - result[0].should == "param_values.value = 'test2' and param_names.name = 'test1'" - result[1].should be_an_instance_of(Proc) - end - - it "should propagate expression type and form to child if expression themselves" do - [@test1, @test2].each do |t| - t.expects(:is_a?).returns(true) - t.expects(:form).returns(false) - t.expects(:type).returns(false) - t.expects(:type=) - t.expects(:form=) - end - - collexpr = ast::CollExpr.new(:test1 => @test1, :test2 => @test2, :oper=>"==", :form => true, :type => true) - result = collexpr.evaluate(@scope) - end - - describe "and when evaluating the produced code" do - before :each do - @resource = mock 'resource' - @resource.expects(:[]).with("test1").at_least(1).returns("test2") - end - - it "should evaluate like the original expression for ==" do - collexpr = ast::CollExpr.new(:test1 => @test1, :test2 => @test2, :oper => "==") - collexpr.evaluate(@scope)[1].call(@resource).should === (@resource["test1"] == "test2") - end - - it "should evaluate like the original expression for !=" do - collexpr = ast::CollExpr.new(:test1 => @test1, :test2 => @test2, :oper => "!=") - collexpr.evaluate(@scope)[1].call(@resource).should === (@resource["test1"] != "test2") - end - end - - it "should warn if this is an exported collection containing parenthesis (unsupported)" do - collexpr = ast::CollExpr.new(:test1 => @test1, :test2 => @test2, :oper=>"==", :parens => true, :form => :exported) - Puppet.expects(:warning) - collexpr.evaluate(@scope) - end - - %w{and or}.each do |op| - it "should raise an error if this is an exported collection with #{op} operator (unsupported)" do - collexpr = ast::CollExpr.new(:test1 => @test1, :test2 => @test2, :oper=> op, :form => :exported) - lambda { collexpr.evaluate(@scope) }.should raise_error(Puppet::ParseError) - end - end + it "should produce a textual representation and code of the expression" do + collexpr = ast::CollExpr.new(:test1 => @test1, :test2 => @test2, :oper=>"==") + result = collexpr.evaluate(@scope) + result[0].should == "param_values.value = 'test2' and param_names.name = 'test1'" + result[1].should be_an_instance_of(Proc) end - describe "when evaluating with tags" do - before :each do - @tag = stub 'tag', :safeevaluate => 'tag' - @value = stub 'value', :safeevaluate => 'value' - - @resource = stub 'resource' - @resource.stubs(:tagged?).with("value").returns(true) - end - - it "should produce a textual representation of the expression" do - collexpr = ast::CollExpr.new(:test1 => @tag, :test2 => @value, :oper=>"==") - result = collexpr.evaluate(@scope) - result[0].should == "puppet_tags.name = 'value'" - end - - it "should inspect resource tags if the query term is on tags" do - collexpr = ast::CollExpr.new(:test1 => @tag, :test2 => @value, :oper => "==") - collexpr.evaluate(@scope)[1].call(@resource).should be_true - end + it "should propagate expression type and form to child if expression themselves" do + [@test1, @test2].each do |t| + t.expects(:is_a?).returns(true) + t.expects(:form).returns(false) + t.expects(:type).returns(false) + t.expects(:type=) + t.expects(:form=) + end + + collexpr = ast::CollExpr.new(:test1 => @test1, :test2 => @test2, :oper=>"==", :form => true, :type => true) + result = collexpr.evaluate(@scope) end - [:exported,:virtual].each do |mode| - it "should check for array member equality if resource parameter is an array for == in mode #{mode}" do - array = mock 'array', :safeevaluate => "array" - test1 = mock 'test1' - test1.expects(:safeevaluate).with(@scope).returns("test1") + describe "and when evaluating the produced code" do + before :each do + @resource = mock 'resource' + @resource.expects(:[]).with("test1").at_least(1).returns("test2") + end + + it "should evaluate like the original expression for ==" do + collexpr = ast::CollExpr.new(:test1 => @test1, :test2 => @test2, :oper => "==") + collexpr.evaluate(@scope)[1].call(@resource).should === (@resource["test1"] == "test2") + end + + it "should evaluate like the original expression for !=" do + collexpr = ast::CollExpr.new(:test1 => @test1, :test2 => @test2, :oper => "!=") + collexpr.evaluate(@scope)[1].call(@resource).should === (@resource["test1"] != "test2") + end + end + + it "should warn if this is an exported collection containing parenthesis (unsupported)" do + collexpr = ast::CollExpr.new(:test1 => @test1, :test2 => @test2, :oper=>"==", :parens => true, :form => :exported) + Puppet.expects(:warning) + collexpr.evaluate(@scope) + end - resource = mock 'resource' - resource.expects(:[]).with("array").at_least(1).returns(["test1","test2","test3"]) - collexpr = ast::CollExpr.new(:test1 => array, :test2 => test1, :oper => "==", :form => mode) - collexpr.evaluate(@scope)[1].call(resource).should be_true + %w{and or}.each do |op| + it "should raise an error if this is an exported collection with #{op} operator (unsupported)" do + collexpr = ast::CollExpr.new(:test1 => @test1, :test2 => @test2, :oper=> op, :form => :exported) + lambda { collexpr.evaluate(@scope) }.should raise_error(Puppet::ParseError) + end end + end + + describe "when evaluating with tags" do + before :each do + @tag = stub 'tag', :safeevaluate => 'tag' + @value = stub 'value', :safeevaluate => 'value' + + @resource = stub 'resource' + @resource.stubs(:tagged?).with("value").returns(true) + end + + it "should produce a textual representation of the expression" do + collexpr = ast::CollExpr.new(:test1 => @tag, :test2 => @value, :oper=>"==") + result = collexpr.evaluate(@scope) + result[0].should == "puppet_tags.name = 'value'" end - it "should raise an error for invalid operator" do - lambda { collexpr = ast::CollExpr.new(:oper=>">") }.should raise_error + it "should inspect resource tags if the query term is on tags" do + collexpr = ast::CollExpr.new(:test1 => @tag, :test2 => @value, :oper => "==") + collexpr.evaluate(@scope)[1].call(@resource).should be_true end + end + + [:exported,:virtual].each do |mode| + it "should check for array member equality if resource parameter is an array for == in mode #{mode}" do + array = mock 'array', :safeevaluate => "array" + test1 = mock 'test1' + test1.expects(:safeevaluate).with(@scope).returns("test1") + + resource = mock 'resource' + resource.expects(:[]).with("array").at_least(1).returns(["test1","test2","test3"]) + collexpr = ast::CollExpr.new(:test1 => array, :test2 => test1, :oper => "==", :form => mode) + collexpr.evaluate(@scope)[1].call(resource).should be_true + end + end + + it "should raise an error for invalid operator" do + lambda { collexpr = ast::CollExpr.new(:oper=>">") }.should raise_error + end end diff --git a/spec/unit/parser/ast/comparison_operator_spec.rb b/spec/unit/parser/ast/comparison_operator_spec.rb index 0ef9117af..724b6c6f7 100755 --- a/spec/unit/parser/ast/comparison_operator_spec.rb +++ b/spec/unit/parser/ast/comparison_operator_spec.rb @@ -3,90 +3,90 @@ require File.dirname(__FILE__) + '/../../../spec_helper' describe Puppet::Parser::AST::ComparisonOperator do - before :each do - @scope = Puppet::Parser::Scope.new - @one = stub 'one', :safeevaluate => "1" - @two = stub 'two', :safeevaluate => "2" + before :each do + @scope = Puppet::Parser::Scope.new + @one = stub 'one', :safeevaluate => "1" + @two = stub 'two', :safeevaluate => "2" + end + + it "should evaluate both branches" do + lval = stub "lval" + lval.expects(:safeevaluate).with(@scope) + rval = stub "rval" + rval.expects(:safeevaluate).with(@scope) + + operator = Puppet::Parser::AST::ComparisonOperator.new :lval => lval, :operator => "==", :rval => rval + operator.evaluate(@scope) + end + + it "should convert arguments strings to numbers if they are" do + Puppet::Parser::Scope.expects(:number?).with("1").returns(1) + Puppet::Parser::Scope.expects(:number?).with("2").returns(2) + + operator = Puppet::Parser::AST::ComparisonOperator.new :lval => @one, :operator => "==", :rval => @two + operator.evaluate(@scope) + end + + %w{< > <= >= ==}.each do |oper| + it "should use string comparison #{oper} if operands are strings" do + lval = stub 'one', :safeevaluate => "one" + rval = stub 'two', :safeevaluate => "two" + Puppet::Parser::Scope.stubs(:number?).with("one").returns(nil) + Puppet::Parser::Scope.stubs(:number?).with("two").returns(nil) + + operator = Puppet::Parser::AST::ComparisonOperator.new :lval => lval, :operator => oper, :rval => rval + operator.evaluate(@scope).should == "one".send(oper,"two") end + end - it "should evaluate both branches" do - lval = stub "lval" - lval.expects(:safeevaluate).with(@scope) - rval = stub "rval" - rval.expects(:safeevaluate).with(@scope) + it "should fail with arguments of different types" do + lval = stub 'one', :safeevaluate => "one" + rval = stub 'two', :safeevaluate => "2" + Puppet::Parser::Scope.stubs(:number?).with("one").returns(nil) + Puppet::Parser::Scope.stubs(:number?).with("2").returns(2) - operator = Puppet::Parser::AST::ComparisonOperator.new :lval => lval, :operator => "==", :rval => rval - operator.evaluate(@scope) - end - - it "should convert arguments strings to numbers if they are" do - Puppet::Parser::Scope.expects(:number?).with("1").returns(1) - Puppet::Parser::Scope.expects(:number?).with("2").returns(2) + operator = Puppet::Parser::AST::ComparisonOperator.new :lval => lval, :operator => ">", :rval => rval + lambda { operator.evaluate(@scope) }.should raise_error(ArgumentError) + end - operator = Puppet::Parser::AST::ComparisonOperator.new :lval => @one, :operator => "==", :rval => @two - operator.evaluate(@scope) - end + it "should fail for an unknown operator" do + lambda { operator = Puppet::Parser::AST::ComparisonOperator.new :lval => @one, :operator => "or", :rval => @two }.should raise_error + end - %w{< > <= >= ==}.each do |oper| - it "should use string comparison #{oper} if operands are strings" do - lval = stub 'one', :safeevaluate => "one" - rval = stub 'two', :safeevaluate => "two" - Puppet::Parser::Scope.stubs(:number?).with("one").returns(nil) - Puppet::Parser::Scope.stubs(:number?).with("two").returns(nil) + %w{< > <= >= ==}.each do |oper| + it "should return the result of using '#{oper}' to compare the left and right sides" do + operator = Puppet::Parser::AST::ComparisonOperator.new :lval => @one, :operator => oper, :rval => @two - operator = Puppet::Parser::AST::ComparisonOperator.new :lval => lval, :operator => oper, :rval => rval - operator.evaluate(@scope).should == "one".send(oper,"two") - end + operator.evaluate(@scope).should == 1.send(oper,2) end + end - it "should fail with arguments of different types" do - lval = stub 'one', :safeevaluate => "one" - rval = stub 'two', :safeevaluate => "2" - Puppet::Parser::Scope.stubs(:number?).with("one").returns(nil) - Puppet::Parser::Scope.stubs(:number?).with("2").returns(2) + it "should return the result of using '!=' to compare the left and right sides" do + operator = Puppet::Parser::AST::ComparisonOperator.new :lval => @one, :operator => '!=', :rval => @two - operator = Puppet::Parser::AST::ComparisonOperator.new :lval => lval, :operator => ">", :rval => rval - lambda { operator.evaluate(@scope) }.should raise_error(ArgumentError) - end + operator.evaluate(@scope).should == true + end - it "should fail for an unknown operator" do - lambda { operator = Puppet::Parser::AST::ComparisonOperator.new :lval => @one, :operator => "or", :rval => @two }.should raise_error - end - - %w{< > <= >= ==}.each do |oper| - it "should return the result of using '#{oper}' to compare the left and right sides" do - operator = Puppet::Parser::AST::ComparisonOperator.new :lval => @one, :operator => oper, :rval => @two + it "should work for variables too" do + one = Puppet::Parser::AST::Variable.new( :value => "one" ) + two = Puppet::Parser::AST::Variable.new( :value => "two" ) - operator.evaluate(@scope).should == 1.send(oper,2) - end - end + @scope.expects(:lookupvar).with("one", false).returns(1) + @scope.expects(:lookupvar).with("two", false).returns(2) - it "should return the result of using '!=' to compare the left and right sides" do - operator = Puppet::Parser::AST::ComparisonOperator.new :lval => @one, :operator => '!=', :rval => @two - - operator.evaluate(@scope).should == true - end - - it "should work for variables too" do - one = Puppet::Parser::AST::Variable.new( :value => "one" ) - two = Puppet::Parser::AST::Variable.new( :value => "two" ) - - @scope.expects(:lookupvar).with("one", false).returns(1) - @scope.expects(:lookupvar).with("two", false).returns(2) - - operator = Puppet::Parser::AST::ComparisonOperator.new :lval => one, :operator => "<", :rval => two - operator.evaluate(@scope).should == true - end + operator = Puppet::Parser::AST::ComparisonOperator.new :lval => one, :operator => "<", :rval => two + operator.evaluate(@scope).should == true + end - # see ticket #1759 - %w{< > <= >=}.each do |oper| - it "should return the correct result of using '#{oper}' to compare 10 and 9" do - ten = stub 'one', :safeevaluate => "10" - nine = stub 'two', :safeevaluate => "9" - operator = Puppet::Parser::AST::ComparisonOperator.new :lval => ten, :operator => oper, :rval => nine + # see ticket #1759 + %w{< > <= >=}.each do |oper| + it "should return the correct result of using '#{oper}' to compare 10 and 9" do + ten = stub 'one', :safeevaluate => "10" + nine = stub 'two', :safeevaluate => "9" + operator = Puppet::Parser::AST::ComparisonOperator.new :lval => ten, :operator => oper, :rval => nine - operator.evaluate(@scope).should == 10.send(oper,9) - end + operator.evaluate(@scope).should == 10.send(oper,9) end + end end diff --git a/spec/unit/parser/ast/function_spec.rb b/spec/unit/parser/ast/function_spec.rb index bb687eac0..c57c7f098 100644 --- a/spec/unit/parser/ast/function_spec.rb +++ b/spec/unit/parser/ast/function_spec.rb @@ -3,81 +3,81 @@ require File.dirname(__FILE__) + '/../../../spec_helper' describe Puppet::Parser::AST::Function do - before :each do - @scope = mock 'scope' - end + before :each do + @scope = mock 'scope' + end - describe "when initializing" do - it "should not fail if the function doesn't exist" do - Puppet::Parser::Functions.stubs(:function).returns(false) + describe "when initializing" do + it "should not fail if the function doesn't exist" do + Puppet::Parser::Functions.stubs(:function).returns(false) - lambda{ Puppet::Parser::AST::Function.new :name => "dontexist" }.should_not raise_error(Puppet::ParseError) + lambda{ Puppet::Parser::AST::Function.new :name => "dontexist" }.should_not raise_error(Puppet::ParseError) - end end + end - it "should return its representation with to_s" do - args = stub 'args', :is_a? => true, :to_s => "[a, b]" - - Puppet::Parser::AST::Function.new(:name => "func", :arguments => args).to_s.should == "func(a, b)" - end + it "should return its representation with to_s" do + args = stub 'args', :is_a? => true, :to_s => "[a, b]" - describe "when evaluating" do + Puppet::Parser::AST::Function.new(:name => "func", :arguments => args).to_s.should == "func(a, b)" + end - it "should fail if the function doesn't exist" do - Puppet::Parser::Functions.stubs(:function).returns(false) - func = Puppet::Parser::AST::Function.new :name => "dontexist" + describe "when evaluating" do - lambda{ func.evaluate(@scope) }.should raise_error(Puppet::ParseError) - end + it "should fail if the function doesn't exist" do + Puppet::Parser::Functions.stubs(:function).returns(false) + func = Puppet::Parser::AST::Function.new :name => "dontexist" - it "should fail if the function is a statement used as rvalue" do - Puppet::Parser::Functions.stubs(:function).with("exist").returns(true) - Puppet::Parser::Functions.stubs(:rvalue?).with("exist").returns(false) + lambda{ func.evaluate(@scope) }.should raise_error(Puppet::ParseError) + end - func = Puppet::Parser::AST::Function.new :name => "exist", :ftype => :rvalue + it "should fail if the function is a statement used as rvalue" do + Puppet::Parser::Functions.stubs(:function).with("exist").returns(true) + Puppet::Parser::Functions.stubs(:rvalue?).with("exist").returns(false) - lambda{ func.evaluate(@scope) }.should raise_error(Puppet::ParseError, "Function 'exist' does not return a value") - end + func = Puppet::Parser::AST::Function.new :name => "exist", :ftype => :rvalue - it "should fail if the function is an rvalue used as statement" do - Puppet::Parser::Functions.stubs(:function).with("exist").returns(true) - Puppet::Parser::Functions.stubs(:rvalue?).with("exist").returns(true) + lambda{ func.evaluate(@scope) }.should raise_error(Puppet::ParseError, "Function 'exist' does not return a value") + end - func = Puppet::Parser::AST::Function.new :name => "exist", :ftype => :statement + it "should fail if the function is an rvalue used as statement" do + Puppet::Parser::Functions.stubs(:function).with("exist").returns(true) + Puppet::Parser::Functions.stubs(:rvalue?).with("exist").returns(true) - lambda{ func.evaluate(@scope) }.should raise_error(Puppet::ParseError,"Function 'exist' must be the value of a statement") - end + func = Puppet::Parser::AST::Function.new :name => "exist", :ftype => :statement - it "should evaluate its arguments" do - argument = stub 'arg' - 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) + lambda{ func.evaluate(@scope) }.should raise_error(Puppet::ParseError,"Function 'exist' must be the value of a statement") + end - argument.expects(:safeevaluate).with(@scope).returns("argument") + it "should evaluate its arguments" do + argument = stub 'arg' + 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) - func.evaluate(@scope) - end + argument.expects(:safeevaluate).with(@scope).returns("argument") - it "should call the underlying ruby function" do - 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 + func.evaluate(@scope) + end - @scope.expects(:function_exist).with("nothing") + it "should call the underlying ruby function" do + 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 - func.evaluate(@scope) - end + @scope.expects(:function_exist).with("nothing") - it "should return the ruby function return for rvalue functions" do - 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") + func.evaluate(@scope) + end - func.evaluate(@scope).should == "returning" - end + it "should return the ruby function return for rvalue functions" do + 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") + func.evaluate(@scope).should == "returning" end + + end end diff --git a/spec/unit/parser/ast/ifstatement_spec.rb b/spec/unit/parser/ast/ifstatement_spec.rb index c1f3305ea..2a9e1e37b 100755 --- a/spec/unit/parser/ast/ifstatement_spec.rb +++ b/spec/unit/parser/ast/ifstatement_spec.rb @@ -3,74 +3,74 @@ require File.dirname(__FILE__) + '/../../../spec_helper' describe Puppet::Parser::AST::IfStatement do - before :each do - @scope = Puppet::Parser::Scope.new - end + before :each do + @scope = Puppet::Parser::Scope.new + end - describe "when evaluating" do + describe "when evaluating" do - before :each do - @test = stub 'test' - @test.stubs(:safeevaluate).with(@scope) + before :each do + @test = stub 'test' + @test.stubs(:safeevaluate).with(@scope) - @stmt = stub 'stmt' - @stmt.stubs(:safeevaluate).with(@scope) + @stmt = stub 'stmt' + @stmt.stubs(:safeevaluate).with(@scope) - @else = stub 'else' - @else.stubs(:safeevaluate).with(@scope) + @else = stub 'else' + @else.stubs(:safeevaluate).with(@scope) - @ifstmt = Puppet::Parser::AST::IfStatement.new :test => @test, :statements => @stmt - @ifelsestmt = Puppet::Parser::AST::IfStatement.new :test => @test, :statements => @stmt, :else => @else - end + @ifstmt = Puppet::Parser::AST::IfStatement.new :test => @test, :statements => @stmt + @ifelsestmt = Puppet::Parser::AST::IfStatement.new :test => @test, :statements => @stmt, :else => @else + end - it "should evaluate test" do - Puppet::Parser::Scope.stubs(:true?).returns(false) + it "should evaluate test" do + Puppet::Parser::Scope.stubs(:true?).returns(false) - @test.expects(:safeevaluate).with(@scope) + @test.expects(:safeevaluate).with(@scope) - @ifstmt.evaluate(@scope) - end + @ifstmt.evaluate(@scope) + end - it "should evaluate if statements if test is true" do - Puppet::Parser::Scope.stubs(:true?).returns(true) + it "should evaluate if statements if test is true" do + Puppet::Parser::Scope.stubs(:true?).returns(true) - @stmt.expects(:safeevaluate).with(@scope) + @stmt.expects(:safeevaluate).with(@scope) - @ifstmt.evaluate(@scope) - end + @ifstmt.evaluate(@scope) + end - it "should not evaluate if statements if test is false" do - Puppet::Parser::Scope.stubs(:true?).returns(false) + it "should not evaluate if statements if test is false" do + Puppet::Parser::Scope.stubs(:true?).returns(false) - @stmt.expects(:safeevaluate).with(@scope).never + @stmt.expects(:safeevaluate).with(@scope).never - @ifstmt.evaluate(@scope) - end + @ifstmt.evaluate(@scope) + end - it "should evaluate the else branch if test is false" do - Puppet::Parser::Scope.stubs(:true?).returns(false) + it "should evaluate the else branch if test is false" do + Puppet::Parser::Scope.stubs(:true?).returns(false) - @else.expects(:safeevaluate).with(@scope) + @else.expects(:safeevaluate).with(@scope) - @ifelsestmt.evaluate(@scope) - end + @ifelsestmt.evaluate(@scope) + end - it "should not evaluate the else branch if test is true" do - Puppet::Parser::Scope.stubs(:true?).returns(true) + it "should not evaluate the else branch if test is true" do + Puppet::Parser::Scope.stubs(:true?).returns(true) - @else.expects(:safeevaluate).with(@scope).never + @else.expects(:safeevaluate).with(@scope).never - @ifelsestmt.evaluate(@scope) - end + @ifelsestmt.evaluate(@scope) + end - it "should reset ephemeral statements after evaluation" do - @scope.expects(:ephemeral_level).returns(:level) - Puppet::Parser::Scope.stubs(:true?).returns(true) + it "should reset ephemeral statements after evaluation" do + @scope.expects(:ephemeral_level).returns(:level) + Puppet::Parser::Scope.stubs(:true?).returns(true) - @stmt.expects(:safeevaluate).with(@scope) - @scope.expects(:unset_ephemeral_var).with(:level) + @stmt.expects(:safeevaluate).with(@scope) + @scope.expects(:unset_ephemeral_var).with(:level) - @ifstmt.evaluate(@scope) - end + @ifstmt.evaluate(@scope) end + end end diff --git a/spec/unit/parser/ast/in_operator_spec.rb b/spec/unit/parser/ast/in_operator_spec.rb index 15128d894..aebe442ab 100644 --- a/spec/unit/parser/ast/in_operator_spec.rb +++ b/spec/unit/parser/ast/in_operator_spec.rb @@ -5,56 +5,56 @@ require File.dirname(__FILE__) + '/../../../spec_helper' require 'puppet/parser/ast/in_operator' describe Puppet::Parser::AST::InOperator do - before :each do - @scope = Puppet::Parser::Scope.new + before :each do + @scope = Puppet::Parser::Scope.new - @lval = stub 'lval' - @lval.stubs(:safeevaluate).with(@scope).returns("left") + @lval = stub 'lval' + @lval.stubs(:safeevaluate).with(@scope).returns("left") - @rval = stub 'rval' - @rval.stubs(:safeevaluate).with(@scope).returns("right") + @rval = stub 'rval' + @rval.stubs(:safeevaluate).with(@scope).returns("right") - @operator = Puppet::Parser::AST::InOperator.new :lval => @lval, :rval => @rval - end + @operator = Puppet::Parser::AST::InOperator.new :lval => @lval, :rval => @rval + end - it "should evaluate the left operand" do - @lval.expects(:safeevaluate).with(@scope).returns("string") + it "should evaluate the left operand" do + @lval.expects(:safeevaluate).with(@scope).returns("string") - @operator.evaluate(@scope) - end + @operator.evaluate(@scope) + end - it "should evaluate the right operand" do - @rval.expects(:safeevaluate).with(@scope).returns("string") + it "should evaluate the right operand" do + @rval.expects(:safeevaluate).with(@scope).returns("string") - @operator.evaluate(@scope) - end + @operator.evaluate(@scope) + end - it "should raise an argument error if lval is not a string" do - @lval.expects(:safeevaluate).with(@scope).returns([12,13]) + it "should raise an argument error if lval is not a string" do + @lval.expects(:safeevaluate).with(@scope).returns([12,13]) - lambda { @operator.evaluate(@scope) }.should raise_error - end + lambda { @operator.evaluate(@scope) }.should raise_error + end - it "should raise an argument error if rval doesn't support the include? method" do - @rval.expects(:safeevaluate).with(@scope).returns(stub('value')) + it "should raise an argument error if rval doesn't support the include? method" do + @rval.expects(:safeevaluate).with(@scope).returns(stub('value')) - lambda { @operator.evaluate(@scope) }.should raise_error - end + lambda { @operator.evaluate(@scope) }.should raise_error + end - it "should not raise an argument error if rval supports the include? method" do - @rval.expects(:safeevaluate).with(@scope).returns(stub('value', :include? => true)) + it "should not raise an argument error if rval supports the include? method" do + @rval.expects(:safeevaluate).with(@scope).returns(stub('value', :include? => true)) - lambda { @operator.evaluate(@scope) }.should_not raise_error - end + lambda { @operator.evaluate(@scope) }.should_not raise_error + end - it "should return rval.include?(lval)" do - lval = stub 'lvalue', :is_a? => true - @lval.stubs(:safeevaluate).with(@scope).returns(lval) + it "should return rval.include?(lval)" do + lval = stub 'lvalue', :is_a? => true + @lval.stubs(:safeevaluate).with(@scope).returns(lval) - rval = stub 'rvalue' - @rval.stubs(:safeevaluate).with(@scope).returns(rval) - rval.expects(:include?).with(lval).returns(:result) + rval = stub 'rvalue' + @rval.stubs(:safeevaluate).with(@scope).returns(rval) + rval.expects(:include?).with(lval).returns(:result) - @operator.evaluate(@scope).should == :result - end + @operator.evaluate(@scope).should == :result + end end diff --git a/spec/unit/parser/ast/leaf_spec.rb b/spec/unit/parser/ast/leaf_spec.rb index d5534debb..379cbfde7 100755 --- a/spec/unit/parser/ast/leaf_spec.rb +++ b/spec/unit/parser/ast/leaf_spec.rb @@ -3,365 +3,365 @@ require File.dirname(__FILE__) + '/../../../spec_helper' describe Puppet::Parser::AST::Leaf do - before :each do - @scope = stub 'scope' - @value = stub 'value' - @leaf = Puppet::Parser::AST::Leaf.new(:value => @value) - end + before :each do + @scope = stub 'scope' + @value = stub 'value' + @leaf = Puppet::Parser::AST::Leaf.new(:value => @value) + end - it "should have a evaluate_match method" do - Puppet::Parser::AST::Leaf.new(:value => "value").should respond_to(:evaluate_match) - end + it "should have a evaluate_match method" do + Puppet::Parser::AST::Leaf.new(:value => "value").should respond_to(:evaluate_match) + end - describe "when evaluate_match is called" do - it "should evaluate itself" do - @leaf.expects(:safeevaluate).with(@scope) + describe "when evaluate_match is called" do + it "should evaluate itself" do + @leaf.expects(:safeevaluate).with(@scope) - @leaf.evaluate_match("value", @scope) - end + @leaf.evaluate_match("value", @scope) + end - it "should match values by equality" do - @value.stubs(:==).returns(false) - @leaf.stubs(:safeevaluate).with(@scope).returns(@value) - @value.expects(:==).with("value") + it "should match values by equality" do + @value.stubs(:==).returns(false) + @leaf.stubs(:safeevaluate).with(@scope).returns(@value) + @value.expects(:==).with("value") - @leaf.evaluate_match("value", @scope) - end + @leaf.evaluate_match("value", @scope) + end - it "should downcase the evaluated value if wanted" do - @leaf.stubs(:safeevaluate).with(@scope).returns(@value) - @value.expects(:downcase).returns("value") + it "should downcase the evaluated value if wanted" do + @leaf.stubs(:safeevaluate).with(@scope).returns(@value) + @value.expects(:downcase).returns("value") - @leaf.evaluate_match("value", @scope) - end + @leaf.evaluate_match("value", @scope) + end - it "should match undef if value is an empty string" do - @leaf.stubs(:safeevaluate).with(@scope).returns("") + it "should match undef if value is an empty string" do + @leaf.stubs(:safeevaluate).with(@scope).returns("") - @leaf.evaluate_match(:undef, @scope).should be_true - end + @leaf.evaluate_match(:undef, @scope).should be_true + end - it "should downcase the parameter value if wanted" do - parameter = stub 'parameter' - parameter.expects(:downcase).returns("value") + it "should downcase the parameter value if wanted" do + parameter = stub 'parameter' + parameter.expects(:downcase).returns("value") - @leaf.evaluate_match(parameter, @scope) - end + @leaf.evaluate_match(parameter, @scope) end + end - describe "when converting to string" do - it "should transform its value to string" do - value = stub 'value', :is_a? => true - value.expects(:to_s) - Puppet::Parser::AST::Leaf.new( :value => value ).to_s - end + describe "when converting to string" do + it "should transform its value to string" do + value = stub 'value', :is_a? => true + value.expects(:to_s) + Puppet::Parser::AST::Leaf.new( :value => value ).to_s end + end - it "should have a match method" do - @leaf.should respond_to(:match) - end + it "should have a match method" do + @leaf.should respond_to(:match) + end - it "should delegate match to ==" do - @value.expects(:==).with("value") + it "should delegate match to ==" do + @value.expects(:==).with("value") - @leaf.match("value") - end + @leaf.match("value") + end end describe Puppet::Parser::AST::FlatString do - describe "when converting to string" do - it "should transform its value to a quoted string" do - value = stub 'value', :is_a? => true, :to_s => "ab" - Puppet::Parser::AST::FlatString.new( :value => value ).to_s.should == "\"ab\"" - end + describe "when converting to string" do + it "should transform its value to a quoted string" do + value = stub 'value', :is_a? => true, :to_s => "ab" + Puppet::Parser::AST::FlatString.new( :value => value ).to_s.should == "\"ab\"" end + end end describe Puppet::Parser::AST::String do - describe "when converting to string" do - it "should transform its value to a quoted string" do - value = stub 'value', :is_a? => true, :to_s => "ab" - Puppet::Parser::AST::String.new( :value => value ).to_s.should == "\"ab\"" - end + describe "when converting to string" do + it "should transform its value to a quoted string" do + value = stub 'value', :is_a? => true, :to_s => "ab" + Puppet::Parser::AST::String.new( :value => value ).to_s.should == "\"ab\"" end + end end describe Puppet::Parser::AST::Undef do - before :each do - @scope = stub 'scope' - @undef = Puppet::Parser::AST::Undef.new(:value => :undef) - end - - it "should match undef with undef" do - @undef.evaluate_match(:undef, @scope).should be_true - end - - it "should not match undef with an empty string" do - @undef.evaluate_match("", @scope).should be_false - end + before :each do + @scope = stub 'scope' + @undef = Puppet::Parser::AST::Undef.new(:value => :undef) + end + + it "should match undef with undef" do + @undef.evaluate_match(:undef, @scope).should be_true + end + + it "should not match undef with an empty string" do + @undef.evaluate_match("", @scope).should be_false + end end describe Puppet::Parser::AST::HashOrArrayAccess do - before :each do - @scope = stub 'scope' - end + before :each do + @scope = stub 'scope' + end - describe "when evaluating" do - it "should evaluate the variable part if necessary" do - @scope.stubs(:lookupvar).with("a").returns(["b"]) + describe "when evaluating" do + it "should evaluate the variable part if necessary" do + @scope.stubs(:lookupvar).with("a").returns(["b"]) - variable = stub 'variable', :evaluate => "a" - access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => variable, :key => 0 ) + variable = stub 'variable', :evaluate => "a" + access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => variable, :key => 0 ) - variable.expects(:safeevaluate).with(@scope).returns("a") + variable.expects(:safeevaluate).with(@scope).returns("a") - access.evaluate(@scope).should == "b" - end + access.evaluate(@scope).should == "b" + end - it "should evaluate the access key part if necessary" do - @scope.stubs(:lookupvar).with("a").returns(["b"]) + it "should evaluate the access key part if necessary" do + @scope.stubs(:lookupvar).with("a").returns(["b"]) - index = stub 'index', :evaluate => 0 - access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => index ) + index = stub 'index', :evaluate => 0 + access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => index ) - index.expects(:safeevaluate).with(@scope).returns(0) + index.expects(:safeevaluate).with(@scope).returns(0) - access.evaluate(@scope).should == "b" - end + access.evaluate(@scope).should == "b" + end - it "should be able to return an array member" do - @scope.stubs(:lookupvar).with("a").returns(["val1", "val2", "val3"]) + it "should be able to return an array member" do + @scope.stubs(:lookupvar).with("a").returns(["val1", "val2", "val3"]) - access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => 1 ) + access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => 1 ) - access.evaluate(@scope).should == "val2" - end + access.evaluate(@scope).should == "val2" + end - it "should be able to return an hash value" do - @scope.stubs(:lookupvar).with("a").returns({ "key1" => "val1", "key2" => "val2", "key3" => "val3" }) + it "should be able to return an hash value" do + @scope.stubs(:lookupvar).with("a").returns({ "key1" => "val1", "key2" => "val2", "key3" => "val3" }) - access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "key2" ) + access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "key2" ) - access.evaluate(@scope).should == "val2" - end + access.evaluate(@scope).should == "val2" + 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") + 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") - access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "key2" ) + access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "key2" ) - lambda { access.evaluate(@scope) }.should raise_error - end + lambda { access.evaluate(@scope) }.should raise_error + end - it "should raise an error if the variable wasn't in the scope" do - @scope.stubs(:lookupvar).with("a").returns(nil) + it "should raise an error if the variable wasn't in the scope" do + @scope.stubs(:lookupvar).with("a").returns(nil) - access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "key2" ) + access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "key2" ) - lambda { access.evaluate(@scope) }.should raise_error - end + lambda { access.evaluate(@scope) }.should raise_error + end - it "should return a correct string representation" do - access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "key2" ) - access.to_s.should == '$a[key2]' - end + it "should return a correct string representation" do + access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "key2" ) + access.to_s.should == '$a[key2]' + end - it "should work with recursive hash access" do - @scope.stubs(:lookupvar).with("a").returns({ "key" => { "subkey" => "b" }}) + it "should work with recursive hash access" do + @scope.stubs(:lookupvar).with("a").returns({ "key" => { "subkey" => "b" }}) - access1 = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "key") - access2 = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => access1, :key => "subkey") + access1 = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "key") + access2 = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => access1, :key => "subkey") - access2.evaluate(@scope).should == 'b' - end + access2.evaluate(@scope).should == 'b' + end - it "should work with interleaved array and hash access" do - @scope.stubs(:lookupvar).with("a").returns({ "key" => [ "a" , "b" ]}) + it "should work with interleaved array and hash access" do + @scope.stubs(:lookupvar).with("a").returns({ "key" => [ "a" , "b" ]}) - access1 = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "key") - access2 = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => access1, :key => 1) + access1 = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "key") + access2 = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => access1, :key => 1) - access2.evaluate(@scope).should == 'b' - end + access2.evaluate(@scope).should == 'b' end + end - describe "when assigning" do - it "should add a new key and value" do - scope = Puppet::Parser::Scope.new - scope.setvar("a", { 'a' => 'b' }) + describe "when assigning" do + it "should add a new key and value" do + scope = Puppet::Parser::Scope.new + scope.setvar("a", { 'a' => 'b' }) - access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "b") - access.assign(scope, "c" ) + access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "b") + access.assign(scope, "c" ) - scope.lookupvar("a").should be_include("b") - end + scope.lookupvar("a").should be_include("b") + 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") + 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") - lambda { access.assign(@scope, "test") }.should raise_error - end + lambda { access.assign(@scope, "test") }.should raise_error end + end end describe Puppet::Parser::AST::Regex do - before :each do - @scope = stub 'scope' - end + before :each do + @scope = stub 'scope' + end - describe "when initializing" do - it "should create a Regexp with its content when value is not a Regexp" do - Regexp.expects(:new).with("/ab/") + describe "when initializing" do + it "should create a Regexp with its content when value is not a Regexp" do + Regexp.expects(:new).with("/ab/") - Puppet::Parser::AST::Regex.new :value => "/ab/" - end - - it "should not create a Regexp with its content when value is a Regexp" do - value = Regexp.new("/ab/") - Regexp.expects(:new).with("/ab/").never - - Puppet::Parser::AST::Regex.new :value => value - end + Puppet::Parser::AST::Regex.new :value => "/ab/" end - describe "when evaluating" do - it "should return self" do - val = Puppet::Parser::AST::Regex.new :value => "/ab/" + it "should not create a Regexp with its content when value is a Regexp" do + value = Regexp.new("/ab/") + Regexp.expects(:new).with("/ab/").never - val.evaluate(@scope).should === val - end + Puppet::Parser::AST::Regex.new :value => value end + end - describe "when evaluate_match" do - before :each do - @value = stub 'regex' - @value.stubs(:match).with("value").returns(true) - Regexp.stubs(:new).returns(@value) - @regex = Puppet::Parser::AST::Regex.new :value => "/ab/" - end - - it "should issue the regexp match" do - @value.expects(:match).with("value") - - @regex.evaluate_match("value", @scope) - end + describe "when evaluating" do + it "should return self" do + val = Puppet::Parser::AST::Regex.new :value => "/ab/" - it "should not downcase the paramater value" do - @value.expects(:match).with("VaLuE") - - @regex.evaluate_match("VaLuE", @scope) - end - - it "should set ephemeral scope vars if there is a match" do - @scope.expects(:ephemeral_from).with(true, nil, nil) - - @regex.evaluate_match("value", @scope) - end - - it "should return the match to the caller" do - @value.stubs(:match).with("value").returns(:match) - @scope.stubs(:ephemeral_from) - - @regex.evaluate_match("value", @scope) - end + val.evaluate(@scope).should === val end + end - it "should return the regex source with to_s" do - regex = stub 'regex' - Regexp.stubs(:new).returns(regex) - - val = Puppet::Parser::AST::Regex.new :value => "/ab/" - - regex.expects(:source) - - val.to_s + describe "when evaluate_match" do + before :each do + @value = stub 'regex' + @value.stubs(:match).with("value").returns(true) + Regexp.stubs(:new).returns(@value) + @regex = Puppet::Parser::AST::Regex.new :value => "/ab/" end - it "should delegate match to the underlying regexp match method" do - regex = Regexp.new("/ab/") - val = Puppet::Parser::AST::Regex.new :value => regex - - regex.expects(:match).with("value") + it "should issue the regexp match" do + @value.expects(:match).with("value") - val.match("value") + @regex.evaluate_match("value", @scope) end -end -describe Puppet::Parser::AST::Variable do - before :each do - @scope = stub 'scope' - @var = Puppet::Parser::AST::Variable.new(:value => "myvar") - end + it "should not downcase the paramater value" do + @value.expects(:match).with("VaLuE") - it "should lookup the variable in scope" do - @scope.expects(:lookupvar).with("myvar", false).returns(:myvalue) - @var.safeevaluate(@scope).should == :myvalue + @regex.evaluate_match("VaLuE", @scope) end - it "should return undef if the variable wasn't set" do - @scope.expects(:lookupvar).with("myvar", false).returns(:undefined) - @var.safeevaluate(@scope).should == :undef - end + it "should set ephemeral scope vars if there is a match" do + @scope.expects(:ephemeral_from).with(true, nil, nil) - describe "when converting to string" do - it "should transform its value to a variable" do - value = stub 'value', :is_a? => true, :to_s => "myvar" - Puppet::Parser::AST::Variable.new( :value => value ).to_s.should == "\$myvar" - end + @regex.evaluate_match("value", @scope) end -end -describe Puppet::Parser::AST::HostName do - before :each do - @scope = stub 'scope' - @value = stub 'value', :=~ => false - @value.stubs(:to_s).returns(@value) - @value.stubs(:downcase).returns(@value) - @host = Puppet::Parser::AST::HostName.new( :value => @value) - end - - it "should raise an error if hostname is not valid" do - lambda { Puppet::Parser::AST::HostName.new( :value => "not an hostname!" ) }.should raise_error - end + it "should return the match to the caller" do + @value.stubs(:match).with("value").returns(:match) + @scope.stubs(:ephemeral_from) - it "should not raise an error if hostname is a regex" do - lambda { Puppet::Parser::AST::HostName.new( :value => Puppet::Parser::AST::Regex.new(:value => "/test/") ) }.should_not raise_error + @regex.evaluate_match("value", @scope) end + end - it "should stringify the value" do - value = stub 'value', :=~ => false + it "should return the regex source with to_s" do + regex = stub 'regex' + Regexp.stubs(:new).returns(regex) - value.expects(:to_s).returns("test") + val = Puppet::Parser::AST::Regex.new :value => "/ab/" - Puppet::Parser::AST::HostName.new(:value => value) - end + regex.expects(:source) - it "should downcase the value" do - value = stub 'value', :=~ => false - value.stubs(:to_s).returns("UPCASED") - host = Puppet::Parser::AST::HostName.new(:value => value) + val.to_s + end - host.value == "upcased" - end + it "should delegate match to the underlying regexp match method" do + regex = Regexp.new("/ab/") + val = Puppet::Parser::AST::Regex.new :value => regex - it "should evaluate to its value" do - @host.evaluate(@scope).should == @value - end + regex.expects(:match).with("value") - it "should delegate eql? to the underlying value if it is an HostName" do - @value.expects(:eql?).with("value") - @host.eql?("value") - end + val.match("value") + end +end - it "should delegate eql? to the underlying value if it is not an HostName" do - value = stub 'compared', :is_a? => true, :value => "value" - @value.expects(:eql?).with("value") - @host.eql?(value) - end +describe Puppet::Parser::AST::Variable do + before :each do + @scope = stub 'scope' + @var = Puppet::Parser::AST::Variable.new(:value => "myvar") + end + + it "should lookup the variable in scope" do + @scope.expects(:lookupvar).with("myvar", false).returns(:myvalue) + @var.safeevaluate(@scope).should == :myvalue + end + + it "should return undef if the variable wasn't set" do + @scope.expects(:lookupvar).with("myvar", false).returns(:undefined) + @var.safeevaluate(@scope).should == :undef + end + + describe "when converting to string" do + it "should transform its value to a variable" do + value = stub 'value', :is_a? => true, :to_s => "myvar" + Puppet::Parser::AST::Variable.new( :value => value ).to_s.should == "\$myvar" + end + end +end - it "should delegate hash to the underlying value" do - @value.expects(:hash) - @host.hash - end +describe Puppet::Parser::AST::HostName do + before :each do + @scope = stub 'scope' + @value = stub 'value', :=~ => false + @value.stubs(:to_s).returns(@value) + @value.stubs(:downcase).returns(@value) + @host = Puppet::Parser::AST::HostName.new( :value => @value) + end + + it "should raise an error if hostname is not valid" do + lambda { Puppet::Parser::AST::HostName.new( :value => "not an hostname!" ) }.should raise_error + end + + it "should not raise an error if hostname is a regex" do + lambda { Puppet::Parser::AST::HostName.new( :value => Puppet::Parser::AST::Regex.new(:value => "/test/") ) }.should_not raise_error + end + + it "should stringify the value" do + value = stub 'value', :=~ => false + + value.expects(:to_s).returns("test") + + Puppet::Parser::AST::HostName.new(:value => value) + end + + it "should downcase the value" do + value = stub 'value', :=~ => false + value.stubs(:to_s).returns("UPCASED") + host = Puppet::Parser::AST::HostName.new(:value => value) + + host.value == "upcased" + end + + it "should evaluate to its value" do + @host.evaluate(@scope).should == @value + end + + it "should delegate eql? to the underlying value if it is an HostName" do + @value.expects(:eql?).with("value") + @host.eql?("value") + end + + it "should delegate eql? to the underlying value if it is not an HostName" do + value = stub 'compared', :is_a? => true, :value => "value" + @value.expects(:eql?).with("value") + @host.eql?(value) + end + + it "should delegate hash to the underlying value" do + @value.expects(:hash) + @host.hash + end end diff --git a/spec/unit/parser/ast/match_operator_spec.rb b/spec/unit/parser/ast/match_operator_spec.rb index e76d076a9..d6e998751 100755 --- a/spec/unit/parser/ast/match_operator_spec.rb +++ b/spec/unit/parser/ast/match_operator_spec.rb @@ -3,48 +3,48 @@ require File.dirname(__FILE__) + '/../../../spec_helper' describe Puppet::Parser::AST::MatchOperator do - before :each do - @scope = Puppet::Parser::Scope.new + before :each do + @scope = Puppet::Parser::Scope.new - @lval = stub 'lval' - @lval.stubs(:safeevaluate).with(@scope).returns("this is a string") + @lval = stub 'lval' + @lval.stubs(:safeevaluate).with(@scope).returns("this is a string") - @rval = stub 'rval' - @rval.stubs(:evaluate_match) + @rval = stub 'rval' + @rval.stubs(:evaluate_match) - @operator = Puppet::Parser::AST::MatchOperator.new :lval => @lval, :rval => @rval, :operator => "=~" - end + @operator = Puppet::Parser::AST::MatchOperator.new :lval => @lval, :rval => @rval, :operator => "=~" + end - it "should evaluate the left operand" do - @lval.expects(:safeevaluate).with(@scope) + it "should evaluate the left operand" do + @lval.expects(:safeevaluate).with(@scope) - @operator.evaluate(@scope) - end + @operator.evaluate(@scope) + end - it "should fail for an unknown operator" do - lambda { operator = Puppet::Parser::AST::MatchOperator.new :lval => @lval, :operator => "unknown", :rval => @rval }.should raise_error - end + it "should fail for an unknown operator" do + lambda { operator = Puppet::Parser::AST::MatchOperator.new :lval => @lval, :operator => "unknown", :rval => @rval }.should raise_error + end - it "should evaluate_match the left operand" do - @rval.expects(:evaluate_match).with("this is a string", @scope).returns(:match) + it "should evaluate_match the left operand" do + @rval.expects(:evaluate_match).with("this is a string", @scope).returns(:match) - @operator.evaluate(@scope) - end + @operator.evaluate(@scope) + end - { "=~" => true, "!~" => false }.each do |op, res| - it "should return #{res} if the regexp matches with #{op}" do - match = stub 'match' - @rval.stubs(:evaluate_match).with("this is a string", @scope).returns(match) + { "=~" => true, "!~" => false }.each do |op, res| + it "should return #{res} if the regexp matches with #{op}" do + match = stub 'match' + @rval.stubs(:evaluate_match).with("this is a string", @scope).returns(match) - operator = Puppet::Parser::AST::MatchOperator.new :lval => @lval, :rval => @rval, :operator => op - operator.evaluate(@scope).should == res - end + operator = Puppet::Parser::AST::MatchOperator.new :lval => @lval, :rval => @rval, :operator => op + operator.evaluate(@scope).should == res + end - it "should return #{!res} if the regexp doesn't match" do - @rval.stubs(:evaluate_match).with("this is a string", @scope).returns(nil) + it "should return #{!res} if the regexp doesn't match" do + @rval.stubs(:evaluate_match).with("this is a string", @scope).returns(nil) - operator = Puppet::Parser::AST::MatchOperator.new :lval => @lval, :rval => @rval, :operator => op - operator.evaluate(@scope).should == !res - end + operator = Puppet::Parser::AST::MatchOperator.new :lval => @lval, :rval => @rval, :operator => op + operator.evaluate(@scope).should == !res end + end end diff --git a/spec/unit/parser/ast/minus_spec.rb b/spec/unit/parser/ast/minus_spec.rb index a2c5a785b..108c8812e 100755 --- a/spec/unit/parser/ast/minus_spec.rb +++ b/spec/unit/parser/ast/minus_spec.rb @@ -3,34 +3,34 @@ require File.dirname(__FILE__) + '/../../../spec_helper' describe Puppet::Parser::AST::Minus do - before :each do - @scope = Puppet::Parser::Scope.new - end - - it "should evaluate its argument" do - value = stub "value" - value.expects(:safeevaluate).with(@scope).returns(123) - - operator = Puppet::Parser::AST::Minus.new :value => value - operator.evaluate(@scope) - end - - it "should fail if argument is not a string or integer" do - array_ast = stub 'array_ast', :safeevaluate => [2] - operator = Puppet::Parser::AST::Minus.new :value => array_ast - lambda { operator.evaluate(@scope) }.should raise_error - end - - it "should work with integer as string" do - string = stub 'string', :safeevaluate => "123" - operator = Puppet::Parser::AST::Minus.new :value => string - operator.evaluate(@scope).should == -123 - end - - it "should work with integers" do - int = stub 'int', :safeevaluate => 123 - operator = Puppet::Parser::AST::Minus.new :value => int - operator.evaluate(@scope).should == -123 - end + before :each do + @scope = Puppet::Parser::Scope.new + end + + it "should evaluate its argument" do + value = stub "value" + value.expects(:safeevaluate).with(@scope).returns(123) + + operator = Puppet::Parser::AST::Minus.new :value => value + operator.evaluate(@scope) + end + + it "should fail if argument is not a string or integer" do + array_ast = stub 'array_ast', :safeevaluate => [2] + operator = Puppet::Parser::AST::Minus.new :value => array_ast + lambda { operator.evaluate(@scope) }.should raise_error + end + + it "should work with integer as string" do + string = stub 'string', :safeevaluate => "123" + operator = Puppet::Parser::AST::Minus.new :value => string + operator.evaluate(@scope).should == -123 + end + + it "should work with integers" do + int = stub 'int', :safeevaluate => 123 + operator = Puppet::Parser::AST::Minus.new :value => int + operator.evaluate(@scope).should == -123 + end end diff --git a/spec/unit/parser/ast/nop_spec.rb b/spec/unit/parser/ast/nop_spec.rb index 5a7132586..3e493197a 100755 --- a/spec/unit/parser/ast/nop_spec.rb +++ b/spec/unit/parser/ast/nop_spec.rb @@ -4,17 +4,17 @@ require File.dirname(__FILE__) + '/../../../spec_helper' describe Puppet::Parser::AST::Nop do - before do - @scope = mock 'scope' - end + before do + @scope = mock 'scope' + end - it "should do nothing on evaluation" do - Puppet::Parser::AST.expects(:safeevaluate).never - Puppet::Parser::AST::Nop.new({}).evaluate(@scope) - end + it "should do nothing on evaluation" do + Puppet::Parser::AST.expects(:safeevaluate).never + Puppet::Parser::AST::Nop.new({}).evaluate(@scope) + end - it "should not return anything" do - Puppet::Parser::AST::Nop.new({}).evaluate(@scope).should be_nil - end + it "should not return anything" do + Puppet::Parser::AST::Nop.new({}).evaluate(@scope).should be_nil + end end diff --git a/spec/unit/parser/ast/not_spec.rb b/spec/unit/parser/ast/not_spec.rb index 3e8b36183..2ef6e0689 100755 --- a/spec/unit/parser/ast/not_spec.rb +++ b/spec/unit/parser/ast/not_spec.rb @@ -3,28 +3,28 @@ require File.dirname(__FILE__) + '/../../../spec_helper' describe Puppet::Parser::AST::Not do - before :each do - @scope = Puppet::Parser::Scope.new - @true_ast = Puppet::Parser::AST::Boolean.new( :value => true) - @false_ast = Puppet::Parser::AST::Boolean.new( :value => false) - end + before :each do + @scope = Puppet::Parser::Scope.new + @true_ast = Puppet::Parser::AST::Boolean.new( :value => true) + @false_ast = Puppet::Parser::AST::Boolean.new( :value => false) + end - it "should evaluate its child expression" do - val = stub "val" - val.expects(:safeevaluate).with(@scope) + it "should evaluate its child expression" do + val = stub "val" + val.expects(:safeevaluate).with(@scope) - operator = Puppet::Parser::AST::Not.new :value => val - operator.evaluate(@scope) - end + operator = Puppet::Parser::AST::Not.new :value => val + operator.evaluate(@scope) + end - it "should return true for ! false" do - operator = Puppet::Parser::AST::Not.new :value => @false_ast - operator.evaluate(@scope).should == true - end + it "should return true for ! false" do + operator = Puppet::Parser::AST::Not.new :value => @false_ast + operator.evaluate(@scope).should == true + end - it "should return false for ! true" do - operator = Puppet::Parser::AST::Not.new :value => @true_ast - operator.evaluate(@scope).should == false - end + it "should return false for ! true" do + operator = Puppet::Parser::AST::Not.new :value => @true_ast + operator.evaluate(@scope).should == false + end end diff --git a/spec/unit/parser/ast/relationship_spec.rb b/spec/unit/parser/ast/relationship_spec.rb index acb46e4ce..2a0f658df 100644 --- a/spec/unit/parser/ast/relationship_spec.rb +++ b/spec/unit/parser/ast/relationship_spec.rb @@ -3,86 +3,86 @@ require File.dirname(__FILE__) + '/../../../spec_helper' describe Puppet::Parser::AST::Relationship do + before do + @class = Puppet::Parser::AST::Relationship + end + + it "should set its 'left' and 'right' arguments accordingly" do + dep = @class.new(:left, :right, '->') + dep.left.should == :left + dep.right.should == :right + end + + it "should set its arrow to whatever arrow is passed" do + @class.new(:left, :right, '->').arrow.should == '->' + end + + it "should set its type to :relationship if the relationship type is '<-'" do + @class.new(:left, :right, '<-').type.should == :relationship + end + + it "should set its type to :relationship if the relationship type is '->'" do + @class.new(:left, :right, '->').type.should == :relationship + end + + it "should set its type to :subscription if the relationship type is '~>'" do + @class.new(:left, :right, '~>').type.should == :subscription + end + + it "should set its type to :subscription if the relationship type is '<~'" do + @class.new(:left, :right, '<~').type.should == :subscription + end + + it "should set its line and file if provided" do + dep = @class.new(:left, :right, '->', :line => 50, :file => "/foo") + dep.line.should == 50 + dep.file.should == "/foo" + end + + describe "when evaluating" do before do - @class = Puppet::Parser::AST::Relationship + @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("foo")) + @scope = Puppet::Parser::Scope.new(:compiler => @compiler) end - it "should set its 'left' and 'right' arguments accordingly" do - dep = @class.new(:left, :right, '->') - dep.left.should == :left - dep.right.should == :right + it "should create a relationship with the evaluated source and target and add it to the scope" do + source = stub 'source', :safeevaluate => :left + target = stub 'target', :safeevaluate => :right + @class.new(source, target, '->').evaluate(@scope) + @compiler.relationships[0].source.should == :left + @compiler.relationships[0].target.should == :right end - it "should set its arrow to whatever arrow is passed" do - @class.new(:left, :right, '->').arrow.should == '->' - end - - it "should set its type to :relationship if the relationship type is '<-'" do - @class.new(:left, :right, '<-').type.should == :relationship - end - - it "should set its type to :relationship if the relationship type is '->'" do - @class.new(:left, :right, '->').type.should == :relationship - end - - it "should set its type to :subscription if the relationship type is '~>'" do - @class.new(:left, :right, '~>').type.should == :subscription - end - - it "should set its type to :subscription if the relationship type is '<~'" do - @class.new(:left, :right, '<~').type.should == :subscription - end - - it "should set its line and file if provided" do - dep = @class.new(:left, :right, '->', :line => 50, :file => "/foo") - dep.line.should == 50 - dep.file.should == "/foo" - end - - describe "when evaluating" do - before do - @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("foo")) - @scope = Puppet::Parser::Scope.new(:compiler => @compiler) - end - - it "should create a relationship with the evaluated source and target and add it to the scope" do - source = stub 'source', :safeevaluate => :left - target = stub 'target', :safeevaluate => :right - @class.new(source, target, '->').evaluate(@scope) - @compiler.relationships[0].source.should == :left - @compiler.relationships[0].target.should == :right - end - - describe "a chained relationship" do - before do - @left = stub 'left', :safeevaluate => :left - @middle = stub 'middle', :safeevaluate => :middle - @right = stub 'right', :safeevaluate => :right - @first = @class.new(@left, @middle, '->') - @second = @class.new(@first, @right, '->') - end - - it "should evaluate the relationship to the left" do - @first.expects(:evaluate).with(@scope).returns Puppet::Parser::Relationship.new(:left, :right, :relationship) - - @second.evaluate(@scope) - end - - it "should use the right side of the left relationship as its source" do - @second.evaluate(@scope) - - @compiler.relationships[0].source.should == :left - @compiler.relationships[0].target.should == :middle - @compiler.relationships[1].source.should == :middle - @compiler.relationships[1].target.should == :right - end - - it "should only evaluate a given AST node once" do - @left.expects(:safeevaluate).once.returns :left - @middle.expects(:safeevaluate).once.returns :middle - @right.expects(:safeevaluate).once.returns :right - @second.evaluate(@scope) - end - end + describe "a chained relationship" do + before do + @left = stub 'left', :safeevaluate => :left + @middle = stub 'middle', :safeevaluate => :middle + @right = stub 'right', :safeevaluate => :right + @first = @class.new(@left, @middle, '->') + @second = @class.new(@first, @right, '->') + end + + it "should evaluate the relationship to the left" do + @first.expects(:evaluate).with(@scope).returns Puppet::Parser::Relationship.new(:left, :right, :relationship) + + @second.evaluate(@scope) + end + + it "should use the right side of the left relationship as its source" do + @second.evaluate(@scope) + + @compiler.relationships[0].source.should == :left + @compiler.relationships[0].target.should == :middle + @compiler.relationships[1].source.should == :middle + @compiler.relationships[1].target.should == :right + end + + it "should only evaluate a given AST node once" do + @left.expects(:safeevaluate).once.returns :left + @middle.expects(:safeevaluate).once.returns :middle + @right.expects(:safeevaluate).once.returns :right + @second.evaluate(@scope) + end end + end end diff --git a/spec/unit/parser/ast/resource_defaults_spec.rb b/spec/unit/parser/ast/resource_defaults_spec.rb index b2cec31c6..7843fd9a9 100755 --- a/spec/unit/parser/ast/resource_defaults_spec.rb +++ b/spec/unit/parser/ast/resource_defaults_spec.rb @@ -4,19 +4,19 @@ require File.dirname(__FILE__) + '/../../../spec_helper' describe Puppet::Parser::AST::ResourceDefaults do - ast = Puppet::Parser::AST + ast = Puppet::Parser::AST - before :each do - @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("mynode")) - @scope = Puppet::Parser::Scope.new(:compiler => @compiler) - @params = Puppet::Parser::AST::ASTArray.new({}) - @compiler.stubs(:add_override) - end + before :each do + @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("mynode")) + @scope = Puppet::Parser::Scope.new(:compiler => @compiler) + @params = Puppet::Parser::AST::ASTArray.new({}) + @compiler.stubs(:add_override) + end - it "should add defaults when evaluated" do - default = Puppet::Parser::AST::ResourceDefaults.new :type => "file", :parameters => Puppet::Parser::AST::ASTArray.new(:children => []) - default.evaluate @scope + it "should add defaults when evaluated" do + default = Puppet::Parser::AST::ResourceDefaults.new :type => "file", :parameters => Puppet::Parser::AST::ASTArray.new(:children => []) + default.evaluate @scope - @scope.lookupdefaults("file").should_not be_nil - end + @scope.lookupdefaults("file").should_not be_nil + end end diff --git a/spec/unit/parser/ast/resource_override_spec.rb b/spec/unit/parser/ast/resource_override_spec.rb index d327b57cd..637ab41fc 100755 --- a/spec/unit/parser/ast/resource_override_spec.rb +++ b/spec/unit/parser/ast/resource_override_spec.rb @@ -4,48 +4,48 @@ require File.dirname(__FILE__) + '/../../../spec_helper' describe Puppet::Parser::AST::ResourceOverride do - ast = Puppet::Parser::AST - - before :each do - @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("mynode")) - @scope = Puppet::Parser::Scope.new(:compiler => @compiler) - @params = ast::ASTArray.new({}) - @compiler.stubs(:add_override) - end - - it "should evaluate the overriden object" do - klass = stub 'klass', :title => "title", :type => "type" - object = mock 'object' - object.expects(:safeevaluate).with(@scope).returns(klass) - ast::ResourceOverride.new(:object => object, :parameters => @params ).evaluate(@scope) - end - - it "should tell the compiler to override the resource with our own" do - @compiler.expects(:add_override) - - klass = stub 'klass', :title => "title", :type => "one" - object = mock 'object', :safeevaluate => klass - ast::ResourceOverride.new(:object => object , :parameters => @params).evaluate(@scope) - end - - it "should return the overriden resource directly when called with one item" do - klass = stub 'klass', :title => "title", :type => "one" - object = mock 'object', :safeevaluate => klass - override = ast::ResourceOverride.new(:object => object , :parameters => @params).evaluate(@scope) - override.should be_an_instance_of(Puppet::Parser::Resource) - override.title.should == "title" - override.type.should == "One" - end - - it "should return an array of overriden resources when called with an array of titles" do - klass1 = stub 'klass1', :title => "title1", :type => "one" - klass2 = stub 'klass2', :title => "title2", :type => "one" - - object = mock 'object', :safeevaluate => [klass1,klass2] - - override = ast::ResourceOverride.new(:object => object , :parameters => @params).evaluate(@scope) - override.should have(2).elements - override.each {|o| o.should be_an_instance_of(Puppet::Parser::Resource) } - end + ast = Puppet::Parser::AST + + before :each do + @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("mynode")) + @scope = Puppet::Parser::Scope.new(:compiler => @compiler) + @params = ast::ASTArray.new({}) + @compiler.stubs(:add_override) + end + + it "should evaluate the overriden object" do + klass = stub 'klass', :title => "title", :type => "type" + object = mock 'object' + object.expects(:safeevaluate).with(@scope).returns(klass) + ast::ResourceOverride.new(:object => object, :parameters => @params ).evaluate(@scope) + end + + it "should tell the compiler to override the resource with our own" do + @compiler.expects(:add_override) + + klass = stub 'klass', :title => "title", :type => "one" + object = mock 'object', :safeevaluate => klass + ast::ResourceOverride.new(:object => object , :parameters => @params).evaluate(@scope) + end + + it "should return the overriden resource directly when called with one item" do + klass = stub 'klass', :title => "title", :type => "one" + object = mock 'object', :safeevaluate => klass + override = ast::ResourceOverride.new(:object => object , :parameters => @params).evaluate(@scope) + override.should be_an_instance_of(Puppet::Parser::Resource) + override.title.should == "title" + override.type.should == "One" + end + + it "should return an array of overriden resources when called with an array of titles" do + klass1 = stub 'klass1', :title => "title1", :type => "one" + klass2 = stub 'klass2', :title => "title2", :type => "one" + + object = mock 'object', :safeevaluate => [klass1,klass2] + + override = ast::ResourceOverride.new(:object => object , :parameters => @params).evaluate(@scope) + override.should have(2).elements + override.each {|o| o.should be_an_instance_of(Puppet::Parser::Resource) } + end end diff --git a/spec/unit/parser/ast/resource_reference_spec.rb b/spec/unit/parser/ast/resource_reference_spec.rb index a2a11e270..7b48119f4 100755 --- a/spec/unit/parser/ast/resource_reference_spec.rb +++ b/spec/unit/parser/ast/resource_reference_spec.rb @@ -4,43 +4,43 @@ require File.dirname(__FILE__) + '/../../../spec_helper' describe Puppet::Parser::AST::ResourceReference do - ast = Puppet::Parser::AST - - before :each do - @scope = Puppet::Parser::Scope.new - end - - def newref(type, title) - title = stub 'title', :safeevaluate => title - ref = Puppet::Parser::AST::ResourceReference.new(:type => type, :title => title) - end - - it "should correctly produce reference strings" do - newref("File", "/tmp/yay").evaluate(@scope).to_s.should == "File[/tmp/yay]" - 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 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 => "File" ) - ref.evaluate(@scope).should == [ - Puppet::Resource.new("file", "title1"), - Puppet::Resource.new("file", "title2") - ] - 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]" - - ast::ResourceReference.new( :type => type, :title => title ).to_s.should == "File[/tmp/a, /tmp/b]" - end + ast = Puppet::Parser::AST + + before :each do + @scope = Puppet::Parser::Scope.new + end + + def newref(type, title) + title = stub 'title', :safeevaluate => title + ref = Puppet::Parser::AST::ResourceReference.new(:type => type, :title => title) + end + + it "should correctly produce reference strings" do + newref("File", "/tmp/yay").evaluate(@scope).to_s.should == "File[/tmp/yay]" + 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 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 => "File" ) + ref.evaluate(@scope).should == [ + Puppet::Resource.new("file", "title1"), + Puppet::Resource.new("file", "title2") + ] + 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]" + + ast::ResourceReference.new( :type => type, :title => title ).to_s.should == "File[/tmp/a, /tmp/b]" + end end diff --git a/spec/unit/parser/ast/resource_spec.rb b/spec/unit/parser/ast/resource_spec.rb index 2473fda25..58ffae925 100755 --- a/spec/unit/parser/ast/resource_spec.rb +++ b/spec/unit/parser/ast/resource_spec.rb @@ -3,118 +3,118 @@ 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") + 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 + + 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] + + @resource.evaluate(@scope) + end + + it "should evaluate its title" do + @resource.evaluate(@scope)[0].title.should == "mytitle" + end + + it "should flatten the titles array" do + titles = [] + %w{one two}.each do |title| + titles << Puppet::Parser::AST::String.new(:value => title) 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] + array = Puppet::Parser::AST::ASTArray.new(:children => titles) - @resource.evaluate(@scope) - end + @resource.title = array + result = @resource.evaluate(@scope).collect { |r| r.title } + result.should be_include("one") + result.should be_include("two") + end - it "should evaluate its title" do - @resource.evaluate(@scope)[0].title.should == "mytitle" + 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 - it "should flatten the titles array" do - titles = [] - %w{one two}.each do |title| - titles << Puppet::Parser::AST::String.new(:value => title) - end + array = Puppet::Parser::AST::ASTArray.new(:children => titles) - array = Puppet::Parser::AST::ASTArray.new(:children => titles) + @resource.title = array + result = @resource.evaluate(@scope).collect { |r| r.title } + result.should be_include("one") + result.should be_include("two") + end - @resource.title = array - result = @resource.evaluate(@scope).collect { |r| r.title } - result.should be_include("one") - result.should be_include("two") + it "should handover resources to the compiler" do + titles = [] + %w{one two}.each do |title| + titles << Puppet::Parser::AST::String.new(:value => title) end - 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 + array = Puppet::Parser::AST::ASTArray.new(:children => titles) - array = Puppet::Parser::AST::ASTArray.new(:children => titles) + @resource.title = array + result = @resource.evaluate(@scope) - @resource.title = array - result = @resource.evaluate(@scope).collect { |r| r.title } - result.should be_include("one") - result.should be_include("two") + 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 + + result = @resource.evaluate(@scope) + result[0].should be_virtual + end + + 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 + + # 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 end - it "should handover resources to the compiler" do - titles = [] - %w{one two}.each do |title| - titles << Puppet::Parser::AST::String.new(:value => title) - end - - array = Puppet::Parser::AST::ASTArray.new(:children => titles) - - @resource.title = array - result = @resource.evaluate(@scope) - - result.each do |res| - @compiler.catalog.resource(res.ref).should be_instance_of(Puppet::Parser::Resource) - 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) end - it "should generate virtual resources if it is virtual" do - @resource.virtual = true - result = @resource.evaluate(@scope) - result[0].should be_virtual + 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 generate virtual and exported resources if it is exported" do - @resource.exported = true + it "should be able to generate resources with unqualified type information" do + resource("one").evaluate(@twoscope)[0].type.should == "One" + end - result = @resource.evaluate(@scope) - result[0].should be_virtual - result[0].should be_exported + it "should correctly generate resources that can look up builtin types" do + resource("file").evaluate(@twoscope)[0].type.should == "File" end - # 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 - 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) - 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 fail for resource types that do not exist" do - lambda { resource("nosuchtype").evaluate(@twoscope) }.should raise_error(Puppet::ParseError) - 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 diff --git a/spec/unit/parser/ast/selector_spec.rb b/spec/unit/parser/ast/selector_spec.rb index e10849c4c..42898475f 100755 --- a/spec/unit/parser/ast/selector_spec.rb +++ b/spec/unit/parser/ast/selector_spec.rb @@ -3,137 +3,137 @@ require File.dirname(__FILE__) + '/../../../spec_helper' describe Puppet::Parser::AST::Selector do - before :each do - @scope = Puppet::Parser::Scope.new - end - - describe "when evaluating" do - - before :each do - @param = stub 'param' - @param.stubs(:safeevaluate).with(@scope).returns("value") - - @value1 = stub 'value1' - @param1 = stub_everything 'param1' - @param1.stubs(:safeevaluate).with(@scope).returns(@param1) - @param1.stubs(:respond_to?).with(:downcase).returns(false) - @value1.stubs(:param).returns(@param1) - @value1.stubs(:value).returns(@value1) + before :each do + @scope = Puppet::Parser::Scope.new + end - @value2 = stub 'value2' - @param2 = stub_everything 'param2' - @param2.stubs(:safeevaluate).with(@scope).returns(@param2) - @param2.stubs(:respond_to?).with(:downcase).returns(false) - @value2.stubs(:param).returns(@param2) - @value2.stubs(:value).returns(@value2) + describe "when evaluating" do - @values = stub 'values', :instance_of? => true - @values.stubs(:each).multiple_yields(@value1, @value2) - - @selector = Puppet::Parser::AST::Selector.new :param => @param, :values => @values - @selector.stubs(:fail) - end + before :each do + @param = stub 'param' + @param.stubs(:safeevaluate).with(@scope).returns("value") + + @value1 = stub 'value1' + @param1 = stub_everything 'param1' + @param1.stubs(:safeevaluate).with(@scope).returns(@param1) + @param1.stubs(:respond_to?).with(:downcase).returns(false) + @value1.stubs(:param).returns(@param1) + @value1.stubs(:value).returns(@value1) + + @value2 = stub 'value2' + @param2 = stub_everything 'param2' + @param2.stubs(:safeevaluate).with(@scope).returns(@param2) + @param2.stubs(:respond_to?).with(:downcase).returns(false) + @value2.stubs(:param).returns(@param2) + @value2.stubs(:value).returns(@value2) + + @values = stub 'values', :instance_of? => true + @values.stubs(:each).multiple_yields(@value1, @value2) + + @selector = Puppet::Parser::AST::Selector.new :param => @param, :values => @values + @selector.stubs(:fail) + end - it "should evaluate param" do - @param.expects(:safeevaluate).with(@scope) + it "should evaluate param" do + @param.expects(:safeevaluate).with(@scope) - @selector.evaluate(@scope) - end + @selector.evaluate(@scope) + end - it "should scan each option" do - @values.expects(:each).multiple_yields(@value1, @value2) + it "should scan each option" do + @values.expects(:each).multiple_yields(@value1, @value2) - @selector.evaluate(@scope) - end + @selector.evaluate(@scope) + end - describe "when scanning values" do - it "should evaluate first matching option" do - @param2.stubs(:evaluate_match).with { |*arg| arg[0] == "value" }.returns(true) - @value2.expects(:safeevaluate).with(@scope) + describe "when scanning values" do + it "should evaluate first matching option" do + @param2.stubs(:evaluate_match).with { |*arg| arg[0] == "value" }.returns(true) + @value2.expects(:safeevaluate).with(@scope) - @selector.evaluate(@scope) - end + @selector.evaluate(@scope) + end - it "should return the first matching evaluated option" do - @param2.stubs(:evaluate_match).with { |*arg| arg[0] == "value" }.returns(true) - @value2.stubs(:safeevaluate).with(@scope).returns(:result) + it "should return the first matching evaluated option" do + @param2.stubs(:evaluate_match).with { |*arg| arg[0] == "value" }.returns(true) + @value2.stubs(:safeevaluate).with(@scope).returns(:result) - @selector.evaluate(@scope).should == :result - end + @selector.evaluate(@scope).should == :result + end - it "should evaluate the default option if none matched" do - @param1.stubs(:is_a?).with(Puppet::Parser::AST::Default).returns(true) - @value1.expects(:safeevaluate).with(@scope).returns(@param1) + it "should evaluate the default option if none matched" do + @param1.stubs(:is_a?).with(Puppet::Parser::AST::Default).returns(true) + @value1.expects(:safeevaluate).with(@scope).returns(@param1) - @selector.evaluate(@scope) - end + @selector.evaluate(@scope) + end - it "should return the default evaluated option if none matched" do - result = stub 'result' - @param1.stubs(:is_a?).with(Puppet::Parser::AST::Default).returns(true) - @value1.stubs(:safeevaluate).returns(result) + it "should return the default evaluated option if none matched" do + result = stub 'result' + @param1.stubs(:is_a?).with(Puppet::Parser::AST::Default).returns(true) + @value1.stubs(:safeevaluate).returns(result) - @selector.evaluate(@scope).should == result - end + @selector.evaluate(@scope).should == result + end - it "should return nil if nothing matched" do - @selector.evaluate(@scope).should be_nil - end + it "should return nil if nothing matched" do + @selector.evaluate(@scope).should be_nil + end - it "should delegate matching to evaluate_match" do - @param1.expects(:evaluate_match).with { |*arg| arg[0] == "value" and arg[1] == @scope } + it "should delegate matching to evaluate_match" do + @param1.expects(:evaluate_match).with { |*arg| arg[0] == "value" and arg[1] == @scope } - @selector.evaluate(@scope) - end + @selector.evaluate(@scope) + end - it "should evaluate the matching param" do - @param1.stubs(:evaluate_match).with { |*arg| arg[0] == "value" and arg[1] == @scope }.returns(true) + it "should evaluate the matching param" do + @param1.stubs(:evaluate_match).with { |*arg| arg[0] == "value" and arg[1] == @scope }.returns(true) - @value1.expects(:safeevaluate).with(@scope) + @value1.expects(:safeevaluate).with(@scope) - @selector.evaluate(@scope) - end + @selector.evaluate(@scope) + end - it "should return this evaluated option if it matches" do - @param1.stubs(:evaluate_match).with { |*arg| arg[0] == "value" and arg[1] == @scope }.returns(true) - @value1.stubs(:safeevaluate).with(@scope).returns(:result) + it "should return this evaluated option if it matches" do + @param1.stubs(:evaluate_match).with { |*arg| arg[0] == "value" and arg[1] == @scope }.returns(true) + @value1.stubs(:safeevaluate).with(@scope).returns(:result) - @selector.evaluate(@scope).should == :result - end + @selector.evaluate(@scope).should == :result + end - it "should unset scope ephemeral variables after option evaluation" do - @scope.stubs(:ephemeral_level).returns(:level) - @param1.stubs(:evaluate_match).with { |*arg| arg[0] == "value" and arg[1] == @scope }.returns(true) - @value1.stubs(:safeevaluate).with(@scope).returns(:result) + it "should unset scope ephemeral variables after option evaluation" do + @scope.stubs(:ephemeral_level).returns(:level) + @param1.stubs(:evaluate_match).with { |*arg| arg[0] == "value" and arg[1] == @scope }.returns(true) + @value1.stubs(:safeevaluate).with(@scope).returns(:result) - @scope.expects(:unset_ephemeral_var).with(:level) + @scope.expects(:unset_ephemeral_var).with(:level) - @selector.evaluate(@scope) - end + @selector.evaluate(@scope) + end - it "should not leak ephemeral variables even if evaluation fails" do - @scope.stubs(:ephemeral_level).returns(:level) - @param1.stubs(:evaluate_match).with { |*arg| arg[0] == "value" and arg[1] == @scope }.returns(true) - @value1.stubs(:safeevaluate).with(@scope).raises + it "should not leak ephemeral variables even if evaluation fails" do + @scope.stubs(:ephemeral_level).returns(:level) + @param1.stubs(:evaluate_match).with { |*arg| arg[0] == "value" and arg[1] == @scope }.returns(true) + @value1.stubs(:safeevaluate).with(@scope).raises - @scope.expects(:unset_ephemeral_var).with(:level) + @scope.expects(:unset_ephemeral_var).with(:level) - lambda { @selector.evaluate(@scope) }.should raise_error - end + lambda { @selector.evaluate(@scope) }.should raise_error + end - it "should fail if there is no default" do - @selector.expects(:fail) + it "should fail if there is no default" do + @selector.expects(:fail) - @selector.evaluate(@scope) - end - end + @selector.evaluate(@scope) + end end - describe "when converting to string" do - it "should produce a string version of this selector" do - values = Puppet::Parser::AST::ASTArray.new :children => [ Puppet::Parser::AST::ResourceParam.new(:param => "type", :value => "value", :add => false) ] - param = Puppet::Parser::AST::Variable.new :value => "myvar" - selector = Puppet::Parser::AST::Selector.new :param => param, :values => values - selector.to_s.should == "$myvar ? { type => value }" - end + end + describe "when converting to string" do + it "should produce a string version of this selector" do + values = Puppet::Parser::AST::ASTArray.new :children => [ Puppet::Parser::AST::ResourceParam.new(:param => "type", :value => "value", :add => false) ] + param = Puppet::Parser::AST::Variable.new :value => "myvar" + selector = Puppet::Parser::AST::Selector.new :param => param, :values => values + selector.to_s.should == "$myvar ? { type => value }" end + end end diff --git a/spec/unit/parser/ast/vardef_spec.rb b/spec/unit/parser/ast/vardef_spec.rb index e133b675e..a90010f5a 100755 --- a/spec/unit/parser/ast/vardef_spec.rb +++ b/spec/unit/parser/ast/vardef_spec.rb @@ -3,58 +3,58 @@ require File.dirname(__FILE__) + '/../../../spec_helper' describe Puppet::Parser::AST::VarDef do - before :each do - @scope = Puppet::Parser::Scope.new - end - - describe "when evaluating" do + before :each do + @scope = Puppet::Parser::Scope.new + end - it "should evaluate arguments" do - name = mock 'name' - value = mock 'value' + describe "when evaluating" do - name.expects(:safeevaluate).with(@scope) - value.expects(:safeevaluate).with(@scope) + it "should evaluate arguments" do + name = mock 'name' + value = mock 'value' - vardef = Puppet::Parser::AST::VarDef.new :name => name, :value => value, :file => nil, - :line => nil - vardef.evaluate(@scope) - end + name.expects(:safeevaluate).with(@scope) + value.expects(:safeevaluate).with(@scope) - it "should be in append=false mode if called without append" do - name = stub 'name', :safeevaluate => "var" - value = stub 'value', :safeevaluate => "1" + vardef = Puppet::Parser::AST::VarDef.new :name => name, :value => value, :file => nil, + :line => nil + vardef.evaluate(@scope) + end - @scope.expects(:setvar).with { |name,value,options| options[:append] == nil } + it "should be in append=false mode if called without append" do + name = stub 'name', :safeevaluate => "var" + value = stub 'value', :safeevaluate => "1" - vardef = Puppet::Parser::AST::VarDef.new :name => name, :value => value, :file => nil, - :line => nil - vardef.evaluate(@scope) - end + @scope.expects(:setvar).with { |name,value,options| options[:append] == nil } - it "should call scope in append mode if append is true" do - name = stub 'name', :safeevaluate => "var" - value = stub 'value', :safeevaluate => "1" + vardef = Puppet::Parser::AST::VarDef.new :name => name, :value => value, :file => nil, + :line => nil + vardef.evaluate(@scope) + end - @scope.expects(:setvar).with { |name,value,options| options[:append] == true } + it "should call scope in append mode if append is true" do + name = stub 'name', :safeevaluate => "var" + value = stub 'value', :safeevaluate => "1" - vardef = Puppet::Parser::AST::VarDef.new :name => name, :value => value, :file => nil, - :line => nil, :append => true - vardef.evaluate(@scope) - end + @scope.expects(:setvar).with { |name,value,options| options[:append] == true } - describe "when dealing with hash" do - it "should delegate to the HashOrArrayAccess assign" do - access = stub 'name' - access.stubs(:is_a?).with(Puppet::Parser::AST::HashOrArrayAccess).returns(true) - value = stub 'value', :safeevaluate => "1" - vardef = Puppet::Parser::AST::VarDef.new :name => access, :value => value, :file => nil, :line => nil + vardef = Puppet::Parser::AST::VarDef.new :name => name, :value => value, :file => nil, + :line => nil, :append => true + vardef.evaluate(@scope) + end - access.expects(:assign).with(@scope, '1') + describe "when dealing with hash" do + it "should delegate to the HashOrArrayAccess assign" do + access = stub 'name' + access.stubs(:is_a?).with(Puppet::Parser::AST::HashOrArrayAccess).returns(true) + value = stub 'value', :safeevaluate => "1" + vardef = Puppet::Parser::AST::VarDef.new :name => access, :value => value, :file => nil, :line => nil - vardef.evaluate(@scope) - end - end + access.expects(:assign).with(@scope, '1') + vardef.evaluate(@scope) + end end + + end end diff --git a/spec/unit/parser/ast_spec.rb b/spec/unit/parser/ast_spec.rb index cd271af98..b743cea2e 100644 --- a/spec/unit/parser/ast_spec.rb +++ b/spec/unit/parser/ast_spec.rb @@ -6,36 +6,36 @@ require 'puppet/parser/ast' describe Puppet::Parser::AST do - it "should use the file lookup module" do - Puppet::Parser::AST.ancestors.should be_include(Puppet::FileCollection::Lookup) + it "should use the file lookup module" do + Puppet::Parser::AST.ancestors.should be_include(Puppet::FileCollection::Lookup) + end + + it "should have a doc accessor" do + ast = Puppet::Parser::AST.new({}) + ast.should respond_to(:doc) + end + + it "should have a use_docs accessor to indicate it wants documentation" do + ast = Puppet::Parser::AST.new({}) + ast.should respond_to(:use_docs) + end + + [ Puppet::Parser::AST::Collection, Puppet::Parser::AST::Else, + Puppet::Parser::AST::Function, Puppet::Parser::AST::IfStatement, + Puppet::Parser::AST::Resource, Puppet::Parser::AST::ResourceDefaults, + Puppet::Parser::AST::ResourceOverride, Puppet::Parser::AST::VarDef + ].each do |k| + it "#{k}.use_docs should return true" do + ast = k.new({}) + ast.use_docs.should be_true end + end - it "should have a doc accessor" do - ast = Puppet::Parser::AST.new({}) - ast.should respond_to(:doc) - end - - it "should have a use_docs accessor to indicate it wants documentation" do - ast = Puppet::Parser::AST.new({}) - ast.should respond_to(:use_docs) - end - - [ Puppet::Parser::AST::Collection, Puppet::Parser::AST::Else, - Puppet::Parser::AST::Function, Puppet::Parser::AST::IfStatement, - Puppet::Parser::AST::Resource, Puppet::Parser::AST::ResourceDefaults, - Puppet::Parser::AST::ResourceOverride, Puppet::Parser::AST::VarDef - ].each do |k| - it "#{k}.use_docs should return true" do - ast = k.new({}) - ast.use_docs.should be_true - end - end - - describe "when initializing" do - it "should store the doc argument if passed" do - ast = Puppet::Parser::AST.new(:doc => "documentation") - ast.doc.should == "documentation" - end + describe "when initializing" do + it "should store the doc argument if passed" do + ast = Puppet::Parser::AST.new(:doc => "documentation") + ast.doc.should == "documentation" end + end end diff --git a/spec/unit/parser/collector_spec.rb b/spec/unit/parser/collector_spec.rb index c414207fa..15808d6ff 100755 --- a/spec/unit/parser/collector_spec.rb +++ b/spec/unit/parser/collector_spec.rb @@ -5,555 +5,555 @@ require File.dirname(__FILE__) + '/../../spec_helper' require 'puppet/parser/collector' describe Puppet::Parser::Collector, "when initializing" do - before do - @scope = mock 'scope' - @resource_type = 'resource_type' - @form = :exported - @vquery = mock 'vquery' - @equery = mock 'equery' - - @collector = Puppet::Parser::Collector.new(@scope, @resource_type, @equery, @vquery, @form) - end - - it "should require a scope" do - @collector.scope.should equal(@scope) - end - - it "should require a resource type" do - @collector.type.should == 'Resource_type' - end - - it "should only accept :virtual or :exported as the collector form" do - proc { @collector = Puppet::Parser::Collector.new(@scope, @resource_type, @vquery, @equery, :other) }.should raise_error(ArgumentError) - end - - it "should accept an optional virtual query" do - @collector.vquery.should equal(@vquery) - end - - it "should accept an optional exported query" do - @collector.equery.should equal(@equery) - end - - it "should canonize the type name" do - @collector = Puppet::Parser::Collector.new(@scope, "resource::type", @equery, @vquery, @form) - @collector.type.should == "Resource::Type" - end - - it "should accept an optional resource override" do - @collector = Puppet::Parser::Collector.new(@scope, "resource::type", @equery, @vquery, @form) - override = { :parameters => "whatever" } - @collector.add_override(override) - @collector.overrides.should equal(override) - end + before do + @scope = mock 'scope' + @resource_type = 'resource_type' + @form = :exported + @vquery = mock 'vquery' + @equery = mock 'equery' + + @collector = Puppet::Parser::Collector.new(@scope, @resource_type, @equery, @vquery, @form) + end + + it "should require a scope" do + @collector.scope.should equal(@scope) + end + + it "should require a resource type" do + @collector.type.should == 'Resource_type' + end + + it "should only accept :virtual or :exported as the collector form" do + proc { @collector = Puppet::Parser::Collector.new(@scope, @resource_type, @vquery, @equery, :other) }.should raise_error(ArgumentError) + end + + it "should accept an optional virtual query" do + @collector.vquery.should equal(@vquery) + end + + it "should accept an optional exported query" do + @collector.equery.should equal(@equery) + end + + it "should canonize the type name" do + @collector = Puppet::Parser::Collector.new(@scope, "resource::type", @equery, @vquery, @form) + @collector.type.should == "Resource::Type" + end + + it "should accept an optional resource override" do + @collector = Puppet::Parser::Collector.new(@scope, "resource::type", @equery, @vquery, @form) + override = { :parameters => "whatever" } + @collector.add_override(override) + @collector.overrides.should equal(override) + end end describe Puppet::Parser::Collector, "when collecting specific virtual resources" do - before do - @scope = mock 'scope' - @vquery = mock 'vquery' - @equery = mock 'equery' - - @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 - @collector.resources = ["File[virtual1]", "File[virtual2]"] - @scope.stubs(:findresource).returns(false) - proc { @collector.evaluate }.should_not raise_error - end - - it "should mark matched resources as non-virtual" do - @collector.resources = ["File[virtual1]", "File[virtual2]"] - one = stub_everything 'one' - one.expects(:virtual=).with(false) - - @scope.stubs(:findresource).with("File[virtual1]").returns(one) - @scope.stubs(:findresource).with("File[virtual2]").returns(nil) - @collector.evaluate - end - - it "should return matched resources" do - @collector.resources = ["File[virtual1]", "File[virtual2]"] - one = stub_everything 'one' - @scope.stubs(:findresource).with("File[virtual1]").returns(one) - @scope.stubs(:findresource).with("File[virtual2]").returns(nil) - @collector.evaluate.should == [one] - end - - it "should delete itself from the compile's collection list if it has found all of its resources" do - @collector.resources = ["File[virtual1]"] - one = stub_everything 'one' - @compiler.expects(:delete_collection).with(@collector) - @scope.expects(:compiler).returns(@compiler) - @scope.stubs(:findresource).with("File[virtual1]").returns(one) - @collector.evaluate - end - - it "should not delete itself from the compile's collection list if it has unfound resources" do - @collector.resources = ["File[virtual1]"] - one = stub_everything 'one' - @compiler.expects(:delete_collection).never - @scope.stubs(:findresource).with("File[virtual1]").returns(nil) - @collector.evaluate - end + before do + @scope = mock 'scope' + @vquery = mock 'vquery' + @equery = mock 'equery' + + @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 + @collector.resources = ["File[virtual1]", "File[virtual2]"] + @scope.stubs(:findresource).returns(false) + proc { @collector.evaluate }.should_not raise_error + end + + it "should mark matched resources as non-virtual" do + @collector.resources = ["File[virtual1]", "File[virtual2]"] + one = stub_everything 'one' + one.expects(:virtual=).with(false) + + @scope.stubs(:findresource).with("File[virtual1]").returns(one) + @scope.stubs(:findresource).with("File[virtual2]").returns(nil) + @collector.evaluate + end + + it "should return matched resources" do + @collector.resources = ["File[virtual1]", "File[virtual2]"] + one = stub_everything 'one' + @scope.stubs(:findresource).with("File[virtual1]").returns(one) + @scope.stubs(:findresource).with("File[virtual2]").returns(nil) + @collector.evaluate.should == [one] + end + + it "should delete itself from the compile's collection list if it has found all of its resources" do + @collector.resources = ["File[virtual1]"] + one = stub_everything 'one' + @compiler.expects(:delete_collection).with(@collector) + @scope.expects(:compiler).returns(@compiler) + @scope.stubs(:findresource).with("File[virtual1]").returns(one) + @collector.evaluate + end + + it "should not delete itself from the compile's collection list if it has unfound resources" do + @collector.resources = ["File[virtual1]"] + one = stub_everything 'one' + @compiler.expects(:delete_collection).never + @scope.stubs(:findresource).with("File[virtual1]").returns(nil) + @collector.evaluate + end end describe Puppet::Parser::Collector, "when collecting virtual and catalog resources" do - before do - @scope = mock 'scope' - @compiler = mock 'compile' - @scope.stubs(:compiler).returns(@compiler) - @resource_type = "Mytype" - @vquery = proc { |res| true } - - @collector = Puppet::Parser::Collector.new(@scope, @resource_type, nil, @vquery, :virtual) - end + before do + @scope = mock 'scope' + @compiler = mock 'compile' + @scope.stubs(:compiler).returns(@compiler) + @resource_type = "Mytype" + @vquery = proc { |res| true } - it "should find all virtual resources matching the vquery" do - one = stub_everything 'one', :type => "Mytype", :virtual? => true - two = stub_everything 'two', :type => "Mytype", :virtual? => true + @collector = Puppet::Parser::Collector.new(@scope, @resource_type, nil, @vquery, :virtual) + end - @compiler.expects(:resources).returns([one, two]) + it "should find all virtual resources matching the vquery" do + one = stub_everything 'one', :type => "Mytype", :virtual? => true + two = stub_everything 'two', :type => "Mytype", :virtual? => true - @collector.evaluate.should == [one, two] - end + @compiler.expects(:resources).returns([one, two]) - it "should find all non-virtual resources matching the vquery" do - one = stub_everything 'one', :type => "Mytype", :virtual? => false - two = stub_everything 'two', :type => "Mytype", :virtual? => false + @collector.evaluate.should == [one, two] + end - @compiler.expects(:resources).returns([one, two]) + it "should find all non-virtual resources matching the vquery" do + one = stub_everything 'one', :type => "Mytype", :virtual? => false + two = stub_everything 'two', :type => "Mytype", :virtual? => false - @collector.evaluate.should == [one, two] - end + @compiler.expects(:resources).returns([one, two]) - it "should mark all matched resources as non-virtual" do - one = stub_everything 'one', :type => "Mytype", :virtual? => true + @collector.evaluate.should == [one, two] + end - one.expects(:virtual=).with(false) + it "should mark all matched resources as non-virtual" do + one = stub_everything 'one', :type => "Mytype", :virtual? => true - @compiler.expects(:resources).returns([one]) + one.expects(:virtual=).with(false) - @collector.evaluate - end + @compiler.expects(:resources).returns([one]) - it "should return matched resources" do - one = stub_everything 'one', :type => "Mytype", :virtual? => true - two = stub_everything 'two', :type => "Mytype", :virtual? => true + @collector.evaluate + end - @compiler.expects(:resources).returns([one, two]) + it "should return matched resources" do + one = stub_everything 'one', :type => "Mytype", :virtual? => true + two = stub_everything 'two', :type => "Mytype", :virtual? => true - @collector.evaluate.should == [one, two] - end + @compiler.expects(:resources).returns([one, two]) - it "should return all resources of the correct type if there is no virtual query" do - one = stub_everything 'one', :type => "Mytype", :virtual? => true - two = stub_everything 'two', :type => "Mytype", :virtual? => true + @collector.evaluate.should == [one, two] + end - one.expects(:virtual=).with(false) - two.expects(:virtual=).with(false) + it "should return all resources of the correct type if there is no virtual query" do + one = stub_everything 'one', :type => "Mytype", :virtual? => true + two = stub_everything 'two', :type => "Mytype", :virtual? => true - @compiler.expects(:resources).returns([one, two]) + one.expects(:virtual=).with(false) + two.expects(:virtual=).with(false) - @collector = Puppet::Parser::Collector.new(@scope, @resource_type, nil, nil, :virtual) + @compiler.expects(:resources).returns([one, two]) - @collector.evaluate.should == [one, two] - end + @collector = Puppet::Parser::Collector.new(@scope, @resource_type, nil, nil, :virtual) - it "should not return or mark resources of a different type" do - one = stub_everything 'one', :type => "Mytype", :virtual? => true - two = stub_everything 'two', :type => :other, :virtual? => true + @collector.evaluate.should == [one, two] + end - one.expects(:virtual=).with(false) - two.expects(:virtual=).never + it "should not return or mark resources of a different type" do + one = stub_everything 'one', :type => "Mytype", :virtual? => true + two = stub_everything 'two', :type => :other, :virtual? => true - @compiler.expects(:resources).returns([one, two]) + one.expects(:virtual=).with(false) + two.expects(:virtual=).never - @collector.evaluate.should == [one] - end + @compiler.expects(:resources).returns([one, two]) - it "should create a resource with overridden parameters" do - one = stub_everything 'one', :type => "Mytype", :virtual? => true, :title => "test" - param = stub 'param' - @compiler.stubs(:add_override) + @collector.evaluate.should == [one] + end - @compiler.expects(:resources).returns([one]) + it "should create a resource with overridden parameters" do + one = stub_everything 'one', :type => "Mytype", :virtual? => true, :title => "test" + param = stub 'param' + @compiler.stubs(:add_override) - @collector.add_override(:parameters => param ) - Puppet::Parser::Resource.expects(:new).with { |type, title, h| - h[:parameters] == param - } + @compiler.expects(:resources).returns([one]) - @collector.evaluate - end + @collector.add_override(:parameters => param ) + Puppet::Parser::Resource.expects(:new).with { |type, title, h| + h[:parameters] == param + } - it "should define a new allow all child_of? on overriden resource" do - one = stub_everything 'one', :type => "Mytype", :virtual? => true, :title => "test" - param = stub 'param' - source = stub 'source' - @compiler.stubs(:add_override) + @collector.evaluate + end - @compiler.expects(:resources).returns([one]) + it "should define a new allow all child_of? on overriden resource" do + one = stub_everything 'one', :type => "Mytype", :virtual? => true, :title => "test" + param = stub 'param' + source = stub 'source' + @compiler.stubs(:add_override) - @collector.add_override(:parameters => param, :source => source ) - Puppet::Parser::Resource.stubs(:new) + @compiler.expects(:resources).returns([one]) - source.expects(:meta_def).with { |name,block| name == :child_of? } + @collector.add_override(:parameters => param, :source => source ) + Puppet::Parser::Resource.stubs(:new) - @collector.evaluate - end + source.expects(:meta_def).with { |name,block| name == :child_of? } + @collector.evaluate + end - it "should not override already overriden resources for this same collection in a previous run" do - one = stub_everything 'one', :type => "Mytype", :virtual? => true, :title => "test" - param = stub 'param' - @compiler.stubs(:add_override) - @compiler.expects(:resources).at_least(2).returns([one]) + it "should not override already overriden resources for this same collection in a previous run" do + one = stub_everything 'one', :type => "Mytype", :virtual? => true, :title => "test" + param = stub 'param' + @compiler.stubs(:add_override) - @collector.add_override(:parameters => param ) - Puppet::Parser::Resource.expects(:new).once.with { |type, title, h| - h[:parameters] == param - } + @compiler.expects(:resources).at_least(2).returns([one]) - @collector.evaluate + @collector.add_override(:parameters => param ) + Puppet::Parser::Resource.expects(:new).once.with { |type, title, h| + h[:parameters] == param + } - @collector.evaluate - end + @collector.evaluate - it "should not return resources that were collected in a previous run of this collector" do - one = stub_everything 'one', :type => "Mytype", :virtual? => true, :title => "test" - @compiler.stubs(:resources).returns([one]) + @collector.evaluate + end - @collector.evaluate + it "should not return resources that were collected in a previous run of this collector" do + one = stub_everything 'one', :type => "Mytype", :virtual? => true, :title => "test" + @compiler.stubs(:resources).returns([one]) - @collector.evaluate.should be_false - end + @collector.evaluate + @collector.evaluate.should be_false + end - it "should tell the compiler about the overriden resources" do - one = stub_everything 'one', :type => "Mytype", :virtual? => true, :title => "test" - param = stub 'param' - one.expects(:virtual=).with(false) - @compiler.expects(:resources).returns([one]) - @collector.add_override(:parameters => param ) - Puppet::Parser::Resource.stubs(:new).returns("whatever") + it "should tell the compiler about the overriden resources" do + one = stub_everything 'one', :type => "Mytype", :virtual? => true, :title => "test" + param = stub 'param' - @compiler.expects(:add_override).with("whatever") + one.expects(:virtual=).with(false) + @compiler.expects(:resources).returns([one]) + @collector.add_override(:parameters => param ) + Puppet::Parser::Resource.stubs(:new).returns("whatever") - @collector.evaluate - end + @compiler.expects(:add_override).with("whatever") - it "should not return or mark non-matching resources" do - @collector.vquery = proc { |res| res.name == :one } + @collector.evaluate + end - one = stub_everything 'one', :name => :one, :type => "Mytype", :virtual? => true - two = stub_everything 'two', :name => :two, :type => "Mytype", :virtual? => true + it "should not return or mark non-matching resources" do + @collector.vquery = proc { |res| res.name == :one } - one.expects(:virtual=).with(false) - two.expects(:virtual=).never + one = stub_everything 'one', :name => :one, :type => "Mytype", :virtual? => true + two = stub_everything 'two', :name => :two, :type => "Mytype", :virtual? => true - @compiler.expects(:resources).returns([one, two]) + one.expects(:virtual=).with(false) + two.expects(:virtual=).never - @collector.evaluate.should == [one] - end + @compiler.expects(:resources).returns([one, two]) + + @collector.evaluate.should == [one] + end end describe Puppet::Parser::Collector, "when collecting exported resources" do - confine "Cannot test Rails integration without ActiveRecord" => Puppet.features.rails? + confine "Cannot test Rails integration without ActiveRecord" => Puppet.features.rails? - before do - @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("mynode")) - @scope = Puppet::Parser::Scope.new :compiler => @compiler - @resource_type = "Mytype" - @equery = "test = true" - @vquery = proc { |r| true } + before do + @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("mynode")) + @scope = Puppet::Parser::Scope.new :compiler => @compiler + @resource_type = "Mytype" + @equery = "test = true" + @vquery = proc { |r| true } - res = stub("resource 1") - res.stubs(:type).returns @resource_type - Puppet::Resource.stubs(:new).returns res + res = stub("resource 1") + res.stubs(:type).returns @resource_type + Puppet::Resource.stubs(:new).returns res - Puppet.settings.stubs(:value).with(:storeconfigs).returns true - Puppet.settings.stubs(:value).with(:environment).returns "production" + Puppet.settings.stubs(:value).with(:storeconfigs).returns true + Puppet.settings.stubs(:value).with(:environment).returns "production" - @collector = Puppet::Parser::Collector.new(@scope, @resource_type, @equery, @vquery, :exported) - end + @collector = Puppet::Parser::Collector.new(@scope, @resource_type, @equery, @vquery, :exported) + end - # Stub most of our interface to Rails. - def stub_rails(everything = false) - ActiveRecord::Base.stubs(:connected?).returns(false) - Puppet::Rails.stubs(:init) - if everything - Puppet::Rails::Host.stubs(:find_by_name).returns(nil) - Puppet::Rails::Resource.stubs(:find).returns([]) - end + # Stub most of our interface to Rails. + def stub_rails(everything = false) + ActiveRecord::Base.stubs(:connected?).returns(false) + Puppet::Rails.stubs(:init) + if everything + Puppet::Rails::Host.stubs(:find_by_name).returns(nil) + Puppet::Rails::Resource.stubs(:find).returns([]) end + end - it "should just return false if :storeconfigs is not enabled" do - Puppet.settings.expects(:value).with(:storeconfigs).returns false - @collector.evaluate.should be_false - end + it "should just return false if :storeconfigs is not enabled" do + Puppet.settings.expects(:value).with(:storeconfigs).returns false + @collector.evaluate.should be_false + end - it "should use initialize the Rails support if ActiveRecord is not connected" do - @compiler.stubs(:resources).returns([]) - ActiveRecord::Base.expects(:connected?).returns(false) - Puppet::Rails.expects(:init) - Puppet::Rails::Host.stubs(:find_by_name).returns(nil) - Puppet::Rails::Resource.stubs(:find).returns([]) + it "should use initialize the Rails support if ActiveRecord is not connected" do + @compiler.stubs(:resources).returns([]) + ActiveRecord::Base.expects(:connected?).returns(false) + Puppet::Rails.expects(:init) + Puppet::Rails::Host.stubs(:find_by_name).returns(nil) + Puppet::Rails::Resource.stubs(:find).returns([]) - @collector.evaluate - end + @collector.evaluate + end - it "should return all matching resources from the current compile and mark them non-virtual and non-exported" do - stub_rails(true) + it "should return all matching resources from the current compile and mark them non-virtual and non-exported" do + stub_rails(true) - one = stub 'one', :type => "Mytype", :virtual? => true, :exported? => true, :ref => "one" - two = stub 'two', :type => "Mytype", :virtual? => true, :exported? => true, :ref => "two" + one = stub 'one', :type => "Mytype", :virtual? => true, :exported? => true, :ref => "one" + two = stub 'two', :type => "Mytype", :virtual? => true, :exported? => true, :ref => "two" - one.stubs(:exported=) - one.stubs(:virtual=) - two.stubs(:exported=) - two.stubs(:virtual=) + one.stubs(:exported=) + one.stubs(:virtual=) + two.stubs(:exported=) + two.stubs(:virtual=) - @compiler.expects(:resources).returns([one, two]) + @compiler.expects(:resources).returns([one, two]) - @collector.evaluate.should == [one, two] - end + @collector.evaluate.should == [one, two] + end - it "should mark all returned resources as not virtual" do - stub_rails(true) + it "should mark all returned resources as not virtual" do + stub_rails(true) - one = stub 'one', :type => "Mytype", :virtual? => true, :exported? => true, :ref => "one" + one = stub 'one', :type => "Mytype", :virtual? => true, :exported? => true, :ref => "one" - one.stubs(:exported=) - one.expects(:virtual=).with(false) + one.stubs(:exported=) + one.expects(:virtual=).with(false) - @compiler.expects(:resources).returns([one]) + @compiler.expects(:resources).returns([one]) - @collector.evaluate.should == [one] - end + @collector.evaluate.should == [one] + end - it "should convert all found resources into parser resources" do - stub_rails - Puppet::Rails::Host.stubs(:find_by_name).returns(nil) + it "should convert all found resources into parser resources" do + stub_rails + Puppet::Rails::Host.stubs(:find_by_name).returns(nil) - one = stub 'one', :restype => "Mytype", :title => "one", :virtual? => true, :exported? => true, :ref => "one" - Puppet::Rails::Resource.stubs(:find).returns([one]) + one = stub 'one', :restype => "Mytype", :title => "one", :virtual? => true, :exported? => true, :ref => "one" + Puppet::Rails::Resource.stubs(:find).returns([one]) - resource = mock 'resource' - one.expects(:to_resource).with(@scope).returns(resource) - resource.stubs(:exported=) - resource.stubs(:virtual=) - resource.stubs(:ref) + resource = mock 'resource' + one.expects(:to_resource).with(@scope).returns(resource) + resource.stubs(:exported=) + resource.stubs(:virtual=) + resource.stubs(:ref) - @compiler.stubs(:resources).returns([]) - @scope.stubs(:findresource).returns(nil) + @compiler.stubs(:resources).returns([]) + @scope.stubs(:findresource).returns(nil) - @compiler.stubs(:add_resource) + @compiler.stubs(:add_resource) - @collector.evaluate.should == [resource] - end + @collector.evaluate.should == [resource] + end - it "should override all exported collected resources if collector has an override" do - stub_rails - Puppet::Rails::Host.stubs(:find_by_name).returns(nil) + it "should override all exported collected resources if collector has an override" do + stub_rails + Puppet::Rails::Host.stubs(:find_by_name).returns(nil) - one = stub 'one', :restype => "Mytype", :title => "one", :virtual? => true, :exported? => true, :ref => "one" - Puppet::Rails::Resource.stubs(:find).returns([one]) + one = stub 'one', :restype => "Mytype", :title => "one", :virtual? => true, :exported? => true, :ref => "one" + Puppet::Rails::Resource.stubs(:find).returns([one]) - resource = mock 'resource', :type => "Mytype" - one.expects(:to_resource).with(@scope).returns(resource) - resource.stubs(:exported=) - resource.stubs(:virtual=) - resource.stubs(:ref) - resource.stubs(:title) + resource = mock 'resource', :type => "Mytype" + one.expects(:to_resource).with(@scope).returns(resource) + resource.stubs(:exported=) + resource.stubs(:virtual=) + resource.stubs(:ref) + resource.stubs(:title) - @compiler.stubs(:resources).returns([]) - @scope.stubs(:findresource).returns(nil) + @compiler.stubs(:resources).returns([]) + @scope.stubs(:findresource).returns(nil) - param = stub 'param' - @compiler.stubs(:add_override) - @compiler.stubs(:add_resource) + param = stub 'param' + @compiler.stubs(:add_override) + @compiler.stubs(:add_resource) - @collector.add_override(:parameters => param ) - Puppet::Parser::Resource.expects(:new).once.with { |type, title, h| - h[:parameters] == param - } + @collector.add_override(:parameters => param ) + Puppet::Parser::Resource.expects(:new).once.with { |type, title, h| + h[:parameters] == param + } - @collector.evaluate - end + @collector.evaluate + end - it "should store converted resources in the compile's resource list" do - stub_rails - Puppet::Rails::Host.stubs(:find_by_name).returns(nil) + it "should store converted resources in the compile's resource list" do + stub_rails + Puppet::Rails::Host.stubs(:find_by_name).returns(nil) - one = stub 'one', :restype => "Mytype", :title => "one", :virtual? => true, :exported? => true, :ref => "one" - Puppet::Rails::Resource.stubs(:find).returns([one]) + one = stub 'one', :restype => "Mytype", :title => "one", :virtual? => true, :exported? => true, :ref => "one" + Puppet::Rails::Resource.stubs(:find).returns([one]) - resource = mock 'resource' - one.expects(:to_resource).with(@scope).returns(resource) - resource.stubs(:exported=) - resource.stubs(:virtual=) - resource.stubs(:ref) + resource = mock 'resource' + one.expects(:to_resource).with(@scope).returns(resource) + resource.stubs(:exported=) + resource.stubs(:virtual=) + resource.stubs(:ref) - @compiler.stubs(:resources).returns([]) - @scope.stubs(:findresource).returns(nil) + @compiler.stubs(:resources).returns([]) + @scope.stubs(:findresource).returns(nil) - @compiler.expects(:add_resource).with(@scope, resource) + @compiler.expects(:add_resource).with(@scope, resource) - @collector.evaluate.should == [resource] - end + @collector.evaluate.should == [resource] + end - # This way one host doesn't store another host's resources as exported. - it "should mark resources collected from the database as not exported" do - stub_rails - Puppet::Rails::Host.stubs(:find_by_name).returns(nil) + # This way one host doesn't store another host's resources as exported. + it "should mark resources collected from the database as not exported" do + stub_rails + Puppet::Rails::Host.stubs(:find_by_name).returns(nil) - one = stub 'one', :restype => "Mytype", :title => "one", :virtual? => true, :exported? => true, :ref => "one" - Puppet::Rails::Resource.stubs(:find).returns([one]) + one = stub 'one', :restype => "Mytype", :title => "one", :virtual? => true, :exported? => true, :ref => "one" + Puppet::Rails::Resource.stubs(:find).returns([one]) - resource = mock 'resource' - one.expects(:to_resource).with(@scope).returns(resource) - resource.expects(:exported=).with(false) - resource.stubs(:virtual=) - resource.stubs(:ref) + resource = mock 'resource' + one.expects(:to_resource).with(@scope).returns(resource) + resource.expects(:exported=).with(false) + resource.stubs(:virtual=) + resource.stubs(:ref) - @compiler.stubs(:resources).returns([]) - @scope.stubs(:findresource).returns(nil) + @compiler.stubs(:resources).returns([]) + @scope.stubs(:findresource).returns(nil) - @compiler.stubs(:add_resource) + @compiler.stubs(:add_resource) - @collector.evaluate - end + @collector.evaluate + end - it "should fail if an equivalent resource already exists in the compile" do - stub_rails - Puppet::Rails::Host.stubs(:find_by_name).returns(nil) + it "should fail if an equivalent resource already exists in the compile" do + stub_rails + Puppet::Rails::Host.stubs(:find_by_name).returns(nil) - rails = stub 'one', :restype => "Mytype", :title => "one", :virtual? => true, :exported? => true, :id => 1, :ref => "yay" - inmemory = stub 'one', :type => "Mytype", :virtual? => true, :exported? => true, :rails_id => 2 + rails = stub 'one', :restype => "Mytype", :title => "one", :virtual? => true, :exported? => true, :id => 1, :ref => "yay" + inmemory = stub 'one', :type => "Mytype", :virtual? => true, :exported? => true, :rails_id => 2 - Puppet::Rails::Resource.stubs(:find).returns([rails]) + Puppet::Rails::Resource.stubs(:find).returns([rails]) - resource = mock 'resource' + resource = mock 'resource' - @compiler.stubs(:resources).returns([]) - @scope.stubs(:findresource).returns(inmemory) + @compiler.stubs(:resources).returns([]) + @scope.stubs(:findresource).returns(inmemory) - @compiler.stubs(:add_resource) + @compiler.stubs(:add_resource) - proc { @collector.evaluate }.should raise_error(Puppet::ParseError) - end + proc { @collector.evaluate }.should raise_error(Puppet::ParseError) + end - it "should ignore exported resources that match already-collected resources" do - stub_rails - Puppet::Rails::Host.stubs(:find_by_name).returns(nil) + it "should ignore exported resources that match already-collected resources" do + stub_rails + Puppet::Rails::Host.stubs(:find_by_name).returns(nil) - rails = stub 'one', :restype => "Mytype", :title => "one", :virtual? => true, :exported? => true, :id => 1, :ref => "yay" - inmemory = stub 'one', :type => "Mytype", :virtual? => true, :exported? => true, :rails_id => 1 + rails = stub 'one', :restype => "Mytype", :title => "one", :virtual? => true, :exported? => true, :id => 1, :ref => "yay" + inmemory = stub 'one', :type => "Mytype", :virtual? => true, :exported? => true, :rails_id => 1 - Puppet::Rails::Resource.stubs(:find).returns([rails]) + Puppet::Rails::Resource.stubs(:find).returns([rails]) - resource = mock 'resource' + resource = mock 'resource' - @compiler.stubs(:resources).returns([]) - @scope.stubs(:findresource).returns(inmemory) + @compiler.stubs(:resources).returns([]) + @scope.stubs(:findresource).returns(inmemory) - @compiler.stubs(:add_resource) + @compiler.stubs(:add_resource) - proc { @collector.evaluate }.should_not raise_error(Puppet::ParseError) - end + proc { @collector.evaluate }.should_not raise_error(Puppet::ParseError) + end end describe Puppet::Parser::Collector, "when building its ActiveRecord query for collecting exported resources" do - confine "Cannot test Rails integration without ActiveRecord" => Puppet.features.rails? - - before do - @scope = stub 'scope', :host => "myhost", :debug => nil - @compiler = mock 'compile' - @scope.stubs(:compiler).returns(@compiler) - @resource_type = "Mytype" - @equery = nil - @vquery = proc { |r| true } - - @resource = stub_everything 'collected' - - @collector = Puppet::Parser::Collector.new(@scope, @resource_type, @equery, @vquery, :exported) - @collector.stubs(:exported_resource).with(@resource).returns(@resource) - @compiler.stubs(:resources).returns([]) - - ActiveRecord::Base.stubs(:connected?).returns(false) - - Puppet::Rails.stubs(:init) - Puppet::Rails::Host.stubs(:find_by_name).returns(nil) - Puppet::Rails::Resource.stubs(:find).returns([]) - - Puppet.settings.stubs(:value).with(:storeconfigs).returns true - end - - it "should exclude all resources from the host if ActiveRecord contains information for this host" do - @host = mock 'host' - @host.stubs(:id).returns 5 - - Puppet::Rails::Host.expects(:find_by_name).with(@scope.host).returns(@host) - - Puppet::Rails::Resource.stubs(:find).with { |*arguments| - options = arguments[1] - options[:conditions][0] =~ /^host_id != \?/ and options[:conditions][1] == 5 - }.returns([@resource]) - - @collector.evaluate.should == [@resource] - end - - it "should join with parameter names, parameter values when querying ActiveRecord" do - @collector.equery = "param_names.name = title" - Puppet::Rails::Resource.stubs(:find).with { |*arguments| - options = arguments[1] - options[:joins] == {:param_values => :param_name} - }.returns([@resource]) - - @collector.evaluate.should == [@resource] - end - - it "should join with tag tables when querying ActiveRecord with a tag exported query" do - @collector.equery = "puppet_tags.name = test" - Puppet::Rails::Resource.stubs(:find).with { |*arguments| - options = arguments[1] - options[:joins] == {:resource_tags => :puppet_tag} - }.returns([@resource]) - - @collector.evaluate.should == [@resource] - end - - it "should not join parameters when querying ActiveRecord with a tag exported query" do - @collector.equery = "puppet_tags.name = test" - Puppet::Rails::Resource.stubs(:find).with { |*arguments| - options = arguments[1] - options[:joins] == {:param_values => :param_name} - }.returns([@resource]) - - @collector.evaluate.should be_false - end - - it "should only search for exported resources with the matching type" do - Puppet::Rails::Resource.stubs(:find).with { |*arguments| - options = arguments[1] - options[:conditions][0].include?("(exported=? AND restype=?)") and options[:conditions][1] == true and options[:conditions][2] == "Mytype" - }.returns([@resource]) - - @collector.evaluate.should == [@resource] - end - - it "should include the export query if one is provided" do - @collector.equery = "test = true" - Puppet::Rails::Resource.stubs(:find).with { |*arguments| - options = arguments[1] - options[:conditions][0].include?("test = true") - }.returns([@resource]) - - @collector.evaluate.should == [@resource] - end + confine "Cannot test Rails integration without ActiveRecord" => Puppet.features.rails? + + before do + @scope = stub 'scope', :host => "myhost", :debug => nil + @compiler = mock 'compile' + @scope.stubs(:compiler).returns(@compiler) + @resource_type = "Mytype" + @equery = nil + @vquery = proc { |r| true } + + @resource = stub_everything 'collected' + + @collector = Puppet::Parser::Collector.new(@scope, @resource_type, @equery, @vquery, :exported) + @collector.stubs(:exported_resource).with(@resource).returns(@resource) + @compiler.stubs(:resources).returns([]) + + ActiveRecord::Base.stubs(:connected?).returns(false) + + Puppet::Rails.stubs(:init) + Puppet::Rails::Host.stubs(:find_by_name).returns(nil) + Puppet::Rails::Resource.stubs(:find).returns([]) + + Puppet.settings.stubs(:value).with(:storeconfigs).returns true + end + + it "should exclude all resources from the host if ActiveRecord contains information for this host" do + @host = mock 'host' + @host.stubs(:id).returns 5 + + Puppet::Rails::Host.expects(:find_by_name).with(@scope.host).returns(@host) + + Puppet::Rails::Resource.stubs(:find).with { |*arguments| + options = arguments[1] + options[:conditions][0] =~ /^host_id != \?/ and options[:conditions][1] == 5 + }.returns([@resource]) + + @collector.evaluate.should == [@resource] + end + + it "should join with parameter names, parameter values when querying ActiveRecord" do + @collector.equery = "param_names.name = title" + Puppet::Rails::Resource.stubs(:find).with { |*arguments| + options = arguments[1] + options[:joins] == {:param_values => :param_name} + }.returns([@resource]) + + @collector.evaluate.should == [@resource] + end + + it "should join with tag tables when querying ActiveRecord with a tag exported query" do + @collector.equery = "puppet_tags.name = test" + Puppet::Rails::Resource.stubs(:find).with { |*arguments| + options = arguments[1] + options[:joins] == {:resource_tags => :puppet_tag} + }.returns([@resource]) + + @collector.evaluate.should == [@resource] + end + + it "should not join parameters when querying ActiveRecord with a tag exported query" do + @collector.equery = "puppet_tags.name = test" + Puppet::Rails::Resource.stubs(:find).with { |*arguments| + options = arguments[1] + options[:joins] == {:param_values => :param_name} + }.returns([@resource]) + + @collector.evaluate.should be_false + end + + it "should only search for exported resources with the matching type" do + Puppet::Rails::Resource.stubs(:find).with { |*arguments| + options = arguments[1] + options[:conditions][0].include?("(exported=? AND restype=?)") and options[:conditions][1] == true and options[:conditions][2] == "Mytype" + }.returns([@resource]) + + @collector.evaluate.should == [@resource] + end + + it "should include the export query if one is provided" do + @collector.equery = "test = true" + Puppet::Rails::Resource.stubs(:find).with { |*arguments| + options = arguments[1] + options[:conditions][0].include?("test = true") + }.returns([@resource]) + + @collector.evaluate.should == [@resource] + end end diff --git a/spec/unit/parser/compiler_spec.rb b/spec/unit/parser/compiler_spec.rb index 872cd7961..a3fe56c0e 100755 --- a/spec/unit/parser/compiler_spec.rb +++ b/spec/unit/parser/compiler_spec.rb @@ -3,752 +3,752 @@ require File.dirname(__FILE__) + '/../../spec_helper' class CompilerTestResource - attr_accessor :builtin, :virtual, :evaluated, :type, :title + attr_accessor :builtin, :virtual, :evaluated, :type, :title - def initialize(type, title) - @type = type - @title = title - end + def initialize(type, title) + @type = type + @title = title + end - def [](attr) - return nil if attr == :stage - :main - end + def [](attr) + return nil if attr == :stage + :main + end - def ref - "#{type.to_s.capitalize}[#{title}]" - end + def ref + "#{type.to_s.capitalize}[#{title}]" + end - def evaluated? - @evaluated - end + def evaluated? + @evaluated + end - def builtin? - @builtin - end + def builtin? + @builtin + end - def virtual? - @virtual - end + def virtual? + @virtual + end - def evaluate - end + def evaluate + end end describe Puppet::Parser::Compiler do - def resource(type, title) - Puppet::Parser::Resource.new(type, title, :scope => @scope) + def resource(type, title) + Puppet::Parser::Resource.new(type, title, :scope => @scope) + end + + before :each do + @node = Puppet::Node.new "testnode" + @known_resource_types = Puppet::Resource::TypeCollection.new "development" + @compiler = Puppet::Parser::Compiler.new(@node) + @scope = Puppet::Parser::Scope.new(:compiler => @compiler, :source => stub('source')) + @scope_resource = Puppet::Parser::Resource.new(:file, "/my/file", :scope => @scope) + @scope.resource = @scope_resource + @compiler.environment.stubs(:known_resource_types).returns @known_resource_types + end + + it "should have a class method that compiles, converts, and returns a catalog" do + compiler = stub 'compiler' + Puppet::Parser::Compiler.expects(:new).with(@node).returns compiler + catalog = stub 'catalog' + compiler.expects(:compile).returns catalog + converted_catalog = stub 'converted_catalog' + catalog.expects(:to_resource).returns converted_catalog + + Puppet::Parser::Compiler.compile(@node).should equal(converted_catalog) + end + + it "should fail intelligently when a class-level compile fails" do + Puppet::Parser::Compiler.expects(:new).raises ArgumentError + lambda { Puppet::Parser::Compiler.compile(@node) }.should raise_error(Puppet::Error) + end + + it "should use the node's environment as its environment" do + @compiler.environment.should equal(@node.environment) + end + + it "should include the resource type collection helper" do + Puppet::Parser::Compiler.ancestors.should be_include(Puppet::Resource::TypeCollectionHelper) + end + + it "should be able to return a class list containing all added classes" do + @compiler.add_class "" + @compiler.add_class "one" + @compiler.add_class "two" + + @compiler.classlist.sort.should == %w{one two}.sort + end + + describe "when initializing" do + + it "should set its node attribute" do + @compiler.node.should equal(@node) end - - before :each do - @node = Puppet::Node.new "testnode" - @known_resource_types = Puppet::Resource::TypeCollection.new "development" - @compiler = Puppet::Parser::Compiler.new(@node) - @scope = Puppet::Parser::Scope.new(:compiler => @compiler, :source => stub('source')) - @scope_resource = Puppet::Parser::Resource.new(:file, "/my/file", :scope => @scope) - @scope.resource = @scope_resource - @compiler.environment.stubs(:known_resource_types).returns @known_resource_types + it "should detect when ast nodes are absent" do + @compiler.ast_nodes?.should be_false end - it "should have a class method that compiles, converts, and returns a catalog" do - compiler = stub 'compiler' - Puppet::Parser::Compiler.expects(:new).with(@node).returns compiler - catalog = stub 'catalog' - compiler.expects(:compile).returns catalog - converted_catalog = stub 'converted_catalog' - catalog.expects(:to_resource).returns converted_catalog - - Puppet::Parser::Compiler.compile(@node).should equal(converted_catalog) + it "should detect when ast nodes are present" do + @known_resource_types.expects(:nodes?).returns true + @compiler.ast_nodes?.should be_true end - it "should fail intelligently when a class-level compile fails" do - Puppet::Parser::Compiler.expects(:new).raises ArgumentError - lambda { Puppet::Parser::Compiler.compile(@node) }.should raise_error(Puppet::Error) + it "should copy the known_resource_types version to the catalog" do + @compiler.catalog.version.should == @known_resource_types.version end - it "should use the node's environment as its environment" do - @compiler.environment.should equal(@node.environment) + it "should copy any node classes into the class list" do + node = Puppet::Node.new("mynode") + node.classes = %w{foo bar} + compiler = Puppet::Parser::Compiler.new(node) + + compiler.classlist.should include("foo") + compiler.classlist.should include("bar") end - it "should include the resource type collection helper" do - Puppet::Parser::Compiler.ancestors.should be_include(Puppet::Resource::TypeCollectionHelper) + it "should add a 'main' stage to the catalog" do + @compiler.catalog.resource(:stage, :main).should be_instance_of(Puppet::Parser::Resource) end + end - it "should be able to return a class list containing all added classes" do - @compiler.add_class "" - @compiler.add_class "one" - @compiler.add_class "two" + describe "when managing scopes" do - @compiler.classlist.sort.should == %w{one two}.sort + it "should create a top scope" do + @compiler.topscope.should be_instance_of(Puppet::Parser::Scope) end - describe "when initializing" do - - it "should set its node attribute" do - @compiler.node.should equal(@node) - end - it "should detect when ast nodes are absent" do - @compiler.ast_nodes?.should be_false - end + it "should be able to create new scopes" do + @compiler.newscope(@compiler.topscope).should be_instance_of(Puppet::Parser::Scope) + end - it "should detect when ast nodes are present" do - @known_resource_types.expects(:nodes?).returns true - @compiler.ast_nodes?.should be_true - end + it "should correctly set the level of newly created scopes" do + @compiler.newscope(@compiler.topscope, :level => 5).level.should == 5 + end - it "should copy the known_resource_types version to the catalog" do - @compiler.catalog.version.should == @known_resource_types.version - end + it "should set the parent scope of the new scope to be the passed-in parent" do + scope = mock 'scope' + newscope = @compiler.newscope(scope) - it "should copy any node classes into the class list" do - node = Puppet::Node.new("mynode") - node.classes = %w{foo bar} - compiler = Puppet::Parser::Compiler.new(node) + newscope.parent.should equal(scope) + end - compiler.classlist.should include("foo") - compiler.classlist.should include("bar") - end + it "should set the parent scope of the new scope to its topscope if the parent passed in is nil" do + scope = mock 'scope' + newscope = @compiler.newscope(nil) - it "should add a 'main' stage to the catalog" do - @compiler.catalog.resource(:stage, :main).should be_instance_of(Puppet::Parser::Resource) - end + newscope.parent.should equal(@compiler.topscope) end + end - describe "when managing scopes" do - - it "should create a top scope" do - @compiler.topscope.should be_instance_of(Puppet::Parser::Scope) - end + describe "when compiling" do - it "should be able to create new scopes" do - @compiler.newscope(@compiler.topscope).should be_instance_of(Puppet::Parser::Scope) - end + def compile_methods + [:set_node_parameters, :evaluate_main, :evaluate_ast_node, :evaluate_node_classes, :evaluate_generators, :fail_on_unevaluated, + :finish, :store, :extract, :evaluate_relationships] + end - it "should correctly set the level of newly created scopes" do - @compiler.newscope(@compiler.topscope, :level => 5).level.should == 5 - end + # Stub all of the main compile methods except the ones we're specifically interested in. + def compile_stub(*except) + (compile_methods - except).each { |m| @compiler.stubs(m) } + end - it "should set the parent scope of the new scope to be the passed-in parent" do - scope = mock 'scope' - newscope = @compiler.newscope(scope) + it "should set node parameters as variables in the top scope" do + params = {"a" => "b", "c" => "d"} + @node.stubs(:parameters).returns(params) + compile_stub(:set_node_parameters) + @compiler.compile + @compiler.topscope.lookupvar("a").should == "b" + @compiler.topscope.lookupvar("c").should == "d" + end - newscope.parent.should equal(scope) - end + it "should set the client and server versions on the catalog" do + params = {"clientversion" => "2", "serverversion" => "3"} + @node.stubs(:parameters).returns(params) + compile_stub(:set_node_parameters) + @compiler.compile + @compiler.catalog.client_version.should == "2" + @compiler.catalog.server_version.should == "3" + end - it "should set the parent scope of the new scope to its topscope if the parent passed in is nil" do - scope = mock 'scope' - newscope = @compiler.newscope(nil) + it "should evaluate any existing classes named in the node" do + classes = %w{one two three four} + main = stub 'main' + one = stub 'one', :name => "one" + three = stub 'three', :name => "three" + @node.stubs(:name).returns("whatever") + @node.stubs(:classes).returns(classes) - newscope.parent.should equal(@compiler.topscope) - end + @compiler.expects(:evaluate_classes).with(classes, @compiler.topscope) + @compiler.class.publicize_methods(:evaluate_node_classes) { @compiler.evaluate_node_classes } end - describe "when compiling" do + it "should evaluate the main class if it exists" do + compile_stub(:evaluate_main) + 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) - def compile_methods - [:set_node_parameters, :evaluate_main, :evaluate_ast_node, :evaluate_node_classes, :evaluate_generators, :fail_on_unevaluated, - :finish, :store, :extract, :evaluate_relationships] - end - - # Stub all of the main compile methods except the ones we're specifically interested in. - def compile_stub(*except) - (compile_methods - except).each { |m| @compiler.stubs(m) } - end + @compiler.compile + end - it "should set node parameters as variables in the top scope" do - params = {"a" => "b", "c" => "d"} - @node.stubs(:parameters).returns(params) - compile_stub(:set_node_parameters) - @compiler.compile - @compiler.topscope.lookupvar("a").should == "b" - @compiler.topscope.lookupvar("c").should == "d" - end + it "should 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) + end - it "should set the client and server versions on the catalog" do - params = {"clientversion" => "2", "serverversion" => "3"} - @node.stubs(:parameters).returns(params) - compile_stub(:set_node_parameters) - @compiler.compile - @compiler.catalog.client_version.should == "2" - @compiler.catalog.server_version.should == "3" - end + it "should add an edge between the main stage and main class" do + @compiler.compile + (stage = @compiler.catalog.resource(:stage, "main")).should be_instance_of(Puppet::Parser::Resource) + (klass = @compiler.catalog.resource(:class, "")).should be_instance_of(Puppet::Parser::Resource) - it "should evaluate any existing classes named in the node" do - classes = %w{one two three four} - main = stub 'main' - one = stub 'one', :name => "one" - three = stub 'three', :name => "three" - @node.stubs(:name).returns("whatever") - @node.stubs(:classes).returns(classes) + @compiler.catalog.edge?(stage, klass).should be_true + end - @compiler.expects(:evaluate_classes).with(classes, @compiler.topscope) - @compiler.class.publicize_methods(:evaluate_node_classes) { @compiler.evaluate_node_classes } - end + it "should evaluate any node classes" do + @node.stubs(:classes).returns(%w{one two three four}) + @compiler.expects(:evaluate_classes).with(%w{one two three four}, @compiler.topscope) + @compiler.send(:evaluate_node_classes) + end - it "should evaluate the main class if it exists" do - compile_stub(:evaluate_main) - 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) + it "should evaluate all added collections" do + colls = [] + # And when the collections fail to evaluate. + colls << mock("coll1-false") + colls << mock("coll2-false") + colls.each { |c| c.expects(:evaluate).returns(false) } - @compiler.compile - end + @compiler.add_collection(colls[0]) + @compiler.add_collection(colls[1]) - 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) - end + compile_stub(:evaluate_generators) + @compiler.compile + end - it "should add an edge between the main stage and main class" do - @compiler.compile - (stage = @compiler.catalog.resource(:stage, "main")).should be_instance_of(Puppet::Parser::Resource) - (klass = @compiler.catalog.resource(:class, "")).should be_instance_of(Puppet::Parser::Resource) + it "should ignore builtin resources" do + resource = resource(:file, "testing") - @compiler.catalog.edge?(stage, klass).should be_true - end + @compiler.add_resource(@scope, resource) + resource.expects(:evaluate).never - it "should evaluate any node classes" do - @node.stubs(:classes).returns(%w{one two three four}) - @compiler.expects(:evaluate_classes).with(%w{one two three four}, @compiler.topscope) - @compiler.send(:evaluate_node_classes) - end + @compiler.compile + end - it "should evaluate all added collections" do - colls = [] - # And when the collections fail to evaluate. - colls << mock("coll1-false") - colls << mock("coll2-false") - colls.each { |c| c.expects(:evaluate).returns(false) } + it "should evaluate unevaluated resources" do + resource = CompilerTestResource.new(:file, "testing") - @compiler.add_collection(colls[0]) - @compiler.add_collection(colls[1]) + @compiler.add_resource(@scope, resource) - compile_stub(:evaluate_generators) - @compiler.compile - end + # We have to now mark the resource as evaluated + resource.expects(:evaluate).with { |*whatever| resource.evaluated = true } - it "should ignore builtin resources" do - resource = resource(:file, "testing") + @compiler.compile + end - @compiler.add_resource(@scope, resource) - resource.expects(:evaluate).never + it "should not evaluate already-evaluated resources" do + resource = resource(:file, "testing") + resource.stubs(:evaluated?).returns true - @compiler.compile - end + @compiler.add_resource(@scope, resource) + resource.expects(:evaluate).never - it "should evaluate unevaluated resources" do - resource = CompilerTestResource.new(:file, "testing") + @compiler.compile + end - @compiler.add_resource(@scope, resource) + it "should evaluate unevaluated resources created by evaluating other resources" do + resource = CompilerTestResource.new(:file, "testing") + @compiler.add_resource(@scope, resource) - # We have to now mark the resource as evaluated - resource.expects(:evaluate).with { |*whatever| resource.evaluated = true } + resource2 = CompilerTestResource.new(:file, "other") - @compiler.compile - end + # We have to now mark the resource as evaluated + resource.expects(:evaluate).with { |*whatever| resource.evaluated = true; @compiler.add_resource(@scope, resource2) } + resource2.expects(:evaluate).with { |*whatever| resource2.evaluated = true } - it "should not evaluate already-evaluated resources" do - resource = resource(:file, "testing") - resource.stubs(:evaluated?).returns true - @compiler.add_resource(@scope, resource) - resource.expects(:evaluate).never + @compiler.compile + end - @compiler.compile - end + describe "when finishing" do + before do + @compiler.send(:evaluate_main) + @catalog = @compiler.catalog + end - it "should evaluate unevaluated resources created by evaluating other resources" do - resource = CompilerTestResource.new(:file, "testing") - @compiler.add_resource(@scope, resource) + def add_resource(name, parent = nil) + resource = Puppet::Parser::Resource.new "file", name, :scope => @scope + @compiler.add_resource(@scope, resource) + @catalog.add_edge(parent, resource) if parent + resource + end - resource2 = CompilerTestResource.new(:file, "other") + it "should call finish() on all resources" do + # Add a resource that does respond to :finish + resource = Puppet::Parser::Resource.new "file", "finish", :scope => @scope + resource.expects(:finish) - # We have to now mark the resource as evaluated - resource.expects(:evaluate).with { |*whatever| resource.evaluated = true; @compiler.add_resource(@scope, resource2) } - resource2.expects(:evaluate).with { |*whatever| resource2.evaluated = true } + @compiler.add_resource(@scope, resource) + # And one that does not + dnf_resource = stub_everything "dnf", :ref => "File[dnf]", :type => "file" - @compiler.compile - end + @compiler.add_resource(@scope, dnf_resource) - describe "when finishing" do - before do - @compiler.send(:evaluate_main) - @catalog = @compiler.catalog - end + @compiler.send(:finish) + end - def add_resource(name, parent = nil) - resource = Puppet::Parser::Resource.new "file", name, :scope => @scope - @compiler.add_resource(@scope, resource) - @catalog.add_edge(parent, resource) if parent - resource - end + it "should call finish() in add_resource order" do + resources = sequence('resources') - it "should call finish() on all resources" do - # Add a resource that does respond to :finish - resource = Puppet::Parser::Resource.new "file", "finish", :scope => @scope - resource.expects(:finish) + resource1 = add_resource("finish1") + resource1.expects(:finish).in_sequence(resources) - @compiler.add_resource(@scope, resource) + resource2 = add_resource("finish2") + resource2.expects(:finish).in_sequence(resources) - # And one that does not - dnf_resource = stub_everything "dnf", :ref => "File[dnf]", :type => "file" + @compiler.send(:finish) + end - @compiler.add_resource(@scope, dnf_resource) + it "should add each container's metaparams to its contained resources" do + main = @catalog.resource(:class, :main) + main[:noop] = true - @compiler.send(:finish) - end + resource1 = add_resource("meh", main) - it "should call finish() in add_resource order" do - resources = sequence('resources') + @compiler.send(:finish) + resource1[:noop].should be_true + end - resource1 = add_resource("finish1") - resource1.expects(:finish).in_sequence(resources) + it "should add metaparams recursively" do + main = @catalog.resource(:class, :main) + main[:noop] = true - resource2 = add_resource("finish2") - resource2.expects(:finish).in_sequence(resources) + resource1 = add_resource("meh", main) + resource2 = add_resource("foo", resource1) - @compiler.send(:finish) - end + @compiler.send(:finish) + resource2[:noop].should be_true + end - it "should add each container's metaparams to its contained resources" do - main = @catalog.resource(:class, :main) - main[:noop] = true + it "should prefer metaparams from immediate parents" do + main = @catalog.resource(:class, :main) + main[:noop] = true - resource1 = add_resource("meh", main) + resource1 = add_resource("meh", main) + resource2 = add_resource("foo", resource1) - @compiler.send(:finish) - resource1[:noop].should be_true - end + resource1[:noop] = false - it "should add metaparams recursively" do - main = @catalog.resource(:class, :main) - main[:noop] = true + @compiler.send(:finish) + resource2[:noop].should be_false + end - resource1 = add_resource("meh", main) - resource2 = add_resource("foo", resource1) + it "should merge tags downward" do + main = @catalog.resource(:class, :main) + main.tag("one") - @compiler.send(:finish) - resource2[:noop].should be_true - end + resource1 = add_resource("meh", main) + resource1.tag "two" + resource2 = add_resource("foo", resource1) - it "should prefer metaparams from immediate parents" do - main = @catalog.resource(:class, :main) - main[:noop] = true + @compiler.send(:finish) + resource2.tags.should be_include("one") + resource2.tags.should be_include("two") + end - resource1 = add_resource("meh", main) - resource2 = add_resource("foo", resource1) + it "should work if only middle resources have metaparams set" do + main = @catalog.resource(:class, :main) - resource1[:noop] = false + resource1 = add_resource("meh", main) + resource1[:noop] = true + resource2 = add_resource("foo", resource1) - @compiler.send(:finish) - resource2[:noop].should be_false - end + @compiler.send(:finish) + resource2[:noop].should be_true + end + end - it "should merge tags downward" do - main = @catalog.resource(:class, :main) - main.tag("one") + it "should return added resources in add order" do + resource1 = resource(:file, "yay") + @compiler.add_resource(@scope, resource1) + resource2 = resource(:file, "youpi") + @compiler.add_resource(@scope, resource2) - resource1 = add_resource("meh", main) - resource1.tag "two" - resource2 = add_resource("foo", resource1) + @compiler.resources.should == [resource1, resource2] + end - @compiler.send(:finish) - resource2.tags.should be_include("one") - resource2.tags.should be_include("two") - end + it "should add resources that do not conflict with existing resources" do + resource = resource(:file, "yay") + @compiler.add_resource(@scope, resource) - it "should work if only middle resources have metaparams set" do - main = @catalog.resource(:class, :main) + @compiler.catalog.should be_vertex(resource) + end - resource1 = add_resource("meh", main) - resource1[:noop] = true - resource2 = add_resource("foo", resource1) + it "should fail to add resources that conflict with existing resources" do + path = Puppet.features.posix? ? "/foo" : "C:/foo" + file1 = Puppet::Type.type(:file).new :path => path + file2 = Puppet::Type.type(:file).new :path => path - @compiler.send(:finish) - resource2[:noop].should be_true - end - end + @compiler.add_resource(@scope, file1) + lambda { @compiler.add_resource(@scope, file2) }.should raise_error(Puppet::Resource::Catalog::DuplicateResourceError) + end - it "should return added resources in add order" do - resource1 = resource(:file, "yay") - @compiler.add_resource(@scope, resource1) - resource2 = resource(:file, "youpi") - @compiler.add_resource(@scope, resource2) + it "should add an edge from the scope resource to the added resource" do + resource = resource(:file, "yay") + @compiler.add_resource(@scope, resource) - @compiler.resources.should == [resource1, resource2] - end + @compiler.catalog.should be_edge(@scope.resource, resource) + end - it "should add resources that do not conflict with existing resources" do - resource = resource(:file, "yay") - @compiler.add_resource(@scope, resource) + it "should add an edge to any specified stage for class resources" do + other_stage = resource(:stage, "other") + @compiler.add_resource(@scope, other_stage) + resource = resource(:class, "foo") + resource[:stage] = 'other' - @compiler.catalog.should be_vertex(resource) - end + @compiler.add_resource(@scope, resource) - it "should fail to add resources that conflict with existing resources" do - path = Puppet.features.posix? ? "/foo" : "C:/foo" - file1 = Puppet::Type.type(:file).new :path => path - file2 = Puppet::Type.type(:file).new :path => path + @compiler.catalog.edge?(other_stage, resource).should be_true + end - @compiler.add_resource(@scope, file1) - lambda { @compiler.add_resource(@scope, file2) }.should raise_error(Puppet::Resource::Catalog::DuplicateResourceError) - end + it "should fail if a non-class resource attempts to set a stage" do + other_stage = resource(:stage, "other") + @compiler.add_resource(@scope, other_stage) + resource = resource(:file, "foo") + resource[:stage] = 'other' - it "should add an edge from the scope resource to the added resource" do - resource = resource(:file, "yay") - @compiler.add_resource(@scope, resource) + lambda { @compiler.add_resource(@scope, resource) }.should raise_error(ArgumentError) + end - @compiler.catalog.should be_edge(@scope.resource, resource) - end + it "should fail if an unknown stage is specified" do + resource = resource(:class, "foo") + resource[:stage] = 'other' - it "should add an edge to any specified stage for class resources" do - other_stage = resource(:stage, "other") - @compiler.add_resource(@scope, other_stage) - resource = resource(:class, "foo") - resource[:stage] = 'other' + lambda { @compiler.add_resource(@scope, resource) }.should raise_error(ArgumentError) + end - @compiler.add_resource(@scope, resource) + it "should add edges from the 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) - @compiler.catalog.edge?(other_stage, resource).should be_true - end + @compiler.catalog.should be_edge(main, resource) + end - it "should fail if a non-class resource attempts to set a stage" do - other_stage = resource(:stage, "other") - @compiler.add_resource(@scope, other_stage) - resource = resource(:file, "foo") - resource[:stage] = 'other' + it "should not add non-class resources that don't specify a stage to the 'main' stage" do + main = @compiler.catalog.resource(:stage, :main) + resource = resource(:file, "foo") + @compiler.add_resource(@scope, resource) - lambda { @compiler.add_resource(@scope, resource) }.should raise_error(ArgumentError) - end + @compiler.catalog.should_not be_edge(main, resource) + end - it "should fail if an unknown stage is specified" do - resource = resource(:class, "foo") - resource[:stage] = 'other' + it "should not add any parent-edges to stages" do + stage = resource(:stage, "other") + @compiler.add_resource(@scope, stage) - lambda { @compiler.add_resource(@scope, resource) }.should raise_error(ArgumentError) - end + @scope.resource = resource(:class, "foo") - it "should add edges from the 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) + @compiler.catalog.edge?(@scope.resource, stage).should be_false + end - @compiler.catalog.should be_edge(main, resource) - end + it "should not attempt to add stages to other stages" do + other_stage = resource(:stage, "other") + second_stage = resource(:stage, "second") + @compiler.add_resource(@scope, other_stage) + @compiler.add_resource(@scope, second_stage) - it "should not add non-class resources that don't specify a stage to the 'main' stage" do - main = @compiler.catalog.resource(:stage, :main) - resource = resource(:file, "foo") - @compiler.add_resource(@scope, resource) + second_stage[:stage] = "other" - @compiler.catalog.should_not be_edge(main, resource) - end + @compiler.catalog.edge?(other_stage, second_stage).should be_false + end - it "should not add any parent-edges to stages" do - stage = resource(:stage, "other") - @compiler.add_resource(@scope, stage) + it "should have a method for looking up resources" do + resource = resource(:yay, "foo") + @compiler.add_resource(@scope, resource) + @compiler.findresource("Yay[foo]").should equal(resource) + end - @scope.resource = resource(:class, "foo") + it "should be able to look resources up by type and title" do + resource = resource(:yay, "foo") + @compiler.add_resource(@scope, resource) + @compiler.findresource("Yay", "foo").should equal(resource) + end - @compiler.catalog.edge?(@scope.resource, stage).should be_false - end + it "should not evaluate virtual defined resources" do + resource = resource(:file, "testing") + resource.virtual = true + @compiler.add_resource(@scope, resource) - it "should not attempt to add stages to other stages" do - other_stage = resource(:stage, "other") - second_stage = resource(:stage, "second") - @compiler.add_resource(@scope, other_stage) - @compiler.add_resource(@scope, second_stage) + resource.expects(:evaluate).never - second_stage[:stage] = "other" + @compiler.compile + end + end - @compiler.catalog.edge?(other_stage, second_stage).should be_false - end + describe "when evaluating collections" do - it "should have a method for looking up resources" do - resource = resource(:yay, "foo") - @compiler.add_resource(@scope, resource) - @compiler.findresource("Yay[foo]").should equal(resource) - end + it "should evaluate each collection" do + 2.times { |i| + coll = mock 'coll%s' % i + @compiler.add_collection(coll) - it "should be able to look resources up by type and title" do - resource = resource(:yay, "foo") - @compiler.add_resource(@scope, resource) - @compiler.findresource("Yay", "foo").should equal(resource) + # This is the hard part -- we have to emulate the fact that + # collections delete themselves if they are done evaluating. + coll.expects(:evaluate).with do + @compiler.delete_collection(coll) end + } - it "should not evaluate virtual defined resources" do - resource = resource(:file, "testing") - resource.virtual = true - @compiler.add_resource(@scope, resource) - - resource.expects(:evaluate).never - - @compiler.compile - end + @compiler.class.publicize_methods(:evaluate_collections) { @compiler.evaluate_collections } end - describe "when evaluating collections" do - - it "should evaluate each collection" do - 2.times { |i| - coll = mock 'coll%s' % i - @compiler.add_collection(coll) - - # This is the hard part -- we have to emulate the fact that - # collections delete themselves if they are done evaluating. - coll.expects(:evaluate).with do - @compiler.delete_collection(coll) - end - } - - @compiler.class.publicize_methods(:evaluate_collections) { @compiler.evaluate_collections } - end + it "should not fail when there are unevaluated resource collections that do not refer to specific resources" do + coll = stub 'coll', :evaluate => false + coll.expects(:resources).returns(nil) - it "should not fail when there are unevaluated resource collections that do not refer to specific resources" do - coll = stub 'coll', :evaluate => false - coll.expects(:resources).returns(nil) + @compiler.add_collection(coll) - @compiler.add_collection(coll) - - lambda { @compiler.compile }.should_not raise_error - end + lambda { @compiler.compile }.should_not raise_error + end - it "should fail when there are unevaluated resource collections that refer to a specific resource" do - coll = stub 'coll', :evaluate => false - coll.expects(:resources).returns(:something) + it "should fail when there are unevaluated resource collections that refer to a specific resource" do + coll = stub 'coll', :evaluate => false + coll.expects(:resources).returns(:something) - @compiler.add_collection(coll) + @compiler.add_collection(coll) - lambda { @compiler.compile }.should raise_error(Puppet::ParseError) - end + lambda { @compiler.compile }.should raise_error(Puppet::ParseError) + end - it "should fail when there are unevaluated resource collections that refer to multiple specific resources" do - coll = stub 'coll', :evaluate => false - coll.expects(:resources).returns([:one, :two]) + it "should fail when there are unevaluated resource collections that refer to multiple specific resources" do + coll = stub 'coll', :evaluate => false + coll.expects(:resources).returns([:one, :two]) - @compiler.add_collection(coll) + @compiler.add_collection(coll) - lambda { @compiler.compile }.should raise_error(Puppet::ParseError) - end + lambda { @compiler.compile }.should raise_error(Puppet::ParseError) end - - describe "when evaluating relationships" do - it "should evaluate each relationship with its catalog" do - dep = stub 'dep' - dep.expects(:evaluate).with(@compiler.catalog) - @compiler.add_relationship dep - @compiler.evaluate_relationships - end + end + + describe "when evaluating relationships" do + it "should evaluate each relationship with its catalog" do + dep = stub 'dep' + dep.expects(:evaluate).with(@compiler.catalog) + @compiler.add_relationship dep + @compiler.evaluate_relationships end + end - describe "when told to evaluate missing classes" do + describe "when told to evaluate missing classes" do - it "should fail if there's no source listed for the scope" do - scope = stub 'scope', :source => nil - proc { @compiler.evaluate_classes(%w{one two}, scope) }.should raise_error(Puppet::DevError) - end + it "should fail if there's no source listed for the scope" do + scope = stub 'scope', :source => nil + proc { @compiler.evaluate_classes(%w{one two}, scope) }.should raise_error(Puppet::DevError) + end - it "should tag the catalog with the name of each not-found class" do - @compiler.catalog.expects(:tag).with("notfound") - @scope.expects(:find_hostclass).with("notfound").returns(nil) - @compiler.evaluate_classes(%w{notfound}, @scope) - end + it "should tag the catalog with the name of each not-found class" do + @compiler.catalog.expects(:tag).with("notfound") + @scope.expects(:find_hostclass).with("notfound").returns(nil) + @compiler.evaluate_classes(%w{notfound}, @scope) end + end - describe "when evaluating found classes" do + describe "when evaluating found classes" do - before do - @class = stub 'class', :name => "my::class" - @scope.stubs(:find_hostclass).with("myclass").returns(@class) + before do + @class = stub 'class', :name => "my::class" + @scope.stubs(:find_hostclass).with("myclass").returns(@class) - @resource = stub 'resource', :ref => "Class[myclass]", :type => "file" - end + @resource = stub 'resource', :ref => "Class[myclass]", :type => "file" + end - it "should evaluate each class" do - @compiler.catalog.stubs(:tag) + it "should evaluate each class" do + @compiler.catalog.stubs(:tag) - @class.expects(:mk_plain_resource).with(@scope) - @scope.stubs(:class_scope).with(@class) + @class.expects(:mk_plain_resource).with(@scope) + @scope.stubs(:class_scope).with(@class) - @compiler.evaluate_classes(%w{myclass}, @scope) - end + @compiler.evaluate_classes(%w{myclass}, @scope) + end - it "should not evaluate the resources created for found classes unless asked" do - @compiler.catalog.stubs(:tag) + it "should not evaluate the resources created for found classes unless asked" do + @compiler.catalog.stubs(:tag) - @resource.expects(:evaluate).never + @resource.expects(:evaluate).never - @class.expects(:mk_plain_resource).returns(@resource) - @scope.stubs(:class_scope).with(@class) + @class.expects(:mk_plain_resource).returns(@resource) + @scope.stubs(:class_scope).with(@class) - @compiler.evaluate_classes(%w{myclass}, @scope) - end + @compiler.evaluate_classes(%w{myclass}, @scope) + end - it "should immediately evaluate the resources created for found classes when asked" do - @compiler.catalog.stubs(:tag) + it "should immediately evaluate the resources created for found classes when asked" do + @compiler.catalog.stubs(:tag) - @resource.expects(:evaluate) - @class.expects(:mk_plain_resource).returns(@resource) - @scope.stubs(:class_scope).with(@class) + @resource.expects(:evaluate) + @class.expects(:mk_plain_resource).returns(@resource) + @scope.stubs(:class_scope).with(@class) - @compiler.evaluate_classes(%w{myclass}, @scope, false) - end + @compiler.evaluate_classes(%w{myclass}, @scope, false) + end - it "should skip classes that have already been evaluated" do - @compiler.catalog.stubs(:tag) + it "should skip classes that have already been evaluated" do + @compiler.catalog.stubs(:tag) - @scope.stubs(:class_scope).with(@class).returns("something") + @scope.stubs(:class_scope).with(@class).returns("something") - @compiler.expects(:add_resource).never + @compiler.expects(:add_resource).never - @resource.expects(:evaluate).never + @resource.expects(:evaluate).never - Puppet::Parser::Resource.expects(:new).never - @compiler.evaluate_classes(%w{myclass}, @scope, false) - end + Puppet::Parser::Resource.expects(:new).never + @compiler.evaluate_classes(%w{myclass}, @scope, false) + end - it "should skip classes previously evaluated with different capitalization" do - @compiler.catalog.stubs(:tag) - @scope.stubs(:find_hostclass).with("MyClass").returns(@class) - @scope.stubs(:class_scope).with(@class).returns("something") - @compiler.expects(:add_resource).never - @resource.expects(:evaluate).never - Puppet::Parser::Resource.expects(:new).never - @compiler.evaluate_classes(%w{MyClass}, @scope, false) - end + it "should skip classes previously evaluated with different capitalization" do + @compiler.catalog.stubs(:tag) + @scope.stubs(:find_hostclass).with("MyClass").returns(@class) + @scope.stubs(:class_scope).with(@class).returns("something") + @compiler.expects(:add_resource).never + @resource.expects(:evaluate).never + Puppet::Parser::Resource.expects(:new).never + @compiler.evaluate_classes(%w{MyClass}, @scope, false) + end - it "should return the list of found classes" do - @compiler.catalog.stubs(:tag) + it "should return the list of found classes" do + @compiler.catalog.stubs(:tag) - @compiler.stubs(:add_resource) - @scope.stubs(:find_hostclass).with("notfound").returns(nil) - @scope.stubs(:class_scope).with(@class) + @compiler.stubs(:add_resource) + @scope.stubs(:find_hostclass).with("notfound").returns(nil) + @scope.stubs(:class_scope).with(@class) - Puppet::Parser::Resource.stubs(:new).returns(@resource) - @class.stubs :mk_plain_resource - @compiler.evaluate_classes(%w{myclass notfound}, @scope).should == %w{myclass} - end + Puppet::Parser::Resource.stubs(:new).returns(@resource) + @class.stubs :mk_plain_resource + @compiler.evaluate_classes(%w{myclass notfound}, @scope).should == %w{myclass} end + end - describe "when evaluating AST nodes with no AST nodes present" do + describe "when evaluating AST nodes with no AST nodes present" do - it "should do nothing" do - @compiler.expects(:ast_nodes?).returns(false) - @compiler.known_resource_types.expects(:nodes).never - Puppet::Parser::Resource.expects(:new).never + it "should do nothing" do + @compiler.expects(:ast_nodes?).returns(false) + @compiler.known_resource_types.expects(:nodes).never + Puppet::Parser::Resource.expects(:new).never - @compiler.send(:evaluate_ast_node) - end + @compiler.send(:evaluate_ast_node) end + end - describe "when evaluating AST nodes with AST nodes present" do + describe "when evaluating AST nodes with AST nodes present" do - before do - @compiler.known_resource_types.stubs(:nodes?).returns true + before do + @compiler.known_resource_types.stubs(:nodes?).returns true - # Set some names for our test - @node.stubs(:names).returns(%w{a b c}) - @compiler.known_resource_types.stubs(:node).with("a").returns(nil) - @compiler.known_resource_types.stubs(:node).with("b").returns(nil) - @compiler.known_resource_types.stubs(:node).with("c").returns(nil) + # Set some names for our test + @node.stubs(:names).returns(%w{a b c}) + @compiler.known_resource_types.stubs(:node).with("a").returns(nil) + @compiler.known_resource_types.stubs(:node).with("b").returns(nil) + @compiler.known_resource_types.stubs(:node).with("c").returns(nil) - # It should check this last, of course. - @compiler.known_resource_types.stubs(:node).with("default").returns(nil) - end + # It should check this last, of course. + @compiler.known_resource_types.stubs(:node).with("default").returns(nil) + end - it "should fail if the named node cannot be found" do - proc { @compiler.send(:evaluate_ast_node) }.should raise_error(Puppet::ParseError) - end + it "should fail if the named node cannot be found" do + proc { @compiler.send(:evaluate_ast_node) }.should raise_error(Puppet::ParseError) + end - it "should evaluate the first node class matching the node name" do - node_class = stub 'node', :name => "c", :evaluate_code => nil - @compiler.known_resource_types.stubs(:node).with("c").returns(node_class) + it "should evaluate the first node class matching the node name" do + node_class = stub 'node', :name => "c", :evaluate_code => nil + @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_resource = stub 'node resource', :ref => "Node[c]", :evaluate => nil, :type => "node" + node_class.expects(:mk_plain_resource).returns(node_resource) - @compiler.compile - end + @compiler.compile + end - it "should match the default node if no matching node can be found" do - node_class = stub 'node', :name => "default", :evaluate_code => nil - @compiler.known_resource_types.stubs(:node).with("default").returns(node_class) + it "should match the default node if no matching node can be found" do + node_class = stub 'node', :name => "default", :evaluate_code => nil + @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_resource = stub 'node resource', :ref => "Node[default]", :evaluate => nil, :type => "node" + node_class.expects(:mk_plain_resource).returns(node_resource) - @compiler.compile - end + @compiler.compile + end - it "should evaluate the node resource immediately rather than using lazy evaluation" do - node_class = stub 'node', :name => "c" - @compiler.known_resource_types.stubs(:node).with("c").returns(node_class) + it "should evaluate the node resource immediately rather than using lazy evaluation" do + node_class = stub 'node', :name => "c" + @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_resource = stub 'node resource', :ref => "Node[c]", :type => "node" + node_class.expects(:mk_plain_resource).returns(node_resource) - node_resource.expects(:evaluate) + node_resource.expects(:evaluate) - @compiler.send(:evaluate_ast_node) - end + @compiler.send(:evaluate_ast_node) + end - it "should set the node's scope as the top scope" do - node_resource = stub 'node resource', :ref => "Node[c]", :evaluate => nil, :type => "node" - node_class = stub 'node', :name => "c", :mk_plain_resource => node_resource + 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 - @compiler.known_resource_types.stubs(:node).with("c").returns(node_class) + @compiler.known_resource_types.stubs(:node).with("c").returns(node_class) - # The #evaluate method normally does this. - scope = stub 'scope', :source => "mysource" - @compiler.topscope.expects(:class_scope).with(node_class).returns(scope) - node_resource.stubs(:evaluate) - @compiler.stubs :create_settings_scope + # The #evaluate method normally does this. + scope = stub 'scope', :source => "mysource" + @compiler.topscope.expects(:class_scope).with(node_class).returns(scope) + node_resource.stubs(:evaluate) + @compiler.stubs :create_settings_scope - @compiler.compile + @compiler.compile - @compiler.topscope.should equal(scope) - end + @compiler.topscope.should equal(scope) end + end - describe "when managing resource overrides" do + describe "when managing resource overrides" do - before do - @override = stub 'override', :ref => "File[/foo]", :type => "my" - @resource = resource(:file, "/foo") - end + before do + @override = stub 'override', :ref => "File[/foo]", :type => "my" + @resource = resource(:file, "/foo") + end - it "should be able to store overrides" do - lambda { @compiler.add_override(@override) }.should_not raise_error - end + it "should be able to store overrides" do + lambda { @compiler.add_override(@override) }.should_not raise_error + end - it "should apply overrides to the appropriate resources" do - @compiler.add_resource(@scope, @resource) - @resource.expects(:merge).with(@override) + it "should apply overrides to the appropriate resources" do + @compiler.add_resource(@scope, @resource) + @resource.expects(:merge).with(@override) - @compiler.add_override(@override) + @compiler.add_override(@override) - @compiler.compile - end + @compiler.compile + end - it "should accept overrides before the related resource has been created" do - @resource.expects(:merge).with(@override) + it "should accept overrides before the related resource has been created" do + @resource.expects(:merge).with(@override) - # First store the override - @compiler.add_override(@override) + # First store the override + @compiler.add_override(@override) - # Then the resource - @compiler.add_resource(@scope, @resource) + # Then the resource + @compiler.add_resource(@scope, @resource) - # And compile, so they get resolved - @compiler.compile - end + # And compile, so they get resolved + @compiler.compile + end - it "should fail if the compile is finished and resource overrides have not been applied" do - @compiler.add_override(@override) + it "should fail if the compile is finished and resource overrides have not been applied" do + @compiler.add_override(@override) - lambda { @compiler.compile }.should raise_error(Puppet::ParseError) - end + lambda { @compiler.compile }.should raise_error(Puppet::ParseError) end + end end diff --git a/spec/unit/parser/files_spec.rb b/spec/unit/parser/files_spec.rb index df96c0e4c..d1b5491a2 100644 --- a/spec/unit/parser/files_spec.rb +++ b/spec/unit/parser/files_spec.rb @@ -6,190 +6,190 @@ require 'puppet/parser/files' describe Puppet::Parser::Files do + before do + @basepath = Puppet.features.posix? ? "/somepath" : "C:/somepath" + end + + it "should have a method for finding a template" do + Puppet::Parser::Files.should respond_to(:find_template) + end + + it "should have a method for finding manifests" do + Puppet::Parser::Files.should respond_to(:find_manifests) + end + + describe "when searching for templates" do + it "should return fully-qualified templates directly" do + Puppet::Parser::Files.expects(:modulepath).never + Puppet::Parser::Files.find_template(@basepath + "/my/template").should == @basepath + "/my/template" + end + + it "should return the template from the first found module" do + mod = mock 'module' + Puppet::Node::Environment.new.expects(:module).with("mymod").returns mod + + mod.expects(:template).returns("/one/mymod/templates/mytemplate") + Puppet::Parser::Files.find_template("mymod/mytemplate").should == "/one/mymod/templates/mytemplate" + end + + it "should return the file in the templatedir if it exists" do + Puppet.settings.expects(:value).with(:templatedir, nil).returns("/my/templates") + Puppet[:modulepath] = "/one:/two" + File.stubs(:directory?).returns(true) + FileTest.stubs(:exist?).returns(true) + Puppet::Parser::Files.find_template("mymod/mytemplate").should == "/my/templates/mymod/mytemplate" + end + + it "should not raise an error if no valid templatedir exists and the template exists in a module" do + mod = mock 'module' + Puppet::Node::Environment.new.expects(:module).with("mymod").returns mod + + mod.expects(:template).returns("/one/mymod/templates/mytemplate") + Puppet::Parser::Files.stubs(:templatepath).with(nil).returns(nil) + + Puppet::Parser::Files.find_template("mymod/mytemplate").should == "/one/mymod/templates/mytemplate" + end + + it "should return unqualified templates if they exist in the template dir" do + FileTest.stubs(:exist?).returns true + Puppet::Parser::Files.stubs(:templatepath).with(nil).returns(["/my/templates"]) + Puppet::Parser::Files.find_template("mytemplate").should == "/my/templates/mytemplate" + end + + it "should only return templates if they actually exist" do + FileTest.expects(:exist?).with("/my/templates/mytemplate").returns true + Puppet::Parser::Files.stubs(:templatepath).with(nil).returns(["/my/templates"]) + Puppet::Parser::Files.find_template("mytemplate").should == "/my/templates/mytemplate" + end + + it "should return nil when asked for a template that doesn't exist" do + FileTest.expects(:exist?).with("/my/templates/mytemplate").returns false + Puppet::Parser::Files.stubs(:templatepath).with(nil).returns(["/my/templates"]) + Puppet::Parser::Files.find_template("mytemplate").should be_nil + end + + it "should search in the template directories before modules" do + FileTest.stubs(:exist?).returns true + Puppet::Parser::Files.stubs(:templatepath).with(nil).returns(["/my/templates"]) + Puppet::Module.expects(:find).never + Puppet::Parser::Files.find_template("mytemplate") + end + + it "should accept relative templatedirs" do + FileTest.stubs(:exist?).returns true + Puppet[:templatedir] = "my/templates" + File.expects(:directory?).with(File.join(Dir.getwd,"my/templates")).returns(true) + Puppet::Parser::Files.find_template("mytemplate").should == File.join(Dir.getwd,"my/templates/mytemplate") + end + + it "should use the environment templatedir if no module is found and an environment is specified" do + FileTest.stubs(:exist?).returns true + Puppet::Parser::Files.stubs(:templatepath).with("myenv").returns(["/myenv/templates"]) + Puppet::Parser::Files.find_template("mymod/mytemplate", "myenv").should == "/myenv/templates/mymod/mytemplate" + end + + it "should use first dir from environment templatedir if no module is found and an environment is specified" do + FileTest.stubs(:exist?).returns true + Puppet::Parser::Files.stubs(:templatepath).with("myenv").returns(["/myenv/templates", "/two/templates"]) + Puppet::Parser::Files.find_template("mymod/mytemplate", "myenv").should == "/myenv/templates/mymod/mytemplate" + end + + it "should use a valid dir when templatedir is a path for unqualified templates and the first dir contains template" do + Puppet::Parser::Files.stubs(:templatepath).returns(["/one/templates", "/two/templates"]) + FileTest.expects(:exist?).with("/one/templates/mytemplate").returns(true) + Puppet::Parser::Files.find_template("mytemplate").should == "/one/templates/mytemplate" + end + + it "should use a valid dir when templatedir is a path for unqualified templates and only second dir contains template" do + Puppet::Parser::Files.stubs(:templatepath).returns(["/one/templates", "/two/templates"]) + FileTest.expects(:exist?).with("/one/templates/mytemplate").returns(false) + FileTest.expects(:exist?).with("/two/templates/mytemplate").returns(true) + Puppet::Parser::Files.find_template("mytemplate").should == "/two/templates/mytemplate" + end + + it "should use the node environment if specified" do + mod = mock 'module' + Puppet::Node::Environment.new("myenv").expects(:module).with("mymod").returns mod + + mod.expects(:template).returns("/my/modules/mymod/templates/envtemplate") + + Puppet::Parser::Files.find_template("mymod/envtemplate", "myenv").should == "/my/modules/mymod/templates/envtemplate" + end + + it "should return nil if no template can be found" do + Puppet::Parser::Files.find_template("foomod/envtemplate", "myenv").should be_nil + end + + after { Puppet.settings.clear } + end + + describe "when searching for manifests" do + it "should ignore invalid modules" do + mod = mock 'module' + Puppet::Node::Environment.new.expects(:module).with("mymod").raises(Puppet::Module::InvalidName, "name is invalid") + Puppet.expects(:value).with(:modulepath).never + Dir.stubs(:glob).returns %w{foo} + + Puppet::Parser::Files.find_manifests("mymod/init.pp") + end + end + + describe "when searching for manifests when no module is found" do before do - @basepath = Puppet.features.posix? ? "/somepath" : "C:/somepath" - end - - it "should have a method for finding a template" do - Puppet::Parser::Files.should respond_to(:find_template) - end - - it "should have a method for finding manifests" do - Puppet::Parser::Files.should respond_to(:find_manifests) - end - - describe "when searching for templates" do - it "should return fully-qualified templates directly" do - Puppet::Parser::Files.expects(:modulepath).never - Puppet::Parser::Files.find_template(@basepath + "/my/template").should == @basepath + "/my/template" - end - - it "should return the template from the first found module" do - mod = mock 'module' - Puppet::Node::Environment.new.expects(:module).with("mymod").returns mod - - mod.expects(:template).returns("/one/mymod/templates/mytemplate") - Puppet::Parser::Files.find_template("mymod/mytemplate").should == "/one/mymod/templates/mytemplate" - end - - it "should return the file in the templatedir if it exists" do - Puppet.settings.expects(:value).with(:templatedir, nil).returns("/my/templates") - Puppet[:modulepath] = "/one:/two" - File.stubs(:directory?).returns(true) - FileTest.stubs(:exist?).returns(true) - Puppet::Parser::Files.find_template("mymod/mytemplate").should == "/my/templates/mymod/mytemplate" - end - - it "should not raise an error if no valid templatedir exists and the template exists in a module" do - mod = mock 'module' - Puppet::Node::Environment.new.expects(:module).with("mymod").returns mod - - mod.expects(:template).returns("/one/mymod/templates/mytemplate") - Puppet::Parser::Files.stubs(:templatepath).with(nil).returns(nil) - - Puppet::Parser::Files.find_template("mymod/mytemplate").should == "/one/mymod/templates/mytemplate" - end - - it "should return unqualified templates if they exist in the template dir" do - FileTest.stubs(:exist?).returns true - Puppet::Parser::Files.stubs(:templatepath).with(nil).returns(["/my/templates"]) - Puppet::Parser::Files.find_template("mytemplate").should == "/my/templates/mytemplate" - end - - it "should only return templates if they actually exist" do - FileTest.expects(:exist?).with("/my/templates/mytemplate").returns true - Puppet::Parser::Files.stubs(:templatepath).with(nil).returns(["/my/templates"]) - Puppet::Parser::Files.find_template("mytemplate").should == "/my/templates/mytemplate" - end - - it "should return nil when asked for a template that doesn't exist" do - FileTest.expects(:exist?).with("/my/templates/mytemplate").returns false - Puppet::Parser::Files.stubs(:templatepath).with(nil).returns(["/my/templates"]) - Puppet::Parser::Files.find_template("mytemplate").should be_nil - end - - it "should search in the template directories before modules" do - FileTest.stubs(:exist?).returns true - Puppet::Parser::Files.stubs(:templatepath).with(nil).returns(["/my/templates"]) - Puppet::Module.expects(:find).never - Puppet::Parser::Files.find_template("mytemplate") - end - - it "should accept relative templatedirs" do - FileTest.stubs(:exist?).returns true - Puppet[:templatedir] = "my/templates" - File.expects(:directory?).with(File.join(Dir.getwd,"my/templates")).returns(true) - Puppet::Parser::Files.find_template("mytemplate").should == File.join(Dir.getwd,"my/templates/mytemplate") - end - - it "should use the environment templatedir if no module is found and an environment is specified" do - FileTest.stubs(:exist?).returns true - Puppet::Parser::Files.stubs(:templatepath).with("myenv").returns(["/myenv/templates"]) - Puppet::Parser::Files.find_template("mymod/mytemplate", "myenv").should == "/myenv/templates/mymod/mytemplate" - end - - it "should use first dir from environment templatedir if no module is found and an environment is specified" do - FileTest.stubs(:exist?).returns true - Puppet::Parser::Files.stubs(:templatepath).with("myenv").returns(["/myenv/templates", "/two/templates"]) - Puppet::Parser::Files.find_template("mymod/mytemplate", "myenv").should == "/myenv/templates/mymod/mytemplate" - end - - it "should use a valid dir when templatedir is a path for unqualified templates and the first dir contains template" do - Puppet::Parser::Files.stubs(:templatepath).returns(["/one/templates", "/two/templates"]) - FileTest.expects(:exist?).with("/one/templates/mytemplate").returns(true) - Puppet::Parser::Files.find_template("mytemplate").should == "/one/templates/mytemplate" - end - - it "should use a valid dir when templatedir is a path for unqualified templates and only second dir contains template" do - Puppet::Parser::Files.stubs(:templatepath).returns(["/one/templates", "/two/templates"]) - FileTest.expects(:exist?).with("/one/templates/mytemplate").returns(false) - FileTest.expects(:exist?).with("/two/templates/mytemplate").returns(true) - Puppet::Parser::Files.find_template("mytemplate").should == "/two/templates/mytemplate" - end - - it "should use the node environment if specified" do - mod = mock 'module' - Puppet::Node::Environment.new("myenv").expects(:module).with("mymod").returns mod - - mod.expects(:template).returns("/my/modules/mymod/templates/envtemplate") - - Puppet::Parser::Files.find_template("mymod/envtemplate", "myenv").should == "/my/modules/mymod/templates/envtemplate" - end - - it "should return nil if no template can be found" do - Puppet::Parser::Files.find_template("foomod/envtemplate", "myenv").should be_nil - end - - after { Puppet.settings.clear } - end - - describe "when searching for manifests" do - it "should ignore invalid modules" do - mod = mock 'module' - Puppet::Node::Environment.new.expects(:module).with("mymod").raises(Puppet::Module::InvalidName, "name is invalid") - Puppet.expects(:value).with(:modulepath).never - Dir.stubs(:glob).returns %w{foo} - - Puppet::Parser::Files.find_manifests("mymod/init.pp") - end - end - - describe "when searching for manifests when no module is found" do - before do - File.stubs(:find).returns(nil) - end - - it "should not look for modules when paths are fully qualified" do - Puppet.expects(:value).with(:modulepath).never - file = @basepath + "/fully/qualified/file.pp" - Dir.stubs(:glob).with(file).returns([file]) - Puppet::Parser::Files.find_manifests(file) - end - - it "should return nil and an array of fully qualified files" do - file = @basepath + "/fully/qualified/file.pp" - Dir.stubs(:glob).with(file).returns([file]) - Puppet::Parser::Files.find_manifests(file).should == [nil, [file]] - end - - 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}) - Puppet::Parser::Files.find_manifests(pattern)[1].should == %w{my file list} - end - - it "should look for files relative to the current directory" do - cwd = Dir.getwd - Dir.expects(:glob).with("#{cwd}/foobar/init.pp").returns(["#{cwd}/foobar/init.pp"]) - Puppet::Parser::Files.find_manifests("foobar/init.pp")[1].should == ["#{cwd}/foobar/init.pp"] - end - - it "should only return files, not directories" do - pattern = @basepath + "/fully/qualified/pattern/*" - file = @basepath + "/my/file" - dir = @basepath + "/my/directory" - 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] - end - end - - describe "when searching for manifests in a found module" do - it "should return the name of the module and the manifests from the first found module" do - mod = Puppet::Module.new("mymod") - Puppet::Node::Environment.new.expects(:module).with("mymod").returns mod - mod.expects(:match_manifests).with("init.pp").returns(%w{/one/mymod/manifests/init.pp}) - Puppet::Parser::Files.find_manifests("mymod/init.pp").should == ["mymod", ["/one/mymod/manifests/init.pp"]] - end - - it "should use the node environment if specified" do - mod = Puppet::Module.new("mymod") - Puppet::Node::Environment.new("myenv").expects(:module).with("mymod").returns mod - mod.expects(:match_manifests).with("init.pp").returns(%w{/one/mymod/manifests/init.pp}) - Puppet::Parser::Files.find_manifests("mymod/init.pp", :environment => "myenv")[1].should == ["/one/mymod/manifests/init.pp"] - end - - after { Puppet.settings.clear } + File.stubs(:find).returns(nil) + end + + it "should not look for modules when paths are fully qualified" do + Puppet.expects(:value).with(:modulepath).never + file = @basepath + "/fully/qualified/file.pp" + Dir.stubs(:glob).with(file).returns([file]) + Puppet::Parser::Files.find_manifests(file) + end + + it "should return nil and an array of fully qualified files" do + file = @basepath + "/fully/qualified/file.pp" + Dir.stubs(:glob).with(file).returns([file]) + Puppet::Parser::Files.find_manifests(file).should == [nil, [file]] + end + + 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}) + Puppet::Parser::Files.find_manifests(pattern)[1].should == %w{my file list} + end + + it "should look for files relative to the current directory" do + cwd = Dir.getwd + Dir.expects(:glob).with("#{cwd}/foobar/init.pp").returns(["#{cwd}/foobar/init.pp"]) + Puppet::Parser::Files.find_manifests("foobar/init.pp")[1].should == ["#{cwd}/foobar/init.pp"] end + + it "should only return files, not directories" do + pattern = @basepath + "/fully/qualified/pattern/*" + file = @basepath + "/my/file" + dir = @basepath + "/my/directory" + 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] + end + end + + describe "when searching for manifests in a found module" do + it "should return the name of the module and the manifests from the first found module" do + mod = Puppet::Module.new("mymod") + Puppet::Node::Environment.new.expects(:module).with("mymod").returns mod + mod.expects(:match_manifests).with("init.pp").returns(%w{/one/mymod/manifests/init.pp}) + Puppet::Parser::Files.find_manifests("mymod/init.pp").should == ["mymod", ["/one/mymod/manifests/init.pp"]] + end + + it "should use the node environment if specified" do + mod = Puppet::Module.new("mymod") + Puppet::Node::Environment.new("myenv").expects(:module).with("mymod").returns mod + mod.expects(:match_manifests).with("init.pp").returns(%w{/one/mymod/manifests/init.pp}) + Puppet::Parser::Files.find_manifests("mymod/init.pp", :environment => "myenv")[1].should == ["/one/mymod/manifests/init.pp"] + end + + after { Puppet.settings.clear } + end end diff --git a/spec/unit/parser/functions/defined_spec.rb b/spec/unit/parser/functions/defined_spec.rb index 90f2f5239..cf3f66e17 100755 --- a/spec/unit/parser/functions/defined_spec.rb +++ b/spec/unit/parser/functions/defined_spec.rb @@ -4,47 +4,47 @@ require File.dirname(__FILE__) + '/../../../spec_helper' describe "the 'defined' 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("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 + 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("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/fqdn_rand_spec.rb b/spec/unit/parser/functions/fqdn_rand_spec.rb index 07390ed42..81c12c6a7 100644 --- a/spec/unit/parser/functions/fqdn_rand_spec.rb +++ b/spec/unit/parser/functions/fqdn_rand_spec.rb @@ -4,59 +4,59 @@ require File.dirname(__FILE__) + '/../../../spec_helper' describe "the fqdn_rand function" do - before :each do - @scope = Puppet::Parser::Scope.new - end - - it "should exist" do - Puppet::Parser::Functions.function("fqdn_rand").should == "function_fqdn_rand" - end - - it "should handle 0 arguments" do - @scope.expects(:lookupvar).with("fqdn").returns("127.0.0.1") - lambda { @scope.function_fqdn_rand([]) }.should_not raise_error(Puppet::ParseError) - end - - it "should handle 1 argument'}" do - @scope.expects(:lookupvar).with("fqdn").returns("127.0.0.1") - lambda { @scope.function_fqdn_rand([3]) }.should_not raise_error(Puppet::ParseError) - end - - - (1..10).each { |n| - it "should handle #{n} additional arguments" do - @scope.expects(:lookupvar).with("fqdn").returns("127.0.0.1") - lambda { @scope.function_fqdn_rand([3,1,2,3,4,5,6,7,8,9,10][0..n]) }.should_not raise_error(Puppet::ParseError) - end - it "should handle #{n} additional string arguments" do - @scope.expects(:lookupvar).with("fqdn").returns("127.0.0.1") - lambda { @scope.function_fqdn_rand([3,%w{ 1 2 3 4 5 6 7 8 9 10}].flatten[0..n]) }.should_not raise_error(Puppet::ParseError) - end - } - - it "should return a value less than max" do - @scope.expects(:lookupvar).with("fqdn").returns("127.0.0.1") - @scope.function_fqdn_rand([3]).should satisfy {|n| n.to_i < 3 } - end - - it "should return the same values on subsequent invocations for the same host" do - @scope.expects(:lookupvar).with("fqdn").returns("127.0.0.1").twice - @scope.function_fqdn_rand([3,4]).should eql(@scope.function_fqdn_rand([3, 4])) - end - - it "should return different sequences of value for different hosts" do - @scope.expects(:lookupvar).with("fqdn").returns("127.0.0.1") - val1 = @scope.function_fqdn_rand([10000000,4]) - @scope.expects(:lookupvar).with("fqdn").returns("127.0.0.2") - val2 = @scope.function_fqdn_rand([10000000,4]) - val1.should_not eql(val2) - end - - it "should return different values for the same hosts with different seeds" do - @scope.expects(:lookupvar).with("fqdn").returns("127.0.0.1") - val1 = @scope.function_fqdn_rand([10000000,4]) - @scope.expects(:lookupvar).with("fqdn").returns("127.0.0.1") - val2 = @scope.function_fqdn_rand([10000000,42]) - val1.should_not eql(val2) - end + before :each do + @scope = Puppet::Parser::Scope.new + end + + it "should exist" do + Puppet::Parser::Functions.function("fqdn_rand").should == "function_fqdn_rand" + end + + it "should handle 0 arguments" do + @scope.expects(:lookupvar).with("fqdn").returns("127.0.0.1") + lambda { @scope.function_fqdn_rand([]) }.should_not raise_error(Puppet::ParseError) + end + + it "should handle 1 argument'}" do + @scope.expects(:lookupvar).with("fqdn").returns("127.0.0.1") + lambda { @scope.function_fqdn_rand([3]) }.should_not raise_error(Puppet::ParseError) + end + + + (1..10).each { |n| + it "should handle #{n} additional arguments" do + @scope.expects(:lookupvar).with("fqdn").returns("127.0.0.1") + lambda { @scope.function_fqdn_rand([3,1,2,3,4,5,6,7,8,9,10][0..n]) }.should_not raise_error(Puppet::ParseError) + end + it "should handle #{n} additional string arguments" do + @scope.expects(:lookupvar).with("fqdn").returns("127.0.0.1") + lambda { @scope.function_fqdn_rand([3,%w{ 1 2 3 4 5 6 7 8 9 10}].flatten[0..n]) }.should_not raise_error(Puppet::ParseError) + end + } + + it "should return a value less than max" do + @scope.expects(:lookupvar).with("fqdn").returns("127.0.0.1") + @scope.function_fqdn_rand([3]).should satisfy {|n| n.to_i < 3 } + end + + it "should return the same values on subsequent invocations for the same host" do + @scope.expects(:lookupvar).with("fqdn").returns("127.0.0.1").twice + @scope.function_fqdn_rand([3,4]).should eql(@scope.function_fqdn_rand([3, 4])) + end + + it "should return different sequences of value for different hosts" do + @scope.expects(:lookupvar).with("fqdn").returns("127.0.0.1") + val1 = @scope.function_fqdn_rand([10000000,4]) + @scope.expects(:lookupvar).with("fqdn").returns("127.0.0.2") + val2 = @scope.function_fqdn_rand([10000000,4]) + val1.should_not eql(val2) + end + + it "should return different values for the same hosts with different seeds" do + @scope.expects(:lookupvar).with("fqdn").returns("127.0.0.1") + val1 = @scope.function_fqdn_rand([10000000,4]) + @scope.expects(:lookupvar).with("fqdn").returns("127.0.0.1") + val2 = @scope.function_fqdn_rand([10000000,42]) + val1.should_not eql(val2) + end end diff --git a/spec/unit/parser/functions/generate_spec.rb b/spec/unit/parser/functions/generate_spec.rb index 27a11aabf..27aabe261 100755 --- a/spec/unit/parser/functions/generate_spec.rb +++ b/spec/unit/parser/functions/generate_spec.rb @@ -4,38 +4,38 @@ require File.dirname(__FILE__) + '/../../../spec_helper' describe "the generate function" do - before :each do - @scope = Puppet::Parser::Scope.new - end - - it "should exist" do - Puppet::Parser::Functions.function("generate").should == "function_generate" - end - - it "should accept a fully-qualified path as a command" do - command = File::SEPARATOR + "command" - Puppet::Util.expects(:execute).with([command]).returns("yay") - lambda { @scope.function_generate([command]) }.should_not raise_error(Puppet::ParseError) - end - - it "should not accept a relative path as a command" do - command = "command" - lambda { @scope.function_generate([command]) }.should raise_error(Puppet::ParseError) - end - - # Really not sure how to implement this test, just sure it needs - # to be implemented. - it "should not accept a command containing illegal characters" - - it "should not accept a command containing '..'" do - command = File::SEPARATOR + "command#{File::SEPARATOR}..#{File::SEPARATOR}" - lambda { @scope.function_generate([command]) }.should raise_error(Puppet::ParseError) - end - - it "should execute the generate script with the correct working directory" do - command = File::SEPARATOR + "command" - Dir.expects(:chdir).with(File.dirname(command)).yields - Puppet::Util.expects(:execute).with([command]).returns("yay") - lambda { @scope.function_generate([command]) }.should_not raise_error(Puppet::ParseError) - end + before :each do + @scope = Puppet::Parser::Scope.new + end + + it "should exist" do + Puppet::Parser::Functions.function("generate").should == "function_generate" + end + + it "should accept a fully-qualified path as a command" do + command = File::SEPARATOR + "command" + Puppet::Util.expects(:execute).with([command]).returns("yay") + lambda { @scope.function_generate([command]) }.should_not raise_error(Puppet::ParseError) + end + + it "should not accept a relative path as a command" do + command = "command" + lambda { @scope.function_generate([command]) }.should raise_error(Puppet::ParseError) + end + + # Really not sure how to implement this test, just sure it needs + # to be implemented. + it "should not accept a command containing illegal characters" + + it "should not accept a command containing '..'" do + command = File::SEPARATOR + "command#{File::SEPARATOR}..#{File::SEPARATOR}" + lambda { @scope.function_generate([command]) }.should raise_error(Puppet::ParseError) + end + + it "should execute the generate script with the correct working directory" do + command = File::SEPARATOR + "command" + Dir.expects(:chdir).with(File.dirname(command)).yields + Puppet::Util.expects(:execute).with([command]).returns("yay") + lambda { @scope.function_generate([command]) }.should_not raise_error(Puppet::ParseError) + end end diff --git a/spec/unit/parser/functions/inline_template_spec.rb b/spec/unit/parser/functions/inline_template_spec.rb index 1da85513a..62f389e5d 100755 --- a/spec/unit/parser/functions/inline_template_spec.rb +++ b/spec/unit/parser/functions/inline_template_spec.rb @@ -4,56 +4,56 @@ require File.dirname(__FILE__) + '/../../../spec_helper' describe "the inline_template function" do - before :each do - @scope = Puppet::Parser::Scope.new - end + before :each do + @scope = Puppet::Parser::Scope.new + end - it "should exist" do - Puppet::Parser::Functions.function("inline_template").should == "function_inline_template" - end + it "should exist" do + Puppet::Parser::Functions.function("inline_template").should == "function_inline_template" + end - it "should create a TemplateWrapper when called" do - tw = stub_everything 'template_wrapper' + it "should create a TemplateWrapper when called" do + tw = stub_everything 'template_wrapper' - Puppet::Parser::TemplateWrapper.expects(:new).returns(tw) + Puppet::Parser::TemplateWrapper.expects(:new).returns(tw) - @scope.function_inline_template("test") - end + @scope.function_inline_template("test") + end - it "should pass the template string to TemplateWrapper.result" do - tw = stub_everything 'template_wrapper' - Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw) + it "should pass the template string to TemplateWrapper.result" do + tw = stub_everything 'template_wrapper' + Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw) - tw.expects(:result).with("test") + tw.expects(:result).with("test") - @scope.function_inline_template("test") - end + @scope.function_inline_template("test") + end - it "should return what TemplateWrapper.result returns" do - tw = stub_everything 'template_wrapper' - Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw) + it "should return what TemplateWrapper.result returns" do + tw = stub_everything 'template_wrapper' + Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw) - tw.expects(:result).returns("template contents evaluated") + tw.expects(:result).returns("template contents evaluated") - @scope.function_inline_template("test").should == "template contents evaluated" - end + @scope.function_inline_template("test").should == "template contents evaluated" + end - it "should concatenate template wrapper outputs for multiple templates" do - tw1 = stub_everything "template_wrapper1" - tw2 = stub_everything "template_wrapper2" - Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw1,tw2) - tw1.stubs(:result).returns("result1") - tw2.stubs(:result).returns("result2") + it "should concatenate template wrapper outputs for multiple templates" do + tw1 = stub_everything "template_wrapper1" + tw2 = stub_everything "template_wrapper2" + Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw1,tw2) + tw1.stubs(:result).returns("result1") + tw2.stubs(:result).returns("result2") - @scope.function_inline_template(["1","2"]).should == "result1result2" - end + @scope.function_inline_template(["1","2"]).should == "result1result2" + end - it "should raise an error if the template raises an error" do - tw = stub_everything 'template_wrapper' - Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw) - tw.stubs(:result).raises + it "should raise an error if the template raises an error" do + tw = stub_everything 'template_wrapper' + Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw) + tw.stubs(:result).raises - lambda { @scope.function_inline_template("1") }.should raise_error(Puppet::ParseError) - end + lambda { @scope.function_inline_template("1") }.should raise_error(Puppet::ParseError) + end end
\ No newline at end of file diff --git a/spec/unit/parser/functions/realize_spec.rb b/spec/unit/parser/functions/realize_spec.rb index 4a55ad417..82f4fa251 100755 --- a/spec/unit/parser/functions/realize_spec.rb +++ b/spec/unit/parser/functions/realize_spec.rb @@ -4,48 +4,48 @@ require File.dirname(__FILE__) + '/../../../spec_helper' describe "the realize function" do - before :each do - @collector = stub_everything 'collector' - @scope = Puppet::Parser::Scope.new - @compiler = stub 'compiler' - @compiler.stubs(:add_collection).with(@collector) - @scope.stubs(:compiler).returns(@compiler) - end + before :each do + @collector = stub_everything 'collector' + @scope = Puppet::Parser::Scope.new + @compiler = stub 'compiler' + @compiler.stubs(:add_collection).with(@collector) + @scope.stubs(:compiler).returns(@compiler) + end - it "should exist" do - Puppet::Parser::Functions.function("realize").should == "function_realize" - end + it "should exist" do + Puppet::Parser::Functions.function("realize").should == "function_realize" + end - it "should create a Collector when called" do + it "should create a Collector when called" do - Puppet::Parser::Collector.expects(:new).returns(@collector) + Puppet::Parser::Collector.expects(:new).returns(@collector) - @scope.function_realize("test") - end + @scope.function_realize("test") + end - it "should assign the passed-in resources to the collector" do - Puppet::Parser::Collector.stubs(:new).returns(@collector) + it "should assign the passed-in resources to the collector" do + Puppet::Parser::Collector.stubs(:new).returns(@collector) - @collector.expects(:resources=).with(["test"]) + @collector.expects(:resources=).with(["test"]) - @scope.function_realize("test") - end + @scope.function_realize("test") + end - it "should flatten the resources assigned to the collector" do - Puppet::Parser::Collector.stubs(:new).returns(@collector) + it "should flatten the resources assigned to the collector" do + Puppet::Parser::Collector.stubs(:new).returns(@collector) - @collector.expects(:resources=).with(["test"]) + @collector.expects(:resources=).with(["test"]) - @scope.function_realize([["test"]]) - end + @scope.function_realize([["test"]]) + end - it "should let the compiler know this collector" do - Puppet::Parser::Collector.stubs(:new).returns(@collector) - @collector.stubs(:resources=).with(["test"]) + it "should let the compiler know this collector" do + Puppet::Parser::Collector.stubs(:new).returns(@collector) + @collector.stubs(:resources=).with(["test"]) - @compiler.expects(:add_collection).with(@collector) + @compiler.expects(:add_collection).with(@collector) - @scope.function_realize("test") - end + @scope.function_realize("test") + end end diff --git a/spec/unit/parser/functions/regsubst_spec.rb b/spec/unit/parser/functions/regsubst_spec.rb index d87b4d9ab..47126dd7a 100755 --- a/spec/unit/parser/functions/regsubst_spec.rb +++ b/spec/unit/parser/functions/regsubst_spec.rb @@ -4,189 +4,189 @@ require File.dirname(__FILE__) + '/../../../spec_helper' describe "the regsubst function" do - before :each do - @scope = Puppet::Parser::Scope.new - end + before :each do + @scope = Puppet::Parser::Scope.new + end - it "should exist" do - Puppet::Parser::Functions.function("regsubst").should == "function_regsubst" - end + it "should exist" do + Puppet::Parser::Functions.function("regsubst").should == "function_regsubst" + end - it "should raise a ParseError if there is less than 3 arguments" do - lambda { @scope.function_regsubst(["foo", "bar"]) }.should( raise_error(Puppet::ParseError)) - end + it "should raise a ParseError if there is less than 3 arguments" do + lambda { @scope.function_regsubst(["foo", "bar"]) }.should( raise_error(Puppet::ParseError)) + end - it "should raise a ParseError if there is more than 5 arguments" do - lambda { @scope.function_regsubst(["foo", "bar", "gazonk", "del", "x", "y"]) }.should( raise_error(Puppet::ParseError)) - end + it "should raise a ParseError if there is more than 5 arguments" do + lambda { @scope.function_regsubst(["foo", "bar", "gazonk", "del", "x", "y"]) }.should( raise_error(Puppet::ParseError)) + end - it "should raise a ParseError when given a bad flag" do - lambda { @scope.function_regsubst(["foo", "bar", "gazonk", "X"]) }.should( raise_error(Puppet::ParseError)) - end + it "should raise a ParseError when given a bad flag" do + lambda { @scope.function_regsubst(["foo", "bar", "gazonk", "X"]) }.should( raise_error(Puppet::ParseError)) + end - it "should raise a ParseError for non-string and non-array target" do - lambda { @scope.function_regsubst([4711, "bar", "gazonk"]) }.should( raise_error(Puppet::ParseError)) - end + it "should raise a ParseError for non-string and non-array target" do + lambda { @scope.function_regsubst([4711, "bar", "gazonk"]) }.should( raise_error(Puppet::ParseError)) + end - it "should raise a ParseError for array target with non-string element" do - lambda { @scope.function_regsubst([["x", ["y"], "z"], "bar", "gazonk"]) }.should( raise_error(Puppet::ParseError)) - end + it "should raise a ParseError for array target with non-string element" do + lambda { @scope.function_regsubst([["x", ["y"], "z"], "bar", "gazonk"]) }.should( raise_error(Puppet::ParseError)) + end - it "should raise a ParseError for a bad regular expression" do - lambda { @scope.function_regsubst(["foo", "(bar", "gazonk"]) }.should( - raise_error(Puppet::ParseError)) - end + it "should raise a ParseError for a bad regular expression" do + lambda { @scope.function_regsubst(["foo", "(bar", "gazonk"]) }.should( + raise_error(Puppet::ParseError)) + end - it "should raise a ParseError for a non-string regular expression" do - lambda { @scope.function_regsubst(["foo", ["bar"], "gazonk"]) }.should( raise_error(Puppet::ParseError)) - end + it "should raise a ParseError for a non-string regular expression" do + lambda { @scope.function_regsubst(["foo", ["bar"], "gazonk"]) }.should( raise_error(Puppet::ParseError)) + end - it "should handle groups" do + it "should handle groups" do - result = @scope.function_regsubst( + result = @scope.function_regsubst( - [ '130.236.254.10', + [ '130.236.254.10', - '^([0-9]+)[.]([0-9]+)[.]([0-9]+)[.]([0-9]+)$', - '\4-\3-\2-\1' - ]) - result.should(eql("10-254-236-130")) - end + '^([0-9]+)[.]([0-9]+)[.]([0-9]+)[.]([0-9]+)$', + '\4-\3-\2-\1' + ]) + result.should(eql("10-254-236-130")) + end - it "should handle simple regexps" do + it "should handle simple regexps" do - result = @scope.function_regsubst( + result = @scope.function_regsubst( - [ "the monkey breaks banana trees", - "b[an]*a", + [ "the monkey breaks banana trees", + "b[an]*a", - "coconut" - ]) - result.should(eql("the monkey breaks coconut trees")) - end + "coconut" + ]) + result.should(eql("the monkey breaks coconut trees")) + end - it "should handle case-sensitive regexps" do + it "should handle case-sensitive regexps" do - result = @scope.function_regsubst( + result = @scope.function_regsubst( - [ "the monkey breaks baNAna trees", - "b[an]+a", + [ "the monkey breaks baNAna trees", + "b[an]+a", - "coconut" - ]) - result.should(eql("the monkey breaks baNAna trees")) - end + "coconut" + ]) + result.should(eql("the monkey breaks baNAna trees")) + end - it "should handle case-insensitive regexps" do + it "should handle case-insensitive regexps" do - result = @scope.function_regsubst( + result = @scope.function_regsubst( - [ "the monkey breaks baNAna trees", - "b[an]+a", - "coconut", + [ "the monkey breaks baNAna trees", + "b[an]+a", + "coconut", - "I" - ]) - result.should(eql("the monkey breaks coconut trees")) - end + "I" + ]) + result.should(eql("the monkey breaks coconut trees")) + end - it "should handle global substitutions" do + it "should handle global substitutions" do - result = @scope.function_regsubst( + result = @scope.function_regsubst( - [ "the monkey breaks\tbanana trees", - "[ \t]", - "--", + [ "the monkey breaks\tbanana trees", + "[ \t]", + "--", - "G" - ]) - result.should(eql("the--monkey--breaks--banana--trees")) - end + "G" + ]) + result.should(eql("the--monkey--breaks--banana--trees")) + end - it "should handle global substitutions with groups" do + it "should handle global substitutions with groups" do - result = @scope.function_regsubst( + result = @scope.function_regsubst( - [ '130.236.254.10', + [ '130.236.254.10', - '([0-9]+)', - '<\1>', - 'G' - ]) - result.should(eql('<130>.<236>.<254>.<10>')) - end + '([0-9]+)', + '<\1>', + 'G' + ]) + result.should(eql('<130>.<236>.<254>.<10>')) + end - it "should apply on all elements of an array" do - data = ['130.236.254.10', 'foo.example.com', 'coconut', '10.20.30.40'] - result = @scope.function_regsubst([ data, '[.]', '-']) - result.should(eql( ['130-236.254.10', 'foo-example.com', 'coconut', '10-20.30.40'])) - end + it "should apply on all elements of an array" do + data = ['130.236.254.10', 'foo.example.com', 'coconut', '10.20.30.40'] + result = @scope.function_regsubst([ data, '[.]', '-']) + result.should(eql( ['130-236.254.10', 'foo-example.com', 'coconut', '10-20.30.40'])) + end - it "should apply global substitutions on all elements of an array" do - data = ['130.236.254.10', 'foo.example.com', 'coconut', '10.20.30.40'] - result = @scope.function_regsubst([ data, '[.]', '-', 'G']) - result.should(eql( ['130-236-254-10', 'foo-example-com', 'coconut', '10-20-30-40'])) - end + it "should apply global substitutions on all elements of an array" do + data = ['130.236.254.10', 'foo.example.com', 'coconut', '10.20.30.40'] + result = @scope.function_regsubst([ data, '[.]', '-', 'G']) + result.should(eql( ['130-236-254-10', 'foo-example-com', 'coconut', '10-20-30-40'])) + end - it "should handle groups on all elements of an array" do - data = ['130.236.254.10', 'foo.example.com', 'coconut', '10.20.30.40'] + it "should handle groups on all elements of an array" do + data = ['130.236.254.10', 'foo.example.com', 'coconut', '10.20.30.40'] - result = @scope.function_regsubst( + result = @scope.function_regsubst( - [ data, + [ data, - '^([0-9]+)[.]([0-9]+)[.]([0-9]+)[.]([0-9]+)$', - '\4-\3-\2-\1' - ]) - result.should(eql( ['10-254-236-130', 'foo.example.com', 'coconut', '40-30-20-10'])) - end + '^([0-9]+)[.]([0-9]+)[.]([0-9]+)[.]([0-9]+)$', + '\4-\3-\2-\1' + ]) + result.should(eql( ['10-254-236-130', 'foo.example.com', 'coconut', '40-30-20-10'])) + end - it "should handle global substitutions with groups on all elements of an array" do - data = ['130.236.254.10', 'foo.example.com', 'coconut', '10.20.30.40'] + it "should handle global substitutions with groups on all elements of an array" do + data = ['130.236.254.10', 'foo.example.com', 'coconut', '10.20.30.40'] - result = @scope.function_regsubst( + result = @scope.function_regsubst( - [ data, + [ data, - '([^.]+)', - '<\1>', - 'G' - ]) + '([^.]+)', + '<\1>', + 'G' + ]) - result.should(eql( + result.should(eql( - ['<130>.<236>.<254>.<10>', '<foo>.<example>.<com>', + ['<130>.<236>.<254>.<10>', '<foo>.<example>.<com>', - '<coconut>', '<10>.<20>.<30>.<40>'])) - end + '<coconut>', '<10>.<20>.<30>.<40>'])) + end - it "should return an array (not a string) for a single element array parameter" do - data = ['130.236.254.10'] + it "should return an array (not a string) for a single element array parameter" do + data = ['130.236.254.10'] - result = @scope.function_regsubst( + result = @scope.function_regsubst( - [ data, + [ data, - '([^.]+)', - '<\1>', - 'G' - ]) - result.should(eql(['<130>.<236>.<254>.<10>'])) - end + '([^.]+)', + '<\1>', + 'G' + ]) + result.should(eql(['<130>.<236>.<254>.<10>'])) + end - it "should return a string (not a one element array) for a simple string parameter" do - data = '130.236.254.10' + it "should return a string (not a one element array) for a simple string parameter" do + data = '130.236.254.10' - result = @scope.function_regsubst( + result = @scope.function_regsubst( - [ data, + [ data, - '([^.]+)', - '<\1>', - 'G' - ]) - result.should(eql('<130>.<236>.<254>.<10>')) - end + '([^.]+)', + '<\1>', + 'G' + ]) + result.should(eql('<130>.<236>.<254>.<10>')) + end end diff --git a/spec/unit/parser/functions/require_spec.rb b/spec/unit/parser/functions/require_spec.rb index 48769d16c..bd42fa579 100755 --- a/spec/unit/parser/functions/require_spec.rb +++ b/spec/unit/parser/functions/require_spec.rb @@ -4,71 +4,71 @@ require File.dirname(__FILE__) + '/../../../spec_helper' describe "the require function" do - before :each do - @catalog = stub 'catalog' - @compiler = stub 'compiler', :catalog => @catalog + before :each do + @catalog = stub 'catalog' + @compiler = stub 'compiler', :catalog => @catalog - @scope = Puppet::Parser::Scope.new - @scope.stubs(:findresource) - @scope.stubs(:compiler).returns(@compiler) - @klass = stub 'class', :name => "myclass" - @scope.stubs(:find_hostclass).returns(@klass) + @scope = Puppet::Parser::Scope.new + @scope.stubs(:findresource) + @scope.stubs(:compiler).returns(@compiler) + @klass = stub 'class', :name => "myclass" + @scope.stubs(:find_hostclass).returns(@klass) - @resource = Puppet::Parser::Resource.new(:file, "/my/file", :scope => @scope, :source => "source") - @resource.stubs(:metaparam_compatibility_mode?).returns false - @scope.stubs(:resource).returns @resource - end + @resource = Puppet::Parser::Resource.new(:file, "/my/file", :scope => @scope, :source => "source") + @resource.stubs(:metaparam_compatibility_mode?).returns false + @scope.stubs(:resource).returns @resource + end - it "should exist" do - Puppet::Parser::Functions.function("require").should == "function_require" - end + it "should exist" do + Puppet::Parser::Functions.function("require").should == "function_require" + end - it "should delegate to the 'include' puppet function" do - @scope.expects(:function_include).with("myclass") + it "should delegate to the 'include' puppet function" do + @scope.expects(:function_include).with("myclass") - @scope.function_require("myclass") - end + @scope.function_require("myclass") + end - it "should set the 'require' prarameter on the resource to a resource reference" do - @scope.stubs(:function_include) - @scope.function_require("myclass") + it "should set the 'require' prarameter on the resource to a resource reference" do + @scope.stubs(:function_include) + @scope.function_require("myclass") - @resource["require"].should be_instance_of(Array) - @resource["require"][0].should be_instance_of(Puppet::Resource) - end + @resource["require"].should be_instance_of(Array) + @resource["require"][0].should be_instance_of(Puppet::Resource) + end - it "should verify the 'include' function is loaded" do - Puppet::Parser::Functions.expects(:function).with(:include).returns(:function_include) - @scope.stubs(:function_include) - @scope.function_require("myclass") - end + it "should verify the 'include' function is loaded" do + Puppet::Parser::Functions.expects(:function).with(:include).returns(:function_include) + @scope.stubs(:function_include) + @scope.function_require("myclass") + end - it "should include the class but not add a dependency if used on a client not at least version 0.25" do - @resource.expects(:metaparam_compatibility_mode?).returns true - @scope.expects(:warning) - @resource.expects(:set_parameter).never - @scope.expects(:function_include) + it "should include the class but not add a dependency if used on a client not at least version 0.25" do + @resource.expects(:metaparam_compatibility_mode?).returns true + @scope.expects(:warning) + @resource.expects(:set_parameter).never + @scope.expects(:function_include) - @scope.function_require("myclass") - end + @scope.function_require("myclass") + end - it "should lookup the absolute class path" do - @scope.stubs(:function_include) + it "should lookup the absolute class path" do + @scope.stubs(:function_include) - @scope.expects(:find_hostclass).with("myclass").returns(@klass) - @klass.expects(:name).returns("myclass") + @scope.expects(:find_hostclass).with("myclass").returns(@klass) + @klass.expects(:name).returns("myclass") - @scope.function_require("myclass") - end + @scope.function_require("myclass") + end - it "should append the required class to the require parameter" do - @scope.stubs(:function_include) + it "should append the required class to the require parameter" do + @scope.stubs(:function_include) - one = Puppet::Resource.new(:file, "/one") - @resource[:require] = one - @scope.function_require("myclass") + one = Puppet::Resource.new(:file, "/one") + @resource[:require] = one + @scope.function_require("myclass") - @resource[:require].should be_include(one) - @resource[:require].detect { |r| r.to_s == "Class[Myclass]" }.should be_instance_of(Puppet::Resource) - end + @resource[:require].should be_include(one) + @resource[:require].detect { |r| r.to_s == "Class[Myclass]" }.should be_instance_of(Puppet::Resource) + end end diff --git a/spec/unit/parser/functions/shellquote_spec.rb b/spec/unit/parser/functions/shellquote_spec.rb index e4eeaeba8..46b9f8d10 100755 --- a/spec/unit/parser/functions/shellquote_spec.rb +++ b/spec/unit/parser/functions/shellquote_spec.rb @@ -4,78 +4,78 @@ require File.dirname(__FILE__) + '/../../../spec_helper' describe "the shellquote function" do - before :each do - @scope = Puppet::Parser::Scope.new - end - - it "should exist" do - Puppet::Parser::Functions.function("shellquote").should == "function_shellquote" - end - - - it "should handle no arguments" do - result = @scope.function_shellquote([]) - result.should(eql("")) - end - - it "should handle several simple arguments" do - result = @scope.function_shellquote( ['foo', 'bar@example.com', 'localhost:/dev/null', 'xyzzy+-4711,23']) - result.should(eql( 'foo bar@example.com localhost:/dev/null xyzzy+-4711,23')) - end - - it "should handle array arguments" do - - result = @scope.function_shellquote( - - ['foo', ['bar@example.com', 'localhost:/dev/null'], - - 'xyzzy+-4711,23']) - result.should(eql( - 'foo bar@example.com localhost:/dev/null xyzzy+-4711,23')) - end - - it "should quote unsafe characters" do - result = @scope.function_shellquote( ['/etc/passwd ', '(ls)', '*', '[?]', "'&'"]) - result.should(eql( '"/etc/passwd " "(ls)" "*" "[?]" "\'&\'"')) - end - - it "should deal with double quotes" do - result = @scope.function_shellquote( - ['"foo"bar"']) - result.should(eql( - '\'"foo"bar"\'')) - end - - it "should cope with dollar signs" do - result = @scope.function_shellquote( ['$PATH', 'foo$bar', '"x$"']) - result.should(eql( "'$PATH' 'foo$bar' '\"x$\"'")) - end - - it "should deal with apostrophes (single quotes)" do - result = @scope.function_shellquote( - ["'foo'bar'", "`$'EDITOR'`"]) - result.should(eql( - '"\'foo\'bar\'" "\\`\\$\'EDITOR\'\\`"')) - end - - it "should cope with grave accents (backquotes)" do - result = @scope.function_shellquote( ['`echo *`', '`ls "$MAILPATH"`']) - result.should(eql( "'`echo *`' '`ls \"$MAILPATH\"`'")) - end - - it "should deal with both single and double quotes" do - result = @scope.function_shellquote( ['\'foo"bar"xyzzy\'', '"foo\'bar\'xyzzy"']) - result.should(eql( '"\'foo\\"bar\\"xyzzy\'" "\\"foo\'bar\'xyzzy\\""')) - end - - it "should handle multiple quotes *and* dollars and backquotes" do - result = @scope.function_shellquote( ['\'foo"$x`bar`"xyzzy\'']) - result.should(eql( '"\'foo\\"\\$x\\`bar\\`\\"xyzzy\'"')) - end - - it "should handle linefeeds" do - result = @scope.function_shellquote( ["foo \n bar"]) - result.should(eql( "\"foo \n bar\"")) - end + before :each do + @scope = Puppet::Parser::Scope.new + end + + it "should exist" do + Puppet::Parser::Functions.function("shellquote").should == "function_shellquote" + end + + + it "should handle no arguments" do + result = @scope.function_shellquote([]) + result.should(eql("")) + end + + it "should handle several simple arguments" do + result = @scope.function_shellquote( ['foo', 'bar@example.com', 'localhost:/dev/null', 'xyzzy+-4711,23']) + result.should(eql( 'foo bar@example.com localhost:/dev/null xyzzy+-4711,23')) + end + + it "should handle array arguments" do + + result = @scope.function_shellquote( + + ['foo', ['bar@example.com', 'localhost:/dev/null'], + + 'xyzzy+-4711,23']) + result.should(eql( + 'foo bar@example.com localhost:/dev/null xyzzy+-4711,23')) + end + + it "should quote unsafe characters" do + result = @scope.function_shellquote( ['/etc/passwd ', '(ls)', '*', '[?]', "'&'"]) + result.should(eql( '"/etc/passwd " "(ls)" "*" "[?]" "\'&\'"')) + end + + it "should deal with double quotes" do + result = @scope.function_shellquote( + ['"foo"bar"']) + result.should(eql( + '\'"foo"bar"\'')) + end + + it "should cope with dollar signs" do + result = @scope.function_shellquote( ['$PATH', 'foo$bar', '"x$"']) + result.should(eql( "'$PATH' 'foo$bar' '\"x$\"'")) + end + + it "should deal with apostrophes (single quotes)" do + result = @scope.function_shellquote( + ["'foo'bar'", "`$'EDITOR'`"]) + result.should(eql( + '"\'foo\'bar\'" "\\`\\$\'EDITOR\'\\`"')) + end + + it "should cope with grave accents (backquotes)" do + result = @scope.function_shellquote( ['`echo *`', '`ls "$MAILPATH"`']) + result.should(eql( "'`echo *`' '`ls \"$MAILPATH\"`'")) + end + + it "should deal with both single and double quotes" do + result = @scope.function_shellquote( ['\'foo"bar"xyzzy\'', '"foo\'bar\'xyzzy"']) + result.should(eql( '"\'foo\\"bar\\"xyzzy\'" "\\"foo\'bar\'xyzzy\\""')) + end + + it "should handle multiple quotes *and* dollars and backquotes" do + result = @scope.function_shellquote( ['\'foo"$x`bar`"xyzzy\'']) + result.should(eql( '"\'foo\\"\\$x\\`bar\\`\\"xyzzy\'"')) + end + + it "should handle linefeeds" do + result = @scope.function_shellquote( ["foo \n bar"]) + result.should(eql( "\"foo \n bar\"")) + end end diff --git a/spec/unit/parser/functions/split_spec.rb b/spec/unit/parser/functions/split_spec.rb index d76c253b0..a1c83bb0f 100755 --- a/spec/unit/parser/functions/split_spec.rb +++ b/spec/unit/parser/functions/split_spec.rb @@ -4,46 +4,46 @@ require File.dirname(__FILE__) + '/../../../spec_helper' describe "the split function" do - before :each do - @scope = Puppet::Parser::Scope.new - end - - it "should exist" do - Puppet::Parser::Functions.function("split").should == "function_split" - end - - it "should raise a ParseError if there is less than 2 arguments" do - lambda { @scope.function_split(["foo"]) }.should( raise_error(Puppet::ParseError)) - end - - it "should raise a ParseError if there is more than 2 arguments" do - lambda { @scope.function_split(["foo", "bar", "gazonk"]) }.should( raise_error(Puppet::ParseError)) - end - - it "should raise a RegexpError if the regexp is malformed" do - lambda { @scope.function_split(["foo", "("]) }.should( - raise_error(RegexpError)) - end - - - it "should handle simple string without metacharacters" do - result = @scope.function_split([ "130;236;254;10", ";"]) - result.should(eql(["130", "236", "254", "10"])) - end - - it "should handle simple regexps" do - result = @scope.function_split([ "130.236;254.;10", "[.;]+"]) - result.should(eql(["130", "236", "254", "10"])) - end - - it "should handle groups" do - result = @scope.function_split([ "130.236;254.;10", "([.;]+)"]) - result.should(eql(["130", ".", "236", ";", "254", ".;", "10"])) - end - - it "should handle simple string without metacharacters" do - result = @scope.function_split([ "130.236.254.10", ";"]) - result.should(eql(["130.236.254.10"])) - end + before :each do + @scope = Puppet::Parser::Scope.new + end + + it "should exist" do + Puppet::Parser::Functions.function("split").should == "function_split" + end + + it "should raise a ParseError if there is less than 2 arguments" do + lambda { @scope.function_split(["foo"]) }.should( raise_error(Puppet::ParseError)) + end + + it "should raise a ParseError if there is more than 2 arguments" do + lambda { @scope.function_split(["foo", "bar", "gazonk"]) }.should( raise_error(Puppet::ParseError)) + end + + it "should raise a RegexpError if the regexp is malformed" do + lambda { @scope.function_split(["foo", "("]) }.should( + raise_error(RegexpError)) + end + + + it "should handle simple string without metacharacters" do + result = @scope.function_split([ "130;236;254;10", ";"]) + result.should(eql(["130", "236", "254", "10"])) + end + + it "should handle simple regexps" do + result = @scope.function_split([ "130.236;254.;10", "[.;]+"]) + result.should(eql(["130", "236", "254", "10"])) + end + + it "should handle groups" do + result = @scope.function_split([ "130.236;254.;10", "([.;]+)"]) + result.should(eql(["130", ".", "236", ";", "254", ".;", "10"])) + end + + it "should handle simple string without metacharacters" do + result = @scope.function_split([ "130.236.254.10", ";"]) + result.should(eql(["130.236.254.10"])) + end end diff --git a/spec/unit/parser/functions/sprintf_spec.rb b/spec/unit/parser/functions/sprintf_spec.rb index 3795479e4..01545a879 100755 --- a/spec/unit/parser/functions/sprintf_spec.rb +++ b/spec/unit/parser/functions/sprintf_spec.rb @@ -4,38 +4,38 @@ require File.dirname(__FILE__) + '/../../../spec_helper' describe "the sprintf function" do - before :each do - @scope = Puppet::Parser::Scope.new - end - - it "should exist" do - Puppet::Parser::Functions.function("sprintf").should == "function_sprintf" - end - - it "should raise a ParseError if there is less than 1 argument" do - lambda { @scope.function_sprintf([]) }.should( raise_error(Puppet::ParseError)) - end - - it "should format integers" do - result = @scope.function_sprintf(["%+05d", "23"]) - result.should(eql("+0023")) - end - - it "should format floats" do - result = @scope.function_sprintf(["%+.2f", "2.7182818284590451"]) - result.should(eql("+2.72")) - end - - it "should format large floats" do - result = @scope.function_sprintf(["%+.2e", "27182818284590451"]) - result.should(eql("+2.72e+16")) - end - - it "should perform more complex formatting" do - result = @scope.function_sprintf( - [ "<%.8s:%#5o %#8X (%-8s)>", - "overlongstring", "23", "48879", "foo" ]) - result.should(eql("<overlong: 027 0XBEEF (foo )>")) - end + before :each do + @scope = Puppet::Parser::Scope.new + end + + it "should exist" do + Puppet::Parser::Functions.function("sprintf").should == "function_sprintf" + end + + it "should raise a ParseError if there is less than 1 argument" do + lambda { @scope.function_sprintf([]) }.should( raise_error(Puppet::ParseError)) + end + + it "should format integers" do + result = @scope.function_sprintf(["%+05d", "23"]) + result.should(eql("+0023")) + end + + it "should format floats" do + result = @scope.function_sprintf(["%+.2f", "2.7182818284590451"]) + result.should(eql("+2.72")) + end + + it "should format large floats" do + result = @scope.function_sprintf(["%+.2e", "27182818284590451"]) + result.should(eql("+2.72e+16")) + end + + it "should perform more complex formatting" do + result = @scope.function_sprintf( + [ "<%.8s:%#5o %#8X (%-8s)>", + "overlongstring", "23", "48879", "foo" ]) + result.should(eql("<overlong: 027 0XBEEF (foo )>")) + end end diff --git a/spec/unit/parser/functions/tag_spec.rb b/spec/unit/parser/functions/tag_spec.rb index 4f08afedf..ff37badbb 100755 --- a/spec/unit/parser/functions/tag_spec.rb +++ b/spec/unit/parser/functions/tag_spec.rb @@ -4,21 +4,21 @@ require File.dirname(__FILE__) + '/../../../spec_helper' describe "the 'tag' function" do - before :each do - @scope = Puppet::Parser::Scope.new - end + before :each do + @scope = Puppet::Parser::Scope.new + end - it "should exist" do - Puppet::Parser::Functions.function(:tag).should == "function_tag" - 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 + 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"] + @scope.function_tag ["one", "two"] - resource.should be_tagged("one") - resource.should be_tagged("two") - end + resource.should be_tagged("one") + resource.should be_tagged("two") + end end diff --git a/spec/unit/parser/functions/template_spec.rb b/spec/unit/parser/functions/template_spec.rb index 87c7d5d24..096b0598e 100755 --- a/spec/unit/parser/functions/template_spec.rb +++ b/spec/unit/parser/functions/template_spec.rb @@ -4,59 +4,59 @@ require File.dirname(__FILE__) + '/../../../spec_helper' describe "the template function" do - before :each do - @scope = Puppet::Parser::Scope.new - end + before :each do + @scope = Puppet::Parser::Scope.new + end - it "should exist" do - Puppet::Parser::Functions.function("template").should == "function_template" - end + it "should exist" do + Puppet::Parser::Functions.function("template").should == "function_template" + end - it "should create a TemplateWrapper when called" do - tw = stub_everything 'template_wrapper' + it "should create a TemplateWrapper when called" do + tw = stub_everything 'template_wrapper' - Puppet::Parser::TemplateWrapper.expects(:new).returns(tw) + Puppet::Parser::TemplateWrapper.expects(:new).returns(tw) - @scope.function_template("test") - end + @scope.function_template("test") + end - it "should give the template filename to the TemplateWrapper" do - tw = stub_everything 'template_wrapper' - Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw) + it "should give the template filename to the TemplateWrapper" do + tw = stub_everything 'template_wrapper' + Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw) - tw.expects(:file=).with("test") + tw.expects(:file=).with("test") - @scope.function_template("test") - end + @scope.function_template("test") + end - it "should return what TemplateWrapper.result returns" do - tw = stub_everything 'template_wrapper' - Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw) - tw.stubs(:file=).with("test") + it "should return what TemplateWrapper.result returns" do + tw = stub_everything 'template_wrapper' + Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw) + tw.stubs(:file=).with("test") - tw.expects(:result).returns("template contents evaluated") + tw.expects(:result).returns("template contents evaluated") - @scope.function_template("test").should == "template contents evaluated" - end + @scope.function_template("test").should == "template contents evaluated" + end - it "should concatenate template wrapper outputs for multiple templates" do - tw1 = stub_everything "template_wrapper1" - tw2 = stub_everything "template_wrapper2" - Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw1,tw2) - tw1.stubs(:file=).with("1") - tw2.stubs(:file=).with("2") - tw1.stubs(:result).returns("result1") - tw2.stubs(:result).returns("result2") + it "should concatenate template wrapper outputs for multiple templates" do + tw1 = stub_everything "template_wrapper1" + tw2 = stub_everything "template_wrapper2" + Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw1,tw2) + tw1.stubs(:file=).with("1") + tw2.stubs(:file=).with("2") + tw1.stubs(:result).returns("result1") + tw2.stubs(:result).returns("result2") - @scope.function_template(["1","2"]).should == "result1result2" - end + @scope.function_template(["1","2"]).should == "result1result2" + end - it "should raise an error if the template raises an error" do - tw = stub_everything 'template_wrapper' - Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw) - tw.stubs(:result).raises + it "should raise an error if the template raises an error" do + tw = stub_everything 'template_wrapper' + Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw) + tw.stubs(:result).raises - lambda { @scope.function_template("1") }.should raise_error(Puppet::ParseError) - end + lambda { @scope.function_template("1") }.should raise_error(Puppet::ParseError) + end end
\ No newline at end of file diff --git a/spec/unit/parser/functions/versioncmp_spec.rb b/spec/unit/parser/functions/versioncmp_spec.rb index d57ea57ad..380c6307a 100755 --- a/spec/unit/parser/functions/versioncmp_spec.rb +++ b/spec/unit/parser/functions/versioncmp_spec.rb @@ -4,26 +4,26 @@ require File.dirname(__FILE__) + '/../../../spec_helper' describe "the versioncmp function" do - before :each do - @scope = Puppet::Parser::Scope.new - end + before :each do + @scope = Puppet::Parser::Scope.new + end - it "should exist" do - Puppet::Parser::Functions.function("versioncmp").should == "function_versioncmp" - end + it "should exist" do + Puppet::Parser::Functions.function("versioncmp").should == "function_versioncmp" + end - it "should raise a ParseError if there is less than 2 arguments" do - lambda { @scope.function_versioncmp(["1.2"]) }.should raise_error(Puppet::ParseError) - end + it "should raise a ParseError if there is less than 2 arguments" do + lambda { @scope.function_versioncmp(["1.2"]) }.should raise_error(Puppet::ParseError) + end - it "should raise a ParseError if there is more than 2 arguments" do - lambda { @scope.function_versioncmp(["1.2", "2.4.5", "3.5.6"]) }.should raise_error(Puppet::ParseError) - end + it "should raise a ParseError if there is more than 2 arguments" do + lambda { @scope.function_versioncmp(["1.2", "2.4.5", "3.5.6"]) }.should raise_error(Puppet::ParseError) + end - it "should call Puppet::Util::Package.versioncmp (included in scope)" do - Puppet::Util::Package.expects(:versioncmp).with("1.2", "1.3").returns(-1) + it "should call Puppet::Util::Package.versioncmp (included in scope)" do + Puppet::Util::Package.expects(:versioncmp).with("1.2", "1.3").returns(-1) - @scope.function_versioncmp(["1.2", "1.3"]) - end + @scope.function_versioncmp(["1.2", "1.3"]) + end end diff --git a/spec/unit/parser/functions_spec.rb b/spec/unit/parser/functions_spec.rb index ee551a147..18aee4b65 100644 --- a/spec/unit/parser/functions_spec.rb +++ b/spec/unit/parser/functions_spec.rb @@ -4,99 +4,99 @@ require File.dirname(__FILE__) + '/../../spec_helper' describe Puppet::Parser::Functions do - after(:each) do - # Rationale: - # our various tests will almost all register to Pupet::Parser::Functions - # a new function called "name". All tests are required to stub Puppet::Parser::Scope - # so that +no+ new real ruby method are defined. - # After each test, we want to leave the whole Puppet::Parser::Functions environment - # as it was before we were called, hence we call rmfunction (which might not succeed - # if the function hasn't been registered in the test). It is also important in this - # section to stub +remove_method+ here so that we don't pollute the scope. - Puppet::Parser::Scope.stubs(:remove_method) - begin - Puppet::Parser::Functions.rmfunction("name") - rescue - end + after(:each) do + # Rationale: + # our various tests will almost all register to Pupet::Parser::Functions + # a new function called "name". All tests are required to stub Puppet::Parser::Scope + # so that +no+ new real ruby method are defined. + # After each test, we want to leave the whole Puppet::Parser::Functions environment + # as it was before we were called, hence we call rmfunction (which might not succeed + # if the function hasn't been registered in the test). It is also important in this + # section to stub +remove_method+ here so that we don't pollute the scope. + Puppet::Parser::Scope.stubs(:remove_method) + begin + Puppet::Parser::Functions.rmfunction("name") + rescue end + end - it "should have a method for returning an environment-specific module" do - Puppet::Parser::Functions.environment_module("myenv").should be_instance_of(Module) - end + it "should have a method for returning an environment-specific module" do + Puppet::Parser::Functions.environment_module("myenv").should be_instance_of(Module) + end - it "should use the current default environment if no environment is provided" do - Puppet::Parser::Functions.environment_module.should be_instance_of(Module) - end + it "should use the current default environment if no environment is provided" do + Puppet::Parser::Functions.environment_module.should be_instance_of(Module) + end - describe "when calling newfunction" do - before do - @module = Module.new - Puppet::Parser::Functions.stubs(:environment_module).returns @module - end + describe "when calling newfunction" do + before do + @module = Module.new + Puppet::Parser::Functions.stubs(:environment_module).returns @module + end - it "should create the function in the environment module" do - @module.expects(:define_method).with { |name,block| name == "function_name" } + it "should create the function in the environment module" do + @module.expects(:define_method).with { |name,block| name == "function_name" } - Puppet::Parser::Functions.newfunction("name", :type => :rvalue) - end + Puppet::Parser::Functions.newfunction("name", :type => :rvalue) + end - it "should raise an error if the function already exists" do - @module.expects(:define_method).with { |name,block| name == "function_name" }.once - Puppet::Parser::Functions.newfunction("name", :type => :rvalue) + it "should raise an error if the function already exists" do + @module.expects(:define_method).with { |name,block| name == "function_name" }.once + Puppet::Parser::Functions.newfunction("name", :type => :rvalue) - lambda { Puppet::Parser::Functions.newfunction("name", :type => :rvalue) }.should raise_error - end + lambda { Puppet::Parser::Functions.newfunction("name", :type => :rvalue) }.should raise_error + end - it "should raise an error if the function type is not correct" do - @module.expects(:define_method).with { |name,block| name == "function_name" }.never + it "should raise an error if the function type is not correct" do + @module.expects(:define_method).with { |name,block| name == "function_name" }.never - lambda { Puppet::Parser::Functions.newfunction("name", :type => :unknown) }.should raise_error - end + lambda { Puppet::Parser::Functions.newfunction("name", :type => :unknown) }.should raise_error end + end - describe "when calling rmfunction" do - before do - @module = Module.new - Puppet::Parser::Functions.stubs(:environment_module).returns @module - end + describe "when calling rmfunction" do + before do + @module = Module.new + Puppet::Parser::Functions.stubs(:environment_module).returns @module + end - it "should remove the function in the scope class" do - @module.expects(:define_method).with { |name,block| name == "function_name" } - Puppet::Parser::Functions.newfunction("name", :type => :rvalue) + it "should remove the function in the scope class" do + @module.expects(:define_method).with { |name,block| name == "function_name" } + Puppet::Parser::Functions.newfunction("name", :type => :rvalue) - @module.expects(:remove_method).with("function_name").once + @module.expects(:remove_method).with("function_name").once - Puppet::Parser::Functions.rmfunction("name") - end + Puppet::Parser::Functions.rmfunction("name") + end - it "should raise an error if the function doesn't exists" do - lambda { Puppet::Parser::Functions.rmfunction("name") }.should raise_error - end + it "should raise an error if the function doesn't exists" do + lambda { Puppet::Parser::Functions.rmfunction("name") }.should raise_error end + end - describe "when calling function to test function existance" do - before do - @module = Module.new - Puppet::Parser::Functions.stubs(:environment_module).returns @module - end + describe "when calling function to test function existance" do + before do + @module = Module.new + Puppet::Parser::Functions.stubs(:environment_module).returns @module + end - it "should return false if the function doesn't exist" do - Puppet::Parser::Functions.autoloader.stubs(:load) + it "should return false if the function doesn't exist" do + Puppet::Parser::Functions.autoloader.stubs(:load) - Puppet::Parser::Functions.function("name").should be_false - end + Puppet::Parser::Functions.function("name").should be_false + end - it "should return its name if the function exists" do - @module.expects(:define_method).with { |name,block| name == "function_name" } - Puppet::Parser::Functions.newfunction("name", :type => :rvalue) + it "should return its name if the function exists" do + @module.expects(:define_method).with { |name,block| name == "function_name" } + Puppet::Parser::Functions.newfunction("name", :type => :rvalue) - Puppet::Parser::Functions.function("name").should == "function_name" - end + Puppet::Parser::Functions.function("name").should == "function_name" + end - it "should try to autoload the function if it doesn't exist yet" do - Puppet::Parser::Functions.autoloader.expects(:load) + it "should try to autoload the function if it doesn't exist yet" do + Puppet::Parser::Functions.autoloader.expects(:load) - Puppet::Parser::Functions.function("name") - end + Puppet::Parser::Functions.function("name") end + end end diff --git a/spec/unit/parser/lexer_spec.rb b/spec/unit/parser/lexer_spec.rb index c31b1b275..81e76a388 100755 --- a/spec/unit/parser/lexer_spec.rb +++ b/spec/unit/parser/lexer_spec.rb @@ -6,635 +6,635 @@ require 'puppet/parser/lexer' # This is a special matcher to match easily lexer output Spec::Matchers.define :be_like do |*expected| - match do |actual| - expected.zip(actual).all? { |e,a| !e or a[0] == e or (e.is_a? Array and a[0] == e[0] and (a[1] == e[1] or (a[1].is_a?(Hash) and a[1][:value] == e[1]))) } - end + match do |actual| + expected.zip(actual).all? { |e,a| !e or a[0] == e or (e.is_a? Array and a[0] == e[0] and (a[1] == e[1] or (a[1].is_a?(Hash) and a[1][:value] == e[1]))) } + end end __ = nil describe Puppet::Parser::Lexer do - describe "when reading strings" do - before { @lexer = Puppet::Parser::Lexer.new } - it "should increment the line count for every carriage return in the string" do - @lexer.line = 10 - @lexer.string = "this\nis\natest'" - @lexer.slurpstring("'") - - @lexer.line.should == 12 - end - - it "should not increment the line count for escapes in the string" do - @lexer.line = 10 - @lexer.string = "this\\nis\\natest'" - @lexer.slurpstring("'") - - @lexer.line.should == 10 - end - end -end + describe "when reading strings" do + before { @lexer = Puppet::Parser::Lexer.new } + it "should increment the line count for every carriage return in the string" do + @lexer.line = 10 + @lexer.string = "this\nis\natest'" + @lexer.slurpstring("'") -describe Puppet::Parser::Lexer::Token do - before do - @token = Puppet::Parser::Lexer::Token.new(%r{something}, :NAME) + @lexer.line.should == 12 end - [:regex, :name, :string, :skip, :incr_line, :skip_text, :accumulate].each do |param| - it "should have a #{param.to_s} reader" do - @token.should be_respond_to(param) - end + it "should not increment the line count for escapes in the string" do + @lexer.line = 10 + @lexer.string = "this\\nis\\natest'" + @lexer.slurpstring("'") - it "should have a #{param.to_s} writer" do - @token.should be_respond_to(param.to_s + "=") - end + @lexer.line.should == 10 end + end end -describe Puppet::Parser::Lexer::Token, "when initializing" do - it "should create a regex if the first argument is a string" do - Puppet::Parser::Lexer::Token.new("something", :NAME).regex.should == %r{something} - end +describe Puppet::Parser::Lexer::Token do + before do + @token = Puppet::Parser::Lexer::Token.new(%r{something}, :NAME) + end - it "should set the string if the first argument is one" do - Puppet::Parser::Lexer::Token.new("something", :NAME).string.should == "something" + [:regex, :name, :string, :skip, :incr_line, :skip_text, :accumulate].each do |param| + it "should have a #{param.to_s} reader" do + @token.should be_respond_to(param) end - it "should set the regex if the first argument is one" do - Puppet::Parser::Lexer::Token.new(%r{something}, :NAME).regex.should == %r{something} + it "should have a #{param.to_s} writer" do + @token.should be_respond_to(param.to_s + "=") end + end end -describe Puppet::Parser::Lexer::TokenList do - before do - @list = Puppet::Parser::Lexer::TokenList.new - end - - it "should have a method for retrieving tokens by the name" do - token = @list.add_token :name, "whatever" - @list[:name].should equal(token) - end - - it "should have a method for retrieving string tokens by the string" do - token = @list.add_token :name, "whatever" - @list.lookup("whatever").should equal(token) - end - - it "should add tokens to the list when directed" do - token = @list.add_token :name, "whatever" - @list[:name].should equal(token) - end - - it "should have a method for adding multiple tokens at once" do - @list.add_tokens "whatever" => :name, "foo" => :bar - @list[:name].should_not be_nil - @list[:bar].should_not be_nil - end - - it "should fail to add tokens sharing a name with an existing token" do - @list.add_token :name, "whatever" - lambda { @list.add_token :name, "whatever" }.should raise_error(ArgumentError) - end - - it "should set provided options on tokens being added" do - token = @list.add_token :name, "whatever", :skip_text => true - token.skip_text.should == true - end - - it "should define any provided blocks as a :convert method" do - token = @list.add_token(:name, "whatever") do "foo" end - token.convert.should == "foo" - end - - it "should store all string tokens in the :string_tokens list" do - one = @list.add_token(:name, "1") - @list.string_tokens.should be_include(one) - end - - it "should store all regex tokens in the :regex_tokens list" do - one = @list.add_token(:name, %r{one}) - @list.regex_tokens.should be_include(one) - end +describe Puppet::Parser::Lexer::Token, "when initializing" do + it "should create a regex if the first argument is a string" do + Puppet::Parser::Lexer::Token.new("something", :NAME).regex.should == %r{something} + end - it "should not store string tokens in the :regex_tokens list" do - one = @list.add_token(:name, "1") - @list.regex_tokens.should_not be_include(one) - end + it "should set the string if the first argument is one" do + Puppet::Parser::Lexer::Token.new("something", :NAME).string.should == "something" + end - it "should not store regex tokens in the :string_tokens list" do - one = @list.add_token(:name, %r{one}) - @list.string_tokens.should_not be_include(one) - end + it "should set the regex if the first argument is one" do + Puppet::Parser::Lexer::Token.new(%r{something}, :NAME).regex.should == %r{something} + end +end - it "should sort the string tokens inversely by length when asked" do - one = @list.add_token(:name, "1") - two = @list.add_token(:other, "12") - @list.sort_tokens - @list.string_tokens.should == [two, one] - end +describe Puppet::Parser::Lexer::TokenList do + before do + @list = Puppet::Parser::Lexer::TokenList.new + end + + it "should have a method for retrieving tokens by the name" do + token = @list.add_token :name, "whatever" + @list[:name].should equal(token) + end + + it "should have a method for retrieving string tokens by the string" do + token = @list.add_token :name, "whatever" + @list.lookup("whatever").should equal(token) + end + + it "should add tokens to the list when directed" do + token = @list.add_token :name, "whatever" + @list[:name].should equal(token) + end + + it "should have a method for adding multiple tokens at once" do + @list.add_tokens "whatever" => :name, "foo" => :bar + @list[:name].should_not be_nil + @list[:bar].should_not be_nil + end + + it "should fail to add tokens sharing a name with an existing token" do + @list.add_token :name, "whatever" + lambda { @list.add_token :name, "whatever" }.should raise_error(ArgumentError) + end + + it "should set provided options on tokens being added" do + token = @list.add_token :name, "whatever", :skip_text => true + token.skip_text.should == true + end + + it "should define any provided blocks as a :convert method" do + token = @list.add_token(:name, "whatever") do "foo" end + token.convert.should == "foo" + end + + it "should store all string tokens in the :string_tokens list" do + one = @list.add_token(:name, "1") + @list.string_tokens.should be_include(one) + end + + it "should store all regex tokens in the :regex_tokens list" do + one = @list.add_token(:name, %r{one}) + @list.regex_tokens.should be_include(one) + end + + it "should not store string tokens in the :regex_tokens list" do + one = @list.add_token(:name, "1") + @list.regex_tokens.should_not be_include(one) + end + + it "should not store regex tokens in the :string_tokens list" do + one = @list.add_token(:name, %r{one}) + @list.string_tokens.should_not be_include(one) + end + + it "should sort the string tokens inversely by length when asked" do + one = @list.add_token(:name, "1") + two = @list.add_token(:other, "12") + @list.sort_tokens + @list.string_tokens.should == [two, one] + end end describe Puppet::Parser::Lexer::TOKENS do - before do - @lexer = Puppet::Parser::Lexer.new - end - - { - :LBRACK => '[', - :RBRACK => ']', - :LBRACE => '{', - :RBRACE => '}', - :LPAREN => '(', - :RPAREN => ')', - :EQUALS => '=', - :ISEQUAL => '==', - :GREATEREQUAL => '>=', - :GREATERTHAN => '>', - :LESSTHAN => '<', - :LESSEQUAL => '<=', - :NOTEQUAL => '!=', - :NOT => '!', - :COMMA => ',', - :DOT => '.', - :COLON => ':', - :AT => '@', - :LLCOLLECT => '<<|', - :RRCOLLECT => '|>>', - :LCOLLECT => '<|', - :RCOLLECT => '|>', - :SEMIC => ';', - :QMARK => '?', - :BACKSLASH => '\\', - :FARROW => '=>', - :PARROW => '+>', - :APPENDS => '+=', - :PLUS => '+', - :MINUS => '-', - :DIV => '/', - :TIMES => '*', - :LSHIFT => '<<', - :RSHIFT => '>>', - :MATCH => '=~', - :NOMATCH => '!~', - :IN_EDGE => '->', - :OUT_EDGE => '<-', - :IN_EDGE_SUB => '~>', - :OUT_EDGE_SUB => '<~', - }.each do |name, string| - it "should have a token named #{name.to_s}" do - Puppet::Parser::Lexer::TOKENS[name].should_not be_nil - end - - it "should match '#{string}' for the token #{name.to_s}" do - Puppet::Parser::Lexer::TOKENS[name].string.should == string - end - end - - { - "case" => :CASE, - "class" => :CLASS, - "default" => :DEFAULT, - "define" => :DEFINE, - "import" => :IMPORT, - "if" => :IF, - "elsif" => :ELSIF, - "else" => :ELSE, - "inherits" => :INHERITS, - "node" => :NODE, - "and" => :AND, - "or" => :OR, - "undef" => :UNDEF, - "false" => :FALSE, - "true" => :TRUE, - "in" => :IN, - }.each do |string, name| - it "should have a keyword named #{name.to_s}" do - Puppet::Parser::Lexer::KEYWORDS[name].should_not be_nil - end - - it "should have the keyword for #{name.to_s} set to #{string}" do - Puppet::Parser::Lexer::KEYWORDS[name].string.should == string - end - end - - # These tokens' strings don't matter, just that the tokens exist. - [:STRING, :DQPRE, :DQMID, :DQPOST, :BOOLEAN, :NAME, :NUMBER, :COMMENT, :MLCOMMENT, :RETURN, :SQUOTE, :DQUOTE, :VARIABLE].each do |name| - it "should have a token named #{name.to_s}" do - Puppet::Parser::Lexer::TOKENS[name].should_not be_nil - end - end + before do + @lexer = Puppet::Parser::Lexer.new + end + + { + :LBRACK => '[', + :RBRACK => ']', + :LBRACE => '{', + :RBRACE => '}', + :LPAREN => '(', + :RPAREN => ')', + :EQUALS => '=', + :ISEQUAL => '==', + :GREATEREQUAL => '>=', + :GREATERTHAN => '>', + :LESSTHAN => '<', + :LESSEQUAL => '<=', + :NOTEQUAL => '!=', + :NOT => '!', + :COMMA => ',', + :DOT => '.', + :COLON => ':', + :AT => '@', + :LLCOLLECT => '<<|', + :RRCOLLECT => '|>>', + :LCOLLECT => '<|', + :RCOLLECT => '|>', + :SEMIC => ';', + :QMARK => '?', + :BACKSLASH => '\\', + :FARROW => '=>', + :PARROW => '+>', + :APPENDS => '+=', + :PLUS => '+', + :MINUS => '-', + :DIV => '/', + :TIMES => '*', + :LSHIFT => '<<', + :RSHIFT => '>>', + :MATCH => '=~', + :NOMATCH => '!~', + :IN_EDGE => '->', + :OUT_EDGE => '<-', + :IN_EDGE_SUB => '~>', + :OUT_EDGE_SUB => '<~', + }.each do |name, string| + it "should have a token named #{name.to_s}" do + Puppet::Parser::Lexer::TOKENS[name].should_not be_nil + end + + it "should match '#{string}' for the token #{name.to_s}" do + Puppet::Parser::Lexer::TOKENS[name].string.should == string + end + end + + { + "case" => :CASE, + "class" => :CLASS, + "default" => :DEFAULT, + "define" => :DEFINE, + "import" => :IMPORT, + "if" => :IF, + "elsif" => :ELSIF, + "else" => :ELSE, + "inherits" => :INHERITS, + "node" => :NODE, + "and" => :AND, + "or" => :OR, + "undef" => :UNDEF, + "false" => :FALSE, + "true" => :TRUE, + "in" => :IN, + }.each do |string, name| + it "should have a keyword named #{name.to_s}" do + Puppet::Parser::Lexer::KEYWORDS[name].should_not be_nil + end + + it "should have the keyword for #{name.to_s} set to #{string}" do + Puppet::Parser::Lexer::KEYWORDS[name].string.should == string + end + end + + # These tokens' strings don't matter, just that the tokens exist. + [:STRING, :DQPRE, :DQMID, :DQPOST, :BOOLEAN, :NAME, :NUMBER, :COMMENT, :MLCOMMENT, :RETURN, :SQUOTE, :DQUOTE, :VARIABLE].each do |name| + it "should have a token named #{name.to_s}" do + Puppet::Parser::Lexer::TOKENS[name].should_not be_nil + end + end end describe Puppet::Parser::Lexer::TOKENS[:CLASSNAME] do - before { @token = Puppet::Parser::Lexer::TOKENS[:CLASSNAME] } + before { @token = Puppet::Parser::Lexer::TOKENS[:CLASSNAME] } - it "should match against lower-case alpha-numeric terms separated by double colons" do - @token.regex.should =~ "one::two" - end + it "should match against lower-case alpha-numeric terms separated by double colons" do + @token.regex.should =~ "one::two" + end - it "should match against many lower-case alpha-numeric terms separated by double colons" do - @token.regex.should =~ "one::two::three::four::five" - end + it "should match against many lower-case alpha-numeric terms separated by double colons" do + @token.regex.should =~ "one::two::three::four::five" + end - it "should match against lower-case alpha-numeric terms prefixed by double colons" do - @token.regex.should =~ "::one" - end + it "should match against lower-case alpha-numeric terms prefixed by double colons" do + @token.regex.should =~ "::one" + end end describe Puppet::Parser::Lexer::TOKENS[:CLASSREF] do - before { @token = Puppet::Parser::Lexer::TOKENS[:CLASSREF] } + before { @token = Puppet::Parser::Lexer::TOKENS[:CLASSREF] } - it "should match against single upper-case alpha-numeric terms" do - @token.regex.should =~ "One" - end + it "should match against single upper-case alpha-numeric terms" do + @token.regex.should =~ "One" + end - it "should match against upper-case alpha-numeric terms separated by double colons" do - @token.regex.should =~ "One::Two" - end + it "should match against upper-case alpha-numeric terms separated by double colons" do + @token.regex.should =~ "One::Two" + end - it "should match against many upper-case alpha-numeric terms separated by double colons" do - @token.regex.should =~ "One::Two::Three::Four::Five" - end + it "should match against many upper-case alpha-numeric terms separated by double colons" do + @token.regex.should =~ "One::Two::Three::Four::Five" + end - it "should match against upper-case alpha-numeric terms prefixed by double colons" do - @token.regex.should =~ "::One" - end + it "should match against upper-case alpha-numeric terms prefixed by double colons" do + @token.regex.should =~ "::One" + end end describe Puppet::Parser::Lexer::TOKENS[:NAME] do - before { @token = Puppet::Parser::Lexer::TOKENS[:NAME] } - - it "should match against lower-case alpha-numeric terms" do - @token.regex.should =~ "one-two" - end - - it "should return itself and the value if the matched term is not a keyword" do - Puppet::Parser::Lexer::KEYWORDS.expects(:lookup).returns(nil) - @token.convert(stub("lexer"), "myval").should == [Puppet::Parser::Lexer::TOKENS[:NAME], "myval"] - end - - it "should return the keyword token and the value if the matched term is a keyword" do - keyword = stub 'keyword', :name => :testing - Puppet::Parser::Lexer::KEYWORDS.expects(:lookup).returns(keyword) - @token.convert(stub("lexer"), "myval").should == [keyword, "myval"] - end - - it "should return the BOOLEAN token and 'true' if the matched term is the string 'true'" do - keyword = stub 'keyword', :name => :TRUE - Puppet::Parser::Lexer::KEYWORDS.expects(:lookup).returns(keyword) - @token.convert(stub('lexer'), "true").should == [Puppet::Parser::Lexer::TOKENS[:BOOLEAN], true] - end - - it "should return the BOOLEAN token and 'false' if the matched term is the string 'false'" do - keyword = stub 'keyword', :name => :FALSE - Puppet::Parser::Lexer::KEYWORDS.expects(:lookup).returns(keyword) - @token.convert(stub('lexer'), "false").should == [Puppet::Parser::Lexer::TOKENS[:BOOLEAN], false] - end + before { @token = Puppet::Parser::Lexer::TOKENS[:NAME] } + + it "should match against lower-case alpha-numeric terms" do + @token.regex.should =~ "one-two" + end + + it "should return itself and the value if the matched term is not a keyword" do + Puppet::Parser::Lexer::KEYWORDS.expects(:lookup).returns(nil) + @token.convert(stub("lexer"), "myval").should == [Puppet::Parser::Lexer::TOKENS[:NAME], "myval"] + end + + it "should return the keyword token and the value if the matched term is a keyword" do + keyword = stub 'keyword', :name => :testing + Puppet::Parser::Lexer::KEYWORDS.expects(:lookup).returns(keyword) + @token.convert(stub("lexer"), "myval").should == [keyword, "myval"] + end + + it "should return the BOOLEAN token and 'true' if the matched term is the string 'true'" do + keyword = stub 'keyword', :name => :TRUE + Puppet::Parser::Lexer::KEYWORDS.expects(:lookup).returns(keyword) + @token.convert(stub('lexer'), "true").should == [Puppet::Parser::Lexer::TOKENS[:BOOLEAN], true] + end + + it "should return the BOOLEAN token and 'false' if the matched term is the string 'false'" do + keyword = stub 'keyword', :name => :FALSE + Puppet::Parser::Lexer::KEYWORDS.expects(:lookup).returns(keyword) + @token.convert(stub('lexer'), "false").should == [Puppet::Parser::Lexer::TOKENS[:BOOLEAN], false] + end end describe Puppet::Parser::Lexer::TOKENS[:NUMBER] do - before do - @token = Puppet::Parser::Lexer::TOKENS[:NUMBER] - @regex = @token.regex - end - - it "should match against numeric terms" do - @regex.should =~ "2982383139" - end - - it "should match against float terms" do - @regex.should =~ "29823.235" - end - - it "should match against hexadecimal terms" do - @regex.should =~ "0xBEEF0023" - end - - it "should match against float with exponent terms" do - @regex.should =~ "10e23" - end - - it "should match against float terms with negative exponents" do - @regex.should =~ "10e-23" - end - - it "should match against float terms with fractional parts and exponent" do - @regex.should =~ "1.234e23" - end - - it "should return the NAME token and the value" do - @token.convert(stub("lexer"), "myval").should == [Puppet::Parser::Lexer::TOKENS[:NAME], "myval"] - end + before do + @token = Puppet::Parser::Lexer::TOKENS[:NUMBER] + @regex = @token.regex + end + + it "should match against numeric terms" do + @regex.should =~ "2982383139" + end + + it "should match against float terms" do + @regex.should =~ "29823.235" + end + + it "should match against hexadecimal terms" do + @regex.should =~ "0xBEEF0023" + end + + it "should match against float with exponent terms" do + @regex.should =~ "10e23" + end + + it "should match against float terms with negative exponents" do + @regex.should =~ "10e-23" + end + + it "should match against float terms with fractional parts and exponent" do + @regex.should =~ "1.234e23" + end + + it "should return the NAME token and the value" do + @token.convert(stub("lexer"), "myval").should == [Puppet::Parser::Lexer::TOKENS[:NAME], "myval"] + end end describe Puppet::Parser::Lexer::TOKENS[:COMMENT] do - before { @token = Puppet::Parser::Lexer::TOKENS[:COMMENT] } + before { @token = Puppet::Parser::Lexer::TOKENS[:COMMENT] } - it "should match against lines starting with '#'" do - @token.regex.should =~ "# this is a comment" - end + it "should match against lines starting with '#'" do + @token.regex.should =~ "# this is a comment" + end - it "should be marked to get skipped" do - @token.skip?.should be_true - end + it "should be marked to get skipped" do + @token.skip?.should be_true + end - it "should be marked to accumulate" do - @token.accumulate?.should be_true - end + it "should be marked to accumulate" do + @token.accumulate?.should be_true + end - it "'s block should return the comment without the #" do - @token.convert(@lexer,"# this is a comment")[1].should == "this is a comment" - end + it "'s block should return the comment without the #" do + @token.convert(@lexer,"# this is a comment")[1].should == "this is a comment" + end end describe Puppet::Parser::Lexer::TOKENS[:MLCOMMENT] do - before do - @token = Puppet::Parser::Lexer::TOKENS[:MLCOMMENT] - @lexer = stub 'lexer', :line => 0 - end + before do + @token = Puppet::Parser::Lexer::TOKENS[:MLCOMMENT] + @lexer = stub 'lexer', :line => 0 + end - it "should match against lines enclosed with '/*' and '*/'" do - @token.regex.should =~ "/* this is a comment */" - end + it "should match against lines enclosed with '/*' and '*/'" do + @token.regex.should =~ "/* this is a comment */" + end - it "should match multiple lines enclosed with '/*' and '*/'" do - @token.regex.should =~ """/* - this is a comment - */""" - end + it "should match multiple lines enclosed with '/*' and '*/'" do + @token.regex.should =~ """/* + this is a comment + */""" + end - it "should increase the lexer current line number by the amount of lines spanned by the comment" do - @lexer.expects(:line=).with(2) - @token.convert(@lexer, "1\n2\n3") - end + it "should increase the lexer current line number by the amount of lines spanned by the comment" do + @lexer.expects(:line=).with(2) + @token.convert(@lexer, "1\n2\n3") + end - it "should not greedily match comments" do - match = @token.regex.match("/* first */ word /* second */") - match[1].should == " first " - end + it "should not greedily match comments" do + match = @token.regex.match("/* first */ word /* second */") + match[1].should == " first " + end - it "should be marked to accumulate" do - @token.accumulate?.should be_true - end + it "should be marked to accumulate" do + @token.accumulate?.should be_true + end - it "'s block should return the comment without the comment marks" do - @lexer.stubs(:line=).with(0) + it "'s block should return the comment without the comment marks" do + @lexer.stubs(:line=).with(0) - @token.convert(@lexer,"/* this is a comment */")[1].should == "this is a comment" - end + @token.convert(@lexer,"/* this is a comment */")[1].should == "this is a comment" + end end describe Puppet::Parser::Lexer::TOKENS[:RETURN] do - before { @token = Puppet::Parser::Lexer::TOKENS[:RETURN] } + before { @token = Puppet::Parser::Lexer::TOKENS[:RETURN] } - it "should match against carriage returns" do - @token.regex.should =~ "\n" - end + it "should match against carriage returns" do + @token.regex.should =~ "\n" + end - it "should be marked to initiate text skipping" do - @token.skip_text.should be_true - end + it "should be marked to initiate text skipping" do + @token.skip_text.should be_true + end - it "should be marked to increment the line" do - @token.incr_line.should be_true - end + it "should be marked to increment the line" do + @token.incr_line.should be_true + end end def tokens_scanned_from(s) - lexer = Puppet::Parser::Lexer.new - lexer.string = s - lexer.fullscan[0..-2] + lexer = Puppet::Parser::Lexer.new + lexer.string = s + lexer.fullscan[0..-2] end 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{"string with an escaped '\\"'"} => [[:STRING,"string with an escaped '\"'"]], - %q{"string with an escaped '\\$'"} => [[:STRING,"string with an escaped '$'"]], - %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']], - %q{"string with $v and $v (but no braces)"} => [[:DQPRE,"string with "],[:VARIABLE,"v"],[:DQMID," and "],[:VARIABLE,"v"],[:DQPOST," (but no braces)"]], - %q["string with ${v} and ${v} in braces"] => [[:DQPRE,"string with "],[:VARIABLE,"v"],[:DQMID," and "],[:VARIABLE,"v"],[:DQPOST," in braces"]], - %q["string with ${'a nested single quoted string'} inside it."] => [[:DQPRE,"string with "],[:STRING,'a nested single quoted string'],[:DQPOST,' inside it.']], - %q["string with ${['an array ',$v2]} in it."] => [[:DQPRE,"string with "],:LBRACK,[:STRING,"an array "],:COMMA,[:VARIABLE,"v2"],:RBRACK,[:DQPOST," in it."]], - %q{a simple "scanner" test} => [[:NAME,"a"],[:NAME,"simple"], [:STRING,"scanner"],[:NAME,"test"]], - %q{a simple 'single quote scanner' test} => [[:NAME,"a"],[:NAME,"simple"], [:STRING,"single quote scanner"],[:NAME,"test"]], - %q{a harder 'a $b \c"'} => [[:NAME,"a"],[:NAME,"harder"], [:STRING,'a $b \c"']], - %q{a harder "scanner test"} => [[:NAME,"a"],[:NAME,"harder"], [:STRING,"scanner test"]], - %q{a hardest "scanner \"test\""} => [[:NAME,"a"],[:NAME,"hardest"],[:STRING,'scanner "test"']], - %Q{a hardestest "scanner \\"test\\"\n"} => [[:NAME,"a"],[:NAME,"hardestest"],[:STRING,%Q{scanner "test"\n}]], - %q{function("call")} => [[:NAME,"function"],[:LPAREN,"("],[:STRING,'call'],[:RPAREN,")"]], - %q["string with ${(3+5)/4} nested math."] => [[:DQPRE,"string with "],:LPAREN,[:NAME,"3"],:PLUS,[:NAME,"5"],:RPAREN,:DIV,[:NAME,"4"],[:DQPOST," nested math."]] - }.each { |src,expected_result| - it "should handle #{src} correctly" do - tokens_scanned_from(src).should be_like(*expected_result) - end - } + { + %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{"string with an escaped '\\"'"} => [[:STRING,"string with an escaped '\"'"]], + %q{"string with an escaped '\\$'"} => [[:STRING,"string with an escaped '$'"]], + %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']], + %q{"string with $v and $v (but no braces)"} => [[:DQPRE,"string with "],[:VARIABLE,"v"],[:DQMID," and "],[:VARIABLE,"v"],[:DQPOST," (but no braces)"]], + %q["string with ${v} and ${v} in braces"] => [[:DQPRE,"string with "],[:VARIABLE,"v"],[:DQMID," and "],[:VARIABLE,"v"],[:DQPOST," in braces"]], + %q["string with ${'a nested single quoted string'} inside it."] => [[:DQPRE,"string with "],[:STRING,'a nested single quoted string'],[:DQPOST,' inside it.']], + %q["string with ${['an array ',$v2]} in it."] => [[:DQPRE,"string with "],:LBRACK,[:STRING,"an array "],:COMMA,[:VARIABLE,"v2"],:RBRACK,[:DQPOST," in it."]], + %q{a simple "scanner" test} => [[:NAME,"a"],[:NAME,"simple"], [:STRING,"scanner"],[:NAME,"test"]], + %q{a simple 'single quote scanner' test} => [[:NAME,"a"],[:NAME,"simple"], [:STRING,"single quote scanner"],[:NAME,"test"]], + %q{a harder 'a $b \c"'} => [[:NAME,"a"],[:NAME,"harder"], [:STRING,'a $b \c"']], + %q{a harder "scanner test"} => [[:NAME,"a"],[:NAME,"harder"], [:STRING,"scanner test"]], + %q{a hardest "scanner \"test\""} => [[:NAME,"a"],[:NAME,"hardest"],[:STRING,'scanner "test"']], + %Q{a hardestest "scanner \\"test\\"\n"} => [[:NAME,"a"],[:NAME,"hardestest"],[:STRING,%Q{scanner "test"\n}]], + %q{function("call")} => [[:NAME,"function"],[:LPAREN,"("],[:STRING,'call'],[:RPAREN,")"]], + %q["string with ${(3+5)/4} nested math."] => [[:DQPRE,"string with "],:LPAREN,[:NAME,"3"],:PLUS,[:NAME,"5"],:RPAREN,:DIV,[:NAME,"4"],[:DQPOST," nested math."]] + }.each { |src,expected_result| + it "should handle #{src} correctly" do + tokens_scanned_from(src).should be_like(*expected_result) + end + } end describe Puppet::Parser::Lexer::TOKENS[:DOLLAR_VAR] do - before { @token = Puppet::Parser::Lexer::TOKENS[:DOLLAR_VAR] } + before { @token = Puppet::Parser::Lexer::TOKENS[:DOLLAR_VAR] } - it "should match against alpha words prefixed with '$'" do - @token.regex.should =~ '$this_var' - end + it "should match against alpha words prefixed with '$'" do + @token.regex.should =~ '$this_var' + end - it "should return the VARIABLE token and the variable name stripped of the '$'" do - @token.convert(stub("lexer"), "$myval").should == [Puppet::Parser::Lexer::TOKENS[:VARIABLE], "myval"] - end + it "should return the VARIABLE token and the variable name stripped of the '$'" do + @token.convert(stub("lexer"), "$myval").should == [Puppet::Parser::Lexer::TOKENS[:VARIABLE], "myval"] + end end describe Puppet::Parser::Lexer::TOKENS[:REGEX] do - before { @token = Puppet::Parser::Lexer::TOKENS[:REGEX] } + before { @token = Puppet::Parser::Lexer::TOKENS[:REGEX] } - it "should match against any expression enclosed in //" do - @token.regex.should =~ '/this is a regex/' + it "should match against any expression enclosed in //" do + @token.regex.should =~ '/this is a regex/' + end + + it 'should not match if there is \n in the regex' do + @token.regex.should_not =~ "/this is \n a regex/" + end + + describe "when scanning" do + it "should not consider escaped slashes to be the end of a regex" do + tokens_scanned_from("$x =~ /this \\/ foo/").should be_like(__,__,[:REGEX,%r{this / foo}]) end - it 'should not match if there is \n in the regex' do - @token.regex.should_not =~ "/this is \n a regex/" + it "should not lex chained division as a regex" do + tokens_scanned_from("$x = $a/$b/$c").collect { |name, data| name }.should_not be_include( :REGEX ) end - describe "when scanning" do - it "should not consider escaped slashes to be the end of a regex" do - tokens_scanned_from("$x =~ /this \\/ foo/").should be_like(__,__,[:REGEX,%r{this / foo}]) - end - - it "should not lex chained division as a regex" do - tokens_scanned_from("$x = $a/$b/$c").collect { |name, data| name }.should_not be_include( :REGEX ) - end - - it "should accept a regular expression after NODE" do - tokens_scanned_from("node /www.*\.mysite\.org/").should be_like(__,[:REGEX,Regexp.new("www.*\.mysite\.org")]) - end - - it "should accept regular expressions in a CASE" do - s = %q{case $variable { - "something": {$othervar = 4096 / 2} - /regex/: {notice("this notably sucks")} - } - } - tokens_scanned_from(s).should be_like( - :CASE,:VARIABLE,:LBRACE,:STRING,:COLON,:LBRACE,:VARIABLE,:EQUALS,:NAME,:DIV,:NAME,:RBRACE,[:REGEX,/regex/],:COLON,:LBRACE,:NAME,:LPAREN,:STRING,:RPAREN,:RBRACE,:RBRACE - ) - end + it "should accept a regular expression after NODE" do + tokens_scanned_from("node /www.*\.mysite\.org/").should be_like(__,[:REGEX,Regexp.new("www.*\.mysite\.org")]) + end + it "should accept regular expressions in a CASE" do + s = %q{case $variable { + "something": {$othervar = 4096 / 2} + /regex/: {notice("this notably sucks")} + } + } + tokens_scanned_from(s).should be_like( + :CASE,:VARIABLE,:LBRACE,:STRING,:COLON,:LBRACE,:VARIABLE,:EQUALS,:NAME,:DIV,:NAME,:RBRACE,[:REGEX,/regex/],:COLON,:LBRACE,:NAME,:LPAREN,:STRING,:RPAREN,:RBRACE,:RBRACE + ) end + end - it "should return the REGEX token and a Regexp" do - @token.convert(stub("lexer"), "/myregex/").should == [Puppet::Parser::Lexer::TOKENS[:REGEX], Regexp.new(/myregex/)] - end + + it "should return the REGEX token and a Regexp" do + @token.convert(stub("lexer"), "/myregex/").should == [Puppet::Parser::Lexer::TOKENS[:REGEX], Regexp.new(/myregex/)] + end end describe Puppet::Parser::Lexer, "when lexing comments" do - before { @lexer = Puppet::Parser::Lexer.new } + before { @lexer = Puppet::Parser::Lexer.new } - it "should accumulate token in munge_token" do - token = stub 'token', :skip => true, :accumulate? => true, :incr_line => nil, :skip_text => false + it "should accumulate token in munge_token" do + token = stub 'token', :skip => true, :accumulate? => true, :incr_line => nil, :skip_text => false - token.stubs(:convert).with(@lexer, "# this is a comment").returns([token, " this is a comment"]) - @lexer.munge_token(token, "# this is a comment") - @lexer.munge_token(token, "# this is a comment") + token.stubs(:convert).with(@lexer, "# this is a comment").returns([token, " this is a comment"]) + @lexer.munge_token(token, "# this is a comment") + @lexer.munge_token(token, "# this is a comment") - @lexer.getcomment.should == " this is a comment\n this is a comment\n" - end + @lexer.getcomment.should == " this is a comment\n this is a comment\n" + end - it "should add a new comment stack level on LBRACE" do - @lexer.string = "{" + it "should add a new comment stack level on LBRACE" do + @lexer.string = "{" - @lexer.expects(:commentpush) + @lexer.expects(:commentpush) - @lexer.fullscan - end + @lexer.fullscan + end - it "should return the current comments on getcomment" do - @lexer.string = "# comment" - @lexer.fullscan + it "should return the current comments on getcomment" do + @lexer.string = "# comment" + @lexer.fullscan - @lexer.getcomment.should == "comment\n" - end + @lexer.getcomment.should == "comment\n" + end - it "should discard the previous comments on blank line" do - @lexer.string = "# 1\n\n# 2" - @lexer.fullscan + it "should discard the previous comments on blank line" do + @lexer.string = "# 1\n\n# 2" + @lexer.fullscan - @lexer.getcomment.should == "2\n" - end + @lexer.getcomment.should == "2\n" + end - it "should skip whitespace before lexing the next token after a non-token" do - tokens_scanned_from("/* 1\n\n */ \ntest").should be_like([:NAME, "test"]) - end + it "should skip whitespace before lexing the next token after a non-token" do + tokens_scanned_from("/* 1\n\n */ \ntest").should be_like([:NAME, "test"]) + end - it "should not return comments seen after the current line" do - @lexer.string = "# 1\n\n# 2" - @lexer.fullscan + it "should not return comments seen after the current line" do + @lexer.string = "# 1\n\n# 2" + @lexer.fullscan - @lexer.getcomment(1).should == "" - end + @lexer.getcomment(1).should == "" + end - it "should return a comment seen before the current line" do - @lexer.string = "# 1\n# 2" - @lexer.fullscan + it "should return a comment seen before the current line" do + @lexer.string = "# 1\n# 2" + @lexer.fullscan - @lexer.getcomment(2).should == "1\n2\n" - end + @lexer.getcomment(2).should == "1\n2\n" + end end # FIXME: We need to rewrite all of these tests, but I just don't want to take the time right now. describe "Puppet::Parser::Lexer in the old tests" do - before { @lexer = Puppet::Parser::Lexer.new } + before { @lexer = Puppet::Parser::Lexer.new } - it "should do simple lexing" do - { - %q{\\} => [[:BACKSLASH,"\\"]], - %q{simplest scanner test} => [[:NAME,"simplest"],[:NAME,"scanner"],[:NAME,"test"]], - %Q{returned scanner test\n} => [[:NAME,"returned"],[:NAME,"scanner"],[:NAME,"test"]] - }.each { |source,expected| - tokens_scanned_from(source).should be_like(*expected) - } - end + it "should do simple lexing" do + { + %q{\\} => [[:BACKSLASH,"\\"]], + %q{simplest scanner test} => [[:NAME,"simplest"],[:NAME,"scanner"],[:NAME,"test"]], + %Q{returned scanner test\n} => [[:NAME,"returned"],[:NAME,"scanner"],[:NAME,"test"]] + }.each { |source,expected| + tokens_scanned_from(source).should be_like(*expected) + } + end - it "should fail usefully" do - lambda { tokens_scanned_from('^') }.should raise_error(RuntimeError) - end + it "should fail usefully" do + lambda { tokens_scanned_from('^') }.should raise_error(RuntimeError) + end - it "should fail if the string is not set" do - lambda { @lexer.fullscan }.should raise_error(Puppet::LexError) - end + it "should fail if the string is not set" do + lambda { @lexer.fullscan }.should raise_error(Puppet::LexError) + end - it "should correctly identify keywords" do - tokens_scanned_from("case").should be_like([:CASE, "case"]) - end + it "should correctly identify keywords" do + tokens_scanned_from("case").should be_like([:CASE, "case"]) + end - it "should correctly parse class references" do - %w{Many Different Words A Word}.each { |t| tokens_scanned_from(t).should be_like([:CLASSREF,t])} - end + it "should correctly parse class references" do + %w{Many Different Words A Word}.each { |t| tokens_scanned_from(t).should be_like([:CLASSREF,t])} + end - # #774 - it "should correctly parse namespaced class refernces token" do - %w{Foo ::Foo Foo::Bar ::Foo::Bar}.each { |t| tokens_scanned_from(t).should be_like([:CLASSREF, t]) } - end + # #774 + it "should correctly parse namespaced class refernces token" do + %w{Foo ::Foo Foo::Bar ::Foo::Bar}.each { |t| tokens_scanned_from(t).should be_like([:CLASSREF, t]) } + end - it "should correctly parse names" do - %w{this is a bunch of names}.each { |t| tokens_scanned_from(t).should be_like([:NAME,t]) } - end + it "should correctly parse names" do + %w{this is a bunch of names}.each { |t| tokens_scanned_from(t).should be_like([:NAME,t]) } + end - it "should correctly parse names with numerals" do - %w{1name name1 11names names11}.each { |t| tokens_scanned_from(t).should be_like([:NAME,t]) } - end + it "should correctly parse names with numerals" do + %w{1name name1 11names names11}.each { |t| tokens_scanned_from(t).should be_like([:NAME,t]) } + end - it "should correctly parse empty strings" do - lambda { tokens_scanned_from('$var = ""') }.should_not raise_error - end + it "should correctly parse empty strings" do + lambda { tokens_scanned_from('$var = ""') }.should_not raise_error + end - it "should correctly parse virtual resources" do - tokens_scanned_from("@type {").should be_like([:AT, "@"], [:NAME, "type"], [:LBRACE, "{"]) - end + it "should correctly parse virtual resources" do + tokens_scanned_from("@type {").should be_like([:AT, "@"], [:NAME, "type"], [:LBRACE, "{"]) + end - it "should correctly deal with namespaces" do - @lexer.string = %{class myclass} - @lexer.fullscan - @lexer.namespace.should == "myclass" + it "should correctly deal with namespaces" do + @lexer.string = %{class myclass} + @lexer.fullscan + @lexer.namespace.should == "myclass" - @lexer.namepop - @lexer.namespace.should == "" + @lexer.namepop + @lexer.namespace.should == "" - @lexer.string = "class base { class sub { class more" - @lexer.fullscan - @lexer.namespace.should == "base::sub::more" + @lexer.string = "class base { class sub { class more" + @lexer.fullscan + @lexer.namespace.should == "base::sub::more" - @lexer.namepop - @lexer.namespace.should == "base::sub" - end + @lexer.namepop + @lexer.namespace.should == "base::sub" + end - it "should correctly handle fully qualified names" do - @lexer.string = "class base { class sub::more {" - @lexer.fullscan - @lexer.namespace.should == "base::sub::more" + it "should correctly handle fully qualified names" do + @lexer.string = "class base { class sub::more {" + @lexer.fullscan + @lexer.namespace.should == "base::sub::more" - @lexer.namepop - @lexer.namespace.should == "base" - end + @lexer.namepop + @lexer.namespace.should == "base" + end - it "should correctly lex variables" do - ["$variable", "$::variable", "$qualified::variable", "$further::qualified::variable"].each do |string| - tokens_scanned_from(string).should be_like([:VARIABLE,string.sub(/^\$/,'')]) - end + it "should correctly lex variables" do + ["$variable", "$::variable", "$qualified::variable", "$further::qualified::variable"].each do |string| + tokens_scanned_from(string).should be_like([:VARIABLE,string.sub(/^\$/,'')]) end + end 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 - lexer = Puppet::Parser::Lexer.new - lexer.file = file - lambda { lexer.fullscan }.should_not raise_error - end - end + extend PuppetTest + extend PuppetTest::Support::Utils + textfiles do |file| + it "should correctly lex #{file}" do + lexer = Puppet::Parser::Lexer.new + lexer.file = file + lambda { lexer.fullscan }.should_not raise_error + end + end end diff --git a/spec/unit/parser/parser_spec.rb b/spec/unit/parser/parser_spec.rb index 42d515d29..0657ab37a 100755 --- a/spec/unit/parser/parser_spec.rb +++ b/spec/unit/parser/parser_spec.rb @@ -4,409 +4,409 @@ require File.dirname(__FILE__) + '/../../spec_helper' describe Puppet::Parser do - ast = Puppet::Parser::AST - - before :each do - @known_resource_types = Puppet::Resource::TypeCollection.new("development") - @parser = Puppet::Parser::Parser.new "development" - @parser.stubs(:known_resource_types).returns @known_resource_types - @true_ast = Puppet::Parser::AST::Boolean.new :value => true + ast = Puppet::Parser::AST + + before :each do + @known_resource_types = Puppet::Resource::TypeCollection.new("development") + @parser = Puppet::Parser::Parser.new "development" + @parser.stubs(:known_resource_types).returns @known_resource_types + @true_ast = Puppet::Parser::AST::Boolean.new :value => true + end + + it "should require an environment at initialization" do + lambda { Puppet::Parser::Parser.new }.should raise_error(ArgumentError) + end + + it "should set the environment" do + env = Puppet::Node::Environment.new + Puppet::Parser::Parser.new(env).environment.should == env + end + + it "should convert the environment into an environment instance if a string is provided" do + env = Puppet::Node::Environment.new("testing") + Puppet::Parser::Parser.new("testing").environment.should == env + end + + it "should be able to look up the environment-specific resource type collection" do + rtc = Puppet::Node::Environment.new("development").known_resource_types + parser = Puppet::Parser::Parser.new "development" + parser.known_resource_types.should equal(rtc) + end + + it "should delegate importing to the known resource type loader" do + parser = Puppet::Parser::Parser.new "development" + parser.known_resource_types.loader.expects(:import).with("newfile", "current_file") + parser.lexer.expects(:file).returns "current_file" + parser.import("newfile") + end + + describe "when parsing files" do + before do + FileTest.stubs(:exist?).returns true + File.stubs(:read).returns "" + @parser.stubs(:watch_file) end - it "should require an environment at initialization" do - lambda { Puppet::Parser::Parser.new }.should raise_error(ArgumentError) + it "should treat files ending in 'rb' as ruby files" do + @parser.expects(:parse_ruby_file) + @parser.file = "/my/file.rb" + @parser.parse end - it "should set the environment" do - env = Puppet::Node::Environment.new - Puppet::Parser::Parser.new(env).environment.should == env - 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" - it "should convert the environment into an environment instance if a string is provided" do - env = Puppet::Node::Environment.new("testing") - Puppet::Parser::Parser.new("testing").environment.should == env + @parser.parse_ruby_file + end end + end - it "should be able to look up the environment-specific resource type collection" do - rtc = Puppet::Node::Environment.new("development").known_resource_types - parser = Puppet::Parser::Parser.new "development" - parser.known_resource_types.should equal(rtc) - end + describe "when parsing append operator" do - it "should delegate importing to the known resource type loader" do - parser = Puppet::Parser::Parser.new "development" - parser.known_resource_types.loader.expects(:import).with("newfile", "current_file") - parser.lexer.expects(:file).returns "current_file" - parser.import("newfile") + it "should not raise syntax errors" do + lambda { @parser.parse("$var += something") }.should_not raise_error end - describe "when parsing files" do - before do - FileTest.stubs(:exist?).returns true - File.stubs(:read).returns "" - @parser.stubs(:watch_file) - end - - it "should treat files ending in 'rb' as ruby files" do - @parser.expects(:parse_ruby_file) - @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 + it "shouldraise syntax error on incomplete syntax " do + lambda { @parser.parse("$var += ") }.should raise_error end - describe "when parsing append operator" do - - it "should not raise syntax errors" do - lambda { @parser.parse("$var += something") }.should_not raise_error - end - - it "shouldraise syntax error on incomplete syntax " 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") + end - it "should call ast::VarDef with append=true" do - ast::VarDef.expects(:new).with { |h| h[:append] == true } - @parser.parse("$var += 2") - end + it "should work with arrays too" do + ast::VarDef.expects(:new).with { |h| h[:append] == true } + @parser.parse("$var += ['test']") + end - it "should work with arrays too" do - ast::VarDef.expects(:new).with { |h| h[:append] == true } - @parser.parse("$var += ['test']") - 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) } + @parser.parse("if ! true { $var = 1 }") 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) } - @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" + } + @parser.parse("if true or true { $var = 1 }") - 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" - } - @parser.parse("if true or true { $var = 1 }") + end - 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]=="<" + } + @parser.parse("if 1 < 2 { $var = 1 }") - 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]=="<" - } - @parser.parse("if 1 < 2 { $var = 1 }") + end - end + end + + 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]==">" + }.returns(aststub) + ast::ComparisonOperator.expects(:new).with { + |h| h[:rval].is_a?(ast::Name) and h[:lval].is_a?(ast::Name) and h[:operator]=="==" + }.returns(aststub) + 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 }") + end + it "should raise an error on incorrect expression" do + lambda { @parser.parse("if (1 > 2 > ) or (1 == 2) { $var = 1 }") }.should raise_error end - 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]==">" - }.returns(aststub) - ast::ComparisonOperator.expects(:new).with { - |h| h[:rval].is_a?(ast::Name) and h[:lval].is_a?(ast::Name) and h[:operator]=="==" - }.returns(aststub) - 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 }") - end + end - it "should raise an error on incorrect expression" do - lambda { @parser.parse("if (1 > 2 > ) or (1 == 2) { $var = 1 }") }.should raise_error - end + describe "when parsing resource references" do + it "should not raise syntax errors" do + lambda { @parser.parse('exec { test: param => File["a"] }') }.should_not raise_error end - describe "when parsing resource references" do + it "should not raise syntax errors with multiple references" do + lambda { @parser.parse('exec { test: param => File["a","b"] }') }.should_not raise_error + end - it "should not raise syntax errors" do - lambda { @parser.parse('exec { test: param => File["a"] }') }.should_not raise_error - 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) + } + @parser.parse('exec { test: command => File["a","b"] }') + end + end - it "should not raise syntax errors with multiple references" do - lambda { @parser.parse('exec { test: param => File["a","b"] }') }.should_not raise_error - end + describe "when parsing resource overrides" do - 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) - } - @parser.parse('exec { test: command => File["a","b"] }') - end + it "should not raise syntax errors" do + lambda { @parser.parse('Resource["title"] { param => value }') }.should_not raise_error end - describe "when parsing resource overrides" do + it "should not raise syntax errors with multiple overrides" do + lambda { @parser.parse('Resource["title1","title2"] { param => value }') }.should_not raise_error + end - it "should not raise syntax errors" do - lambda { @parser.parse('Resource["title"] { param => value }') }.should_not raise_error - 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 }') + end - it "should not raise syntax errors with multiple overrides" do - lambda { @parser.parse('Resource["title1","title2"] { param => value }') }.should_not raise_error - end + 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 }') - end + describe "when parsing if statements" do + it "should not raise errors with empty if" do + lambda { @parser.parse("if true { }") }.should_not raise_error end - describe "when parsing if statements" do + it "should not raise errors with empty else" do + lambda { @parser.parse("if false { notice('if') } else { }") }.should_not raise_error + end - it "should not raise errors with empty if" do - lambda { @parser.parse("if true { }") }.should_not raise_error - end + it "should not raise errors with empty if and else" do + lambda { @parser.parse("if false { } else { }") }.should_not raise_error + end - it "should not raise errors with empty else" do - lambda { @parser.parse("if false { notice('if') } else { }") }.should_not raise_error - end + it "should create a nop node for empty branch" do + ast::Nop.expects(:new) + @parser.parse("if true { }") + end - it "should not raise errors with empty if and else" do - lambda { @parser.parse("if false { } else { }") }.should_not raise_error - end + it "should create a nop node for empty else branch" do + ast::Nop.expects(:new) + @parser.parse("if true { notice('test') } else { }") + end - it "should create a nop node for empty branch" do - ast::Nop.expects(:new) - @parser.parse("if true { }") - end + it "should build a chain of 'ifs' if there's an 'elsif'" do + ast = @parser.parse(<<-PP) + if true { notice('test') } elsif true {} else { } + PP + end - it "should create a nop node for empty else branch" do - ast::Nop.expects(:new) - @parser.parse("if true { notice('test') } else { }") - end + end - it "should build a chain of 'ifs' if there's an 'elsif'" do - ast = @parser.parse(<<-PP) - if true { notice('test') } elsif true {} else { } - PP - end + describe "when parsing function calls" do + it "should not raise errors with no arguments" do + lambda { @parser.parse("tag()") }.should_not raise_error end - describe "when parsing function calls" do + it "should not raise errors with rvalue function with no args" do + lambda { @parser.parse("$a = template()") }.should_not raise_error + end - it "should not raise errors with no arguments" do - lambda { @parser.parse("tag()") }.should_not raise_error - end + it "should not raise errors with arguments" do + lambda { @parser.parse("notice(1)") }.should_not raise_error + end - it "should not raise errors with rvalue function with no args" do - lambda { @parser.parse("$a = template()") }.should_not raise_error - end + it "should not raise errors with multiple arguments" do + lambda { @parser.parse("notice(1,2)") }.should_not raise_error + end - it "should not raise errors with arguments" do - lambda { @parser.parse("notice(1)") }.should_not raise_error - end + it "should not raise errors with multiple arguments and a trailing comma" do + lambda { @parser.parse("notice(1,2,)") }.should_not raise_error + end - it "should not raise errors with multiple arguments" do - lambda { @parser.parse("notice(1,2)") }.should_not raise_error - end + end - it "should not raise errors with multiple arguments and a trailing comma" do - lambda { @parser.parse("notice(1,2,)") }.should_not raise_error - end + describe "when parsing arrays with trailing comma" do + it "should not raise errors with a trailing comma" do + lambda { @parser.parse("$a = [1,2,]") }.should_not raise_error end + end - describe "when parsing arrays with trailing comma" do - - it "should not raise errors with a trailing comma" do - lambda { @parser.parse("$a = [1,2,]") }.should_not raise_error - end + describe "when providing AST context" do + before do + @lexer = stub 'lexer', :line => 50, :file => "/foo/bar", :getcomment => "whev" + @parser.stubs(:lexer).returns @lexer end - describe "when providing AST context" do - before do - @lexer = stub 'lexer', :line => 50, :file => "/foo/bar", :getcomment => "whev" - @parser.stubs(:lexer).returns @lexer - end + it "should include the lexer's line" do + @parser.ast_context[:line].should == 50 + end - it "should include the lexer's line" do - @parser.ast_context[:line].should == 50 - end + it "should include the lexer's file" do + @parser.ast_context[:file].should == "/foo/bar" + end - it "should include the lexer's file" do - @parser.ast_context[:file].should == "/foo/bar" - end + it "should include the docs if directed to do so" do + @parser.ast_context(true)[:doc].should == "whev" + end - it "should include the docs if directed to do so" do - @parser.ast_context(true)[:doc].should == "whev" - end + it "should not include the docs when told not to" do + @parser.ast_context(false)[:doc].should be_nil + end - it "should not include the docs when told not to" do - @parser.ast_context(false)[:doc].should be_nil - end + it "should not include the docs by default" do + @parser.ast_context[:doc].should be_nil + end + end - it "should not include the docs by default" do - @parser.ast_context[:doc].should be_nil - end + describe "when building ast nodes" do + before do + @lexer = stub 'lexer', :line => 50, :file => "/foo/bar", :getcomment => "whev" + @parser.stubs(:lexer).returns @lexer + @class = stub 'class', :use_docs => false end - describe "when building ast nodes" do - before do - @lexer = stub 'lexer', :line => 50, :file => "/foo/bar", :getcomment => "whev" - @parser.stubs(:lexer).returns @lexer - @class = stub 'class', :use_docs => false - end + it "should return a new instance of the provided class created with the provided options" do + @class.expects(:new).with { |opts| opts[:foo] == "bar" } + @parser.ast(@class, :foo => "bar") + end - it "should return a new instance of the provided class created with the provided options" do - @class.expects(:new).with { |opts| opts[:foo] == "bar" } - @parser.ast(@class, :foo => "bar") - end + it "should merge the ast context into the provided options" do + @class.expects(:new).with { |opts| opts[:file] == "/foo" } + @parser.expects(:ast_context).returns :file => "/foo" + @parser.ast(@class, :foo => "bar") + end - it "should merge the ast context into the provided options" do - @class.expects(:new).with { |opts| opts[:file] == "/foo" } - @parser.expects(:ast_context).returns :file => "/foo" - @parser.ast(@class, :foo => "bar") - end + it "should prefer provided options over AST context" do + @class.expects(:new).with { |opts| opts[:file] == "/bar" } + @parser.expects(:ast_context).returns :file => "/foo" + @parser.ast(@class, :file => "/bar") + end - it "should prefer provided options over AST context" do - @class.expects(:new).with { |opts| opts[:file] == "/bar" } - @parser.expects(:ast_context).returns :file => "/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.ast(@class, :file => "/bar") + end + 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.ast(@class, :file => "/bar") - 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 - 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) + it "should return an array of nodes" do + @parser.newnode(@nodename).should be_instance_of(Array) + end + end - @nodename = stub 'nodename', :is_a? => false, :value => "foo" - @nodename.stubs(:is_a?).with(Puppet::Parser::AST::HostName).returns(true) - end + describe "when retrieving a specific node" do + it "should delegate to the known_resource_types node" do + @known_resource_types.expects(:node).with("node") - it "should return an array of nodes" do - @parser.newnode(@nodename).should be_instance_of(Array) - end + @parser.node("node") end + end - describe "when retrieving a specific node" do - it "should delegate to the known_resource_types node" do - @known_resource_types.expects(:node).with("node") + describe "when retrieving a specific class" do + it "should delegate to the loaded code" do + @known_resource_types.expects(:hostclass).with("class") - @parser.node("node") - end + @parser.hostclass("class") end + end - describe "when retrieving a specific class" do - it "should delegate to the loaded code" do - @known_resource_types.expects(:hostclass).with("class") + describe "when retrieving a specific definitions" do + it "should delegate to the loaded code" do + @known_resource_types.expects(:definition).with("define") - @parser.hostclass("class") - end + @parser.definition("define") end + end - describe "when retrieving a specific definitions" do - it "should delegate to the loaded code" do - @known_resource_types.expects(:definition).with("define") + describe "when determining the configuration version" do + it "should determine it from the resource type collection" do + @parser.known_resource_types.expects(:version).returns "foo" + @parser.version.should == "foo" + end + end - @parser.definition("define") - end - end - - describe "when determining the configuration version" do - it "should determine it from the resource type collection" do - @parser.known_resource_types.expects(:version).returns "foo" - @parser.version.should == "foo" - end + describe "when looking up definitions" do + it "should use the known resource types to check for them by name" do + @parser.known_resource_types.stubs(:find_or_load).with("namespace","name",:definition).returns(:this_value) + @parser.find_definition("namespace","name").should == :this_value end + end - describe "when looking up definitions" do - it "should use the known resource types to check for them by name" do - @parser.known_resource_types.stubs(:find_or_load).with("namespace","name",:definition).returns(:this_value) - @parser.find_definition("namespace","name").should == :this_value - end + describe "when looking up hostclasses" do + it "should use the known resource types to check for them by name" do + @parser.known_resource_types.stubs(:find_or_load).with("namespace","name",:hostclass).returns(:this_value) + @parser.find_hostclass("namespace","name").should == :this_value end - - describe "when looking up hostclasses" do - it "should use the known resource types to check for them by name" do - @parser.known_resource_types.stubs(:find_or_load).with("namespace","name",:hostclass).returns(:this_value) - @parser.find_hostclass("namespace","name").should == :this_value - end + end + + describe "when parsing classes" do + before :each do + @krt = Puppet::Resource::TypeCollection.new("development") + @parser = Puppet::Parser::Parser.new "development" + @parser.stubs(:known_resource_types).returns @krt end - describe "when parsing classes" do - before :each do - @krt = Puppet::Resource::TypeCollection.new("development") - @parser = Puppet::Parser::Parser.new "development" - @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) - end + it "should create new classes" do + @parser.parse("class foobar {}") + @krt.hostclass("foobar").should be_instance_of(Puppet::Resource::Type) + 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" - 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" + 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 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 - 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 + end - it "should define parameters when provided" do - @parser.parse("class foobar($biz,$baz) {}") - @krt.hostclass("foobar").arguments.should == {"biz" => nil, "baz" => nil} - end + it "should define parameters when provided" do + @parser.parse("class foobar($biz,$baz) {}") + @krt.hostclass("foobar").arguments.should == {"biz" => nil, "baz" => nil} end + end - describe "when parsing resources" do - before :each do - @krt = Puppet::Resource::TypeCollection.new("development") - @parser = Puppet::Parser::Parser.new "development" - @parser.stubs(:known_resource_types).returns @krt - end + describe "when parsing resources" do + before :each do + @krt = Puppet::Resource::TypeCollection.new("development") + @parser = Puppet::Parser::Parser.new "development" + @parser.stubs(:known_resource_types).returns @krt + end - it "should be able to parse class resources" 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 be able to parse class resources" 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 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 + 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/relationship_spec.rb b/spec/unit/parser/relationship_spec.rb index bd4ff5632..57f1a772b 100644 --- a/spec/unit/parser/relationship_spec.rb +++ b/spec/unit/parser/relationship_spec.rb @@ -5,66 +5,66 @@ require File.dirname(__FILE__) + '/../../spec_helper' require 'puppet/parser/relationship' describe Puppet::Parser::Relationship do + before do + @source = Puppet::Resource.new(:mytype, "source") + @target = Puppet::Resource.new(:mytype, "target") + @dep = Puppet::Parser::Relationship.new(@source, @target, :relationship) + end + + describe "when evaluating" do before do - @source = Puppet::Resource.new(:mytype, "source") - @target = Puppet::Resource.new(:mytype, "target") - @dep = Puppet::Parser::Relationship.new(@source, @target, :relationship) + @catalog = Puppet::Resource::Catalog.new + @catalog.add_resource(@source) + @catalog.add_resource(@target) end - describe "when evaluating" do - before do - @catalog = Puppet::Resource::Catalog.new - @catalog.add_resource(@source) - @catalog.add_resource(@target) - end - - it "should fail if the source resource cannot be found" do - @catalog = Puppet::Resource::Catalog.new - @catalog.add_resource @target - lambda { @dep.evaluate(@catalog) }.should raise_error(ArgumentError) - end + it "should fail if the source resource cannot be found" do + @catalog = Puppet::Resource::Catalog.new + @catalog.add_resource @target + lambda { @dep.evaluate(@catalog) }.should raise_error(ArgumentError) + end - it "should fail if the target resource cannot be found" do - @catalog = Puppet::Resource::Catalog.new - @catalog.add_resource @source - lambda { @dep.evaluate(@catalog) }.should raise_error(ArgumentError) - end + it "should fail if the target resource cannot be found" do + @catalog = Puppet::Resource::Catalog.new + @catalog.add_resource @source + lambda { @dep.evaluate(@catalog) }.should raise_error(ArgumentError) + end - it "should add the target as a 'before' value if the type is 'relationship'" do - @dep.type = :relationship - @dep.evaluate(@catalog) - @source[:before].should be_include("Mytype[target]") - end + it "should add the target as a 'before' value if the type is 'relationship'" do + @dep.type = :relationship + @dep.evaluate(@catalog) + @source[:before].should be_include("Mytype[target]") + end - it "should add the target as a 'notify' value if the type is 'subscription'" do - @dep.type = :subscription - @dep.evaluate(@catalog) - @source[:notify].should be_include("Mytype[target]") - end + it "should add the target as a 'notify' value if the type is 'subscription'" do + @dep.type = :subscription + @dep.evaluate(@catalog) + @source[:notify].should be_include("Mytype[target]") + end - it "should supplement rather than clobber existing relationship values" do - @source[:before] = "File[/bar]" - @dep.evaluate(@catalog) - @source[:before].should be_include("Mytype[target]") - @source[:before].should be_include("File[/bar]") - end + it "should supplement rather than clobber existing relationship values" do + @source[:before] = "File[/bar]" + @dep.evaluate(@catalog) + @source[:before].should be_include("Mytype[target]") + @source[:before].should be_include("File[/bar]") + end - it "should use the collected retargets if the target is a Collector" do - orig_target = @target - @target = Puppet::Parser::Collector.new(stub("scope"), :file, "equery", "vquery", :virtual) - @target.collected[:foo] = @target - @dep.evaluate(@catalog) + it "should use the collected retargets if the target is a Collector" do + orig_target = @target + @target = Puppet::Parser::Collector.new(stub("scope"), :file, "equery", "vquery", :virtual) + @target.collected[:foo] = @target + @dep.evaluate(@catalog) - @source[:before].should be_include("Mytype[target]") - end + @source[:before].should be_include("Mytype[target]") + end - it "should use the collected resources if the source is a Collector" do - orig_source = @source - @source = Puppet::Parser::Collector.new(stub("scope"), :file, "equery", "vquery", :virtual) - @source.collected[:foo] = @source - @dep.evaluate(@catalog) + it "should use the collected resources if the source is a Collector" do + orig_source = @source + @source = Puppet::Parser::Collector.new(stub("scope"), :file, "equery", "vquery", :virtual) + @source.collected[:foo] = @source + @dep.evaluate(@catalog) - orig_source[:before].should be_include("Mytype[target]") - end + orig_source[:before].should be_include("Mytype[target]") end + end end diff --git a/spec/unit/parser/resource_spec.rb b/spec/unit/parser/resource_spec.rb index 31bde27dd..da49940b0 100755 --- a/spec/unit/parser/resource_spec.rb +++ b/spec/unit/parser/resource_spec.rb @@ -6,559 +6,559 @@ require File.dirname(__FILE__) + '/../../spec_helper' # not moved all tests over yet. describe Puppet::Parser::Resource do - before do - @node = Puppet::Node.new("yaynode") - @known_resource_types = Puppet::Resource::TypeCollection.new("env") - @compiler = Puppet::Parser::Compiler.new(@node) - @compiler.environment.stubs(:known_resource_types).returns @known_resource_types - @source = newclass "" - @scope = @compiler.topscope + before do + @node = Puppet::Node.new("yaynode") + @known_resource_types = Puppet::Resource::TypeCollection.new("env") + @compiler = Puppet::Parser::Compiler.new(@node) + @compiler.environment.stubs(:known_resource_types).returns @known_resource_types + @source = newclass "" + @scope = @compiler.topscope + end + + def mkresource(args = {}) + args[:source] ||= @source + args[:scope] ||= @scope + + params = args[:parameters] || {:one => "yay", :three => "rah"} + if args[:parameters] == :none + args.delete(:parameters) + elsif not args[:parameters].is_a? Array + args[:parameters] = paramify(args[:source], params) end - def mkresource(args = {}) - args[:source] ||= @source - args[:scope] ||= @scope + Puppet::Parser::Resource.new("resource", "testing", args) + end + + def param(name, value, source) + Puppet::Parser::Resource::Param.new(:name => name, :value => value, :source => source) + end - params = args[:parameters] || {:one => "yay", :three => "rah"} - if args[:parameters] == :none - args.delete(:parameters) - elsif not args[:parameters].is_a? Array - args[:parameters] = paramify(args[:source], params) - end + def paramify(source, hash) + hash.collect do |name, value| + Puppet::Parser::Resource::Param.new( + :name => name, :value => value, :source => source + ) + end + end + + 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 + + it "should use the file lookup module" 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 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" + Puppet::Parser::Resource.new("file", "whatever", :scope => @scope).environment.should == "myenv" + 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("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("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("whatever", "whatever", :scope => @scope, :source => @source).isomorphic?.should be_true + end + + it "should have a array-indexing method for retrieving parameter values" do + @resource = mkresource + @resource[:one].should == "yay" + end + + it "should use a Puppet::Resource for converting to a ral resource" do + trans = mock 'resource', :to_ral => "yay" + @resource = mkresource + @resource.expects(:to_resource).returns trans + @resource.to_ral.should == "yay" + end + + it "should be able to use the indexing operator to access parameters" do + 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("resource", "testing", :source => @source, :scope => @scope)[:title].should == "testing" + end + + describe "when initializing" do + before do + @arguments = {:scope => @scope} + end + + it "should fail unless #{name.to_s} is specified" do + lambda { Puppet::Parser::Resource.new('file', '/my/file') }.should raise_error(ArgumentError) + end - Puppet::Parser::Resource.new("resource", "testing", args) + it "should set the reference correctly" do + res = Puppet::Parser::Resource.new("resource", "testing", @arguments) + res.ref.should == "Resource[testing]" end - def param(name, value, source) - Puppet::Parser::Resource::Param.new(:name => name, :value => value, :source => source) + it "should be tagged with user tags" do + tags = [ "tag1", "tag2" ] + @arguments[:parameters] = [ param(:tag, tags , :source) ] + res = Puppet::Parser::Resource.new("resource", "testing", @arguments) + (res.tags & tags).should == tags end + end - def paramify(source, hash) - hash.collect do |name, value| - Puppet::Parser::Resource::Param.new( - :name => name, :value => value, :source => source - ) - end + describe "when evaluating" do + it "should evaluate the associated AST definition" do + definition = newdefine "mydefine" + res = Puppet::Parser::Resource.new("mydefine", "whatever", :scope => @scope, :source => @source) + definition.expects(:evaluate_code).with(res) + + res.evaluate end - def newclass(name) - @known_resource_types.add Puppet::Resource::Type.new(:hostclass, name) + it "should evaluate the associated AST class" do + @class = newclass "myclass" + res = Puppet::Parser::Resource.new("class", "myclass", :scope => @scope, :source => @source) + @class.expects(:evaluate_code).with(res) + res.evaluate end - def newdefine(name) - @known_resource_types.add Puppet::Resource::Type.new(:definition, name) + it "should evaluate the associated AST node" do + nodedef = newnode("mynode") + res = Puppet::Parser::Resource.new("node", "mynode", :scope => @scope, :source => @source) + nodedef.expects(:evaluate_code).with(res) + res.evaluate end + end + + describe "when finishing" do + before do + @class = newclass "myclass" + @nodedef = newnode("mynode") - def newnode(name) - @known_resource_types.add Puppet::Resource::Type.new(:node, name) + @resource = Puppet::Parser::Resource.new("file", "whatever", :scope => @scope, :source => @source) end - it "should use the file lookup module" do - Puppet::Parser::Resource.ancestors.should be_include(Puppet::FileCollection::Lookup) + it "should do nothing if it has already been finished" do + @resource.finish + @resource.expects(:add_metaparams).never + @resource.finish 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" + it "should add all defaults available from the scope" do + @resource.scope.expects(:lookupdefaults).with(@resource.type).returns(:owner => param(:owner, "default", @resource.source)) + @resource.finish + + @resource[:owner].should == "default" 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} + it "should not replace existing parameters with defaults" do + @resource.set_parameter :owner, "oldvalue" + @resource.scope.expects(:lookupdefaults).with(@resource.type).returns(:owner => :replaced) + @resource.finish + + @resource[:owner].should == "oldvalue" end - it "should use the resource type collection helper module" do - Puppet::Parser::Resource.ancestors.should be_include(Puppet::Resource::TypeCollectionHelper) + it "should add a copy of each default, rather than the actual default parameter instance" do + newparam = param(:owner, "default", @resource.source) + other = newparam.dup + other.value = "other" + newparam.expects(:dup).returns(other) + @resource.scope.expects(:lookupdefaults).with(@resource.type).returns(:owner => newparam) + @resource.finish + + @resource[:owner].should == "other" end - it "should use the scope's environment as its environment" do - @scope.expects(:environment).returns "myenv" - Puppet::Parser::Resource.new("file", "whatever", :scope => @scope).environment.should == "myenv" + it "should be running in metaparam compatibility mode if running a version below 0.25" do + catalog = stub 'catalog', :client_version => "0.24.8" + @resource.stubs(:catalog).returns catalog + @resource.should be_metaparam_compatibility_mode 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("file", "whatever", :scope => @scope, :source => @source).isomorphic?.should be_true + it "should be running in metaparam compatibility mode if running no client version is available" do + catalog = stub 'catalog', :client_version => nil + @resource.stubs(:catalog).returns catalog + @resource.should be_metaparam_compatibility_mode 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("file", "whatever", :scope => @scope, :source => @source).isomorphic?.should be_false + it "should not be running in metaparam compatibility mode if running a version at or above 0.25" do + catalog = stub 'catalog', :client_version => "0.25.0" + @resource.stubs(:catalog).returns catalog + @resource.should_not be_metaparam_compatibility_mode end - it "should be isomorphic if it is not builtin" do - newdefine "whatever" - @resource = Puppet::Parser::Resource.new("whatever", "whatever", :scope => @scope, :source => @source).isomorphic?.should be_true + it "should not copy relationship metaparams when not in metaparam compatibility mode" do + @scope.setvar("require", "bar") + + @resource.stubs(:metaparam_compatibility_mode?).returns false + @resource.class.publicize_methods(:add_metaparams) { @resource.add_metaparams } + + @resource["require"].should be_nil end - it "should have a array-indexing method for retrieving parameter values" do - @resource = mkresource - @resource[:one].should == "yay" + it "should copy relationship metaparams when in metaparam compatibility mode" do + @scope.setvar("require", "bar") + + @resource.stubs(:metaparam_compatibility_mode?).returns true + @resource.class.publicize_methods(:add_metaparams) { @resource.add_metaparams } + + @resource["require"].should == "bar" end - it "should use a Puppet::Resource for converting to a ral resource" do - trans = mock 'resource', :to_ral => "yay" - @resource = mkresource - @resource.expects(:to_resource).returns trans - @resource.to_ral.should == "yay" + it "should stack relationship metaparams when in metaparam compatibility mode" do + @resource.set_parameter("require", "foo") + @scope.setvar("require", "bar") + + @resource.stubs(:metaparam_compatibility_mode?).returns true + @resource.class.publicize_methods(:add_metaparams) { @resource.add_metaparams } + + @resource["require"].should == ["foo", "bar"] end + end - it "should be able to use the indexing operator to access parameters" do - resource = Puppet::Parser::Resource.new("resource", "testing", :source => "source", :scope => @scope) - resource["foo"] = "bar" - resource["foo"].should == "bar" + describe "when being tagged" do + before do + @scope_resource = stub 'scope_resource', :tags => %w{srone srtwo} + @scope.stubs(:resource).returns @scope_resource + @resource = Puppet::Parser::Resource.new("file", "yay", :scope => @scope, :source => mock('source')) end - it "should return the title when asked for a parameter named 'title'" do - Puppet::Parser::Resource.new("resource", "testing", :source => @source, :scope => @scope)[:title].should == "testing" + it "should get tagged with the resource type" do + @resource.tags.should be_include("file") end - describe "when initializing" do - before do - @arguments = {:scope => @scope} - end + it "should get tagged with the title" do + @resource.tags.should be_include("yay") + 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 get tagged with each name in the title if the title is a qualified class name" do + 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 set the reference correctly" do - res = Puppet::Parser::Resource.new("resource", "testing", @arguments) - res.ref.should == "Resource[testing]" - 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("one::two", "whatever", :scope => @scope, :source => mock('source')) + resource.tags.should be_include("one") + resource.tags.should be_include("two") + end - it "should be tagged with user tags" do - tags = [ "tag1", "tag2" ] - @arguments[:parameters] = [ param(:tag, tags , :source) ] - res = Puppet::Parser::Resource.new("resource", "testing", @arguments) - (res.tags & tags).should == tags - end + it "should not get tagged with non-alphanumeric titles" do + 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 - describe "when evaluating" do - it "should evaluate the associated AST definition" do - definition = newdefine "mydefine" - res = Puppet::Parser::Resource.new("mydefine", "whatever", :scope => @scope, :source => @source) - definition.expects(:evaluate_code).with(res) + it "should fail on tags containing '*' characters" do + lambda { @resource.tag("bad*tag") }.should raise_error(Puppet::ParseError) + end - res.evaluate - end + it "should fail on tags starting with '-' characters" do + lambda { @resource.tag("-badtag") }.should raise_error(Puppet::ParseError) + end - it "should evaluate the associated AST class" do - @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 fail on tags containing ' ' characters" do + lambda { @resource.tag("bad tag") }.should raise_error(Puppet::ParseError) + end - it "should evaluate the associated AST node" do - nodedef = newnode("mynode") - res = Puppet::Parser::Resource.new("node", "mynode", :scope => @scope, :source => @source) - nodedef.expects(:evaluate_code).with(res) - res.evaluate - end + it "should allow alpha tags" do + lambda { @resource.tag("good_tag") }.should_not raise_error(Puppet::ParseError) end + end - describe "when finishing" do - before do - @class = newclass "myclass" - @nodedef = newnode("mynode") + describe "when merging overrides" do + before do + @source = "source1" + @resource = mkresource :source => @source + @override = mkresource :source => @source + end - @resource = Puppet::Parser::Resource.new("file", "whatever", :scope => @scope, :source => @source) - end + it "should fail when the override was not created by a parent class" do + @override.source = "source2" + @override.source.expects(:child_of?).with("source1").returns(false) + lambda { @resource.merge(@override) }.should raise_error(Puppet::ParseError) + end - it "should do nothing if it has already been finished" do - @resource.finish - @resource.expects(:add_metaparams).never - @resource.finish - end + it "should succeed when the override was created in the current scope" do + @resource.source = "source3" + @override.source = @resource.source + @override.source.expects(:child_of?).with("source3").never + params = {:a => :b, :c => :d} + @override.expects(:parameters).returns(params) + @resource.expects(:override_parameter).with(:b) + @resource.expects(:override_parameter).with(:d) + @resource.merge(@override) + end - it "should add all defaults available from the scope" do - @resource.scope.expects(:lookupdefaults).with(@resource.type).returns(:owner => param(:owner, "default", @resource.source)) - @resource.finish + it "should succeed when a parent class created the override" do + @resource.source = "source3" + @override.source = "source4" + @override.source.expects(:child_of?).with("source3").returns(true) + params = {:a => :b, :c => :d} + @override.expects(:parameters).returns(params) + @resource.expects(:override_parameter).with(:b) + @resource.expects(:override_parameter).with(:d) + @resource.merge(@override) + end - @resource[:owner].should == "default" - end + it "should add new parameters when the parameter is not set" do + @source.stubs(:child_of?).returns true + @override.set_parameter(:testing, "value") + @resource.merge(@override) - it "should not replace existing parameters with defaults" do - @resource.set_parameter :owner, "oldvalue" - @resource.scope.expects(:lookupdefaults).with(@resource.type).returns(:owner => :replaced) - @resource.finish + @resource[:testing].should == "value" + end - @resource[:owner].should == "oldvalue" - end + it "should replace existing parameter values" do + @source.stubs(:child_of?).returns true + @resource.set_parameter(:testing, "old") + @override.set_parameter(:testing, "value") - it "should add a copy of each default, rather than the actual default parameter instance" do - newparam = param(:owner, "default", @resource.source) - other = newparam.dup - other.value = "other" - newparam.expects(:dup).returns(other) - @resource.scope.expects(:lookupdefaults).with(@resource.type).returns(:owner => newparam) - @resource.finish + @resource.merge(@override) - @resource[:owner].should == "other" - end - - it "should be running in metaparam compatibility mode if running a version below 0.25" do - catalog = stub 'catalog', :client_version => "0.24.8" - @resource.stubs(:catalog).returns catalog - @resource.should be_metaparam_compatibility_mode - end - - it "should be running in metaparam compatibility mode if running no client version is available" do - catalog = stub 'catalog', :client_version => nil - @resource.stubs(:catalog).returns catalog - @resource.should be_metaparam_compatibility_mode - end - - it "should not be running in metaparam compatibility mode if running a version at or above 0.25" do - catalog = stub 'catalog', :client_version => "0.25.0" - @resource.stubs(:catalog).returns catalog - @resource.should_not be_metaparam_compatibility_mode - end - - it "should not copy relationship metaparams when not in metaparam compatibility mode" do - @scope.setvar("require", "bar") - - @resource.stubs(:metaparam_compatibility_mode?).returns false - @resource.class.publicize_methods(:add_metaparams) { @resource.add_metaparams } - - @resource["require"].should be_nil - end - - it "should copy relationship metaparams when in metaparam compatibility mode" do - @scope.setvar("require", "bar") - - @resource.stubs(:metaparam_compatibility_mode?).returns true - @resource.class.publicize_methods(:add_metaparams) { @resource.add_metaparams } - - @resource["require"].should == "bar" - end - - it "should stack relationship metaparams when in metaparam compatibility mode" do - @resource.set_parameter("require", "foo") - @scope.setvar("require", "bar") - - @resource.stubs(:metaparam_compatibility_mode?).returns true - @resource.class.publicize_methods(:add_metaparams) { @resource.add_metaparams } - - @resource["require"].should == ["foo", "bar"] - end - end - - describe "when being tagged" do - before do - @scope_resource = stub 'scope_resource', :tags => %w{srone srtwo} - @scope.stubs(:resource).returns @scope_resource - @resource = Puppet::Parser::Resource.new("file", "yay", :scope => @scope, :source => mock('source')) - end - - it "should get tagged with the resource type" do - @resource.tags.should be_include("file") - end - - it "should get tagged with the title" do - @resource.tags.should be_include("yay") - 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("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("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("file", "this is a test", :scope => @scope, :source => mock('source')) - resource.tags.should_not be_include("this is a test") - end - - it "should fail on tags containing '*' characters" do - lambda { @resource.tag("bad*tag") }.should raise_error(Puppet::ParseError) - end - - it "should fail on tags starting with '-' characters" do - lambda { @resource.tag("-badtag") }.should raise_error(Puppet::ParseError) - end - - it "should fail on tags containing ' ' characters" do - lambda { @resource.tag("bad tag") }.should raise_error(Puppet::ParseError) - end - - it "should allow alpha tags" do - lambda { @resource.tag("good_tag") }.should_not raise_error(Puppet::ParseError) - end + @resource[:testing].should == "value" end - describe "when merging overrides" do - before do - @source = "source1" - @resource = mkresource :source => @source - @override = mkresource :source => @source - end + it "should add values to the parameter when the override was created with the '+>' syntax" do + @source.stubs(:child_of?).returns true + param = Puppet::Parser::Resource::Param.new(:name => :testing, :value => "testing", :source => @resource.source) + param.add = true - it "should fail when the override was not created by a parent class" do - @override.source = "source2" - @override.source.expects(:child_of?).with("source1").returns(false) - lambda { @resource.merge(@override) }.should raise_error(Puppet::ParseError) - end + @override.set_parameter(param) - it "should succeed when the override was created in the current scope" do - @resource.source = "source3" - @override.source = @resource.source - @override.source.expects(:child_of?).with("source3").never - params = {:a => :b, :c => :d} - @override.expects(:parameters).returns(params) - @resource.expects(:override_parameter).with(:b) - @resource.expects(:override_parameter).with(:d) - @resource.merge(@override) - end + @resource.set_parameter(:testing, "other") + + @resource.merge(@override) + + @resource[:testing].should == %w{other testing} + end - it "should succeed when a parent class created the override" do - @resource.source = "source3" - @override.source = "source4" - @override.source.expects(:child_of?).with("source3").returns(true) - params = {:a => :b, :c => :d} - @override.expects(:parameters).returns(params) - @resource.expects(:override_parameter).with(:b) - @resource.expects(:override_parameter).with(:d) - @resource.merge(@override) - end + it "should not merge parameter values when multiple resources are overriden with '+>' at once " do + @resource_2 = mkresource :source => @source - it "should add new parameters when the parameter is not set" do - @source.stubs(:child_of?).returns true - @override.set_parameter(:testing, "value") - @resource.merge(@override) + @resource. set_parameter(:testing, "old_val_1") + @resource_2.set_parameter(:testing, "old_val_2") - @resource[:testing].should == "value" - end + @source.stubs(:child_of?).returns true + param = Puppet::Parser::Resource::Param.new(:name => :testing, :value => "new_val", :source => @resource.source) + param.add = true + @override.set_parameter(param) - it "should replace existing parameter values" do - @source.stubs(:child_of?).returns true - @resource.set_parameter(:testing, "old") - @override.set_parameter(:testing, "value") + @resource. merge(@override) + @resource_2.merge(@override) - @resource.merge(@override) + @resource [:testing].should == %w{old_val_1 new_val} + @resource_2[:testing].should == %w{old_val_2 new_val} + end - @resource[:testing].should == "value" - end + it "should promote tag overrides to real tags" do + @source.stubs(:child_of?).returns true + param = Puppet::Parser::Resource::Param.new(:name => :tag, :value => "testing", :source => @resource.source) - it "should add values to the parameter when the override was created with the '+>' syntax" do - @source.stubs(:child_of?).returns true - param = Puppet::Parser::Resource::Param.new(:name => :testing, :value => "testing", :source => @resource.source) - param.add = true + @override.set_parameter(param) - @override.set_parameter(param) + @resource.merge(@override) - @resource.set_parameter(:testing, "other") + @resource.tagged?("testing").should be_true + end - @resource.merge(@override) + end - @resource[:testing].should == %w{other testing} - end + it "should be able to be converted to a normal resource" do + @source = stub 'scope', :name => "myscope" + @resource = mkresource :source => @source + @resource.should respond_to(:to_resource) + end - it "should not merge parameter values when multiple resources are overriden with '+>' at once " do - @resource_2 = mkresource :source => @source + it "should use its resource converter to convert to a transportable resource" do + @source = stub 'scope', :name => "myscope" + @resource = mkresource :source => @source - @resource. set_parameter(:testing, "old_val_1") - @resource_2.set_parameter(:testing, "old_val_2") + newresource = Puppet::Resource.new(:file, "/my") + Puppet::Resource.expects(:new).returns(newresource) - @source.stubs(:child_of?).returns true - param = Puppet::Parser::Resource::Param.new(:name => :testing, :value => "new_val", :source => @resource.source) - param.add = true - @override.set_parameter(param) + newresource.expects(:to_trans).returns "mytrans" - @resource. merge(@override) - @resource_2.merge(@override) + @resource.to_trans.should == "mytrans" + end - @resource [:testing].should == %w{old_val_1 new_val} - @resource_2[:testing].should == %w{old_val_2 new_val} - end + it "should return nil if converted to a transportable resource and it is virtual" do + @source = stub 'scope', :name => "myscope" + @resource = mkresource :source => @source - it "should promote tag overrides to real tags" do - @source.stubs(:child_of?).returns true - param = Puppet::Parser::Resource::Param.new(:name => :tag, :value => "testing", :source => @resource.source) + @resource.expects(:virtual?).returns true + @resource.to_trans.should be_nil + end - @override.set_parameter(param) + describe "when being converted to a resource" do + before do + @parser_resource = mkresource :scope => @scope, :parameters => {:foo => "bar", :fee => "fum"} + end - @resource.merge(@override) + it "should create an instance of Puppet::Resource" do + @parser_resource.to_resource.should be_instance_of(Puppet::Resource) + end - @resource.tagged?("testing").should be_true - end + it "should set the type correctly on the Puppet::Resource" do + @parser_resource.to_resource.type.should == @parser_resource.type + end + it "should set the title correctly on the Puppet::Resource" do + @parser_resource.to_resource.title.should == @parser_resource.title end - it "should be able to be converted to a normal resource" do - @source = stub 'scope', :name => "myscope" - @resource = mkresource :source => @source - @resource.should respond_to(:to_resource) + it "should copy over all of the parameters" do + result = @parser_resource.to_resource.to_hash + + # The name will be in here, also. + result[:foo].should == "bar" + result[:fee].should == "fum" end - it "should use its resource converter to convert to a transportable resource" do - @source = stub 'scope', :name => "myscope" - @resource = mkresource :source => @source - - newresource = Puppet::Resource.new(:file, "/my") - Puppet::Resource.expects(:new).returns(newresource) + it "should copy over the tags" do + @parser_resource.tag "foo" + @parser_resource.tag "bar" - newresource.expects(:to_trans).returns "mytrans" + @parser_resource.to_resource.tags.should == @parser_resource.tags + end - @resource.to_trans.should == "mytrans" + it "should copy over the line" do + @parser_resource.line = 40 + @parser_resource.to_resource.line.should == 40 end - it "should return nil if converted to a transportable resource and it is virtual" do - @source = stub 'scope', :name => "myscope" - @resource = mkresource :source => @source + it "should copy over the file" do + @parser_resource.file = "/my/file" + @parser_resource.to_resource.file.should == "/my/file" + end - @resource.expects(:virtual?).returns true - @resource.to_trans.should be_nil + it "should copy over the 'exported' value" do + @parser_resource.exported = true + @parser_resource.to_resource.exported.should be_true end - describe "when being converted to a resource" do - before do - @parser_resource = mkresource :scope => @scope, :parameters => {:foo => "bar", :fee => "fum"} - end + it "should copy over the 'virtual' value" do + @parser_resource.virtual = true + @parser_resource.to_resource.virtual.should be_true + end - it "should create an instance of Puppet::Resource" do - @parser_resource.to_resource.should be_instance_of(Puppet::Resource) - end + it "should convert any parser resource references to Puppet::Resource instances" do + ref = Puppet::Resource.new("file", "/my/file") + @parser_resource = mkresource :source => @source, :parameters => {:foo => "bar", :fee => ref} + result = @parser_resource.to_resource + result[:fee].should == Puppet::Resource.new(:file, "/my/file") + end - it "should set the type correctly on the Puppet::Resource" do - @parser_resource.to_resource.type.should == @parser_resource.type - end + 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, :parameters => {:foo => "bar", :fee => ["a", ref]} + result = @parser_resource.to_resource + result[:fee].should == ["a", Puppet::Resource.new(:file, "/my/file")] + end - it "should set the title correctly on the Puppet::Resource" do - @parser_resource.to_resource.title.should == @parser_resource.title - end + 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, :parameters => {:foo => "bar", :fee => ["a", [ref1,ref2]]} + result = @parser_resource.to_resource + result[:fee].should == ["a", Puppet::Resource.new(:file, "/my/file1"), Puppet::Resource.new(:file, "/my/file2")] + end - it "should copy over all of the parameters" do - result = @parser_resource.to_resource.to_hash + it "should fail if the same param is declared twice" do + lambda do + @parser_resource = mkresource :source => @source, :parameters => [ + Puppet::Parser::Resource::Param.new( + :name => :foo, :value => "bar", :source => @source + ), + Puppet::Parser::Resource::Param.new( + :name => :foo, :value => "baz", :source => @source + ) + ] + 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 => @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 - # The name will be in here, also. - result[:foo].should == "bar" - result[:fee].should == "fum" - end + it "should raise a parse error when there's a failure" do + resource = Puppet::Parser::Resource.new :foo, "bar", :scope => @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 - it "should copy over the tags" do - @parser_resource.tag "foo" - @parser_resource.tag "bar" + describe "when setting parameters" do + before do + @source = newclass "foobar" + @resource = Puppet::Parser::Resource.new :foo, "bar", :scope => @scope, :source => @source + end - @parser_resource.to_resource.tags.should == @parser_resource.tags - 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 copy over the line" do - @parser_resource.line = 40 - @parser_resource.to_resource.line.should == 40 - 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 copy over the file" do - @parser_resource.file = "/my/file" - @parser_resource.to_resource.file.should == "/my/file" - end + it "should allow parameters to be set to 'false'" do + @resource.set_parameter("myparam", false) + @resource["myparam"].should be_false + end - it "should copy over the 'exported' value" do - @parser_resource.exported = true - @parser_resource.to_resource.exported.should be_true - end - - it "should copy over the 'virtual' value" do - @parser_resource.virtual = true - @parser_resource.to_resource.virtual.should be_true - end - - it "should convert any parser resource references to Puppet::Resource instances" do - ref = Puppet::Resource.new("file", "/my/file") - @parser_resource = mkresource :source => @source, :parameters => {:foo => "bar", :fee => ref} - result = @parser_resource.to_resource - result[:fee].should == Puppet::Resource.new(:file, "/my/file") - end - - 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, :parameters => {:foo => "bar", :fee => ["a", ref]} - result = @parser_resource.to_resource - result[:fee].should == ["a", Puppet::Resource.new(:file, "/my/file")] - end - - 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, :parameters => {:foo => "bar", :fee => ["a", [ref1,ref2]]} - result = @parser_resource.to_resource - 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 - lambda do - @parser_resource = mkresource :source => @source, :parameters => [ - Puppet::Parser::Resource::Param.new( - :name => :foo, :value => "bar", :source => @source - ), - Puppet::Parser::Resource::Param.new( - :name => :foo, :value => "baz", :source => @source - ) - ] - 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 => @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 => @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 => @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 allow parameters to be set to 'false'" do - @resource.set_parameter("myparam", false) - @resource["myparam"].should be_false - 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 + 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/scope_spec.rb b/spec/unit/parser/scope_spec.rb index 035d49c84..9895f446b 100755 --- a/spec/unit/parser/scope_spec.rb +++ b/spec/unit/parser/scope_spec.rb @@ -3,627 +3,627 @@ require File.dirname(__FILE__) + '/../../spec_helper' describe Puppet::Parser::Scope do - before :each do - @topscope = Puppet::Parser::Scope.new - # 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 + before :each do + @topscope = Puppet::Parser::Scope.new + # 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 + + it "should be able to store references to class scopes" do + lambda { @scope.class_set "myname", "myscope" }.should_not raise_error + end + + it "should be able to retrieve class scopes by name" do + @scope.class_set "myname", "myscope" + @scope.class_scope("myname").should == "myscope" + end + + it "should be able to retrieve class scopes by object" do + klass = mock 'ast_class' + klass.expects(:name).returns("myname") + @scope.class_set "myname", "myscope" + @scope.class_scope(klass).should == "myscope" + 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" + + @scope.parent_module_name.should == "foo" + end + + it "should return a nil parent module name if it has no parent" do + @topscope.parent_module_name.should be_nil + end + + it "should return a nil parent module name if its parent has no source" do + @scope.parent_module_name.should be_nil + end + + it "should get its environment from its compiler" do + env = stub 'environment' + compiler = stub 'compiler', :environment => env + scope = Puppet::Parser::Scope.new :compiler => compiler + scope.environment.should equal(env) + end + + it "should use the resource type collection helper to find its known resource types" do + Puppet::Parser::Scope.ancestors.should include(Puppet::Resource::TypeCollectionHelper) + end + + describe "when initializing" do + it "should extend itself with its environment's Functions module as well as the default" do + env = Puppet::Node::Environment.new("myenv") + compiler = stub 'compiler', :environment => env + mod = Module.new + root_mod = Module.new + Puppet::Parser::Functions.expects(:environment_module).with(Puppet::Node::Environment.root).returns root_mod + Puppet::Parser::Functions.expects(:environment_module).with(env).returns mod + + Puppet::Parser::Scope.new(:compiler => compiler).singleton_class.ancestors.should be_include(mod) end - it "should be able to store references to class scopes" do - lambda { @scope.class_set "myname", "myscope" }.should_not raise_error - end + it "should extend itself with the default Functions module if it has no environment" do + mod = Module.new + Puppet::Parser::Functions.expects(:environment_module).with(Puppet::Node::Environment.root).returns(mod) - it "should be able to retrieve class scopes by name" do - @scope.class_set "myname", "myscope" - @scope.class_scope("myname").should == "myscope" - end + Puppet::Parser::Functions.expects(:environment_module).with(nil).returns mod - it "should be able to retrieve class scopes by object" do - klass = mock 'ast_class' - klass.expects(:name).returns("myname") - @scope.class_set "myname", "myscope" - @scope.class_scope(klass).should == "myscope" + Puppet::Parser::Scope.new.singleton_class.ancestors.should be_include(mod) end + 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" - - @scope.parent_module_name.should == "foo" + describe "when looking up a variable" do + it "should default to an empty string" do + @scope.lookupvar("var").should == "" end - it "should return a nil parent module name if it has no parent" do - @topscope.parent_module_name.should be_nil + it "should return an string when asked for a string" do + @scope.lookupvar("var", true).should == "" end - it "should return a nil parent module name if its parent has no source" do - @scope.parent_module_name.should be_nil + it "should return ':undefined' for unset variables when asked not to return a string" do + @scope.lookupvar("var", false).should == :undefined end - it "should get its environment from its compiler" do - env = stub 'environment' - compiler = stub 'compiler', :environment => env - scope = Puppet::Parser::Scope.new :compiler => compiler - scope.environment.should equal(env) + it "should be able to look up values" do + @scope.setvar("var", "yep") + @scope.lookupvar("var").should == "yep" end - it "should use the resource type collection helper to find its known resource types" do - Puppet::Parser::Scope.ancestors.should include(Puppet::Resource::TypeCollectionHelper) + it "should be able to look up hashes" do + @scope.setvar("var", {"a" => "b"}) + @scope.lookupvar("var").should == {"a" => "b"} end - describe "when initializing" do - it "should extend itself with its environment's Functions module as well as the default" do - env = Puppet::Node::Environment.new("myenv") - compiler = stub 'compiler', :environment => env - mod = Module.new - root_mod = Module.new - Puppet::Parser::Functions.expects(:environment_module).with(Puppet::Node::Environment.root).returns root_mod - Puppet::Parser::Functions.expects(:environment_module).with(env).returns mod - - Puppet::Parser::Scope.new(:compiler => compiler).singleton_class.ancestors.should be_include(mod) - end - - it "should extend itself with the default Functions module if it has no environment" do - mod = Module.new - Puppet::Parser::Functions.expects(:environment_module).with(Puppet::Node::Environment.root).returns(mod) - - Puppet::Parser::Functions.expects(:environment_module).with(nil).returns mod - - Puppet::Parser::Scope.new.singleton_class.ancestors.should be_include(mod) - end + it "should be able to look up variables in parent scopes" do + @topscope.setvar("var", "parentval") + @scope.lookupvar("var").should == "parentval" end - describe "when looking up a variable" do - it "should default to an empty string" do - @scope.lookupvar("var").should == "" - end - - it "should return an string when asked for a string" do - @scope.lookupvar("var", true).should == "" - end - - it "should return ':undefined' for unset variables when asked not to return a string" do - @scope.lookupvar("var", false).should == :undefined - end - - it "should be able to look up values" do - @scope.setvar("var", "yep") - @scope.lookupvar("var").should == "yep" - end - - it "should be able to look up hashes" do - @scope.setvar("var", {"a" => "b"}) - @scope.lookupvar("var").should == {"a" => "b"} - end - - it "should be able to look up variables in parent scopes" do - @topscope.setvar("var", "parentval") - @scope.lookupvar("var").should == "parentval" - end - - it "should prefer its own values to parent values" do - @topscope.setvar("var", "parentval") - @scope.setvar("var", "childval") - @scope.lookupvar("var").should == "childval" - end + it "should prefer its own values to parent values" do + @topscope.setvar("var", "parentval") + @scope.setvar("var", "childval") + @scope.lookupvar("var").should == "childval" + end - describe "and the variable is qualified" do - before do - @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("foonode")) - @scope.compiler = @compiler - @known_resource_types = @scope.known_resource_types - end + describe "and the variable is qualified" do + before do + @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("foonode")) + @scope.compiler = @compiler + @known_resource_types = @scope.known_resource_types + end - def newclass(name) - @known_resource_types.add Puppet::Resource::Type.new(:hostclass, name) - end + def newclass(name) + @known_resource_types.add Puppet::Resource::Type.new(:hostclass, name) + end - def create_class_scope(name) - klass = newclass(name) - Puppet::Parser::Resource.new("class", name, :scope => @scope, :source => mock('source')).evaluate + def create_class_scope(name) + klass = newclass(name) + Puppet::Parser::Resource.new("class", name, :scope => @scope, :source => mock('source')).evaluate - @scope.class_scope(klass) - end + @scope.class_scope(klass) + end - it "should be able to look up explicitly fully qualified variables from main" do - other_scope = create_class_scope("") + it "should be able to look up explicitly fully qualified variables from main" do + other_scope = create_class_scope("") - other_scope.setvar("othervar", "otherval") + other_scope.setvar("othervar", "otherval") - @scope.lookupvar("::othervar").should == "otherval" - end + @scope.lookupvar("::othervar").should == "otherval" + end - it "should be able to look up explicitly fully qualified variables from other scopes" do - other_scope = create_class_scope("other") + it "should be able to look up explicitly fully qualified variables from other scopes" do + other_scope = create_class_scope("other") - other_scope.setvar("var", "otherval") + other_scope.setvar("var", "otherval") - @scope.lookupvar("::other::var").should == "otherval" - end + @scope.lookupvar("::other::var").should == "otherval" + end - it "should be able to look up deeply qualified variables" do - other_scope = create_class_scope("other::deep::klass") + it "should be able to look up deeply qualified variables" do + other_scope = create_class_scope("other::deep::klass") - other_scope.setvar("var", "otherval") + other_scope.setvar("var", "otherval") - @scope.lookupvar("other::deep::klass::var").should == "otherval" - end + @scope.lookupvar("other::deep::klass::var").should == "otherval" + end - it "should return an empty string for qualified variables that cannot be found in other classes" do - other_scope = create_class_scope("other::deep::klass") + it "should return an empty string for qualified variables that cannot be found in other classes" do + other_scope = create_class_scope("other::deep::klass") - @scope.lookupvar("other::deep::klass::var").should == "" - end + @scope.lookupvar("other::deep::klass::var").should == "" + end - it "should warn and return an empty string for qualified variables whose classes have not been evaluated" do - klass = newclass("other::deep::klass") - @scope.expects(:warning) - @scope.lookupvar("other::deep::klass::var").should == "" - end + it "should warn and return an empty string for qualified variables whose classes have not been evaluated" do + klass = newclass("other::deep::klass") + @scope.expects(:warning) + @scope.lookupvar("other::deep::klass::var").should == "" + end - it "should warn and return an empty string for qualified variables whose classes do not exist" do - @scope.expects(:warning) - @scope.lookupvar("other::deep::klass::var").should == "" - end + it "should warn and return an empty string for qualified variables whose classes do not exist" do + @scope.expects(:warning) + @scope.lookupvar("other::deep::klass::var").should == "" + end - it "should return ':undefined' when asked for a non-string qualified variable from a class that does not exist" do - @scope.stubs(:warning) - @scope.lookupvar("other::deep::klass::var", false).should == :undefined - end + it "should return ':undefined' when asked for a non-string qualified variable from a class that does not exist" do + @scope.stubs(:warning) + @scope.lookupvar("other::deep::klass::var", false).should == :undefined + end - it "should return ':undefined' when asked for a non-string qualified variable from a class that has not been evaluated" do - @scope.stubs(:warning) - klass = newclass("other::deep::klass") - @scope.lookupvar("other::deep::klass::var", false).should == :undefined - end - end + it "should return ':undefined' when asked for a non-string qualified variable from a class that has not been evaluated" do + @scope.stubs(:warning) + klass = newclass("other::deep::klass") + @scope.lookupvar("other::deep::klass::var", false).should == :undefined + end end + end - describe "when setvar is called with append=true" do - it "should raise error if the variable is already defined in this scope" do - @scope.setvar("var","1", :append => false) - lambda { @scope.setvar("var","1", :append => true) }.should raise_error(Puppet::ParseError) - end - - it "should lookup current variable value" do - @scope.expects(:lookupvar).with("var").returns("2") - @scope.setvar("var","1", :append => true) - end - - it "should store the concatenated string '42'" do - @topscope.setvar("var","4", :append => false) - @scope.setvar("var","2", :append => true) - @scope.lookupvar("var").should == "42" - end - - it "should store the concatenated array [4,2]" do - @topscope.setvar("var",[4], :append => false) - @scope.setvar("var",[2], :append => true) - @scope.lookupvar("var").should == [4,2] - end + describe "when setvar is called with append=true" do + it "should raise error if the variable is already defined in this scope" do + @scope.setvar("var","1", :append => false) + lambda { @scope.setvar("var","1", :append => true) }.should raise_error(Puppet::ParseError) + end - it "should store the merged hash {a => b, c => d}" do - @topscope.setvar("var",{"a" => "b"}, :append => false) - @scope.setvar("var",{"c" => "d"}, :append => true) - @scope.lookupvar("var").should == {"a" => "b", "c" => "d"} - end + it "should lookup current variable value" do + @scope.expects(:lookupvar).with("var").returns("2") + @scope.setvar("var","1", :append => true) + end - it "should raise an error when appending a hash with something other than another hash" do - @topscope.setvar("var",{"a" => "b"}, :append => false) - lambda { @scope.setvar("var","not a hash", :append => true) }.should raise_error - end + it "should store the concatenated string '42'" do + @topscope.setvar("var","4", :append => false) + @scope.setvar("var","2", :append => true) + @scope.lookupvar("var").should == "42" end - describe "when calling number?" do - it "should return nil if called with anything not a number" do - Puppet::Parser::Scope.number?([2]).should be_nil - end + it "should store the concatenated array [4,2]" do + @topscope.setvar("var",[4], :append => false) + @scope.setvar("var",[2], :append => true) + @scope.lookupvar("var").should == [4,2] + end - it "should return a Fixnum for a Fixnum" do - Puppet::Parser::Scope.number?(2).should be_an_instance_of(Fixnum) - end + it "should store the merged hash {a => b, c => d}" do + @topscope.setvar("var",{"a" => "b"}, :append => false) + @scope.setvar("var",{"c" => "d"}, :append => true) + @scope.lookupvar("var").should == {"a" => "b", "c" => "d"} + end - it "should return a Float for a Float" do - Puppet::Parser::Scope.number?(2.34).should be_an_instance_of(Float) - end + it "should raise an error when appending a hash with something other than another hash" do + @topscope.setvar("var",{"a" => "b"}, :append => false) + lambda { @scope.setvar("var","not a hash", :append => true) }.should raise_error + end + end - it "should return 234 for '234'" do - Puppet::Parser::Scope.number?("234").should == 234 - end + describe "when calling number?" do + it "should return nil if called with anything not a number" do + Puppet::Parser::Scope.number?([2]).should be_nil + end - it "should return nil for 'not a number'" do - Puppet::Parser::Scope.number?("not a number").should be_nil - end + it "should return a Fixnum for a Fixnum" do + Puppet::Parser::Scope.number?(2).should be_an_instance_of(Fixnum) + end - it "should return 23.4 for '23.4'" do - Puppet::Parser::Scope.number?("23.4").should == 23.4 - end + it "should return a Float for a Float" do + Puppet::Parser::Scope.number?(2.34).should be_an_instance_of(Float) + end - it "should return 23.4e13 for '23.4e13'" do - Puppet::Parser::Scope.number?("23.4e13").should == 23.4e13 - end + it "should return 234 for '234'" do + Puppet::Parser::Scope.number?("234").should == 234 + end - it "should understand negative numbers" do - Puppet::Parser::Scope.number?("-234").should == -234 - end + it "should return nil for 'not a number'" do + Puppet::Parser::Scope.number?("not a number").should be_nil + end - it "should know how to convert exponential float numbers ala '23e13'" do - Puppet::Parser::Scope.number?("23e13").should == 23e13 - end + it "should return 23.4 for '23.4'" do + Puppet::Parser::Scope.number?("23.4").should == 23.4 + end - it "should understand hexadecimal numbers" do - Puppet::Parser::Scope.number?("0x234").should == 0x234 - end + it "should return 23.4e13 for '23.4e13'" do + Puppet::Parser::Scope.number?("23.4e13").should == 23.4e13 + end - it "should understand octal numbers" do - Puppet::Parser::Scope.number?("0755").should == 0755 - end + it "should understand negative numbers" do + Puppet::Parser::Scope.number?("-234").should == -234 + end - it "should return nil on malformed integers" do - Puppet::Parser::Scope.number?("0.24.5").should be_nil - end + it "should know how to convert exponential float numbers ala '23e13'" do + Puppet::Parser::Scope.number?("23e13").should == 23e13 + end - it "should convert strings with leading 0 to integer if they are not octal" do - Puppet::Parser::Scope.number?("0788").should == 788 - end + it "should understand hexadecimal numbers" do + Puppet::Parser::Scope.number?("0x234").should == 0x234 + end - it "should convert strings of negative integers" do - Puppet::Parser::Scope.number?("-0788").should == -788 - end + it "should understand octal numbers" do + Puppet::Parser::Scope.number?("0755").should == 0755 + end - it "should return nil on malformed hexadecimal numbers" do - Puppet::Parser::Scope.number?("0x89g").should be_nil - end + it "should return nil on malformed integers" do + Puppet::Parser::Scope.number?("0.24.5").should be_nil end - describe "when using ephemeral variables" do - it "should store the variable value" do - @scope.setvar("1", :value, :ephemeral => true) + it "should convert strings with leading 0 to integer if they are not octal" do + Puppet::Parser::Scope.number?("0788").should == 788 + end - @scope.lookupvar("1").should == :value - end + it "should convert strings of negative integers" do + Puppet::Parser::Scope.number?("-0788").should == -788 + end - it "should remove the variable value when unset_ephemeral_var is called" do - @scope.setvar("1", :value, :ephemeral => true) - @scope.stubs(:parent).returns(nil) + it "should return nil on malformed hexadecimal numbers" do + Puppet::Parser::Scope.number?("0x89g").should be_nil + end + end - @scope.unset_ephemeral_var + describe "when using ephemeral variables" do + it "should store the variable value" do + @scope.setvar("1", :value, :ephemeral => true) - @scope.lookupvar("1", false).should == :undefined - end + @scope.lookupvar("1").should == :value + end - it "should not remove classic variables when unset_ephemeral_var is called" do - @scope.setvar("myvar", :value1) - @scope.setvar("1", :value2, :ephemeral => true) - @scope.stubs(:parent).returns(nil) + it "should remove the variable value when unset_ephemeral_var is called" do + @scope.setvar("1", :value, :ephemeral => true) + @scope.stubs(:parent).returns(nil) - @scope.unset_ephemeral_var + @scope.unset_ephemeral_var - @scope.lookupvar("myvar", false).should == :value1 - end + @scope.lookupvar("1", false).should == :undefined + end - it "should raise an error when setting it again" do - @scope.setvar("1", :value2, :ephemeral => true) - lambda { @scope.setvar("1", :value3, :ephemeral => true) }.should raise_error - end + it "should not remove classic variables when unset_ephemeral_var is called" do + @scope.setvar("myvar", :value1) + @scope.setvar("1", :value2, :ephemeral => true) + @scope.stubs(:parent).returns(nil) - it "should declare ephemeral number only variable names" do - @scope.ephemeral?("0").should be_true - end + @scope.unset_ephemeral_var - it "should not declare ephemeral other variable names" do - @scope.ephemeral?("abc0").should be_nil - end + @scope.lookupvar("myvar", false).should == :value1 + end - describe "with more than one level" do - it "should prefer latest ephemeral scopes" do - @scope.setvar("0", :earliest, :ephemeral => true) - @scope.new_ephemeral - @scope.setvar("0", :latest, :ephemeral => true) - @scope.lookupvar("0", false).should == :latest - end - - it "should be able to report the current level" do - @scope.ephemeral_level.should == 1 - @scope.new_ephemeral - @scope.ephemeral_level.should == 2 - end - - it "should check presence of an ephemeral variable accross multiple levels" do - @scope.new_ephemeral - @scope.setvar("1", :value1, :ephemeral => true) - @scope.new_ephemeral - @scope.setvar("0", :value2, :ephemeral => true) - @scope.new_ephemeral - @scope.ephemeral_include?("1").should be_true - end - - it "should return false when an ephemeral variable doesn't exist in any ephemeral scope" do - @scope.new_ephemeral - @scope.setvar("1", :value1, :ephemeral => true) - @scope.new_ephemeral - @scope.setvar("0", :value2, :ephemeral => true) - @scope.new_ephemeral - @scope.ephemeral_include?("2").should be_false - end - - it "should get ephemeral values from earlier scope when not in later" do - @scope.setvar("1", :value1, :ephemeral => true) - @scope.new_ephemeral - @scope.setvar("0", :value2, :ephemeral => true) - @scope.lookupvar("1", false).should == :value1 - end - - describe "when calling unset_ephemeral_var without a level" do - it "should remove all the variables values" do - @scope.setvar("1", :value1, :ephemeral => true) - @scope.new_ephemeral - @scope.setvar("1", :value2, :ephemeral => true) - - @scope.unset_ephemeral_var - - @scope.lookupvar("1", false).should == :undefined - end - end - - describe "when calling unset_ephemeral_var with a level" do - it "should remove ephemeral scopes up to this level" do - @scope.setvar("1", :value1, :ephemeral => true) - @scope.new_ephemeral - @scope.setvar("1", :value2, :ephemeral => true) - @scope.new_ephemeral - @scope.setvar("1", :value3, :ephemeral => true) - - @scope.unset_ephemeral_var(2) - - @scope.lookupvar("1", false).should == :value2 - end - end - end + it "should raise an error when setting it again" do + @scope.setvar("1", :value2, :ephemeral => true) + lambda { @scope.setvar("1", :value3, :ephemeral => true) }.should raise_error end - describe "when interpolating string" do - (0..9).each do |n| - it "should allow $#{n} to match" do - @scope.setvar(n.to_s, "value", :ephemeral => true) + it "should declare ephemeral number only variable names" do + @scope.ephemeral?("0").should be_true + end - @scope.strinterp("$#{n}").should == "value" - end - end + it "should not declare ephemeral other variable names" do + @scope.ephemeral?("abc0").should be_nil + end - (0..9).each do |n| - it "should not allow $#{n} to match if not ephemeral" do - @scope.setvar(n.to_s, "value", :ephemeral => false) + describe "with more than one level" do + it "should prefer latest ephemeral scopes" do + @scope.setvar("0", :earliest, :ephemeral => true) + @scope.new_ephemeral + @scope.setvar("0", :latest, :ephemeral => true) + @scope.lookupvar("0", false).should == :latest + end + + it "should be able to report the current level" do + @scope.ephemeral_level.should == 1 + @scope.new_ephemeral + @scope.ephemeral_level.should == 2 + end + + it "should check presence of an ephemeral variable accross multiple levels" do + @scope.new_ephemeral + @scope.setvar("1", :value1, :ephemeral => true) + @scope.new_ephemeral + @scope.setvar("0", :value2, :ephemeral => true) + @scope.new_ephemeral + @scope.ephemeral_include?("1").should be_true + end + + it "should return false when an ephemeral variable doesn't exist in any ephemeral scope" do + @scope.new_ephemeral + @scope.setvar("1", :value1, :ephemeral => true) + @scope.new_ephemeral + @scope.setvar("0", :value2, :ephemeral => true) + @scope.new_ephemeral + @scope.ephemeral_include?("2").should be_false + end + + it "should get ephemeral values from earlier scope when not in later" do + @scope.setvar("1", :value1, :ephemeral => true) + @scope.new_ephemeral + @scope.setvar("0", :value2, :ephemeral => true) + @scope.lookupvar("1", false).should == :value1 + end + + describe "when calling unset_ephemeral_var without a level" do + it "should remove all the variables values" do + @scope.setvar("1", :value1, :ephemeral => true) + @scope.new_ephemeral + @scope.setvar("1", :value2, :ephemeral => true) + + @scope.unset_ephemeral_var + + @scope.lookupvar("1", false).should == :undefined + end + end + + describe "when calling unset_ephemeral_var with a level" do + it "should remove ephemeral scopes up to this level" do + @scope.setvar("1", :value1, :ephemeral => true) + @scope.new_ephemeral + @scope.setvar("1", :value2, :ephemeral => true) + @scope.new_ephemeral + @scope.setvar("1", :value3, :ephemeral => true) + + @scope.unset_ephemeral_var(2) + + @scope.lookupvar("1", false).should == :value2 + end + end + end + end - @scope.strinterp("$#{n}").should_not == "value" - end - end + describe "when interpolating string" do + (0..9).each do |n| + it "should allow $#{n} to match" do + @scope.setvar(n.to_s, "value", :ephemeral => true) - it "should not allow $10 to match" do - @scope.setvar("10", "value", :ephemeral => true) + @scope.strinterp("$#{n}").should == "value" + end + end - @scope.strinterp('==$10==').should_not == "==value==" - end + (0..9).each do |n| + it "should not allow $#{n} to match if not ephemeral" do + @scope.setvar(n.to_s, "value", :ephemeral => false) - it "should not allow ${10} to match" do - @scope.setvar("10", "value", :ephemeral => true) + @scope.strinterp("$#{n}").should_not == "value" + end + end - @scope.strinterp('==${10}==').should == "==value==" - end + it "should not allow $10 to match" do + @scope.setvar("10", "value", :ephemeral => true) - 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.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.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 + @scope.strinterp('==$10==').should_not == "==value==" + 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 + it "should not allow ${10} to match" do + @scope.setvar("10", "value", :ephemeral => true) - # #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 + @scope.strinterp('==${10}==').should == "==value==" 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 + 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.class_scope(klass) + @scopes[""].setvar("test", "value") - assert_nothing_raised { - scope.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.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 - scopes = {"" => scope} + 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 - %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.class_scope(klass) - scopes[name].setvar("test", "value-#{name.sub(/.+::/,'')}") - 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.class_scope(klass) + scopes[name].setvar("test", "value-#{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 #{input.inspect}") do - assert_equal(output, scope.strinterp(input), 'did not parserret %s correctly' % input.inspect) - end - 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 #{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) + 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 + # #523 + %w{d f h l w z}.each do |l| + string = "\\#{l}" + assert_nothing_raised do - assert_equal( - string, scope.strinterp(string), + assert_equal( + string, scope.strinterp(string), - 'did not parserret %s correctly' % string) - end + 'did not parserret %s correctly' % string) + end - assert( - logs.detect { |m| m.message =~ /Unrecognised escape/ }, + assert( + logs.detect { |m| m.message =~ /Unrecognised escape/ }, - "Did not get warning about escape sequence with #{string}") - logs.clear - end + "Did not get warning about escape sequence with #{string}") + logs.clear end + end - describe "when setting ephemeral vars from matches" do - before :each do - @match = stub 'match', :is_a? => true - @match.stubs(:[]).with(0).returns("this is a string") - @match.stubs(:captures).returns([]) - @scope.stubs(:setvar) - end - - it "should accept only MatchData" do - lambda { @scope.ephemeral_from("match") }.should raise_error - end - - it "should set $0 with the full match" do - @scope.expects(:setvar).with { |*arg| arg[0] == "0" and arg[1] == "this is a string" and arg[2][:ephemeral] } - - @scope.ephemeral_from(@match) - end + describe "when setting ephemeral vars from matches" do + before :each do + @match = stub 'match', :is_a? => true + @match.stubs(:[]).with(0).returns("this is a string") + @match.stubs(:captures).returns([]) + @scope.stubs(:setvar) + end - it "should set every capture as ephemeral var" do - @match.stubs(:captures).returns([:capture1,:capture2]) - @scope.expects(:setvar).with { |*arg| arg[0] == "1" and arg[1] == :capture1 and arg[2][:ephemeral] } - @scope.expects(:setvar).with { |*arg| arg[0] == "2" and arg[1] == :capture2 and arg[2][:ephemeral] } + it "should accept only MatchData" do + lambda { @scope.ephemeral_from("match") }.should raise_error + end - @scope.ephemeral_from(@match) - end + it "should set $0 with the full match" do + @scope.expects(:setvar).with { |*arg| arg[0] == "0" and arg[1] == "this is a string" and arg[2][:ephemeral] } - it "should create a new ephemeral level" do - @scope.expects(:new_ephemeral) - @scope.ephemeral_from(@match) - end + @scope.ephemeral_from(@match) end - describe "when unsetting variables" do - it "should be able to unset normal variables" do - @scope.setvar("foo", "bar") - @scope.unsetvar("foo") - @scope.lookupvar("foo").should == "" - end + it "should set every capture as ephemeral var" do + @match.stubs(:captures).returns([:capture1,:capture2]) + @scope.expects(:setvar).with { |*arg| arg[0] == "1" and arg[1] == :capture1 and arg[2][:ephemeral] } + @scope.expects(:setvar).with { |*arg| arg[0] == "2" and arg[1] == :capture2 and arg[2][:ephemeral] } - it "should be able to unset ephemeral variables" do - @scope.setvar("0", "bar", :ephemeral => true) - @scope.unsetvar("0") - @scope.lookupvar("0").should == "" - end + @scope.ephemeral_from(@match) + end - it "should not unset ephemeral variables in previous ephemeral scope" do - @scope.setvar("0", "bar", :ephemeral => true) - @scope.new_ephemeral - @scope.unsetvar("0") - @scope.lookupvar("0").should == "bar" - end + it "should create a new ephemeral level" do + @scope.expects(:new_ephemeral) + @scope.ephemeral_from(@match) 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) + describe "when unsetting variables" do + it "should be able to unset normal variables" do + @scope.setvar("foo", "bar") + @scope.unsetvar("foo") + @scope.lookupvar("foo").should == "" 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) + it "should be able to unset ephemeral variables" do + @scope.setvar("0", "bar", :ephemeral => true) + @scope.unsetvar("0") + @scope.lookupvar("0").should == "" 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 not unset ephemeral variables in previous ephemeral scope" do + @scope.setvar("0", "bar", :ephemeral => true) + @scope.new_ephemeral + @scope.unsetvar("0") + @scope.lookupvar("0").should == "bar" + 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 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) + 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 + @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) + 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 = @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 + child_scope.lookupdefaults(:mytype).should == {:myparam => param1, :other => param2} end + end end diff --git a/spec/unit/parser/templatewrapper_spec.rb b/spec/unit/parser/templatewrapper_spec.rb index a684727de..d4d1d1b8e 100755 --- a/spec/unit/parser/templatewrapper_spec.rb +++ b/spec/unit/parser/templatewrapper_spec.rb @@ -3,142 +3,142 @@ require File.dirname(__FILE__) + '/../../spec_helper' describe Puppet::Parser::TemplateWrapper do - before(:each) do - @known_resource_types = Puppet::Resource::TypeCollection.new("env") - @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("mynode")) - @compiler.environment.stubs(:known_resource_types).returns @known_resource_types - @scope = Puppet::Parser::Scope.new :compiler => @compiler - - @file = "fake_template" - Puppet::Parser::Files.stubs(:find_template).returns("/tmp/fake_template") - FileTest.stubs(:exists?).returns("true") - File.stubs(:read).with("/tmp/fake_template").returns("template content") - @tw = Puppet::Parser::TemplateWrapper.new(@scope) - end - - it "should create a new object TemplateWrapper from a scope" do - tw = Puppet::Parser::TemplateWrapper.new(@scope) - - tw.should be_a_kind_of(Puppet::Parser::TemplateWrapper) - end - - it "should check template file existance and read its content" do - Puppet::Parser::Files.expects(:find_template).with("fake_template", @scope.environment.to_s).returns("/tmp/fake_template") - File.expects(:read).with("/tmp/fake_template").returns("template content") - - @tw.file = @file - end - - it "should mark the file for watching" do - Puppet::Parser::Files.expects(:find_template).returns("/tmp/fake_template") - File.stubs(:read) - - @known_resource_types.expects(:watch_file).with("/tmp/fake_template") - @tw.file = @file - end - - it "should fail if a template cannot be found" do - Puppet::Parser::Files.expects(:find_template).returns nil - - lambda { @tw.file = @file }.should raise_error(Puppet::ParseError) - end - - it "should turn into a string like template[name] for file based template" do - @tw.file = @file - @tw.to_s.should eql("template[/tmp/fake_template]") - end - - it "should turn into a string like template[inline] for string-based template" do - @tw.to_s.should eql("template[inline]") - end - - it "should return the processed template contents with a call to result" do - template_mock = mock("template", :result => "woot!") - File.expects(:read).with("/tmp/fake_template").returns("template contents") - ERB.expects(:new).with("template contents", 0, "-").returns(template_mock) - - @tw.file = @file - @tw.result.should eql("woot!") - end - - it "should return the processed template contents with a call to result and a string" do - template_mock = mock("template", :result => "woot!") - ERB.expects(:new).with("template contents", 0, "-").returns(template_mock) - - @tw.result("template contents").should eql("woot!") - end - - it "should return the contents of a variable if called via method_missing" do - @scope.expects(:lookupvar).with("chicken", false).returns("is good") - tw = Puppet::Parser::TemplateWrapper.new(@scope) - tw.chicken.should eql("is good") - end - - it "should throw an exception if a variable is called via method_missing and it does not exist" do - @scope.expects(:lookupvar).with("chicken", false).returns(:undefined) - tw = Puppet::Parser::TemplateWrapper.new(@scope) - lambda { tw.chicken }.should raise_error(Puppet::ParseError) - end - - it "should allow you to check whether a variable is defined with has_variable?" do - @scope.expects(:lookupvar).with("chicken", false).returns("is good") - tw = Puppet::Parser::TemplateWrapper.new(@scope) - tw.has_variable?("chicken").should eql(true) - end - - it "should allow you to check whether a variable is not defined with has_variable?" do - @scope.expects(:lookupvar).with("chicken", false).returns(:undefined) - tw = Puppet::Parser::TemplateWrapper.new(@scope) - tw.has_variable?("chicken").should eql(false) - end - - it "should allow you to retrieve the defined classes with classes" do - catalog = mock 'catalog', :classes => ["class1", "class2"] - @scope.expects(:catalog).returns( catalog ) - tw = Puppet::Parser::TemplateWrapper.new(@scope) - tw.classes.should == ["class1", "class2"] - end - - it "should allow you to retrieve all the tags with all_tags" do - catalog = mock 'catalog', :tags => ["tag1", "tag2"] - @scope.expects(:catalog).returns( catalog ) - tw = Puppet::Parser::TemplateWrapper.new(@scope) - tw.all_tags.should == ["tag1","tag2"] - end - - it "should allow you to retrieve the tags defined in the current scope" do - @scope.expects(:tags).returns( ["tag1", "tag2"] ) - tw = Puppet::Parser::TemplateWrapper.new(@scope) - tw.tags.should == ["tag1","tag2"] - end - - it "should set all of the scope's variables as instance variables" do - template_mock = mock("template", :result => "woot!") - ERB.expects(:new).with("template contents", 0, "-").returns(template_mock) - - @scope.expects(:to_hash).returns("one" => "foo") - @tw.result("template contents") - - @tw.instance_variable_get("@one").should == "foo" - end - - it "should not error out if one of the variables is a symbol" do - template_mock = mock("template", :result => "woot!") - ERB.expects(:new).with("template contents", 0, "-").returns(template_mock) - - @scope.expects(:to_hash).returns(:_timestamp => "1234") - @tw.result("template contents") - end - - %w{! . ; :}.each do |badchar| - it "should translate #{badchar} to _ when setting the instance variables" do - template_mock = mock("template", :result => "woot!") - ERB.expects(:new).with("template contents", 0, "-").returns(template_mock) - - @scope.expects(:to_hash).returns("one#{badchar}" => "foo") - @tw.result("template contents") - - @tw.instance_variable_get("@one_").should == "foo" - end - end + before(:each) do + @known_resource_types = Puppet::Resource::TypeCollection.new("env") + @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("mynode")) + @compiler.environment.stubs(:known_resource_types).returns @known_resource_types + @scope = Puppet::Parser::Scope.new :compiler => @compiler + + @file = "fake_template" + Puppet::Parser::Files.stubs(:find_template).returns("/tmp/fake_template") + FileTest.stubs(:exists?).returns("true") + File.stubs(:read).with("/tmp/fake_template").returns("template content") + @tw = Puppet::Parser::TemplateWrapper.new(@scope) + end + + it "should create a new object TemplateWrapper from a scope" do + tw = Puppet::Parser::TemplateWrapper.new(@scope) + + tw.should be_a_kind_of(Puppet::Parser::TemplateWrapper) + end + + it "should check template file existance and read its content" do + Puppet::Parser::Files.expects(:find_template).with("fake_template", @scope.environment.to_s).returns("/tmp/fake_template") + File.expects(:read).with("/tmp/fake_template").returns("template content") + + @tw.file = @file + end + + it "should mark the file for watching" do + Puppet::Parser::Files.expects(:find_template).returns("/tmp/fake_template") + File.stubs(:read) + + @known_resource_types.expects(:watch_file).with("/tmp/fake_template") + @tw.file = @file + end + + it "should fail if a template cannot be found" do + Puppet::Parser::Files.expects(:find_template).returns nil + + lambda { @tw.file = @file }.should raise_error(Puppet::ParseError) + end + + it "should turn into a string like template[name] for file based template" do + @tw.file = @file + @tw.to_s.should eql("template[/tmp/fake_template]") + end + + it "should turn into a string like template[inline] for string-based template" do + @tw.to_s.should eql("template[inline]") + end + + it "should return the processed template contents with a call to result" do + template_mock = mock("template", :result => "woot!") + File.expects(:read).with("/tmp/fake_template").returns("template contents") + ERB.expects(:new).with("template contents", 0, "-").returns(template_mock) + + @tw.file = @file + @tw.result.should eql("woot!") + end + + it "should return the processed template contents with a call to result and a string" do + template_mock = mock("template", :result => "woot!") + ERB.expects(:new).with("template contents", 0, "-").returns(template_mock) + + @tw.result("template contents").should eql("woot!") + end + + it "should return the contents of a variable if called via method_missing" do + @scope.expects(:lookupvar).with("chicken", false).returns("is good") + tw = Puppet::Parser::TemplateWrapper.new(@scope) + tw.chicken.should eql("is good") + end + + it "should throw an exception if a variable is called via method_missing and it does not exist" do + @scope.expects(:lookupvar).with("chicken", false).returns(:undefined) + tw = Puppet::Parser::TemplateWrapper.new(@scope) + lambda { tw.chicken }.should raise_error(Puppet::ParseError) + end + + it "should allow you to check whether a variable is defined with has_variable?" do + @scope.expects(:lookupvar).with("chicken", false).returns("is good") + tw = Puppet::Parser::TemplateWrapper.new(@scope) + tw.has_variable?("chicken").should eql(true) + end + + it "should allow you to check whether a variable is not defined with has_variable?" do + @scope.expects(:lookupvar).with("chicken", false).returns(:undefined) + tw = Puppet::Parser::TemplateWrapper.new(@scope) + tw.has_variable?("chicken").should eql(false) + end + + it "should allow you to retrieve the defined classes with classes" do + catalog = mock 'catalog', :classes => ["class1", "class2"] + @scope.expects(:catalog).returns( catalog ) + tw = Puppet::Parser::TemplateWrapper.new(@scope) + tw.classes.should == ["class1", "class2"] + end + + it "should allow you to retrieve all the tags with all_tags" do + catalog = mock 'catalog', :tags => ["tag1", "tag2"] + @scope.expects(:catalog).returns( catalog ) + tw = Puppet::Parser::TemplateWrapper.new(@scope) + tw.all_tags.should == ["tag1","tag2"] + end + + it "should allow you to retrieve the tags defined in the current scope" do + @scope.expects(:tags).returns( ["tag1", "tag2"] ) + tw = Puppet::Parser::TemplateWrapper.new(@scope) + tw.tags.should == ["tag1","tag2"] + end + + it "should set all of the scope's variables as instance variables" do + template_mock = mock("template", :result => "woot!") + ERB.expects(:new).with("template contents", 0, "-").returns(template_mock) + + @scope.expects(:to_hash).returns("one" => "foo") + @tw.result("template contents") + + @tw.instance_variable_get("@one").should == "foo" + end + + it "should not error out if one of the variables is a symbol" do + template_mock = mock("template", :result => "woot!") + ERB.expects(:new).with("template contents", 0, "-").returns(template_mock) + + @scope.expects(:to_hash).returns(:_timestamp => "1234") + @tw.result("template contents") + end + + %w{! . ; :}.each do |badchar| + it "should translate #{badchar} to _ when setting the instance variables" do + template_mock = mock("template", :result => "woot!") + ERB.expects(:new).with("template contents", 0, "-").returns(template_mock) + + @scope.expects(:to_hash).returns("one#{badchar}" => "foo") + @tw.result("template contents") + + @tw.instance_variable_get("@one_").should == "foo" + end + end end diff --git a/spec/unit/parser/type_loader_spec.rb b/spec/unit/parser/type_loader_spec.rb index 2cd837c78..db72a236e 100644 --- a/spec/unit/parser/type_loader_spec.rb +++ b/spec/unit/parser/type_loader_spec.rb @@ -6,196 +6,196 @@ require 'puppet/parser/type_loader' require 'puppet_spec/files' describe Puppet::Parser::TypeLoader do - include PuppetSpec::Files + include PuppetSpec::Files + before do + @loader = Puppet::Parser::TypeLoader.new(:myenv) + end + + it "should support an environment" do + loader = Puppet::Parser::TypeLoader.new(:myenv) + loader.environment.name.should == :myenv + end + + it "should include the Environment Helper" do + @loader.class.ancestors.should be_include(Puppet::Node::Environment::Helper) + end + + it "should delegate its known resource types to its environment" do + @loader.known_resource_types.should be_instance_of(Puppet::Resource::TypeCollection) + end + + 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 } + end + + it "should attempt to import each generated name" do + @loader.expects(:name2files).returns %w{foo bar} + @loader.expects(:import).with("foo") + @loader.expects(:import).with("bar") + @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") + @loader.expects(:import).with("bar") + @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") + @loader.expects(:import).with("bar") + @loader.expects(:import).with("baz").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") + @loader.expects(:import).with("bar") + @loader.expects(:import).with("baz").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") + @loader.expects(:import).with("bar") + @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") + @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 + end + end + + describe "when importing" do + before do + Puppet::Parser::Files.stubs(:find_manifests).returns ["modname", %w{file}] + @loader.stubs(:parse_file) + end + + it "should return immediately when imports are being ignored" do + Puppet::Parser::Files.expects(:find_manifests).never + Puppet[:ignoreimport] = true + @loader.import("foo").should be_nil + end + + it "should find all manifests matching the file or pattern" do + Puppet::Parser::Files.expects(:find_manifests).with { |pat, opts| pat == "myfile" }.returns ["modname", %w{one}] + @loader.import("myfile") + end + + it "should use the directory of the current file if one is set" do + Puppet::Parser::Files.expects(:find_manifests).with { |pat, opts| opts[:cwd] == "/current" }.returns ["modname", %w{one}] + @loader.import("myfile", "/current/file") + end + + it "should pass the environment when looking for files" do + Puppet::Parser::Files.expects(:find_manifests).with { |pat, opts| opts[:environment] == @loader.environment }.returns ["modname", %w{one}] + @loader.import("myfile") + end + + it "should fail if no files are found" do + Puppet::Parser::Files.expects(:find_manifests).returns [nil, []] + lambda { @loader.import("myfile") }.should raise_error(Puppet::ImportError) + end + + it "should parse each found file" do + Puppet::Parser::Files.expects(:find_manifests).returns ["modname", %w{/one}] + @loader.expects(:parse_file).with("/one") + @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.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 + @loader.import("myfile") + + # This will fail if it tries to reimport the file. + @loader.import("myfile") + end + end + + describe "when parsing a file" do before do - @loader = Puppet::Parser::TypeLoader.new(:myenv) - end - - it "should support an environment" do - loader = Puppet::Parser::TypeLoader.new(:myenv) - loader.environment.name.should == :myenv - end - - it "should include the Environment Helper" do - @loader.class.ancestors.should be_include(Puppet::Node::Environment::Helper) - end - - it "should delegate its known resource types to its environment" do - @loader.known_resource_types.should be_instance_of(Puppet::Resource::TypeCollection) - end - - 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 } - end - - it "should attempt to import each generated name" do - @loader.expects(:name2files).returns %w{foo bar} - @loader.expects(:import).with("foo") - @loader.expects(:import).with("bar") - @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") - @loader.expects(:import).with("bar") - @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") - @loader.expects(:import).with("bar") - @loader.expects(:import).with("baz").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") - @loader.expects(:import).with("bar") - @loader.expects(:import).with("baz").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") - @loader.expects(:import).with("bar") - @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") - @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 - end - end - - describe "when importing" do - before do - Puppet::Parser::Files.stubs(:find_manifests).returns ["modname", %w{file}] - @loader.stubs(:parse_file) - end - - it "should return immediately when imports are being ignored" do - Puppet::Parser::Files.expects(:find_manifests).never - Puppet[:ignoreimport] = true - @loader.import("foo").should be_nil - end - - it "should find all manifests matching the file or pattern" do - Puppet::Parser::Files.expects(:find_manifests).with { |pat, opts| pat == "myfile" }.returns ["modname", %w{one}] - @loader.import("myfile") - end - - it "should use the directory of the current file if one is set" do - Puppet::Parser::Files.expects(:find_manifests).with { |pat, opts| opts[:cwd] == "/current" }.returns ["modname", %w{one}] - @loader.import("myfile", "/current/file") - end - - it "should pass the environment when looking for files" do - Puppet::Parser::Files.expects(:find_manifests).with { |pat, opts| opts[:environment] == @loader.environment }.returns ["modname", %w{one}] - @loader.import("myfile") - end - - it "should fail if no files are found" do - Puppet::Parser::Files.expects(:find_manifests).returns [nil, []] - lambda { @loader.import("myfile") }.should raise_error(Puppet::ImportError) - end - - it "should parse each found file" do - Puppet::Parser::Files.expects(:find_manifests).returns ["modname", %w{/one}] - @loader.expects(:parse_file).with("/one") - @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.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 - @loader.import("myfile") - - # This will fail if it tries to reimport the file. - @loader.import("myfile") - end - end - - describe "when parsing a file" do - before do - @parser = Puppet::Parser::Parser.new(@loader.environment) - @parser.stubs(:parse) - @parser.stubs(:file=) - Puppet::Parser::Parser.stubs(:new).with(@loader.environment).returns @parser - end - - it "should create a new parser instance for each file using the current environment" do - Puppet::Parser::Parser.expects(:new).with(@loader.environment).returns @parser - @loader.parse_file("/my/file") - end - - it "should assign the parser its file and parse" do - @parser.expects(:file=).with("/my/file") - @parser.expects(:parse) - @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.open(file, "w") { |f| f.puts "class foo {}" } - @loader.import(file) - - @loader.known_resource_types.hostclass("foo").should be_instance_of(Puppet::Resource::Type) + @parser = Puppet::Parser::Parser.new(@loader.environment) + @parser.stubs(:parse) + @parser.stubs(:file=) + Puppet::Parser::Parser.stubs(:new).with(@loader.environment).returns @parser end + + it "should create a new parser instance for each file using the current environment" do + Puppet::Parser::Parser.expects(:new).with(@loader.environment).returns @parser + @loader.parse_file("/my/file") + end + + it "should assign the parser its file and parse" do + @parser.expects(:file=).with("/my/file") + @parser.expects(:parse) + @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.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 end |
