From 4cf9710bd27fdb5f0720f4d8478ef940e7c4ba59 Mon Sep 17 00:00:00 2001 From: Brice Figureau Date: Fri, 26 Sep 2008 23:03:39 +0200 Subject: Add parser for arbitrary expressions The expressions can be used in if 'test' and in the right side of assignements. The expressions can contain any number of sub-expressions combined by either arithmetic operators, comparison operators, or boolean operators. Random Usage Examples: $result = ((( $two + 2) / $one) + 4 * 5.45) - (6 << 7) + (0x800 + -9) or if ($a < 10) and ($a + 10 != 200) { ... } --- spec/unit/parser/parser.rb | 48 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) (limited to 'spec/unit/parser/parser.rb') diff --git a/spec/unit/parser/parser.rb b/spec/unit/parser/parser.rb index 94b19be40..17e80bb6a 100755 --- a/spec/unit/parser/parser.rb +++ b/spec/unit/parser/parser.rb @@ -8,6 +8,7 @@ describe Puppet::Parser do before :each do @parser = Puppet::Parser::Parser.new :environment => "development" + @true_ast = AST::Boolean.new :value => true end describe "when parsing append operator" do @@ -31,4 +32,49 @@ describe Puppet::Parser do end end -end + + describe Puppet::Parser, "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 }") + + 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 }") + + end + + end + + describe Puppet::Parser, "when parsing if complex expressions" do + it "should create a correct ast tree" do + AST::ComparisonOperator.expects(:new).with { + |h| h[:rval].is_a?(AST::Name) and h[:lval].is_a?(AST::Name) and h[:operator]==">" + }.returns("whatever") + AST::ComparisonOperator.expects(:new).with { + |h| h[:rval].is_a?(AST::Name) and h[:lval].is_a?(AST::Name) and h[:operator]=="==" + }.returns("whatever") + AST::BooleanOperator.expects(:new).with { + |h| h[:rval]=="whatever" and h[:lval]=="whatever" 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 + + end + end -- cgit From 79bb1f201c1479a15fa2f0f8ad5467bd357ed707 Mon Sep 17 00:00:00 2001 From: Brice Figureau Date: Sat, 4 Oct 2008 00:16:17 +0200 Subject: Rspec Tests for #381. Moved part of the old resource reference tests to rspec. --- spec/unit/parser/parser.rb | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) (limited to 'spec/unit/parser/parser.rb') diff --git a/spec/unit/parser/parser.rb b/spec/unit/parser/parser.rb index 17e80bb6a..0092a9970 100755 --- a/spec/unit/parser/parser.rb +++ b/spec/unit/parser/parser.rb @@ -76,5 +76,44 @@ describe Puppet::Parser do lambda { @parser.parse("if (1 > 2 > ) or (1 == 2) { $var = 1 }") }.should raise_error end - end + end + + describe Puppet::Parser, "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 + + 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 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 + + describe Puppet::Parser, "when parsing resource overrides" do + + it "should not raise syntax errors" do + lambda { @parser.parse('Resource["title"] { param => value }') }.should_not raise_error + end + + 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 create an AST::ResourceOverride" do + AST::ResourceOverride.expects(:new).with { |arg| + arg[:line]==1 and arg[:object].is_a?(AST::ResourceReference) and arg[:params].is_a?(AST::ResourceParam) + } + @parser.parse('Resource["title1","title2"] { param => value }') + end + + end + end -- cgit From 0c297be5dad784e305ef194cee29b11a92d31b6b Mon Sep 17 00:00:00 2001 From: Brice Figureau Date: Sat, 4 Oct 2008 16:11:03 +0200 Subject: Fix #1109 - allow empty if or else branches This changesets allow empty if or else branches: if true { } else { } It works by emitting on the parser stack an AST node that doesn't do anything (a no-op). This allows the less intrusive code as no part of the if evaluation code has been touched. --- spec/unit/parser/parser.rb | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'spec/unit/parser/parser.rb') diff --git a/spec/unit/parser/parser.rb b/spec/unit/parser/parser.rb index 0092a9970..c0d22a2cc 100755 --- a/spec/unit/parser/parser.rb +++ b/spec/unit/parser/parser.rb @@ -116,4 +116,30 @@ describe Puppet::Parser do end + describe Puppet::Parser, "when parsing if statements" do + + 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 else" do + lambda { @parser.parse("if false { notice('if') } else { }") }.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 create a nop node for empty branch" do + AST::Nop.expects(:new) + @parser.parse("if true { }") + 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 + end -- cgit