ripper_ruby_parser 1.1.1 → 1.1.2
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 +4 -4
- data/CHANGELOG.md +19 -0
- data/Rakefile +2 -2
- data/lib/ripper_ruby_parser/commenting_ripper_parser.rb +55 -4
- data/lib/ripper_ruby_parser/sexp_handlers/blocks.rb +20 -13
- data/lib/ripper_ruby_parser/sexp_handlers/conditionals.rb +27 -12
- data/lib/ripper_ruby_parser/sexp_handlers/hashes.rb +25 -12
- data/lib/ripper_ruby_parser/sexp_handlers/helper_methods.rb +4 -2
- data/lib/ripper_ruby_parser/sexp_handlers/literals.rb +19 -15
- data/lib/ripper_ruby_parser/sexp_handlers/loops.rb +25 -11
- data/lib/ripper_ruby_parser/sexp_handlers/method_calls.rb +12 -4
- data/lib/ripper_ruby_parser/sexp_handlers/methods.rb +8 -4
- data/lib/ripper_ruby_parser/sexp_handlers/operators.rb +1 -5
- data/lib/ripper_ruby_parser/version.rb +1 -1
- data/lib/ripper_ruby_parser.rb +2 -2
- data/test/end_to_end/comments_test.rb +4 -4
- data/test/end_to_end/comparison_test.rb +15 -15
- data/test/end_to_end/error_conditions_test.rb +16 -16
- data/test/end_to_end/lib_comparison_test.rb +3 -3
- data/test/end_to_end/line_numbering_test.rb +4 -4
- data/test/end_to_end/samples_comparison_test.rb +4 -4
- data/test/end_to_end/test_comparison_test.rb +3 -3
- data/test/pt_testcase/pt_test.rb +4 -4
- data/test/test_helper.rb +1 -1
- data/test/unit/commenting_ripper_parser_test.rb +33 -33
- data/test/unit/parser_assignment_test.rb +30 -30
- data/test/unit/parser_blocks_test.rb +83 -65
- data/test/unit/parser_conditionals_test.rb +96 -64
- data/test/unit/parser_literals_test.rb +308 -212
- data/test/unit/parser_loops_test.rb +85 -15
- data/test/unit/parser_method_calls_test.rb +100 -41
- data/test/unit/parser_operators_test.rb +60 -28
- data/test/unit/parser_test.rb +435 -410
- data/test/unit/sexp_processor_test.rb +82 -82
- data/test/unit/version_test.rb +1 -1
- metadata +2 -2
@@ -1,342 +1,352 @@
|
|
1
1
|
require File.expand_path('../test_helper.rb', File.dirname(__FILE__))
|
2
2
|
|
3
3
|
describe RipperRubyParser::Parser do
|
4
|
-
describe
|
5
|
-
describe
|
6
|
-
it
|
7
|
-
|
4
|
+
describe '#parse' do
|
5
|
+
describe 'for regexp literals' do
|
6
|
+
it 'works for a simple regex literal' do
|
7
|
+
'/foo/'.
|
8
8
|
must_be_parsed_as s(:lit, /foo/)
|
9
9
|
end
|
10
10
|
|
11
|
-
it
|
11
|
+
it 'works for regex literals with escaped right bracket' do
|
12
12
|
'/\\)/'.
|
13
13
|
must_be_parsed_as s(:lit, /\)/)
|
14
14
|
end
|
15
15
|
|
16
|
-
it
|
16
|
+
it 'works for regex literals with escape sequences' do
|
17
17
|
'/\\)\\n\\\\/'.
|
18
18
|
must_be_parsed_as s(:lit, /\)\n\\/)
|
19
19
|
end
|
20
20
|
|
21
|
-
it
|
22
|
-
|
21
|
+
it 'works for a regex literal with the multiline flag' do
|
22
|
+
'/foo/m'.
|
23
23
|
must_be_parsed_as s(:lit, /foo/m)
|
24
24
|
end
|
25
25
|
|
26
|
-
it
|
27
|
-
|
26
|
+
it 'works for a regex literal with the extended flag' do
|
27
|
+
'/foo/x'.
|
28
28
|
must_be_parsed_as s(:lit, /foo/x)
|
29
29
|
end
|
30
30
|
|
31
|
-
it
|
32
|
-
|
31
|
+
it 'works for a regex literal with the ignorecase flag' do
|
32
|
+
'/foo/i'.
|
33
33
|
must_be_parsed_as s(:lit, /foo/i)
|
34
34
|
end
|
35
35
|
|
36
|
-
it
|
37
|
-
|
36
|
+
it 'works for a regex literal with a combination of flags' do
|
37
|
+
'/foo/ixm'.
|
38
38
|
must_be_parsed_as s(:lit, /foo/ixm)
|
39
39
|
end
|
40
40
|
|
41
|
-
it
|
41
|
+
it 'works with the no-encoding flag' do
|
42
42
|
parser = RipperRubyParser::Parser.new
|
43
|
-
result = parser.parse
|
43
|
+
result = parser.parse '/foo/n'
|
44
44
|
# Use inspect since regular == finds no difference between /foo/n
|
45
45
|
# and /foo/
|
46
46
|
result.inspect.must_equal s(:lit, /foo/n).inspect
|
47
47
|
end
|
48
48
|
|
49
|
-
describe
|
50
|
-
it
|
49
|
+
describe 'with interpolations' do
|
50
|
+
it 'works for a simple interpolation' do
|
51
51
|
'/foo#{bar}baz/'.
|
52
52
|
must_be_parsed_as s(:dregx,
|
53
|
-
|
53
|
+
'foo',
|
54
54
|
s(:evstr, s(:call, nil, :bar)),
|
55
|
-
s(:str,
|
55
|
+
s(:str, 'baz'))
|
56
56
|
end
|
57
57
|
|
58
|
-
it
|
58
|
+
it 'works for a regex literal with flags and interpolation' do
|
59
59
|
'/foo#{bar}/ixm'.
|
60
60
|
must_be_parsed_as s(:dregx,
|
61
|
-
|
61
|
+
'foo',
|
62
62
|
s(:evstr, s(:call, nil, :bar)),
|
63
63
|
7)
|
64
64
|
end
|
65
65
|
|
66
|
-
it
|
66
|
+
it 'works with the no-encoding flag' do
|
67
67
|
'/foo#{bar}/n'.
|
68
68
|
must_be_parsed_as s(:dregx,
|
69
|
-
|
69
|
+
'foo',
|
70
70
|
s(:evstr,
|
71
71
|
s(:call, nil, :bar)), 32)
|
72
72
|
end
|
73
73
|
|
74
|
-
it
|
74
|
+
it 'works with the unicode-encoding flag' do
|
75
75
|
'/foo#{bar}/u'.
|
76
76
|
must_be_parsed_as s(:dregx,
|
77
|
-
|
77
|
+
'foo',
|
78
78
|
s(:evstr,
|
79
79
|
s(:call, nil, :bar)), 16)
|
80
80
|
end
|
81
81
|
|
82
|
-
it
|
82
|
+
it 'works with the euc-encoding flag' do
|
83
83
|
'/foo#{bar}/e'.
|
84
84
|
must_be_parsed_as s(:dregx,
|
85
|
-
|
85
|
+
'foo',
|
86
86
|
s(:evstr,
|
87
87
|
s(:call, nil, :bar)), 16)
|
88
88
|
end
|
89
89
|
|
90
|
-
it
|
90
|
+
it 'works with the sjis-encoding flag' do
|
91
91
|
'/foo#{bar}/s'.
|
92
92
|
must_be_parsed_as s(:dregx,
|
93
|
-
|
93
|
+
'foo',
|
94
94
|
s(:evstr,
|
95
95
|
s(:call, nil, :bar)), 16)
|
96
96
|
end
|
97
97
|
|
98
|
-
it
|
98
|
+
it 'works for a regex literal with interpolate-once flag' do
|
99
99
|
'/foo#{bar}/o'.
|
100
100
|
must_be_parsed_as s(:dregx_once,
|
101
|
-
|
101
|
+
'foo',
|
102
102
|
s(:evstr, s(:call, nil, :bar)))
|
103
103
|
end
|
104
104
|
|
105
|
-
it
|
105
|
+
it 'works with an empty interpolation' do
|
106
106
|
'/foo#{}bar/'.
|
107
107
|
must_be_parsed_as s(:dregx,
|
108
|
-
|
108
|
+
'foo',
|
109
109
|
s(:evstr),
|
110
|
-
s(:str,
|
110
|
+
s(:str, 'bar'))
|
111
111
|
end
|
112
112
|
|
113
|
-
describe
|
114
|
-
it
|
113
|
+
describe 'containing just a literal string' do
|
114
|
+
it 'performs the interpolation when it is at the end' do
|
115
115
|
'/foo#{"bar"}/'.must_be_parsed_as s(:lit, /foobar/)
|
116
116
|
end
|
117
117
|
|
118
|
-
it
|
118
|
+
it 'performs the interpolation when it is in the middle' do
|
119
119
|
'/foo#{"bar"}baz/'.must_be_parsed_as s(:lit, /foobarbaz/)
|
120
120
|
end
|
121
121
|
|
122
|
-
it
|
122
|
+
it 'performs the interpolation when it is at the start' do
|
123
123
|
'/#{"foo"}bar/'.must_be_parsed_as s(:lit, /foobar/)
|
124
124
|
end
|
125
125
|
end
|
126
126
|
end
|
127
127
|
end
|
128
128
|
|
129
|
-
describe
|
130
|
-
it
|
129
|
+
describe 'for string literals' do
|
130
|
+
it 'works for empty strings' do
|
131
131
|
"''".
|
132
|
-
must_be_parsed_as s(:str,
|
132
|
+
must_be_parsed_as s(:str, '')
|
133
133
|
end
|
134
134
|
|
135
|
-
it
|
135
|
+
it 'sets the encoding for literal strings to utf8 even if ascii would do' do
|
136
136
|
parser = RipperRubyParser::Parser.new
|
137
|
-
result = parser.parse "
|
138
|
-
result.must_equal s(:str,
|
139
|
-
result[1].encoding.to_s.must_equal
|
137
|
+
result = parser.parse '"foo"'
|
138
|
+
result.must_equal s(:str, 'foo')
|
139
|
+
result[1].encoding.to_s.must_equal 'UTF-8'
|
140
140
|
end
|
141
141
|
|
142
|
-
describe
|
143
|
-
it
|
144
|
-
"
|
142
|
+
describe 'with double-quoted strings with escape sequences' do
|
143
|
+
it 'works for strings with escape sequences' do
|
144
|
+
'"\\n"'.
|
145
145
|
must_be_parsed_as s(:str, "\n")
|
146
146
|
end
|
147
147
|
|
148
|
-
it
|
149
|
-
"
|
150
|
-
must_be_parsed_as s(:str,
|
148
|
+
it 'works for strings with useless escape sequences' do
|
149
|
+
'"F\\OO"'.
|
150
|
+
must_be_parsed_as s(:str, 'FOO')
|
151
151
|
end
|
152
152
|
|
153
|
-
it
|
154
|
-
"
|
155
|
-
must_be_parsed_as s(:str,
|
153
|
+
it 'works for strings with escaped backslashes' do
|
154
|
+
'"\\\\n"'.
|
155
|
+
must_be_parsed_as s(:str, '\\n')
|
156
156
|
end
|
157
157
|
|
158
|
-
it
|
159
|
-
"
|
160
|
-
must_be_parsed_as s(:str,
|
158
|
+
it 'works for a representation of a regex literal with escaped right bracket' do
|
159
|
+
'"/\\\\)/"'.
|
160
|
+
must_be_parsed_as s(:str, '/\\)/')
|
161
161
|
end
|
162
162
|
|
163
|
-
it
|
164
|
-
"
|
165
|
-
must_be_parsed_as s(:str,
|
163
|
+
it 'works for a uselessly escaped right bracket' do
|
164
|
+
'"/\\)/"'.
|
165
|
+
must_be_parsed_as s(:str, '/)/')
|
166
166
|
end
|
167
167
|
|
168
|
-
it
|
169
|
-
"
|
170
|
-
must_be_parsed_as s(:str, "
|
168
|
+
it 'works for a string containing escaped quotes' do
|
169
|
+
'"\\""'.
|
170
|
+
must_be_parsed_as s(:str, '"')
|
171
171
|
end
|
172
172
|
|
173
|
-
it
|
174
|
-
"
|
175
|
-
"
|
176
|
-
"
|
177
|
-
"
|
173
|
+
it 'works with hex escapes' do
|
174
|
+
'"\\x36"'.must_be_parsed_as s(:str, '6')
|
175
|
+
'"\\x4a"'.must_be_parsed_as s(:str, 'J')
|
176
|
+
'"\\x4A"'.must_be_parsed_as s(:str, 'J')
|
177
|
+
'"\\x3Z"'.must_be_parsed_as s(:str, "\x03Z")
|
178
178
|
end
|
179
179
|
|
180
|
-
it
|
181
|
-
"
|
182
|
-
"
|
183
|
-
"
|
184
|
-
"
|
185
|
-
"
|
186
|
-
"
|
187
|
-
"
|
188
|
-
"
|
189
|
-
"
|
180
|
+
it 'works with single-letter escapes' do
|
181
|
+
'"foo\\abar"'.must_be_parsed_as s(:str, "foo\abar")
|
182
|
+
'"foo\\bbar"'.must_be_parsed_as s(:str, "foo\bbar")
|
183
|
+
'"foo\\ebar"'.must_be_parsed_as s(:str, "foo\ebar")
|
184
|
+
'"foo\\fbar"'.must_be_parsed_as s(:str, "foo\fbar")
|
185
|
+
'"foo\\nbar"'.must_be_parsed_as s(:str, "foo\nbar")
|
186
|
+
'"foo\\rbar"'.must_be_parsed_as s(:str, "foo\rbar")
|
187
|
+
'"foo\\sbar"'.must_be_parsed_as s(:str, "foo\sbar")
|
188
|
+
'"foo\\tbar"'.must_be_parsed_as s(:str, "foo\tbar")
|
189
|
+
'"foo\\vbar"'.must_be_parsed_as s(:str, "foo\vbar")
|
190
190
|
end
|
191
191
|
|
192
|
-
it
|
193
|
-
"
|
194
|
-
"
|
195
|
-
"
|
192
|
+
it 'works with octal number escapes' do
|
193
|
+
'"foo\\123bar"'.must_be_parsed_as s(:str, "foo\123bar")
|
194
|
+
'"foo\\23bar"'.must_be_parsed_as s(:str, "foo\023bar")
|
195
|
+
'"foo\\3bar"'.must_be_parsed_as s(:str, "foo\003bar")
|
196
196
|
|
197
|
-
"
|
198
|
-
"
|
197
|
+
'"foo\\118bar"'.must_be_parsed_as s(:str, "foo\0118bar")
|
198
|
+
'"foo\\18bar"'.must_be_parsed_as s(:str, "foo\0018bar")
|
199
199
|
end
|
200
200
|
|
201
|
-
it
|
202
|
-
"
|
203
|
-
"
|
201
|
+
it 'works with simple short hand control sequence escapes' do
|
202
|
+
'"foo\\cabar"'.must_be_parsed_as s(:str, "foo\cabar")
|
203
|
+
'"foo\\cZbar"'.must_be_parsed_as s(:str, "foo\cZbar")
|
204
204
|
end
|
205
205
|
|
206
|
-
it
|
207
|
-
"
|
208
|
-
"
|
206
|
+
it 'works with simple regular control sequence escapes' do
|
207
|
+
'"foo\\C-abar"'.must_be_parsed_as s(:str, "foo\C-abar")
|
208
|
+
'"foo\\C-Zbar"'.must_be_parsed_as s(:str, "foo\C-Zbar")
|
209
209
|
end
|
210
210
|
|
211
211
|
# TODO: Implement remaining escape sequence cases.
|
212
212
|
|
213
213
|
# TODO: Behave differently in extra_compatible mode.
|
214
|
-
it
|
215
|
-
"
|
214
|
+
it 'works with unicode escapes (unlike RubyParser)' do
|
215
|
+
'"foo\\u273bbar"'.must_be_parsed_as s(:str, 'foo✻bar')
|
216
216
|
end
|
217
217
|
end
|
218
218
|
|
219
|
-
describe
|
220
|
-
describe
|
221
|
-
it
|
222
|
-
'"foo#{"bar"}"'.must_be_parsed_as s(:str,
|
219
|
+
describe 'with interpolations' do
|
220
|
+
describe 'containing just a literal string' do
|
221
|
+
it 'performs the interpolation when it is at the end' do
|
222
|
+
'"foo#{"bar"}"'.must_be_parsed_as s(:str, 'foobar')
|
223
223
|
end
|
224
224
|
|
225
|
-
it
|
226
|
-
'"foo#{"bar"}baz"'.must_be_parsed_as s(:str,
|
225
|
+
it 'performs the interpolation when it is in the middle' do
|
226
|
+
'"foo#{"bar"}baz"'.must_be_parsed_as s(:str, 'foobarbaz')
|
227
227
|
end
|
228
228
|
|
229
|
-
it
|
230
|
-
'"#{"foo"}bar"'.must_be_parsed_as s(:str,
|
229
|
+
it 'performs the interpolation when it is at the start' do
|
230
|
+
'"#{"foo"}bar"'.must_be_parsed_as s(:str, 'foobar')
|
231
231
|
end
|
232
232
|
end
|
233
233
|
|
234
|
-
describe
|
235
|
-
it
|
234
|
+
describe 'without braces' do
|
235
|
+
it 'works for ivars' do
|
236
236
|
"\"foo\#@bar\"".must_be_parsed_as s(:dstr,
|
237
|
-
|
237
|
+
'foo',
|
238
238
|
s(:evstr, s(:ivar, :@bar)))
|
239
239
|
end
|
240
240
|
|
241
|
-
it
|
241
|
+
it 'works for gvars' do
|
242
242
|
"\"foo\#$bar\"".must_be_parsed_as s(:dstr,
|
243
|
-
|
243
|
+
'foo',
|
244
244
|
s(:evstr, s(:gvar, :$bar)))
|
245
245
|
end
|
246
246
|
|
247
|
-
it
|
247
|
+
it 'works for cvars' do
|
248
248
|
"\"foo\#@@bar\"".must_be_parsed_as s(:dstr,
|
249
|
-
|
249
|
+
'foo',
|
250
250
|
s(:evstr, s(:cvar, :@@bar)))
|
251
251
|
end
|
252
252
|
end
|
253
253
|
|
254
|
-
describe
|
255
|
-
it
|
254
|
+
describe 'with braces' do
|
255
|
+
it 'works for trivial interpolated strings' do
|
256
256
|
'"#{foo}"'.
|
257
257
|
must_be_parsed_as s(:dstr,
|
258
|
-
|
258
|
+
'',
|
259
259
|
s(:evstr,
|
260
260
|
s(:call, nil, :foo)))
|
261
261
|
end
|
262
262
|
|
263
|
-
it
|
263
|
+
it 'works for basic interpolated strings' do
|
264
264
|
'"foo#{bar}"'.
|
265
265
|
must_be_parsed_as s(:dstr,
|
266
|
-
|
266
|
+
'foo',
|
267
267
|
s(:evstr,
|
268
268
|
s(:call, nil, :bar)))
|
269
269
|
end
|
270
270
|
|
271
|
-
it
|
271
|
+
it 'works for strings with several interpolations' do
|
272
272
|
'"foo#{bar}baz#{qux}"'.
|
273
273
|
must_be_parsed_as s(:dstr,
|
274
|
-
|
274
|
+
'foo',
|
275
275
|
s(:evstr, s(:call, nil, :bar)),
|
276
|
-
s(:str,
|
276
|
+
s(:str, 'baz'),
|
277
277
|
s(:evstr, s(:call, nil, :qux)))
|
278
278
|
end
|
279
279
|
|
280
|
-
it
|
280
|
+
it 'correctly handles two interpolations in a row' do
|
281
281
|
"\"\#{bar}\#{qux}\"".
|
282
282
|
must_be_parsed_as s(:dstr,
|
283
|
-
|
283
|
+
'',
|
284
284
|
s(:evstr, s(:call, nil, :bar)),
|
285
285
|
s(:evstr, s(:call, nil, :qux)))
|
286
286
|
end
|
287
287
|
|
288
|
-
it
|
288
|
+
it 'works for strings with interpolations followed by escape sequences' do
|
289
289
|
'"#{foo}\\n"'.
|
290
290
|
must_be_parsed_as s(:dstr,
|
291
|
-
|
291
|
+
'',
|
292
292
|
s(:evstr, s(:call, nil, :foo)),
|
293
293
|
s(:str, "\n"))
|
294
294
|
end
|
295
295
|
|
296
|
-
it
|
296
|
+
it 'works with an empty interpolation' do
|
297
297
|
"\"foo\#{}bar\"".
|
298
298
|
must_be_parsed_as s(:dstr,
|
299
|
-
|
299
|
+
'foo',
|
300
300
|
s(:evstr),
|
301
|
-
s(:str,
|
301
|
+
s(:str, 'bar'))
|
302
302
|
end
|
303
303
|
end
|
304
304
|
end
|
305
305
|
|
306
|
-
describe
|
307
|
-
it
|
308
|
-
"
|
306
|
+
describe 'with string concatenation' do
|
307
|
+
it 'performs the concatenation in the case of two simple literal strings' do
|
308
|
+
'"foo" "bar"'.must_be_parsed_as s(:str, 'foobar')
|
309
309
|
end
|
310
310
|
|
311
|
-
it
|
311
|
+
it 'performs the concatenation when the right string has interpolations' do
|
312
312
|
"\"foo\" \"bar\#{baz}\"".
|
313
313
|
must_be_parsed_as s(:dstr,
|
314
|
-
|
314
|
+
'foobar',
|
315
315
|
s(:evstr, s(:call, nil, :baz)))
|
316
316
|
end
|
317
317
|
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
318
|
+
describe 'when the left string has interpolations' do
|
319
|
+
it 'performs the concatenation' do
|
320
|
+
"\"foo\#{bar}\" \"baz\"".
|
321
|
+
must_be_parsed_as s(:dstr,
|
322
|
+
'foo',
|
323
|
+
s(:evstr, s(:call, nil, :bar)),
|
324
|
+
s(:str, 'baz'))
|
325
|
+
end
|
326
|
+
|
327
|
+
it 'performs the concatenation with an empty string' do
|
328
|
+
"\"foo\#{bar}\" \"\"".
|
329
|
+
must_be_parsed_as s(:dstr,
|
330
|
+
'foo',
|
331
|
+
s(:evstr, s(:call, nil, :bar)),
|
332
|
+
s(:str, ''))
|
333
|
+
end
|
324
334
|
end
|
325
335
|
|
326
|
-
describe
|
327
|
-
it
|
336
|
+
describe 'when both strings have interpolations' do
|
337
|
+
it 'performs the concatenation' do
|
328
338
|
"\"foo\#{bar}\" \"baz\#{qux}\"".
|
329
339
|
must_be_parsed_as s(:dstr,
|
330
|
-
|
340
|
+
'foo',
|
331
341
|
s(:evstr, s(:call, nil, :bar)),
|
332
|
-
s(:str,
|
342
|
+
s(:str, 'baz'),
|
333
343
|
s(:evstr, s(:call, nil, :qux)))
|
334
344
|
end
|
335
345
|
|
336
|
-
it
|
346
|
+
it 'removes empty substrings from the concatenation' do
|
337
347
|
"\"foo\#{bar}\" \"\#{qux}\"".
|
338
348
|
must_be_parsed_as s(:dstr,
|
339
|
-
|
349
|
+
'foo',
|
340
350
|
s(:evstr, s(:call, nil, :bar)),
|
341
351
|
s(:evstr, s(:call, nil, :qux)))
|
342
352
|
end
|
@@ -344,149 +354,194 @@ describe RipperRubyParser::Parser do
|
|
344
354
|
end
|
345
355
|
end
|
346
356
|
|
347
|
-
describe
|
348
|
-
it
|
357
|
+
describe 'for word list literals' do
|
358
|
+
it 'works for the simle case with %w' do
|
359
|
+
'%W(foo bar)'.
|
360
|
+
must_be_parsed_as s(:array, s(:str, 'foo'), s(:str, 'bar'))
|
361
|
+
end
|
362
|
+
|
363
|
+
it 'works for the simle case with %W' do
|
364
|
+
'%W(foo bar)'.
|
365
|
+
must_be_parsed_as s(:array, s(:str, 'foo'), s(:str, 'bar'))
|
366
|
+
end
|
367
|
+
|
368
|
+
it 'correctly handles interpolation' do
|
349
369
|
"%W(foo \#{bar} baz)".
|
350
370
|
must_be_parsed_as s(:array,
|
351
|
-
s(:str,
|
352
|
-
s(:dstr,
|
353
|
-
s(:str,
|
371
|
+
s(:str, 'foo'),
|
372
|
+
s(:dstr, '', s(:evstr, s(:call, nil, :bar))),
|
373
|
+
s(:str, 'baz'))
|
354
374
|
end
|
355
375
|
|
356
|
-
it
|
376
|
+
it 'correctly handles braceless interpolation' do
|
357
377
|
"%W(foo \#@bar baz)".
|
358
378
|
must_be_parsed_as s(:array,
|
359
|
-
s(:str,
|
360
|
-
s(:dstr,
|
361
|
-
s(:str,
|
379
|
+
s(:str, 'foo'),
|
380
|
+
s(:dstr, '', s(:evstr, s(:ivar, :@bar))),
|
381
|
+
s(:str, 'baz'))
|
382
|
+
end
|
383
|
+
|
384
|
+
it 'correctly handles in-word interpolation' do
|
385
|
+
"%W(foo \#{bar}baz)".
|
386
|
+
must_be_parsed_as s(:array,
|
387
|
+
s(:str, 'foo'),
|
388
|
+
s(:dstr,
|
389
|
+
'',
|
390
|
+
s(:evstr, s(:call, nil, :bar)),
|
391
|
+
s(:str, 'baz')))
|
362
392
|
end
|
363
393
|
end
|
364
394
|
|
365
|
-
describe
|
366
|
-
it
|
367
|
-
|
368
|
-
must_be_parsed_as s(:
|
395
|
+
describe 'for symbol list literals' do
|
396
|
+
it 'works for an array created with %i' do
|
397
|
+
'%i(foo bar)'.
|
398
|
+
must_be_parsed_as s(:array, s(:lit, :foo), s(:lit, :bar))
|
369
399
|
end
|
370
400
|
|
371
|
-
it
|
372
|
-
|
401
|
+
it 'works for an array created with %I' do
|
402
|
+
'%I(foo bar)'.
|
403
|
+
must_be_parsed_as s(:array, s(:lit, :foo), s(:lit, :bar))
|
404
|
+
end
|
405
|
+
|
406
|
+
it 'correctly handles interpolation' do
|
407
|
+
"%I(foo \#{bar} baz)".
|
408
|
+
must_be_parsed_as s(:array,
|
409
|
+
s(:lit, :foo),
|
410
|
+
s(:dsym, "", s(:evstr, s(:call, nil, :bar))),
|
411
|
+
s(:lit, :baz))
|
412
|
+
end
|
413
|
+
|
414
|
+
it 'correctly handles in-word interpolation' do
|
415
|
+
"%I(foo \#{bar}baz)".
|
416
|
+
must_be_parsed_as s(:array,
|
417
|
+
s(:lit, :foo),
|
418
|
+
s(:dsym,
|
419
|
+
"",
|
420
|
+
s(:evstr, s(:call, nil, :bar)),
|
421
|
+
s(:str, "baz")))
|
422
|
+
end
|
423
|
+
end
|
424
|
+
|
425
|
+
describe 'for character literals' do
|
426
|
+
it 'works for simple character literals' do
|
427
|
+
'?a'.
|
428
|
+
must_be_parsed_as s(:str, 'a')
|
429
|
+
end
|
430
|
+
|
431
|
+
it 'works for escaped character literals' do
|
432
|
+
'?\\n'.
|
373
433
|
must_be_parsed_as s(:str, "\n")
|
374
434
|
end
|
375
435
|
|
376
|
-
it
|
377
|
-
|
436
|
+
it 'works for escaped character literals with ctrl' do
|
437
|
+
'?\\C-a'.
|
378
438
|
must_be_parsed_as s(:str, "\u0001")
|
379
439
|
end
|
380
440
|
|
381
|
-
it
|
382
|
-
|
383
|
-
must_be_parsed_as s(:str, "\xE1".force_encoding(
|
441
|
+
it 'works for escaped character literals with meta' do
|
442
|
+
'?\\M-a'.
|
443
|
+
must_be_parsed_as s(:str, "\xE1".force_encoding('ascii-8bit'))
|
384
444
|
end
|
385
445
|
|
386
|
-
it
|
387
|
-
|
388
|
-
must_be_parsed_as s(:str, "\x81".force_encoding(
|
446
|
+
it 'works for escaped character literals with meta plus shorthand ctrl' do
|
447
|
+
'?\\M-\\ca'.
|
448
|
+
must_be_parsed_as s(:str, "\x81".force_encoding('ascii-8bit'))
|
389
449
|
end
|
390
450
|
|
391
|
-
it
|
392
|
-
|
393
|
-
must_be_parsed_as s(:str, "\x81".force_encoding(
|
451
|
+
it 'works for escaped character literals with shorthand ctrl plus meta' do
|
452
|
+
'?\\c\\M-a'.
|
453
|
+
must_be_parsed_as s(:str, "\x81".force_encoding('ascii-8bit'))
|
394
454
|
end
|
395
455
|
|
396
|
-
it
|
397
|
-
|
398
|
-
must_be_parsed_as s(:str, "\x81".force_encoding(
|
456
|
+
it 'works for escaped character literals with meta plus ctrl' do
|
457
|
+
'?\\M-\\C-a'.
|
458
|
+
must_be_parsed_as s(:str, "\x81".force_encoding('ascii-8bit'))
|
399
459
|
end
|
400
460
|
|
401
|
-
it
|
402
|
-
|
403
|
-
must_be_parsed_as s(:str, "\x81".force_encoding(
|
461
|
+
it 'works for escaped character literals with ctrl plus meta' do
|
462
|
+
'?\\C-\\M-a'.
|
463
|
+
must_be_parsed_as s(:str, "\x81".force_encoding('ascii-8bit'))
|
404
464
|
end
|
405
465
|
end
|
406
466
|
|
407
|
-
describe
|
408
|
-
it
|
409
|
-
|
467
|
+
describe 'for symbol literals' do
|
468
|
+
it 'works for simple symbols' do
|
469
|
+
':foo'.
|
410
470
|
must_be_parsed_as s(:lit, :foo)
|
411
471
|
end
|
412
472
|
|
413
|
-
it
|
414
|
-
|
473
|
+
it 'works for symbols that look like instance variable names' do
|
474
|
+
':@foo'.
|
415
475
|
must_be_parsed_as s(:lit, :@foo)
|
416
476
|
end
|
417
477
|
|
418
|
-
it
|
478
|
+
it 'works for simple dsyms' do
|
419
479
|
':"foo"'.
|
420
480
|
must_be_parsed_as s(:lit, :foo)
|
421
481
|
end
|
422
482
|
|
423
|
-
it
|
483
|
+
it 'works for dsyms with interpolations' do
|
424
484
|
':"foo#{bar}"'.
|
425
485
|
must_be_parsed_as s(:dsym,
|
426
|
-
|
486
|
+
'foo',
|
427
487
|
s(:evstr, s(:call, nil, :bar)))
|
428
488
|
end
|
429
489
|
end
|
430
490
|
|
431
|
-
describe
|
432
|
-
it
|
491
|
+
describe 'for backtick string literals' do
|
492
|
+
it 'works for basic backtick strings' do
|
433
493
|
'`foo`'.
|
434
|
-
must_be_parsed_as s(:xstr,
|
494
|
+
must_be_parsed_as s(:xstr, 'foo')
|
435
495
|
end
|
436
496
|
|
437
|
-
it
|
497
|
+
it 'works for interpolated backtick strings' do
|
438
498
|
'`foo#{bar}`'.
|
439
499
|
must_be_parsed_as s(:dxstr,
|
440
|
-
|
500
|
+
'foo',
|
441
501
|
s(:evstr, s(:call, nil, :bar)))
|
442
502
|
end
|
443
503
|
|
444
|
-
it
|
504
|
+
it 'works for backtick strings with escape sequences' do
|
445
505
|
'`foo\\n`'.
|
446
506
|
must_be_parsed_as s(:xstr, "foo\n")
|
447
507
|
end
|
448
508
|
end
|
449
509
|
|
450
|
-
describe
|
451
|
-
it
|
452
|
-
|
510
|
+
describe 'for array literals' do
|
511
|
+
it 'works for an empty array' do
|
512
|
+
'[]'.
|
453
513
|
must_be_parsed_as s(:array)
|
454
514
|
end
|
455
515
|
|
456
|
-
it
|
457
|
-
|
516
|
+
it 'works for a simple case with splat' do
|
517
|
+
'[*foo]'.
|
458
518
|
must_be_parsed_as s(:array,
|
459
519
|
s(:splat, s(:call, nil, :foo)))
|
460
520
|
end
|
461
521
|
|
462
|
-
it
|
463
|
-
|
522
|
+
it 'works for a multi-element case with splat' do
|
523
|
+
'[foo, *bar]'.
|
464
524
|
must_be_parsed_as s(:array,
|
465
525
|
s(:call, nil, :foo),
|
466
526
|
s(:splat, s(:call, nil, :bar)))
|
467
527
|
end
|
468
|
-
|
469
|
-
it "works for an array created with %W" do
|
470
|
-
"%W(foo bar)".
|
471
|
-
must_be_parsed_as s(:array, s(:str, "foo"), s(:str, "bar"))
|
472
|
-
end
|
473
528
|
end
|
474
529
|
|
475
|
-
describe
|
476
|
-
it
|
477
|
-
|
530
|
+
describe 'for hash literals' do
|
531
|
+
it 'works for an empty hash' do
|
532
|
+
'{}'.
|
478
533
|
must_be_parsed_as s(:hash)
|
479
534
|
end
|
480
535
|
|
481
|
-
it
|
482
|
-
|
536
|
+
it 'works for a hash with one pair' do
|
537
|
+
'{foo => bar}'.
|
483
538
|
must_be_parsed_as s(:hash,
|
484
539
|
s(:call, nil, :foo),
|
485
540
|
s(:call, nil, :bar))
|
486
541
|
end
|
487
542
|
|
488
|
-
it
|
489
|
-
|
543
|
+
it 'works for a hash with multiple pairs' do
|
544
|
+
'{foo => bar, baz => qux}'.
|
490
545
|
must_be_parsed_as s(:hash,
|
491
546
|
s(:call, nil, :foo),
|
492
547
|
s(:call, nil, :bar),
|
@@ -494,26 +549,67 @@ describe RipperRubyParser::Parser do
|
|
494
549
|
s(:call, nil, :qux))
|
495
550
|
end
|
496
551
|
|
497
|
-
it
|
498
|
-
|
552
|
+
it 'works for a hash with label keys' do
|
553
|
+
'{foo: bar, baz: qux}'.
|
499
554
|
must_be_parsed_as s(:hash,
|
500
555
|
s(:lit, :foo),
|
501
556
|
s(:call, nil, :bar),
|
502
557
|
s(:lit, :baz),
|
503
558
|
s(:call, nil, :qux))
|
504
559
|
end
|
560
|
+
|
561
|
+
it 'works for a hash with dynamic label keys' do
|
562
|
+
skip 'This is not valid syntax below Ruby 2.2' if RUBY_VERSION < '2.2.0'
|
563
|
+
"{'foo': bar}".
|
564
|
+
must_be_parsed_as s(:hash,
|
565
|
+
s(:lit, :foo),
|
566
|
+
s(:call, nil, :bar))
|
567
|
+
end
|
568
|
+
|
569
|
+
it 'works for a hash with splat' do
|
570
|
+
'{foo: bar, baz: qux, **quux}'.
|
571
|
+
must_be_parsed_as s(:hash,
|
572
|
+
s(:lit, :foo), s(:call, nil, :bar),
|
573
|
+
s(:lit, :baz), s(:call, nil, :qux),
|
574
|
+
s(:kwsplat, s(:call, nil, :quux)))
|
575
|
+
end
|
505
576
|
end
|
506
577
|
|
507
|
-
describe
|
508
|
-
it
|
509
|
-
|
578
|
+
describe 'for number literals' do
|
579
|
+
it 'works for floats' do
|
580
|
+
'3.14'.
|
510
581
|
must_be_parsed_as s(:lit, 3.14)
|
511
582
|
end
|
512
583
|
|
513
|
-
it
|
514
|
-
|
584
|
+
it 'works for octal integer literals' do
|
585
|
+
'0700'.
|
515
586
|
must_be_parsed_as s(:lit, 448)
|
516
587
|
end
|
588
|
+
|
589
|
+
it 'handles negative sign for integers' do
|
590
|
+
'-1'.
|
591
|
+
must_be_parsed_as s(:lit, -1)
|
592
|
+
end
|
593
|
+
|
594
|
+
it 'handles space after negative sign for integers' do
|
595
|
+
'-1 '.
|
596
|
+
must_be_parsed_as s(:lit, -1)
|
597
|
+
end
|
598
|
+
|
599
|
+
it 'handles negative sign for floats' do
|
600
|
+
'-3.14'.
|
601
|
+
must_be_parsed_as s(:lit, -3.14)
|
602
|
+
end
|
603
|
+
|
604
|
+
it 'handles space after negative sign for floats' do
|
605
|
+
'-3.14 '.
|
606
|
+
must_be_parsed_as s(:lit, -3.14)
|
607
|
+
end
|
608
|
+
|
609
|
+
it 'handles positive sign' do
|
610
|
+
'+1'.
|
611
|
+
must_be_parsed_as s(:lit, 1)
|
612
|
+
end
|
517
613
|
end
|
518
614
|
end
|
519
615
|
end
|