1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
|
#! /usr/bin/env ruby
require 'spec_helper'
describe Puppet::Parser::AST::ArithmeticOperator do
ast = Puppet::Parser::AST
before :each do
node = Puppet::Node.new('localhost')
compiler = Puppet::Parser::Compiler.new(node)
@scope = Puppet::Parser::Scope.new(compiler)
@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
context "when applied to array" do
before :each do
Puppet[:parser] = 'future'
end
it "+ should concatenate an array" do
one = stub 'one', :safeevaluate => [1,2,3]
two = stub 'two', :safeevaluate => [4,5]
operator = ast::ArithmeticOperator.new :lval => one, :operator => "+", :rval => two
operator.evaluate(@scope).should == [1,2,3,4,5]
end
it "<< should append array to an array" do
one = stub 'one', :safeevaluate => [1,2,3]
two = stub 'two', :safeevaluate => [4,5]
operator = ast::ArithmeticOperator.new :lval => one, :operator => "<<", :rval => two
operator.evaluate(@scope).should == [1,2,3, [4,5]]
end
it "<< should append object to an array" do
one = stub 'one', :safeevaluate => [1,2,3]
two = stub 'two', :safeevaluate => 'a b c'
operator = ast::ArithmeticOperator.new :lval => one, :operator => "<<", :rval => two
operator.evaluate(@scope).should == [1,2,3, 'a b c']
end
context "and input is invalid" do
it "should raise error for + if left is not an array" do
one = stub 'one', :safeevaluate => 4
two = stub 'two', :safeevaluate => [4,5]
operator = ast::ArithmeticOperator.new :lval => one, :operator => "+", :rval => two
lambda { operator.evaluate(@scope).should == [1,2,3,4,5] }.should raise_error(/left/)
end
it "should raise error for << if left is not an array" do
one = stub 'one', :safeevaluate => 4
two = stub 'two', :safeevaluate => [4,5]
operator = ast::ArithmeticOperator.new :lval => one, :operator => "<<", :rval => two
lambda { operator.evaluate(@scope).should == [1,2,3,4,5] }.should raise_error(/left/)
end
it "should raise error for + if right is not an array" do
one = stub 'one', :safeevaluate => [1,2]
two = stub 'two', :safeevaluate => 45
operator = ast::ArithmeticOperator.new :lval => one, :operator => "+", :rval => two
lambda { operator.evaluate(@scope).should == [1,2,3,4,5] }.should raise_error(/right/)
end
%w{ - * / % >>}.each do |op|
it "should raise error for '#{op}'" do
one = stub 'one', :safeevaluate => [1,2,3]
two = stub 'two', :safeevaluate => [4,5]
operator = ast::ArithmeticOperator.new :lval => @one, :operator => op, :rval => @two
lambda { operator.evaluate(@scope).should == [1,2,3,4,5] }.should raise_error
end
end
end
context "when applied to hash" do
before :each do
Puppet[:parser] = 'future'
end
it "+ should merge two hashes" do
one = stub 'one', :safeevaluate => {'a' => 1, 'b' => 2}
two = stub 'two', :safeevaluate => {'c' => 3 }
operator = ast::ArithmeticOperator.new :lval => one, :operator => "+", :rval => two
operator.evaluate(@scope).should == {'a' => 1, 'b' => 2, 'c' => 3}
end
context "and input is invalid" do
it "should raise error for + if left is not a hash" do
one = stub 'one', :safeevaluate => 4
two = stub 'two', :safeevaluate => {'a' => 1}
operator = ast::ArithmeticOperator.new :lval => one, :operator => "+", :rval => two
lambda { operator.evaluate(@scope).should == [1,2,3,4,5] }.should raise_error(/left/)
end
it "should raise error for + if right is not a hash" do
one = stub 'one', :safeevaluate => {'a' => 1}
two = stub 'two', :safeevaluate => 1
operator = ast::ArithmeticOperator.new :lval => one, :operator => "+", :rval => two
lambda { operator.evaluate(@scope).should == {'a'=>1, 1=>nil} }.should raise_error(/right/)
end
%w{ - * / % << >>}.each do |op|
it "should raise error for '#{op}'" do
one = stub 'one', :safeevaluate => {'a' => 1, 'b' => 2}
two = stub 'two', :safeevaluate => {'c' => 3 }
operator = ast::ArithmeticOperator.new :lval => @one, :operator => op, :rval => @two
lambda { operator.evaluate(@scope).should == [1,2,3,4,5] }.should raise_error
end
end
end
end
end
end
|