From 0d2e0672eb516a1b1f2ced6b8c74bd2064dd205e Mon Sep 17 00:00:00 2001 From: Luke Kanies Date: Wed, 8 Jun 2011 07:03:54 -0700 Subject: Adding []/[]= support to Scope The interface to scope is much clearer this way anyway, but this is needed to integrate Puppet with Hiera[1]. It just provides hash-like behavior to Scope, which Hiera and others can now easily rely on. I also went through all of the code that used Scope#lookupvar and Scope#setvar and changed it if possible, and at the same time cleaned up a lot of tests that were unnecessarily stubbing (and thus making it difficult to tell if I had actually broken anything). 1 - https://github.com/ripienaar/hiera Signed-off-by: Luke Kanies Reviewed-by: Nick Lewis --- spec/unit/parser/ast/casestatement_spec.rb | 2 +- spec/unit/parser/ast/leaf_spec.rb | 53 ++++++++-------- spec/unit/parser/ast/resource_reference_spec.rb | 2 +- spec/unit/parser/compiler_spec.rb | 4 +- spec/unit/parser/functions/extlookup_spec.rb | 10 +-- spec/unit/parser/functions/fqdn_rand_spec.rb | 12 +--- spec/unit/parser/resource_spec.rb | 6 +- spec/unit/parser/scope_spec.rb | 83 +++++++++++++------------ spec/unit/parser/templatewrapper_spec.rb | 6 +- 9 files changed, 85 insertions(+), 93 deletions(-) (limited to 'spec/unit/parser') diff --git a/spec/unit/parser/ast/casestatement_spec.rb b/spec/unit/parser/ast/casestatement_spec.rb index e21190706..a76a9ae1f 100755 --- a/spec/unit/parser/ast/casestatement_spec.rb +++ b/spec/unit/parser/ast/casestatement_spec.rb @@ -154,7 +154,7 @@ describe Puppet::Parser::AST::CaseStatement do tests.each do |should, values| values.each do |value| @scope = Puppet::Parser::Scope.new - @scope.setvar("testparam", value) + @scope['testparam'] = value result = ast.evaluate(@scope) result.should == should diff --git a/spec/unit/parser/ast/leaf_spec.rb b/spec/unit/parser/ast/leaf_spec.rb index ff3fed5e9..36c790a41 100755 --- a/spec/unit/parser/ast/leaf_spec.rb +++ b/spec/unit/parser/ast/leaf_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' describe Puppet::Parser::AST::Leaf do before :each do - @scope = stub 'scope' + @scope = Puppet::Parser::Scope.new @value = stub 'value' @leaf = Puppet::Parser::AST::Leaf.new(:value => @value) end @@ -56,7 +56,7 @@ end describe Puppet::Parser::AST::Concat do describe "when evaluating" do before :each do - @scope = stub_everything 'scope' + @scope = Puppet::Parser::Scope.new end it "should interpolate variables and concatenate their values" do one = Puppet::Parser::AST::String.new(:value => "one") @@ -86,7 +86,7 @@ end describe Puppet::Parser::AST::Undef do before :each do - @scope = stub 'scope' + @scope = Puppet::Parser::Scope.new @undef = Puppet::Parser::AST::Undef.new(:value => :undef) end @@ -101,12 +101,12 @@ end describe Puppet::Parser::AST::HashOrArrayAccess do before :each do - @scope = stub 'scope' + @scope = Puppet::Parser::Scope.new end describe "when evaluating" do it "should evaluate the variable part if necessary" do - @scope.stubs(:lookupvar).with { |name,options| name == 'a'}.returns(["b"]) + @scope["a"] = ["b"] variable = stub 'variable', :evaluate => "a" access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => variable, :key => 0 ) @@ -117,7 +117,7 @@ describe Puppet::Parser::AST::HashOrArrayAccess do end it "should evaluate the access key part if necessary" do - @scope.stubs(:lookupvar).with { |name,options| name == 'a'}.returns(["b"]) + @scope["a"] = ["b"] index = stub 'index', :evaluate => 0 access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => index ) @@ -128,7 +128,7 @@ describe Puppet::Parser::AST::HashOrArrayAccess do end it "should be able to return an array member" do - @scope.stubs(:lookupvar).with { |name,options| name == 'a'}.returns(["val1", "val2", "val3"]) + @scope["a"] = %w{val1 val2 val3} access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => 1 ) @@ -136,7 +136,7 @@ describe Puppet::Parser::AST::HashOrArrayAccess do end it "should be able to return an array member when index is a stringified number" do - @scope.stubs(:lookupvar).with { |name,options| name == "a" }.returns(["val1", "val2", "val3"]) + @scope["a"] = %w{val1 val2 val3} access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "1" ) @@ -144,7 +144,7 @@ describe Puppet::Parser::AST::HashOrArrayAccess do end it "should raise an error when accessing an array with a key" do - @scope.stubs(:lookupvar).with { |name,options| name == "a"}.returns(["val1", "val2", "val3"]) + @scope["a"] = ["val1", "val2", "val3"] access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "get_me_the_second_element_please" ) @@ -152,7 +152,7 @@ describe Puppet::Parser::AST::HashOrArrayAccess do end it "should be able to return an hash value" do - @scope.stubs(:lookupvar).with { |name,options| name == 'a'}.returns({ "key1" => "val1", "key2" => "val2", "key3" => "val3" }) + @scope["a"] = { "key1" => "val1", "key2" => "val2", "key3" => "val3" } access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "key2" ) @@ -160,7 +160,7 @@ describe Puppet::Parser::AST::HashOrArrayAccess do end it "should be able to return an hash value with a numerical key" do - @scope.stubs(:lookupvar).with { |name,options| name == "a"}.returns({ "key1" => "val1", "key2" => "val2", "45" => "45", "key3" => "val3" }) + @scope["a"] = { "key1" => "val1", "key2" => "val2", "45" => "45", "key3" => "val3" } access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "45" ) @@ -168,7 +168,7 @@ describe Puppet::Parser::AST::HashOrArrayAccess do end it "should raise an error if the variable lookup didn't return an hash or an array" do - @scope.stubs(:lookupvar).with { |name,options| name == "a"}.returns("I'm a string") + @scope["a"] = "I'm a string" access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "key2" ) @@ -176,8 +176,6 @@ describe Puppet::Parser::AST::HashOrArrayAccess do end it "should raise an error if the variable wasn't in the scope" do - @scope.stubs(:lookupvar).with { |name,options| name == 'a'}.returns(nil) - access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "key2" ) lambda { access.evaluate(@scope) }.should raise_error @@ -189,7 +187,7 @@ describe Puppet::Parser::AST::HashOrArrayAccess do end it "should work with recursive hash access" do - @scope.stubs(:lookupvar).with { |name,options| name == 'a'}.returns({ "key" => { "subkey" => "b" }}) + @scope["a"] = { "key" => { "subkey" => "b" }} access1 = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "key") access2 = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => access1, :key => "subkey") @@ -198,7 +196,7 @@ describe Puppet::Parser::AST::HashOrArrayAccess do end it "should work with interleaved array and hash access" do - @scope.stubs(:lookupvar).with { |name,options| name == 'a'}.returns({ "key" => [ "a" , "b" ]}) + @scope['a'] = { "key" => [ "a" , "b" ]} access1 = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "key") access2 = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => access1, :key => 1) @@ -210,16 +208,16 @@ describe Puppet::Parser::AST::HashOrArrayAccess do describe "when assigning" do it "should add a new key and value" do scope = Puppet::Parser::Scope.new - scope.setvar("a", { 'a' => 'b' }) + scope['a'] = { 'a' => 'b' } access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "b") access.assign(scope, "c" ) - scope.lookupvar("a").should be_include("b") + scope['a'].should be_include("b") end it "should raise an error when assigning an array element with a key" do - @scope.stubs(:lookupvar).with { |name,options| name == "a"}.returns([]) + @scope['a'] = [] access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "get_me_the_second_element_please" ) @@ -228,16 +226,16 @@ describe Puppet::Parser::AST::HashOrArrayAccess do it "should be able to return an array member when index is a stringified number" do scope = Puppet::Parser::Scope.new - scope.setvar("a", []) + scope['a'] = [] access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "0" ) access.assign(scope, "val2") - scope.lookupvar("a").should == ["val2"] + scope['a'].should == ["val2"] end it "should raise an error when trying to overwrite an hash value" do - @scope.stubs(:lookupvar).with { |name,options| name == "a" }.returns({ "key" => [ "a" , "b" ]}) + @scope['a'] = { "key" => [ "a" , "b" ]} access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "key") lambda { access.assign(@scope, "test") }.should raise_error @@ -247,7 +245,7 @@ end describe Puppet::Parser::AST::Regex do before :each do - @scope = stub 'scope' + @scope = Puppet::Parser::Scope.new end describe "when initializing" do @@ -330,22 +328,21 @@ end describe Puppet::Parser::AST::Variable do before :each do - @scope = stub 'scope' + @scope = Puppet::Parser::Scope.new @var = Puppet::Parser::AST::Variable.new(:value => "myvar", :file => 'my.pp', :line => 222) end it "should lookup the variable in scope" do - @scope.expects(:lookupvar).with { |name,options| name == "myvar" }.returns(:myvalue) + @scope["myvar"] = :myvalue @var.safeevaluate(@scope).should == :myvalue end it "should pass the source location to lookupvar" do - @scope.expects(:lookupvar).with { |name,options| name == "myvar" and options[:file] == 'my.pp' and options[:line] == 222 }.returns(:myvalue) + @scope.setvar("myvar", :myvalue, :file => 'my.pp', :line => 222 ) @var.safeevaluate(@scope).should == :myvalue end it "should return undef if the variable wasn't set" do - @scope.expects(:lookupvar).with { |name,options| name == "myvar" }.returns(:undefined) @var.safeevaluate(@scope).should == :undef end @@ -359,7 +356,7 @@ end describe Puppet::Parser::AST::HostName do before :each do - @scope = stub 'scope' + @scope = Puppet::Parser::Scope.new @value = stub 'value', :=~ => false @value.stubs(:to_s).returns(@value) @value.stubs(:downcase).returns(@value) diff --git a/spec/unit/parser/ast/resource_reference_spec.rb b/spec/unit/parser/ast/resource_reference_spec.rb index 4d1c191cf..4e069cca0 100755 --- a/spec/unit/parser/ast/resource_reference_spec.rb +++ b/spec/unit/parser/ast/resource_reference_spec.rb @@ -36,7 +36,7 @@ describe Puppet::Parser::AST::ResourceReference do end it "should return an array of resources if given a variable containing an array of titles" do - @scope.setvar("my_files", ["foo", "bar"]) + @scope["my_files"] = ["foo", "bar"] titles = Puppet::Parser::AST::Variable.new(:value => "my_files") ref = newref('File', titles) ref.evaluate(@scope).should == [ diff --git a/spec/unit/parser/compiler_spec.rb b/spec/unit/parser/compiler_spec.rb index fcce9f6f4..9648e292c 100755 --- a/spec/unit/parser/compiler_spec.rb +++ b/spec/unit/parser/compiler_spec.rb @@ -177,8 +177,8 @@ describe Puppet::Parser::Compiler do @node.stubs(:parameters).returns(params) compile_stub(:set_node_parameters) @compiler.compile - @compiler.topscope.lookupvar("a").should == "b" - @compiler.topscope.lookupvar("c").should == "d" + @compiler.topscope['a'].should == "b" + @compiler.topscope['c'].should == "d" end it "should set the client and server versions on the catalog" do diff --git a/spec/unit/parser/functions/extlookup_spec.rb b/spec/unit/parser/functions/extlookup_spec.rb index f68daaf3f..30962e137 100755 --- a/spec/unit/parser/functions/extlookup_spec.rb +++ b/spec/unit/parser/functions/extlookup_spec.rb @@ -64,7 +64,7 @@ describe "the extlookup function" do describe "should look in $extlookup_datadir for data files listed by $extlookup_precedence" do before do - @scope.stubs(:lookupvar).with('::extlookup_datadir').returns("/tmp") + @scope.stubs(:[]).with('::extlookup_datadir').returns("/tmp") File.open("/tmp/one.csv","w"){|one| one.puts "key,value1" } File.open("/tmp/two.csv","w") do |two| two.puts "key,value2" @@ -73,21 +73,21 @@ describe "the extlookup function" do end it "when the key is in the first file" do - @scope.stubs(:lookupvar).with('::extlookup_precedence').returns(["one","two"]) + @scope.stubs(:[]).with('::extlookup_precedence').returns(["one","two"]) result = @scope.function_extlookup([ "key" ]) result.should == "value1" end it "when the key is in the second file" do - @scope.stubs(:lookupvar).with('::extlookup_precedence').returns(["one","two"]) + @scope.stubs(:[]).with('::extlookup_precedence').returns(["one","two"]) result = @scope.function_extlookup([ "key2" ]) result.should == "value_two" end it "should not modify extlookup_precedence data" do variable = '%{fqdn}' - @scope.stubs(:lookupvar).with('::extlookup_precedence').returns([variable,"one"]) - @scope.stubs(:lookupvar).with('::fqdn').returns('myfqdn') + @scope.stubs(:[]).with('::extlookup_precedence').returns([variable,"one"]) + @scope.stubs(:[]).with('::fqdn').returns('myfqdn') result = @scope.function_extlookup([ "key" ]) variable.should == '%{fqdn}' end diff --git a/spec/unit/parser/functions/fqdn_rand_spec.rb b/spec/unit/parser/functions/fqdn_rand_spec.rb index 90fc0ef41..53c498453 100755 --- a/spec/unit/parser/functions/fqdn_rand_spec.rb +++ b/spec/unit/parser/functions/fqdn_rand_spec.rb @@ -8,6 +8,7 @@ describe "the fqdn_rand function" do before :each do @scope = Puppet::Parser::Scope.new + @scope[:fqdn] = "127.0.0.1" end it "should exist" do @@ -15,49 +16,40 @@ describe "the fqdn_rand function" do 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") + @scope.expects(:[]).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 diff --git a/spec/unit/parser/resource_spec.rb b/spec/unit/parser/resource_spec.rb index 1190716d7..8513b8997 100755 --- a/spec/unit/parser/resource_spec.rb +++ b/spec/unit/parser/resource_spec.rb @@ -271,7 +271,7 @@ describe Puppet::Parser::Resource do end it "should not copy relationship metaparams when not in metaparam compatibility mode" do - @scope.setvar("require", "bar") + @scope['require'] = "bar" @resource.stubs(:metaparam_compatibility_mode?).returns false @resource.class.publicize_methods(:add_metaparams) { @resource.add_metaparams } @@ -280,7 +280,7 @@ describe Puppet::Parser::Resource do end it "should copy relationship metaparams when in metaparam compatibility mode" do - @scope.setvar("require", "bar") + @scope['require'] = "bar" @resource.stubs(:metaparam_compatibility_mode?).returns true @resource.class.publicize_methods(:add_metaparams) { @resource.add_metaparams } @@ -290,7 +290,7 @@ describe Puppet::Parser::Resource do it "should stack relationship metaparams when in metaparam compatibility mode" do @resource.set_parameter("require", "foo") - @scope.setvar("require", "bar") + @scope['require'] = "bar" @resource.stubs(:metaparam_compatibility_mode?).returns true @resource.class.publicize_methods(:add_metaparams) { @resource.add_metaparams } diff --git a/spec/unit/parser/scope_spec.rb b/spec/unit/parser/scope_spec.rb index 5308856ed..cd34df065 100755 --- a/spec/unit/parser/scope_spec.rb +++ b/spec/unit/parser/scope_spec.rb @@ -83,29 +83,34 @@ describe Puppet::Parser::Scope do end describe "when looking up a variable" do + it "should support :lookupvar and :setvar for backward compatibility" do + @scope.setvar("var", "yep") + @scope.lookupvar("var").should == "yep" + end + it "should return ':undefined' for unset variables" do - @scope.lookupvar("var").should == :undefined + @scope["var"].should == :undefined end it "should be able to look up values" do - @scope.setvar("var", "yep") - @scope.lookupvar("var").should == "yep" + @scope["var"] = "yep" + @scope["var"].should == "yep" end it "should be able to look up hashes" do - @scope.setvar("var", {"a" => "b"}) - @scope.lookupvar("var").should == {"a" => "b"} + @scope["var"] = {"a" => "b"} + @scope["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" + @topscope["var"] = "parentval" + @scope["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" + @topscope["var"] = "parentval" + @scope["var"] = "childval" + @scope["var"].should == "childval" end describe "and the variable is qualified" do @@ -133,84 +138,84 @@ describe Puppet::Parser::Scope do 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["othervar"] = "otherval" - @scope.lookupvar("::othervar").should == "otherval" + @scope["::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") - other_scope.setvar("var", "otherval") + other_scope["var"] = "otherval" - @scope.lookupvar("::other::var").should == "otherval" + @scope["::other::var"].should == "otherval" end 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["var"] = "otherval" - @scope.lookupvar("other::deep::klass::var").should == "otherval" + @scope["other::deep::klass::var"].should == "otherval" end it "should return ':undefined' 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 == :undefined + @scope["other::deep::klass::var"].should == :undefined end it "should warn and return ':undefined' 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 == :undefined + @scope["other::deep::klass::var"].should == :undefined end it "should warn and return ':undefined' for qualified variables whose classes do not exist" do @scope.expects(:warning) - @scope.lookupvar("other::deep::klass::var").should == :undefined + @scope["other::deep::klass::var"].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").should == :undefined + @scope["other::deep::klass::var"].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").should == :undefined + @scope["other::deep::klass::var"].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 + describe "when variables are set with append=true" do + it "should raise an 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.expects(:[]).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" + @scope["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] + @scope["var"].should == [4,2] 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"} + @scope["var"].should == {"a" => "b", "c" => "d"} end it "should raise an error when appending a hash with something other than another hash" do @@ -285,7 +290,7 @@ describe Puppet::Parser::Scope do it "should store the variable value" do @scope.setvar("1", :value, :ephemeral => true) - @scope.lookupvar("1").should == :value + @scope["1"].should == :value end it "should remove the variable value when unset_ephemeral_var is called" do @@ -294,17 +299,17 @@ describe Puppet::Parser::Scope do @scope.unset_ephemeral_var - @scope.lookupvar("1").should == :undefined + @scope["1"].should == :undefined end it "should not remove classic variables when unset_ephemeral_var is called" do - @scope.setvar("myvar", :value1) + @scope['myvar'] = :value1 @scope.setvar("1", :value2, :ephemeral => true) @scope.stubs(:parent).returns(nil) @scope.unset_ephemeral_var - @scope.lookupvar("myvar").should == :value1 + @scope["myvar"].should == :value1 end it "should raise an error when setting it again" do @@ -325,7 +330,7 @@ describe Puppet::Parser::Scope do @scope.setvar("0", :earliest, :ephemeral => true) @scope.new_ephemeral @scope.setvar("0", :latest, :ephemeral => true) - @scope.lookupvar("0").should == :latest + @scope["0"].should == :latest end it "should be able to report the current level" do @@ -356,7 +361,7 @@ describe Puppet::Parser::Scope do @scope.setvar("1", :value1, :ephemeral => true) @scope.new_ephemeral @scope.setvar("0", :value2, :ephemeral => true) - @scope.lookupvar("1").should == :value1 + @scope["1"].should == :value1 end describe "when calling unset_ephemeral_var without a level" do @@ -367,7 +372,7 @@ describe Puppet::Parser::Scope do @scope.unset_ephemeral_var - @scope.lookupvar("1").should == :undefined + @scope["1"].should == :undefined end end @@ -381,7 +386,7 @@ describe Puppet::Parser::Scope do @scope.unset_ephemeral_var(2) - @scope.lookupvar("1").should == :value2 + @scope["1"].should == :value2 end end end @@ -421,22 +426,22 @@ describe Puppet::Parser::Scope do describe "when unsetting variables" do it "should be able to unset normal variables" do - @scope.setvar("foo", "bar") + @scope["foo"] = "bar" @scope.unsetvar("foo") - @scope.lookupvar("foo").should == :undefined + @scope["foo"].should == :undefined end it "should be able to unset ephemeral variables" do @scope.setvar("0", "bar", :ephemeral => true) @scope.unsetvar("0") - @scope.lookupvar("0").should == :undefined + @scope["0"].should == :undefined 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" + @scope["0"].should == "bar" end end diff --git a/spec/unit/parser/templatewrapper_spec.rb b/spec/unit/parser/templatewrapper_spec.rb index 600293bbf..6080346fb 100755 --- a/spec/unit/parser/templatewrapper_spec.rb +++ b/spec/unit/parser/templatewrapper_spec.rb @@ -72,25 +72,23 @@ describe Puppet::Parser::TemplateWrapper do end it "should return the contents of a variable if called via method_missing" do - @scope.expects(:lookupvar).with { |name,options| name == "chicken"}.returns("is good") + @scope["chicken"] = "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 { |name,options| name == "chicken"}.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 { |name,options| name == "chicken"}.returns("is good") + @scope["chicken"] = "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 { |name,options| name == "chicken"}.returns(:undefined) tw = Puppet::Parser::TemplateWrapper.new(@scope) tw.has_variable?("chicken").should eql(false) end -- cgit From 06e86e40bbb173fa24a7d1c2ecf4e54e1748de67 Mon Sep 17 00:00:00 2001 From: Luke Kanies Date: Wed, 8 Jun 2011 18:55:10 -0700 Subject: Adding default environment to Scope We were previously not defaulting to an environment, which is silly given that there's always a default. It just made setup code harder. We now default to the default environment. This makes further testing involving scopes much easier. Signed-off-by: Luke Kanies Reviewed-by: Nick Lewis --- spec/unit/parser/scope_spec.rb | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'spec/unit/parser') diff --git a/spec/unit/parser/scope_spec.rb b/spec/unit/parser/scope_spec.rb index cd34df065..e08180020 100755 --- a/spec/unit/parser/scope_spec.rb +++ b/spec/unit/parser/scope_spec.rb @@ -47,6 +47,10 @@ describe Puppet::Parser::Scope do scope = Puppet::Parser::Scope.new :compiler => compiler scope.environment.should equal(env) end + + it "should use the default environment if none is available" do + Puppet::Parser::Scope.new.environment.should equal(Puppet::Node::Environment.new) + 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) @@ -55,22 +59,18 @@ describe Puppet::Parser::Scope do 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") + root = Puppet::Node::Environment.root 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) + scope = Puppet::Parser::Scope.new(:compiler => compiler) + scope.singleton_class.ancestors.should be_include(Puppet::Parser::Functions.environment_module(env)) + scope.singleton_class.ancestors.should be_include(Puppet::Parser::Functions.environment_module(root)) 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) + it "should extend itself with the default Functions module if its environment is the default" do + root = Puppet::Node::Environment.root + scope = Puppet::Parser::Scope.new + scope.singleton_class.ancestors.should be_include(Puppet::Parser::Functions.environment_module(root)) end it "should remember if it is dynamic" do -- cgit From 9d608ea176224f38c6af349883065d9363dd1bb1 Mon Sep 17 00:00:00 2001 From: Luke Kanies Date: Wed, 8 Jun 2011 22:36:25 -0700 Subject: Resource type defaults cleanup This is again done to make support for hiera easier. The way we were handling lookup of resource defaults was over-complicated. This does a decent bit of cleanup overall, but primarily focused on resource type defaults and how they get set during compilation. Signed-off-by: Luke Kanies Reviewed-by: Nick Lewis --- spec/unit/parser/compiler_spec.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'spec/unit/parser') diff --git a/spec/unit/parser/compiler_spec.rb b/spec/unit/parser/compiler_spec.rb index 9648e292c..06f8044e3 100755 --- a/spec/unit/parser/compiler_spec.rb +++ b/spec/unit/parser/compiler_spec.rb @@ -614,15 +614,15 @@ describe Puppet::Parser::Compiler do @node.classes = klass klass = Puppet::Resource::Type.new(:hostclass, 'foo', :arguments => {'1' => nil, '2' => nil}) @compiler.topscope.known_resource_types.add klass - lambda { @compiler.compile }.should raise_error Puppet::ParseError, "Must pass 2 to Class[Foo]" + lambda { @compiler.compile }.should raise_error(Puppet::ParseError, "Must pass 2 to Class[Foo]") end it "should fail if invalid parameters are passed" do klass = {'foo'=>{'3'=>'one'}} @node.classes = klass - klass = Puppet::Resource::Type.new(:hostclass, 'foo', :arguments => {'1' => nil, '2' => nil}) + klass = Puppet::Resource::Type.new(:hostclass, 'foo', :arguments => {}) @compiler.topscope.known_resource_types.add klass - lambda { @compiler.compile }.should raise_error Puppet::ParseError, "Invalid parameter 3" + lambda { @compiler.compile }.should raise_error(Puppet::ParseError, "Invalid parameter 3") end it "should ensure class is in catalog without params" do -- cgit From b3c155430965280ab59b1dd70c020c6da3396fc9 Mon Sep 17 00:00:00 2001 From: Luke Kanies Date: Thu, 16 Jun 2011 18:37:04 -0700 Subject: Adding Scope#include? method This is primarily for Hiera/DataLibrary support, but is a decent idea regardless. Signed-off-by: Luke Kanies Reviewed-by: Nick Lewis --- spec/unit/parser/scope_spec.rb | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'spec/unit/parser') diff --git a/spec/unit/parser/scope_spec.rb b/spec/unit/parser/scope_spec.rb index e08180020..887890ead 100755 --- a/spec/unit/parser/scope_spec.rb +++ b/spec/unit/parser/scope_spec.rb @@ -113,6 +113,15 @@ describe Puppet::Parser::Scope do @scope["var"].should == "childval" end + it "should be able to detect when variables are set" do + @scope["var"] = "childval" + @scope.should be_include("var") + end + + it "should be able to detect when variables are not set" do + @scope.should_not be_include("var") + end + describe "and the variable is qualified" do before do @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("foonode")) -- cgit From 3b2a24602d11d4ca2f7e761fb831f126ecf2de62 Mon Sep 17 00:00:00 2001 From: Luke Kanies Date: Thu, 16 Jun 2011 18:41:19 -0700 Subject: Adding Scope#each method The capability was already there via to_hash, and Enumerable was already included, but this method was missing. Given the kind of hacking RI is doing, this seemed appropriate. Signed-off-by: Luke Kanies Reviewed-by: Nick Lewis --- spec/unit/parser/scope_spec.rb | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'spec/unit/parser') diff --git a/spec/unit/parser/scope_spec.rb b/spec/unit/parser/scope_spec.rb index 887890ead..78feaf08b 100755 --- a/spec/unit/parser/scope_spec.rb +++ b/spec/unit/parser/scope_spec.rb @@ -122,6 +122,18 @@ describe Puppet::Parser::Scope do @scope.should_not be_include("var") end + it "should support iteration over its variables" do + @scope["one"] = "two" + @scope["three"] = "four" + hash = {} + @scope.each { |name, value| hash[name] = value } + hash.should == {"one" => "two", "three" => "four" } + end + + it "should include Enumerable" do + @scope.singleton_class.ancestors.should be_include(Enumerable) + end + describe "and the variable is qualified" do before do @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("foonode")) -- cgit From ef7e25b468c70537d172129b70f096364ac3e6d5 Mon Sep 17 00:00:00 2001 From: Luke Kanies Date: Tue, 5 Jul 2011 11:58:26 -0700 Subject: Cleanup up a small amount of whitespace Signed-off-by: Luke Kanies Reviewed-by: Nick Lewis --- spec/unit/parser/scope_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'spec/unit/parser') diff --git a/spec/unit/parser/scope_spec.rb b/spec/unit/parser/scope_spec.rb index 78feaf08b..00212a2d5 100755 --- a/spec/unit/parser/scope_spec.rb +++ b/spec/unit/parser/scope_spec.rb @@ -47,7 +47,7 @@ describe Puppet::Parser::Scope do scope = Puppet::Parser::Scope.new :compiler => compiler scope.environment.should equal(env) end - + it "should use the default environment if none is available" do Puppet::Parser::Scope.new.environment.should equal(Puppet::Node::Environment.new) end -- cgit From 79c8023d45d8c86f0f21cf6c4c27e0e5389c7528 Mon Sep 17 00:00:00 2001 From: Luke Kanies Date: Tue, 5 Jul 2011 11:58:34 -0700 Subject: Fixing default parameter value assignment The method for adding class resources to the catalog was only working in cases where the default values weren't AST objects. This commit fixes this, along with the tests that were failing and drew out the problem. Signed-off-by: Luke Kanies Reviewed-by: Nick Lewis --- spec/unit/parser/compiler_spec.rb | 76 ++++++++++++++++++++++++--------------- 1 file changed, 48 insertions(+), 28 deletions(-) (limited to 'spec/unit/parser') diff --git a/spec/unit/parser/compiler_spec.rb b/spec/unit/parser/compiler_spec.rb index 06f8044e3..e6f481114 100755 --- a/spec/unit/parser/compiler_spec.rb +++ b/spec/unit/parser/compiler_spec.rb @@ -571,42 +571,62 @@ describe Puppet::Parser::Compiler do @compiler.evaluate_classes(%w{myclass}, @scope) end - it "should ensure each node class hash is in catalog and have appropriate parameters", :'fails_on_ruby_1.9.2' => true do - klasses = {'foo'=>{'1'=>'one'}, 'bar::foo'=>{'2'=>'two'}, 'bar'=>{'1'=> [1,2,3], '2'=>{'foo'=>'bar'}}} - @node.classes = klasses - ast_obj = Puppet::Parser::AST::String.new(:value => 'foo') - klasses.each do |name, params| - klass = Puppet::Resource::Type.new(:hostclass, name, :arguments => {'1' => ast_obj, '2' => ast_obj}) + describe "and the classes are specified as a hash with parameters" do + before do + @node.classes = {} + @ast_obj = Puppet::Parser::AST::String.new(:value => 'foo') + end + + # Define the given class with default parameters + def define_class(name, parameters) + @node.classes[name] = parameters + klass = Puppet::Resource::Type.new(:hostclass, name, :arguments => {'1' => @ast_obj, '2' => @ast_obj}) @compiler.topscope.known_resource_types.add klass end - catalog = @compiler.compile - catalog.classes.should =~ ['foo', 'bar::foo', 'settings', 'bar'] - r1 = catalog.resources.detect {|r| r.title == 'Foo' } - r1.to_hash.should == {:'1' => 'one', :'2' => 'foo'} - r1.tags. should =~ ['class', 'foo'] + def compile + @catalog = @compiler.compile + end - r2 = catalog.resources.detect {|r| r.title == 'Bar::Foo' } - r2.to_hash.should == {:'1' => 'foo', :'2' => 'two'} - r2.tags.should =~ ['bar::foo', 'class', 'bar', 'foo'] + it "should record which classes are evaluated" do + classes = {'foo'=>{}, 'bar::foo'=>{}, 'bar'=>{}} + classes.each { |c, params| define_class(c, params) } + compile() + classes.each { |name, p| @catalog.classes.should include(name) } + end - r2 = catalog.resources.detect {|r| r.title == 'Bar' } - r2.to_hash.should == {:'1' => [1,2,3], :'2' => {'foo'=>'bar'}} - r2.tags.should =~ ['class', 'bar'] - end + it "should provide default values for parameters that have no values specified" do + define_class('foo', {}) + compile() + @catalog.resource(:class, 'foo')['1'].should == "foo" + end - it "should ensure each node class is in catalog and has appropriate tags", :'fails_on_ruby_1.9.2' => true do - klasses = ['bar::foo'] - @node.classes = klasses - ast_obj = Puppet::Parser::AST::String.new(:value => 'foo') - klasses.each do |name| - klass = Puppet::Resource::Type.new(:hostclass, name, :arguments => {'1' => ast_obj, '2' => ast_obj}) - @compiler.topscope.known_resource_types.add klass + it "should use any provided values" do + define_class('foo', {'1' => 'real_value'}) + compile() + @catalog.resource(:class, 'foo')['1'].should == "real_value" end - catalog = @compiler.compile - r2 = catalog.resources.detect {|r| r.title == 'Bar::Foo' } - r2.tags.should =~ ['bar::foo', 'class', 'bar', 'foo'] + it "should support providing some but not all values" do + define_class('foo', {'1' => 'real_value'}) + compile() + @catalog.resource(:class, 'Foo')['1'].should == "real_value" + @catalog.resource(:class, 'Foo')['2'].should == "foo" + end + + it "should ensure each node class is in catalog and has appropriate tags", :'fails_on_ruby_1.9.2' => true do + klasses = ['bar::foo'] + @node.classes = klasses + ast_obj = Puppet::Parser::AST::String.new(:value => 'foo') + klasses.each do |name| + klass = Puppet::Resource::Type.new(:hostclass, name, :arguments => {'1' => ast_obj, '2' => ast_obj}) + @compiler.topscope.known_resource_types.add klass + end + catalog = @compiler.compile + + r2 = catalog.resources.detect {|r| r.title == 'Bar::Foo' } + r2.tags.should =~ ['bar::foo', 'class', 'bar', 'foo'] + end end it "should fail if required parameters are missing" do -- cgit From baf32de1dcda02f7da8b2926abee7f46d0d47fe1 Mon Sep 17 00:00:00 2001 From: Luke Kanies Date: Tue, 5 Jul 2011 12:25:54 -0700 Subject: Making the Functions module more resilient We were previously storing the module name with the environment instances as the key, which meant if the environment instances were removed, we could never get those modules again. Given that the functions weren't reloaded, this meant the functions were gone if we ever reloaded the environment. This makes the Functions environment module resilient across environment reloads, and it also makes the method work correctly when handed either an environment or a string. Signed-off-by: Luke Kanies Reviewed-by: Nick Lewis --- spec/unit/parser/scope_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'spec/unit/parser') diff --git a/spec/unit/parser/scope_spec.rb b/spec/unit/parser/scope_spec.rb index 00212a2d5..d3ea8dfa8 100755 --- a/spec/unit/parser/scope_spec.rb +++ b/spec/unit/parser/scope_spec.rb @@ -42,7 +42,7 @@ describe Puppet::Parser::Scope do end it "should get its environment from its compiler" do - env = stub 'environment' + env = Puppet::Node::Environment.new compiler = stub 'compiler', :environment => env scope = Puppet::Parser::Scope.new :compiler => compiler scope.environment.should equal(env) -- cgit From 540377b526424e7ef9b2c06460d43af2b780a4af Mon Sep 17 00:00:00 2001 From: Luke Kanies Date: Tue, 5 Jul 2011 12:28:44 -0700 Subject: Removing an unnecessary stub in the Scope tests Signed-off-by: Luke Kanies Reviewed-by: Nick Lewis --- spec/unit/parser/functions_spec.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'spec/unit/parser') diff --git a/spec/unit/parser/functions_spec.rb b/spec/unit/parser/functions_spec.rb index 8240a184c..7eb6f299b 100755 --- a/spec/unit/parser/functions_spec.rb +++ b/spec/unit/parser/functions_spec.rb @@ -20,13 +20,17 @@ describe Puppet::Parser::Functions do end it "should have a method for returning an environment-specific module" do - Puppet::Parser::Functions.environment_module("myenv").should be_instance_of(Module) + Puppet::Parser::Functions.environment_module(Puppet::Node::Environment.new("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 be able to retrieve environment modules asked for by name rather than instance" do + Puppet::Parser::Functions.environment_module(Puppet::Node::Environment.new("myenv")).should equal(Puppet::Parser::Functions.environment_module("myenv")) + end + describe "when calling newfunction" do before do @module = Module.new -- cgit From 9662045bfe551821823b38fe6511e621998aef0b Mon Sep 17 00:00:00 2001 From: Luke Kanies Date: Tue, 5 Jul 2011 12:34:49 -0700 Subject: Fixing a failing test because of mismatched error string Signed-off-by: Luke Kanies Reviewed-by: Nick Lewis --- spec/unit/parser/functions/create_resources_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'spec/unit/parser') diff --git a/spec/unit/parser/functions/create_resources_spec.rb b/spec/unit/parser/functions/create_resources_spec.rb index da76e75d0..94b1e7c68 100755 --- a/spec/unit/parser/functions/create_resources_spec.rb +++ b/spec/unit/parser/functions/create_resources_spec.rb @@ -78,7 +78,7 @@ notify{test:} end it 'should fail if defines are missing params' do @scope.function_create_resources(['foo', {'blah'=>{}}]) - lambda { @scope.compiler.compile }.should raise_error(Puppet::ParseError, 'Must pass one to Foo[blah] at line 1') + lambda { @scope.compiler.compile }.should raise_error(Puppet::ParseError, /Must pass one to Foo\[blah\]/) end it 'should be able to add multiple defines' do hash = {} -- cgit From bdc0f8716ae8ccb2b2657dfab591afe9589d8902 Mon Sep 17 00:00:00 2001 From: Luke Kanies Date: Tue, 5 Jul 2011 16:32:03 -0700 Subject: Scope[] now returns nil for undefined variables Given that we have the 'include?' method, this feature is unnecessary, and it makes sense to convert to more ruby-like behavior. Any code that previously checked whether lookupvar (or the new []) returned :undefined should now check whether 'scope.include?(var)'. Thus, you can have the same behavior, but it takes a bit different code to get it. Signed-off-by: Luke Kanies Reviewed-by: Nick Lewis --- spec/unit/parser/scope_spec.rb | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'spec/unit/parser') diff --git a/spec/unit/parser/scope_spec.rb b/spec/unit/parser/scope_spec.rb index d3ea8dfa8..3c0d15cd7 100755 --- a/spec/unit/parser/scope_spec.rb +++ b/spec/unit/parser/scope_spec.rb @@ -88,8 +88,8 @@ describe Puppet::Parser::Scope do @scope.lookupvar("var").should == "yep" end - it "should return ':undefined' for unset variables" do - @scope["var"].should == :undefined + it "should return nil for unset variables" do + @scope["var"].should be_nil end it "should be able to look up values" do @@ -180,32 +180,32 @@ describe Puppet::Parser::Scope do @scope["other::deep::klass::var"].should == "otherval" end - it "should return ':undefined' for qualified variables that cannot be found in other classes" do + it "should return nil for qualified variables that cannot be found in other classes" do other_scope = create_class_scope("other::deep::klass") - @scope["other::deep::klass::var"].should == :undefined + @scope["other::deep::klass::var"].should be_nil end - it "should warn and return ':undefined' for qualified variables whose classes have not been evaluated" do + it "should warn and return nil for qualified variables whose classes have not been evaluated" do klass = newclass("other::deep::klass") @scope.expects(:warning) - @scope["other::deep::klass::var"].should == :undefined + @scope["other::deep::klass::var"].should be_nil end - it "should warn and return ':undefined' for qualified variables whose classes do not exist" do + it "should warn and return nil for qualified variables whose classes do not exist" do @scope.expects(:warning) - @scope["other::deep::klass::var"].should == :undefined + @scope["other::deep::klass::var"].should be_nil end - it "should return ':undefined' when asked for a non-string qualified variable from a class that does not exist" do + it "should return nil when asked for a non-string qualified variable from a class that does not exist" do @scope.stubs(:warning) - @scope["other::deep::klass::var"].should == :undefined + @scope["other::deep::klass::var"].should be_nil end - it "should return ':undefined' when asked for a non-string qualified variable from a class that has not been evaluated" do + it "should return nil 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["other::deep::klass::var"].should == :undefined + @scope["other::deep::klass::var"].should be_nil end end end @@ -320,7 +320,7 @@ describe Puppet::Parser::Scope do @scope.unset_ephemeral_var - @scope["1"].should == :undefined + @scope["1"].should be_nil end it "should not remove classic variables when unset_ephemeral_var is called" do @@ -393,7 +393,7 @@ describe Puppet::Parser::Scope do @scope.unset_ephemeral_var - @scope["1"].should == :undefined + @scope["1"].should be_nil end end @@ -449,13 +449,13 @@ describe Puppet::Parser::Scope do it "should be able to unset normal variables" do @scope["foo"] = "bar" @scope.unsetvar("foo") - @scope["foo"].should == :undefined + @scope["foo"].should be_nil end it "should be able to unset ephemeral variables" do @scope.setvar("0", "bar", :ephemeral => true) @scope.unsetvar("0") - @scope["0"].should == :undefined + @scope["0"].should be_nil end it "should not unset ephemeral variables in previous ephemeral scope" do -- cgit