File: parse_calls_spec.rb

package info (click to toggle)
puppet 5.5.10-4
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 21,116 kB
  • sloc: ruby: 250,669; sh: 1,620; xml: 218; makefile: 151; sql: 103
file content (172 lines) | stat: -rw-r--r-- 5,553 bytes parent folder | download
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