#!/usr/bin/env ruby 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) @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) @selector.evaluate(@scope) end it "should downcase the evaluated param value if allowed" do Puppet.stubs(:[]).with(:casesensitive).returns(false) value = stub 'param' @param.stubs(:safeevaluate).with(@scope).returns(value) value.expects(:downcase) @selector.evaluate(@scope) end it "should scan each option" do @values.expects(:each).multiple_yields(@value1, @value2) @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) @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) @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) @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) @selector.evaluate(@scope).should == result 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 } @selector.evaluate(@scope) end it "should transmit the sensitive parameter to evaluate_match" do Puppet.stubs(:[]).with(:casesensitive).returns(:sensitive) @param1.expects(:evaluate_match).with { |*arg| arg[2][:sensitive] == :sensitive } @selector.evaluate(@scope) end it "should transmit the AST file and line to evaluate_match" do @selector.file = :file @selector.line = :line @param1.expects(:evaluate_match).with { |*arg| arg[2][:file] == :file and arg[2][:line] == :line } @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) @value1.expects(:safeevaluate).with(@scope) @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) @selector.evaluate(@scope).should == :result end it "should unset scope ephemeral variables after option evaluation" do @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) @selector.evaluate(@scope) end it "should not leak ephemeral variables even if evaluation fails" do @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) lambda { @selector.evaluate(@scope) }.should raise_error end it "should fail if there is no default" do @selector.expects(:fail) @selector.evaluate(@scope) end end end end