diff options
-rw-r--r-- | lib/puppet/parser/ast.rb | 1 | ||||
-rw-r--r-- | lib/puppet/parser/ast/comparison_operator.rb | 37 | ||||
-rwxr-xr-x | spec/unit/parser/ast/comparison_operator.rb | 52 |
3 files changed, 90 insertions, 0 deletions
diff --git a/lib/puppet/parser/ast.rb b/lib/puppet/parser/ast.rb index 66744525e..da82a30c7 100644 --- a/lib/puppet/parser/ast.rb +++ b/lib/puppet/parser/ast.rb @@ -81,6 +81,7 @@ require 'puppet/parser/ast/caseopt' require 'puppet/parser/ast/casestatement' require 'puppet/parser/ast/collection' require 'puppet/parser/ast/collexpr' +require 'puppet/parser/ast/comparison_operator' require 'puppet/parser/ast/definition' require 'puppet/parser/ast/else' require 'puppet/parser/ast/function' diff --git a/lib/puppet/parser/ast/comparison_operator.rb b/lib/puppet/parser/ast/comparison_operator.rb new file mode 100644 index 000000000..63aa36c7f --- /dev/null +++ b/lib/puppet/parser/ast/comparison_operator.rb @@ -0,0 +1,37 @@ +require 'puppet' +require 'puppet/parser/ast/branch' + +class Puppet::Parser::AST + class ComparisonOperator < AST::Branch + + attr_accessor :operator, :lval, :rval + + # Iterate across all of our children. + def each + [@lval,@rval,@operator].each { |child| yield child } + end + + # Returns a boolean which is the result of the boolean operation + # of lval and rval operands + def evaluate(scope) + # evaluate the operands, should return a boolean value + lval = @lval.safeevaluate(scope) + rval = @rval.safeevaluate(scope) + + # return result + unless @operator == '!=' + lval.send(@operator,rval) + else + lval != rval + end + end + + def initialize(hash) + super + + unless %w{== != < > <= >=}.include?(@operator) + raise ArgumentError, "Invalid comparison operator %s" % @operator + end + end + end +end diff --git a/spec/unit/parser/ast/comparison_operator.rb b/spec/unit/parser/ast/comparison_operator.rb new file mode 100755 index 000000000..dbea349f2 --- /dev/null +++ b/spec/unit/parser/ast/comparison_operator.rb @@ -0,0 +1,52 @@ +#!/usr/bin/env ruby + +require File.dirname(__FILE__) + '/../../../spec_helper' + +describe Puppet::Parser::AST::ComparisonOperator do + before :each do + @scope = Puppet::Parser::Scope.new() + @one = Puppet::Parser::AST::FlatString.new( :value => 1 ) + @two = Puppet::Parser::AST::FlatString.new( :value => 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 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 + one = stub 'one', :safeevaluate => "1" + two = stub 'two', :safeevaluate => "2" + operator = Puppet::Parser::AST::ComparisonOperator.new :lval => one, :operator => oper, :rval => two + operator.evaluate(@scope).should == 1.send(oper,2) + end + end + + it "should return the result of using '!=' to compare the left and right sides" do + one = stub 'one', :safeevaluate => "1" + two = stub 'two', :safeevaluate => "2" + operator = Puppet::Parser::AST::ComparisonOperator.new :lval => one, :operator => '!=', :rval => two + operator.evaluate(@scope).should == true + end + + it "should work for variables too" do + @scope.expects(:lookupvar).with("one").returns(1) + @scope.expects(:lookupvar).with("two").returns(2) + one = Puppet::Parser::AST::Variable.new( :value => "one" ) + two = Puppet::Parser::AST::Variable.new( :value => "two" ) + + operator = Puppet::Parser::AST::ComparisonOperator.new :lval => one, :operator => "<", :rval => two + operator.evaluate(@scope).should == true + end + +end |