ripper_ruby_parser 0.0.8 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/{README.rdoc → README.md} +17 -17
- data/Rakefile +3 -1
- data/lib/ripper_ruby_parser/{commenting_sexp_builder.rb → commenting_ripper_parser.rb} +22 -6
- data/lib/ripper_ruby_parser/parser.rb +3 -18
- data/lib/ripper_ruby_parser/sexp_handlers/arrays.rb +2 -1
- data/lib/ripper_ruby_parser/sexp_handlers/assignment.rb +6 -10
- data/lib/ripper_ruby_parser/sexp_handlers/blocks.rb +37 -60
- data/lib/ripper_ruby_parser/sexp_handlers/conditionals.rb +31 -25
- data/lib/ripper_ruby_parser/sexp_handlers/helper_methods.rb +18 -8
- data/lib/ripper_ruby_parser/sexp_handlers/literals.rb +22 -18
- data/lib/ripper_ruby_parser/sexp_handlers/loops.rb +12 -23
- data/lib/ripper_ruby_parser/sexp_handlers/method_calls.rb +16 -8
- data/lib/ripper_ruby_parser/sexp_handlers/methods.rb +41 -15
- data/lib/ripper_ruby_parser/sexp_handlers/operators.rb +40 -23
- data/lib/ripper_ruby_parser/sexp_processor.rb +38 -19
- data/lib/ripper_ruby_parser/version.rb +1 -1
- data/test/pt_testcase/pt_test.rb +15 -1
- data/test/test_helper.rb +6 -3
- data/test/unit/commenting_ripper_parser_test.rb +121 -0
- data/test/unit/parser_assignment_test.rb +23 -24
- data/test/unit/parser_blocks_test.rb +207 -35
- data/test/unit/parser_conditionals_test.rb +251 -9
- data/test/unit/parser_literals_test.rb +348 -8
- data/test/unit/parser_loops_test.rb +20 -21
- data/test/unit/parser_method_calls_test.rb +132 -8
- data/test/unit/parser_operators_test.rb +97 -7
- data/test/unit/parser_test.rb +631 -1231
- data/test/unit/sexp_processor_test.rb +26 -28
- metadata +28 -38
- data/test/unit/commenting_sexp_builder_test.rb +0 -113
@@ -2,25 +2,267 @@ require File.expand_path('../test_helper.rb', File.dirname(__FILE__))
|
|
2
2
|
|
3
3
|
describe RipperRubyParser::Parser do
|
4
4
|
describe "#parse" do
|
5
|
+
describe "for regular if" do
|
6
|
+
it "works with a single statement" do
|
7
|
+
"if foo; bar; end".
|
8
|
+
must_be_parsed_as s(:if,
|
9
|
+
s(:call, nil, :foo),
|
10
|
+
s(:call, nil, :bar),
|
11
|
+
nil)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "works with multiple statements" do
|
15
|
+
"if foo; bar; baz; end".
|
16
|
+
must_be_parsed_as s(:if,
|
17
|
+
s(:call, nil, :foo),
|
18
|
+
s(:block,
|
19
|
+
s(:call, nil, :bar),
|
20
|
+
s(:call, nil, :baz)),
|
21
|
+
nil)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "works with an else clause" do
|
25
|
+
"if foo; bar; else; baz; end".
|
26
|
+
must_be_parsed_as s(:if,
|
27
|
+
s(:call, nil, :foo),
|
28
|
+
s(:call, nil, :bar),
|
29
|
+
s(:call, nil, :baz))
|
30
|
+
end
|
31
|
+
|
32
|
+
it "works with an elsif clause" do
|
33
|
+
"if foo; bar; elsif baz; qux; end".
|
34
|
+
must_be_parsed_as s(:if,
|
35
|
+
s(:call, nil, :foo),
|
36
|
+
s(:call, nil, :bar),
|
37
|
+
s(:if,
|
38
|
+
s(:call, nil, :baz),
|
39
|
+
s(:call, nil, :qux),
|
40
|
+
nil))
|
41
|
+
end
|
42
|
+
|
43
|
+
it "handles a negative condition correctly" do
|
44
|
+
"if not foo; bar; end".
|
45
|
+
must_be_parsed_as s(:if,
|
46
|
+
s(:call, s(:call, nil, :foo), :!),
|
47
|
+
s(:call, nil, :bar),
|
48
|
+
nil)
|
49
|
+
end
|
50
|
+
|
51
|
+
it "handles a negative condition in elsif correctly" do
|
52
|
+
"if foo; bar; elsif not baz; qux; end".
|
53
|
+
must_be_parsed_as s(:if,
|
54
|
+
s(:call, nil, :foo),
|
55
|
+
s(:call, nil, :bar),
|
56
|
+
s(:if,
|
57
|
+
s(:call, s(:call, nil, :baz), :!),
|
58
|
+
s(:call, nil, :qux), nil))
|
59
|
+
end
|
60
|
+
|
61
|
+
it "handles bare regex literal in condition" do
|
62
|
+
"if /foo/; bar; end".
|
63
|
+
must_be_parsed_as s(:if,
|
64
|
+
s(:match, s(:lit, /foo/)),
|
65
|
+
s(:call, nil, :bar),
|
66
|
+
nil)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "handles interpolated regex in condition" do
|
70
|
+
'if /#{foo}/; bar; end'.
|
71
|
+
must_be_parsed_as s(:if,
|
72
|
+
s(:dregx, "", s(:evstr, s(:call, nil, :foo))),
|
73
|
+
s(:call, nil, :bar),
|
74
|
+
nil)
|
75
|
+
end
|
76
|
+
|
77
|
+
it "handles block conditions" do
|
78
|
+
"if (foo; bar); baz; end".
|
79
|
+
must_be_parsed_as s(:if,
|
80
|
+
s(:block, s(:call, nil, :foo), s(:call, nil, :bar)),
|
81
|
+
s(:call, nil, :baz),
|
82
|
+
nil)
|
83
|
+
end
|
84
|
+
|
85
|
+
it "converts :dot2 to :flip2" do
|
86
|
+
"if foo..bar; baz; end".
|
87
|
+
must_be_parsed_as s(:if,
|
88
|
+
s(:flip2, s(:call, nil, :foo), s(:call, nil, :bar)),
|
89
|
+
s(:call, nil, :baz),
|
90
|
+
nil)
|
91
|
+
end
|
92
|
+
|
93
|
+
it "converts :dot3 to :flip3" do
|
94
|
+
"if foo...bar; baz; end".
|
95
|
+
must_be_parsed_as s(:if,
|
96
|
+
s(:flip3, s(:call, nil, :foo), s(:call, nil, :bar)),
|
97
|
+
s(:call, nil, :baz),
|
98
|
+
nil)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
5
102
|
describe "for postfix if" do
|
6
|
-
it "
|
103
|
+
it "works with a simple condition" do
|
104
|
+
"foo if bar".
|
105
|
+
must_be_parsed_as s(:if,
|
106
|
+
s(:call, nil, :bar),
|
107
|
+
s(:call, nil, :foo),
|
108
|
+
nil)
|
109
|
+
end
|
110
|
+
|
111
|
+
it "handles negative conditions" do
|
7
112
|
"foo if not bar".
|
8
113
|
must_be_parsed_as s(:if,
|
9
|
-
s(:call, nil, :bar,
|
114
|
+
s(:call, s(:call, nil, :bar), :!),
|
115
|
+
s(:call, nil, :foo),
|
116
|
+
nil)
|
117
|
+
end
|
118
|
+
|
119
|
+
it "handles bare regex literal in condition" do
|
120
|
+
"foo if /bar/".
|
121
|
+
must_be_parsed_as s(:if,
|
122
|
+
s(:match, s(:lit, /bar/)),
|
123
|
+
s(:call, nil, :foo),
|
124
|
+
nil)
|
125
|
+
end
|
126
|
+
|
127
|
+
it "handles interpolated regex in condition" do
|
128
|
+
'foo if /#{bar}/'.
|
129
|
+
must_be_parsed_as s(:if,
|
130
|
+
s(:dregx, "", s(:evstr, s(:call, nil, :bar))),
|
131
|
+
s(:call, nil, :foo),
|
132
|
+
nil)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
describe "for regular unless" do
|
137
|
+
it "works with a single statement" do
|
138
|
+
"unless bar; foo; end".
|
139
|
+
must_be_parsed_as s(:if,
|
140
|
+
s(:call, nil, :bar),
|
141
|
+
nil,
|
142
|
+
s(:call, nil, :foo))
|
143
|
+
end
|
144
|
+
|
145
|
+
it "works with an else clause" do
|
146
|
+
"unless foo; bar; else; baz; end".
|
147
|
+
must_be_parsed_as s(:if,
|
148
|
+
s(:call, nil, :foo),
|
149
|
+
s(:call, nil, :baz),
|
150
|
+
s(:call, nil, :bar))
|
151
|
+
end
|
152
|
+
it "handles bare regex literal in condition" do
|
153
|
+
"unless /foo/; bar; end".
|
154
|
+
must_be_parsed_as s(:if,
|
155
|
+
s(:match, s(:lit, /foo/)),
|
156
|
+
nil,
|
157
|
+
s(:call, nil, :bar))
|
158
|
+
end
|
159
|
+
|
160
|
+
it "handles interpolated regex in condition" do
|
161
|
+
'unless /#{foo}/; bar; end'.
|
162
|
+
must_be_parsed_as s(:if,
|
163
|
+
s(:dregx, "", s(:evstr, s(:call, nil, :foo))),
|
164
|
+
nil,
|
165
|
+
s(:call, nil, :bar))
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
describe "for postfix unless" do
|
170
|
+
it "works with a simple condition" do
|
171
|
+
"foo unless bar".
|
172
|
+
must_be_parsed_as s(:if,
|
173
|
+
s(:call, nil, :bar),
|
174
|
+
nil,
|
175
|
+
s(:call, nil, :foo))
|
176
|
+
end
|
177
|
+
|
178
|
+
it "handles bare regex literal in condition" do
|
179
|
+
"foo unless /bar/".
|
180
|
+
must_be_parsed_as s(:if,
|
181
|
+
s(:match, s(:lit, /bar/)),
|
182
|
+
nil,
|
183
|
+
s(:call, nil, :foo))
|
184
|
+
end
|
185
|
+
|
186
|
+
it "handles interpolated regex in condition" do
|
187
|
+
'foo unless /#{bar}/'.
|
188
|
+
must_be_parsed_as s(:if,
|
189
|
+
s(:dregx, "", s(:evstr, s(:call, nil, :bar))),
|
10
190
|
nil,
|
11
|
-
s(:call, nil, :foo
|
191
|
+
s(:call, nil, :foo))
|
12
192
|
end
|
13
193
|
end
|
14
194
|
|
15
|
-
describe "for case" do
|
16
|
-
it "
|
195
|
+
describe "for case block" do
|
196
|
+
it "works with a single when clause" do
|
197
|
+
"case foo; when bar; baz; end".
|
198
|
+
must_be_parsed_as s(:case,
|
199
|
+
s(:call, nil, :foo),
|
200
|
+
s(:when,
|
201
|
+
s(:array, s(:call, nil, :bar)),
|
202
|
+
s(:call, nil, :baz)),
|
203
|
+
nil)
|
204
|
+
end
|
205
|
+
|
206
|
+
it "works with multiple when clauses" do
|
207
|
+
"case foo; when bar; baz; when qux; quux; end".
|
208
|
+
must_be_parsed_as s(:case,
|
209
|
+
s(:call, nil, :foo),
|
210
|
+
s(:when,
|
211
|
+
s(:array, s(:call, nil, :bar)),
|
212
|
+
s(:call, nil, :baz)),
|
213
|
+
s(:when,
|
214
|
+
s(:array, s(:call, nil, :qux)),
|
215
|
+
s(:call, nil, :quux)),
|
216
|
+
nil)
|
217
|
+
end
|
218
|
+
|
219
|
+
it "works with multiple statements in the when block" do
|
220
|
+
"case foo; when bar; baz; qux; end".
|
221
|
+
must_be_parsed_as s(:case,
|
222
|
+
s(:call, nil, :foo),
|
223
|
+
s(:when,
|
224
|
+
s(:array, s(:call, nil, :bar)),
|
225
|
+
s(:call, nil, :baz),
|
226
|
+
s(:call, nil, :qux)),
|
227
|
+
nil)
|
228
|
+
end
|
229
|
+
|
230
|
+
it "works with an else clause" do
|
231
|
+
"case foo; when bar; baz; else; qux; end".
|
232
|
+
must_be_parsed_as s(:case,
|
233
|
+
s(:call, nil, :foo),
|
234
|
+
s(:when,
|
235
|
+
s(:array, s(:call, nil, :bar)),
|
236
|
+
s(:call, nil, :baz)),
|
237
|
+
s(:call, nil, :qux))
|
238
|
+
end
|
239
|
+
|
240
|
+
it "works with an empty when block" do
|
241
|
+
"case foo; when bar; end".
|
242
|
+
must_be_parsed_as s(:case,
|
243
|
+
s(:call, nil, :foo),
|
244
|
+
s(:when, s(:array, s(:call, nil, :bar)), nil),
|
245
|
+
nil)
|
246
|
+
end
|
247
|
+
|
248
|
+
it "works with an empty else block" do
|
249
|
+
"case foo; when bar; baz; else; end".
|
250
|
+
must_be_parsed_as s(:case,
|
251
|
+
s(:call, nil, :foo),
|
252
|
+
s(:when,
|
253
|
+
s(:array, s(:call, nil, :bar)),
|
254
|
+
s(:call, nil, :baz)),
|
255
|
+
nil)
|
256
|
+
end
|
257
|
+
|
258
|
+
it "works with a splat in the when clause" do
|
17
259
|
"case foo; when *bar; baz; end".
|
18
|
-
must_be_parsed_as s(:case,
|
260
|
+
must_be_parsed_as s(:case,
|
261
|
+
s(:call, nil, :foo),
|
19
262
|
s(:when,
|
20
263
|
s(:array,
|
21
|
-
s(:
|
22
|
-
|
23
|
-
s(:call, nil, :baz, s(:arglist))),
|
264
|
+
s(:splat, s(:call, nil, :bar))),
|
265
|
+
s(:call, nil, :baz)),
|
24
266
|
nil)
|
25
267
|
|
26
268
|
end
|
@@ -4,6 +4,41 @@ require File.expand_path('../test_helper.rb', File.dirname(__FILE__))
|
|
4
4
|
describe RipperRubyParser::Parser do
|
5
5
|
describe "#parse" do
|
6
6
|
describe "for regexp literals" do
|
7
|
+
it "works for a simple regex literal" do
|
8
|
+
"/foo/".
|
9
|
+
must_be_parsed_as s(:lit, /foo/)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "works for regex literals with escaped right bracket" do
|
13
|
+
'/\\)/'.
|
14
|
+
must_be_parsed_as s(:lit, /\)/)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "works for regex literals with escape sequences" do
|
18
|
+
'/\\)\\n\\\\/'.
|
19
|
+
must_be_parsed_as s(:lit, /\)\n\\/)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "works for a regex literal with the multiline flag" do
|
23
|
+
"/foo/m".
|
24
|
+
must_be_parsed_as s(:lit, /foo/m)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "works for a regex literal with the extended flag" do
|
28
|
+
"/foo/x".
|
29
|
+
must_be_parsed_as s(:lit, /foo/x)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "works for a regex literal with the ignorecase flag" do
|
33
|
+
"/foo/i".
|
34
|
+
must_be_parsed_as s(:lit, /foo/i)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "works for a regex literal with a combination of flags" do
|
38
|
+
"/foo/ixm".
|
39
|
+
must_be_parsed_as s(:lit, /foo/ixm)
|
40
|
+
end
|
41
|
+
|
7
42
|
it "works with the no-encoding flag" do
|
8
43
|
parser = RipperRubyParser::Parser.new
|
9
44
|
result = parser.parse "/foo/n"
|
@@ -13,12 +48,28 @@ describe RipperRubyParser::Parser do
|
|
13
48
|
end
|
14
49
|
|
15
50
|
describe "with interpolations" do
|
51
|
+
it "works for a simple interpolation" do
|
52
|
+
'/foo#{bar}baz/'.
|
53
|
+
must_be_parsed_as s(:dregx,
|
54
|
+
"foo",
|
55
|
+
s(:evstr, s(:call, nil, :bar)),
|
56
|
+
s(:str, "baz"))
|
57
|
+
end
|
58
|
+
|
59
|
+
it "works for a regex literal with flags and interpolation" do
|
60
|
+
'/foo#{bar}/ixm'.
|
61
|
+
must_be_parsed_as s(:dregx,
|
62
|
+
"foo",
|
63
|
+
s(:evstr, s(:call, nil, :bar)),
|
64
|
+
7)
|
65
|
+
end
|
66
|
+
|
16
67
|
it "works with the no-encoding flag" do
|
17
68
|
'/foo#{bar}/n'.
|
18
69
|
must_be_parsed_as s(:dregx,
|
19
70
|
"foo",
|
20
71
|
s(:evstr,
|
21
|
-
s(:call, nil, :bar
|
72
|
+
s(:call, nil, :bar)), 32)
|
22
73
|
end
|
23
74
|
|
24
75
|
it "works with the unicode-encoding flag" do
|
@@ -26,7 +77,7 @@ describe RipperRubyParser::Parser do
|
|
26
77
|
must_be_parsed_as s(:dregx,
|
27
78
|
"foo",
|
28
79
|
s(:evstr,
|
29
|
-
s(:call, nil, :bar
|
80
|
+
s(:call, nil, :bar)), 16)
|
30
81
|
end
|
31
82
|
|
32
83
|
it "works with the euc-encoding flag" do
|
@@ -34,7 +85,7 @@ describe RipperRubyParser::Parser do
|
|
34
85
|
must_be_parsed_as s(:dregx,
|
35
86
|
"foo",
|
36
87
|
s(:evstr,
|
37
|
-
s(:call, nil, :bar
|
88
|
+
s(:call, nil, :bar)), 16)
|
38
89
|
end
|
39
90
|
|
40
91
|
it "works with the sjis-encoding flag" do
|
@@ -42,7 +93,22 @@ describe RipperRubyParser::Parser do
|
|
42
93
|
must_be_parsed_as s(:dregx,
|
43
94
|
"foo",
|
44
95
|
s(:evstr,
|
45
|
-
s(:call, nil, :bar
|
96
|
+
s(:call, nil, :bar)), 16)
|
97
|
+
end
|
98
|
+
|
99
|
+
it "works for a regex literal with interpolate-once flag" do
|
100
|
+
'/foo#{bar}/o'.
|
101
|
+
must_be_parsed_as s(:dregx_once,
|
102
|
+
"foo",
|
103
|
+
s(:evstr, s(:call, nil, :bar)))
|
104
|
+
end
|
105
|
+
|
106
|
+
it "works with an empty interpolation" do
|
107
|
+
'/foo#{}bar/'.
|
108
|
+
must_be_parsed_as s(:dregx,
|
109
|
+
"foo",
|
110
|
+
s(:evstr),
|
111
|
+
s(:str, "bar"))
|
46
112
|
end
|
47
113
|
|
48
114
|
describe "containing just a literal string" do
|
@@ -62,7 +128,49 @@ describe RipperRubyParser::Parser do
|
|
62
128
|
end
|
63
129
|
|
64
130
|
describe "for string literals" do
|
131
|
+
it "works for empty strings" do
|
132
|
+
"''".
|
133
|
+
must_be_parsed_as s(:str, "")
|
134
|
+
end
|
135
|
+
|
136
|
+
it "sets the encoding for literal strings to utf8 even if ascii would do" do
|
137
|
+
parser = RipperRubyParser::Parser.new
|
138
|
+
result = parser.parse "\"foo\""
|
139
|
+
result.must_equal s(:str, "foo")
|
140
|
+
result[1].encoding.to_s.must_equal "UTF-8"
|
141
|
+
end
|
142
|
+
|
65
143
|
describe "with escape sequences" do
|
144
|
+
it "works for strings with escape sequences" do
|
145
|
+
"\"\\n\"".
|
146
|
+
must_be_parsed_as s(:str, "\n")
|
147
|
+
end
|
148
|
+
|
149
|
+
it "works for strings with useless escape sequences" do
|
150
|
+
"\"F\\OO\"".
|
151
|
+
must_be_parsed_as s(:str, "FOO")
|
152
|
+
end
|
153
|
+
|
154
|
+
it "works for strings with escaped backslashes" do
|
155
|
+
"\"\\\\n\"".
|
156
|
+
must_be_parsed_as s(:str, "\\n")
|
157
|
+
end
|
158
|
+
|
159
|
+
it "works for a double-quoted string representing a regex literal with escaped right bracket" do
|
160
|
+
"\"/\\\\)/\"".
|
161
|
+
must_be_parsed_as s(:str, "/\\)/")
|
162
|
+
end
|
163
|
+
|
164
|
+
it "works for a double-quoted string containing a uselessly escaped right bracket" do
|
165
|
+
"\"/\\)/\"".
|
166
|
+
must_be_parsed_as s(:str, "/)/")
|
167
|
+
end
|
168
|
+
|
169
|
+
it "works for a string containing escaped quotes" do
|
170
|
+
"\"\\\"\"".
|
171
|
+
must_be_parsed_as s(:str, "\"")
|
172
|
+
end
|
173
|
+
|
66
174
|
it "works with hex escapes" do
|
67
175
|
"\"\\x36\"".must_be_parsed_as s(:str, "6")
|
68
176
|
"\"\\x4a\"".must_be_parsed_as s(:str, "J")
|
@@ -143,6 +251,57 @@ describe RipperRubyParser::Parser do
|
|
143
251
|
s(:evstr, s(:cvar, :@@bar)))
|
144
252
|
end
|
145
253
|
end
|
254
|
+
|
255
|
+
describe "with braces" do
|
256
|
+
it "works for trivial interpolated strings" do
|
257
|
+
'"#{foo}"'.
|
258
|
+
must_be_parsed_as s(:dstr,
|
259
|
+
"",
|
260
|
+
s(:evstr,
|
261
|
+
s(:call, nil, :foo)))
|
262
|
+
end
|
263
|
+
|
264
|
+
it "works for basic interpolated strings" do
|
265
|
+
'"foo#{bar}"'.
|
266
|
+
must_be_parsed_as s(:dstr,
|
267
|
+
"foo",
|
268
|
+
s(:evstr,
|
269
|
+
s(:call, nil, :bar)))
|
270
|
+
end
|
271
|
+
|
272
|
+
it "works for strings with several interpolations" do
|
273
|
+
'"foo#{bar}baz#{qux}"'.
|
274
|
+
must_be_parsed_as s(:dstr,
|
275
|
+
"foo",
|
276
|
+
s(:evstr, s(:call, nil, :bar)),
|
277
|
+
s(:str, "baz"),
|
278
|
+
s(:evstr, s(:call, nil, :qux)))
|
279
|
+
end
|
280
|
+
|
281
|
+
it "correctly handles two interpolations in a row" do
|
282
|
+
"\"\#{bar}\#{qux}\"".
|
283
|
+
must_be_parsed_as s(:dstr,
|
284
|
+
"",
|
285
|
+
s(:evstr, s(:call, nil, :bar)),
|
286
|
+
s(:evstr, s(:call, nil, :qux)))
|
287
|
+
end
|
288
|
+
|
289
|
+
it "works for strings with interpolations followed by escape sequences" do
|
290
|
+
'"#{foo}\\n"'.
|
291
|
+
must_be_parsed_as s(:dstr,
|
292
|
+
"",
|
293
|
+
s(:evstr, s(:call, nil, :foo)),
|
294
|
+
s(:str, "\n"))
|
295
|
+
end
|
296
|
+
|
297
|
+
it "works with an empty interpolation" do
|
298
|
+
"\"foo\#{}bar\"".
|
299
|
+
must_be_parsed_as s(:dstr,
|
300
|
+
"foo",
|
301
|
+
s(:evstr),
|
302
|
+
s(:str, "bar"))
|
303
|
+
end
|
304
|
+
end
|
146
305
|
end
|
147
306
|
|
148
307
|
describe "with string concatenation" do
|
@@ -154,14 +313,14 @@ describe RipperRubyParser::Parser do
|
|
154
313
|
"\"foo\" \"bar\#{baz}\"".
|
155
314
|
must_be_parsed_as s(:dstr,
|
156
315
|
"foobar",
|
157
|
-
s(:evstr, s(:call, nil, :baz
|
316
|
+
s(:evstr, s(:call, nil, :baz)))
|
158
317
|
end
|
159
318
|
|
160
319
|
it "performs the concatenation when the left string has interpolations" do
|
161
320
|
"\"foo\#{bar}\" \"baz\"".
|
162
321
|
must_be_parsed_as s(:dstr,
|
163
322
|
"foo",
|
164
|
-
s(:evstr, s(:call, nil, :bar
|
323
|
+
s(:evstr, s(:call, nil, :bar)),
|
165
324
|
s(:str, "baz"))
|
166
325
|
end
|
167
326
|
|
@@ -169,11 +328,192 @@ describe RipperRubyParser::Parser do
|
|
169
328
|
"\"foo\#{bar}\" \"baz\#{qux}\"".
|
170
329
|
must_be_parsed_as s(:dstr,
|
171
330
|
"foo",
|
172
|
-
s(:evstr, s(:call, nil, :bar
|
331
|
+
s(:evstr, s(:call, nil, :bar)),
|
173
332
|
s(:str, "baz"),
|
174
|
-
s(:evstr, s(:call, nil, :qux
|
333
|
+
s(:evstr, s(:call, nil, :qux)))
|
334
|
+
end
|
335
|
+
|
336
|
+
it "removes empty substrings from the concatenation when both strings have interpolations" do
|
337
|
+
"\"foo\#{bar}\" \"\#{qux}\"".
|
338
|
+
must_be_parsed_as s(:dstr,
|
339
|
+
"foo",
|
340
|
+
s(:evstr, s(:call, nil, :bar)),
|
341
|
+
s(:evstr, s(:call, nil, :qux)))
|
175
342
|
end
|
176
343
|
end
|
177
344
|
end
|
345
|
+
|
346
|
+
describe "for word list literals" do
|
347
|
+
it "correctly handles interpolation" do
|
348
|
+
"%W(foo \#{bar} baz)".
|
349
|
+
must_be_parsed_as s(:array,
|
350
|
+
s(:str, "foo"),
|
351
|
+
s(:dstr, "", s(:evstr, s(:call, nil, :bar))),
|
352
|
+
s(:str, "baz"))
|
353
|
+
end
|
354
|
+
|
355
|
+
it "correctly handles braceless interpolation" do
|
356
|
+
"%W(foo \#@bar baz)".
|
357
|
+
must_be_parsed_as s(:array,
|
358
|
+
s(:str, "foo"),
|
359
|
+
s(:dstr, "", s(:evstr, s(:ivar, :@bar))),
|
360
|
+
s(:str, "baz"))
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
describe "for character literals" do
|
365
|
+
it "works for simple character literals" do
|
366
|
+
"?a".
|
367
|
+
must_be_parsed_as s(:str, "a")
|
368
|
+
end
|
369
|
+
|
370
|
+
it "works for escaped character literals" do
|
371
|
+
"?\\n".
|
372
|
+
must_be_parsed_as s(:str, "\n")
|
373
|
+
end
|
374
|
+
|
375
|
+
it "works for escaped character literals with ctrl" do
|
376
|
+
"?\\C-a".
|
377
|
+
must_be_parsed_as s(:str, "\u0001")
|
378
|
+
end
|
379
|
+
|
380
|
+
it "works for escaped character literals with meta" do
|
381
|
+
"?\\M-a".
|
382
|
+
must_be_parsed_as s(:str, "\xE1".force_encoding("ascii-8bit"))
|
383
|
+
end
|
384
|
+
|
385
|
+
it "works for escaped character literals with meta plus shorthand ctrl" do
|
386
|
+
"?\\M-\\ca".
|
387
|
+
must_be_parsed_as s(:str, "\x81".force_encoding("ascii-8bit"))
|
388
|
+
end
|
389
|
+
|
390
|
+
it "works for escaped character literals with shorthand ctrl plus meta" do
|
391
|
+
"?\\c\\M-a".
|
392
|
+
must_be_parsed_as s(:str, "\x81".force_encoding("ascii-8bit"))
|
393
|
+
end
|
394
|
+
|
395
|
+
it "works for escaped character literals with meta plus ctrl" do
|
396
|
+
"?\\M-\\C-a".
|
397
|
+
must_be_parsed_as s(:str, "\x81".force_encoding("ascii-8bit"))
|
398
|
+
end
|
399
|
+
|
400
|
+
it "works for escaped character literals with ctrl plus meta" do
|
401
|
+
"?\\C-\\M-a".
|
402
|
+
must_be_parsed_as s(:str, "\x81".force_encoding("ascii-8bit"))
|
403
|
+
end
|
404
|
+
end
|
405
|
+
|
406
|
+
describe "for symbol literals" do
|
407
|
+
it "works for simple symbols" do
|
408
|
+
":foo".
|
409
|
+
must_be_parsed_as s(:lit, :foo)
|
410
|
+
end
|
411
|
+
|
412
|
+
it "works for symbols that look like instance variable names" do
|
413
|
+
":@foo".
|
414
|
+
must_be_parsed_as s(:lit, :@foo)
|
415
|
+
end
|
416
|
+
|
417
|
+
it "works for simple dsyms" do
|
418
|
+
':"foo"'.
|
419
|
+
must_be_parsed_as s(:lit, :foo)
|
420
|
+
end
|
421
|
+
|
422
|
+
it "works for dsyms with interpolations" do
|
423
|
+
':"foo#{bar}"'.
|
424
|
+
must_be_parsed_as s(:dsym,
|
425
|
+
"foo",
|
426
|
+
s(:evstr, s(:call, nil, :bar)))
|
427
|
+
end
|
428
|
+
end
|
429
|
+
|
430
|
+
describe "for backtick string literals" do
|
431
|
+
it "works for basic backtick strings" do
|
432
|
+
'`foo`'.
|
433
|
+
must_be_parsed_as s(:xstr, "foo")
|
434
|
+
end
|
435
|
+
|
436
|
+
it "works for interpolated backtick strings" do
|
437
|
+
'`foo#{bar}`'.
|
438
|
+
must_be_parsed_as s(:dxstr,
|
439
|
+
"foo",
|
440
|
+
s(:evstr, s(:call, nil, :bar)))
|
441
|
+
end
|
442
|
+
|
443
|
+
it "works for backtick strings with escape sequences" do
|
444
|
+
'`foo\\n`'.
|
445
|
+
must_be_parsed_as s(:xstr, "foo\n")
|
446
|
+
end
|
447
|
+
end
|
448
|
+
|
449
|
+
describe "for array literals" do
|
450
|
+
it "works for an empty array" do
|
451
|
+
"[]".
|
452
|
+
must_be_parsed_as s(:array)
|
453
|
+
end
|
454
|
+
|
455
|
+
it "works for a simple case with splat" do
|
456
|
+
"[*foo]".
|
457
|
+
must_be_parsed_as s(:array,
|
458
|
+
s(:splat, s(:call, nil, :foo)))
|
459
|
+
end
|
460
|
+
|
461
|
+
it "works for a multi-element case with splat" do
|
462
|
+
"[foo, *bar]".
|
463
|
+
must_be_parsed_as s(:array,
|
464
|
+
s(:call, nil, :foo),
|
465
|
+
s(:splat, s(:call, nil, :bar)))
|
466
|
+
end
|
467
|
+
|
468
|
+
it "works for an array created with %W" do
|
469
|
+
"%W(foo bar)".
|
470
|
+
must_be_parsed_as s(:array, s(:str, "foo"), s(:str, "bar"))
|
471
|
+
end
|
472
|
+
end
|
473
|
+
|
474
|
+
describe "for hash literals" do
|
475
|
+
it "works for an empty hash" do
|
476
|
+
"{}".
|
477
|
+
must_be_parsed_as s(:hash)
|
478
|
+
end
|
479
|
+
|
480
|
+
it "works for a hash with one pair" do
|
481
|
+
"{foo => bar}".
|
482
|
+
must_be_parsed_as s(:hash,
|
483
|
+
s(:call, nil, :foo),
|
484
|
+
s(:call, nil, :bar))
|
485
|
+
end
|
486
|
+
|
487
|
+
it "works for a hash with multiple pairs" do
|
488
|
+
"{foo => bar, baz => qux}".
|
489
|
+
must_be_parsed_as s(:hash,
|
490
|
+
s(:call, nil, :foo),
|
491
|
+
s(:call, nil, :bar),
|
492
|
+
s(:call, nil, :baz),
|
493
|
+
s(:call, nil, :qux))
|
494
|
+
end
|
495
|
+
|
496
|
+
it "works for a hash with label keys (Ruby 1.9 only)" do
|
497
|
+
"{foo: bar, baz: qux}".
|
498
|
+
must_be_parsed_as s(:hash,
|
499
|
+
s(:lit, :foo),
|
500
|
+
s(:call, nil, :bar),
|
501
|
+
s(:lit, :baz),
|
502
|
+
s(:call, nil, :qux))
|
503
|
+
end
|
504
|
+
end
|
505
|
+
|
506
|
+
describe "for number literals" do
|
507
|
+
it "works for floats" do
|
508
|
+
"3.14".
|
509
|
+
must_be_parsed_as s(:lit, 3.14)
|
510
|
+
end
|
511
|
+
|
512
|
+
it "works for octal integer literals" do
|
513
|
+
"0700".
|
514
|
+
must_be_parsed_as s(:lit, 448)
|
515
|
+
end
|
516
|
+
end
|
517
|
+
|
178
518
|
end
|
179
519
|
end
|