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 161 162 163 164 165 166 167 168 169 170 171 172
|
#! /usr/bin/env ruby
require 'spec_helper'
require 'puppet/pops'
# relative to this spec file (./) does not work as this file is loaded by rspec
require File.join(File.dirname(__FILE__), '/parser_rspec_helper')
describe "egrammar parsing function calls" do
include ParserRspecHelper
context "When parsing calls as statements" do
context "in top level scope" do
it "foo()" do
expect(dump(parse("foo()"))).to eq("(invoke foo)")
end
it "notice bar" do
expect(dump(parse("notice bar"))).to eq("(invoke notice bar)")
end
it "notice(bar)" do
expect(dump(parse("notice bar"))).to eq("(invoke notice bar)")
end
it "foo(bar)" do
expect(dump(parse("foo(bar)"))).to eq("(invoke foo bar)")
end
it "notice {a=>2}" do
expect(dump(parse("notice {a => 2}"))).to eq("(invoke notice ({} ('a' 2)))")
end
it 'notice a=>2' do
expect{parse('notice a => 2')}.to raise_error(/Syntax error at '=>'/)
end
it "foo(bar,)" do
expect(dump(parse("foo(bar,)"))).to eq("(invoke foo bar)")
end
it "foo(bar, fum,)" do
expect(dump(parse("foo(bar,fum,)"))).to eq("(invoke foo bar fum)")
end
it 'foo(a=>1)' do
expect(dump(parse('foo(a=>1)'))).to eq('(invoke foo ({} (a 1)))')
end
it 'foo(a=>1, b=>2)' do
expect(dump(parse('foo(a=>1, b=>2)'))).to eq('(invoke foo ({} (a 1) (b 2)))')
end
it 'foo({a=>1, b=>2})' do
expect(dump(parse('foo({a=>1, b=>2})'))).to eq('(invoke foo ({} (a 1) (b 2)))')
end
it 'foo({a=>1}, b=>2)' do
expect(dump(parse('foo({a=>1}, b=>2)'))).to eq('(invoke foo ({} (a 1)) ({} (b 2)))')
end
it 'foo(a=>1, {b=>2})' do
expect(dump(parse('foo(a=>1, {b=>2})'))).to eq('(invoke foo ({} (a 1)) ({} (b 2)))')
end
it "notice fqdn_rand(30)" do
expect(dump(parse("notice fqdn_rand(30)"))).to eq('(invoke notice (call fqdn_rand 30))')
end
it "notice type(42)" do
expect(dump(parse("notice type(42)"))).to eq('(invoke notice (call type 42))')
end
it "is required to place the '(' on the same line as the name of the function to recognize it as arguments in call" do
expect(dump(parse("notice foo\n(42)"))).to eq("(block\n (invoke notice foo)\n 42\n)")
end
end
context "in nested scopes" do
it "if true { foo() }" do
expect(dump(parse("if true {foo()}"))).to eq("(if true\n (then (invoke foo)))")
end
it "if true { notice bar}" do
expect(dump(parse("if true {notice bar}"))).to eq("(if true\n (then (invoke notice bar)))")
end
end
end
context "When parsing calls as expressions" do
it "$a = foo()" do
expect(dump(parse("$a = foo()"))).to eq("(= $a (call foo))")
end
it "$a = foo(bar)" do
expect(dump(parse("$a = foo()"))).to eq("(= $a (call foo))")
end
# For egrammar where a bare word can be a "statement"
it "$a = foo bar # illegal, must have parentheses" do
expect(dump(parse("$a = foo bar"))).to eq("(block\n (= $a foo)\n bar\n)")
end
context "in nested scopes" do
it "if true { $a = foo() }" do
expect(dump(parse("if true { $a = foo()}"))).to eq("(if true\n (then (= $a (call foo))))")
end
it "if true { $a= foo(bar)}" do
expect(dump(parse("if true {$a = foo(bar)}"))).to eq("(if true\n (then (= $a (call foo bar))))")
end
end
end
context "When parsing method calls" do
it "$a.foo" do
expect(dump(parse("$a.foo"))).to eq("(call-method (. $a foo))")
end
it "$a.foo || { }" do
expect(dump(parse("$a.foo || { }"))).to eq("(call-method (. $a foo) (lambda ()))")
end
it "$a.foo |$x| { }" do
expect(dump(parse("$a.foo |$x|{ }"))).to eq("(call-method (. $a foo) (lambda (parameters x) ()))")
end
it "$a.foo |$x|{ }" do
expect(dump(parse("$a.foo |$x|{ $b = $x}"))).to eq([
"(call-method (. $a foo) (lambda (parameters x) (block",
" (= $b $x)",
")))"
].join("\n"))
end
it "notice 42.type()" do
expect(dump(parse("notice 42.type()"))).to eq('(invoke notice (call-method (. 42 type)))')
end
it 'notice Hash.assert_type(a => 42)' do
expect(dump(parse('notice Hash.assert_type(a => 42)'))).to eq('(invoke notice (call-method (. Hash assert_type) ({} (a 42))))')
end
it "notice 42.type(detailed)" do
expect(dump(parse("notice 42.type(detailed)"))).to eq('(invoke notice (call-method (. 42 type) detailed))')
end
it "is required to place the '(' on the same line as the name of the method to recognize it as arguments in call" do
expect(dump(parse("notice 42.type\n(detailed)"))).to eq("(block\n (invoke notice (call-method (. 42 type)))\n detailed\n)")
end
end
context "When parsing an illegal argument list" do
it "raises an error if argument list is not for a call" do
expect do
parse("$a = 10, 3")
end.to raise_error(/illegal comma/)
end
it "raises an error if argument list is for a potential call not allowed without parentheses" do
expect do
parse("foo 10, 3")
end.to raise_error(/attempt to pass argument list to the function 'foo' which cannot be called without parentheses/)
end
it "does no raise an error for an argument list to an allowed call" do
expect do
parse("notice 10, 3")
end.to_not raise_error()
end
end
end
|