ripper_ruby_parser 1.7.0 → 1.9.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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +76 -0
  3. data/README.md +6 -4
  4. data/lib/ripper_ruby_parser/commenting_ripper_parser.rb +24 -12
  5. data/lib/ripper_ruby_parser/sexp_handlers.rb +2 -0
  6. data/lib/ripper_ruby_parser/sexp_handlers/assignment.rb +9 -4
  7. data/lib/ripper_ruby_parser/sexp_handlers/blocks.rb +40 -52
  8. data/lib/ripper_ruby_parser/sexp_handlers/conditionals.rb +17 -19
  9. data/lib/ripper_ruby_parser/sexp_handlers/helper_methods.rb +35 -2
  10. data/lib/ripper_ruby_parser/sexp_handlers/literals.rb +15 -242
  11. data/lib/ripper_ruby_parser/sexp_handlers/method_calls.rb +9 -5
  12. data/lib/ripper_ruby_parser/sexp_handlers/methods.rb +22 -17
  13. data/lib/ripper_ruby_parser/sexp_handlers/operators.rb +3 -3
  14. data/lib/ripper_ruby_parser/sexp_handlers/string_literals.rb +256 -0
  15. data/lib/ripper_ruby_parser/sexp_processor.rb +12 -56
  16. data/lib/ripper_ruby_parser/unescape.rb +89 -43
  17. data/lib/ripper_ruby_parser/version.rb +1 -1
  18. metadata +125 -76
  19. data/Rakefile +0 -33
  20. data/test/end_to_end/comments_test.rb +0 -59
  21. data/test/end_to_end/comparison_test.rb +0 -104
  22. data/test/end_to_end/lib_comparison_test.rb +0 -29
  23. data/test/end_to_end/line_numbering_test.rb +0 -31
  24. data/test/end_to_end/samples_comparison_test.rb +0 -13
  25. data/test/end_to_end/test_comparison_test.rb +0 -32
  26. data/test/pt_testcase/pt_test.rb +0 -44
  27. data/test/ripper_ruby_parser/commenting_ripper_parser_test.rb +0 -200
  28. data/test/ripper_ruby_parser/parser_test.rb +0 -553
  29. data/test/ripper_ruby_parser/sexp_handlers/assignment_test.rb +0 -613
  30. data/test/ripper_ruby_parser/sexp_handlers/blocks_test.rb +0 -679
  31. data/test/ripper_ruby_parser/sexp_handlers/conditionals_test.rb +0 -536
  32. data/test/ripper_ruby_parser/sexp_handlers/literals_test.rb +0 -1106
  33. data/test/ripper_ruby_parser/sexp_handlers/loops_test.rb +0 -209
  34. data/test/ripper_ruby_parser/sexp_handlers/method_calls_test.rb +0 -267
  35. data/test/ripper_ruby_parser/sexp_handlers/methods_test.rb +0 -421
  36. data/test/ripper_ruby_parser/sexp_handlers/operators_test.rb +0 -399
  37. data/test/ripper_ruby_parser/sexp_processor_test.rb +0 -303
  38. data/test/ripper_ruby_parser/version_test.rb +0 -7
  39. data/test/samples/assignment.rb +0 -17
  40. data/test/samples/comments.rb +0 -13
  41. data/test/samples/conditionals.rb +0 -23
  42. data/test/samples/lambdas.rb +0 -5
  43. data/test/samples/loops.rb +0 -36
  44. data/test/samples/misc.rb +0 -281
  45. data/test/samples/number.rb +0 -7
  46. data/test/samples/operators.rb +0 -18
  47. data/test/samples/strings.rb +0 -147
  48. data/test/test_helper.rb +0 -107
@@ -1,1106 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require File.expand_path("../../test_helper.rb", File.dirname(__FILE__))
4
-
5
- describe RipperRubyParser::Parser do
6
- let(:parser) { RipperRubyParser::Parser.new }
7
-
8
- describe "#parse" do
9
- describe "for regexp literals" do
10
- it "works for a simple regex literal" do
11
- _("/foo/")
12
- .must_be_parsed_as s(:lit, /foo/)
13
- end
14
-
15
- it "works for regex literals with escaped right parenthesis" do
16
- _('/\\)/')
17
- .must_be_parsed_as s(:lit, /\)/)
18
- end
19
-
20
- it "works for regex literals with escape sequences" do
21
- _('/\\)\\n\\\\/')
22
- .must_be_parsed_as s(:lit, /\)\n\\/)
23
- end
24
-
25
- it "does not fix encoding" do
26
- _('/2\302\275/')
27
- .must_be_parsed_as s(:lit, /2\302\275/)
28
- end
29
-
30
- it "works for a regex literal with the multiline flag" do
31
- _("/foo/m")
32
- .must_be_parsed_as s(:lit, /foo/m)
33
- end
34
-
35
- it "works for a regex literal with the extended flag" do
36
- _("/foo/x")
37
- .must_be_parsed_as s(:lit, /foo/x)
38
- end
39
-
40
- it "works for a regex literal with the ignorecase flag" do
41
- _("/foo/i")
42
- .must_be_parsed_as s(:lit, /foo/i)
43
- end
44
-
45
- it "works for a regex literal with a combination of flags" do
46
- _("/foo/ixmn")
47
- .must_be_parsed_as s(:lit, /foo/mixn)
48
- end
49
-
50
- it "works with the no-encoding flag" do
51
- _("/foo/n")
52
- .must_be_parsed_as s(:lit, /foo/n)
53
- end
54
-
55
- it "works with line continuation" do
56
- _("/foo\\\nbar/")
57
- .must_be_parsed_as s(:lit, /foobar/)
58
- end
59
-
60
- describe "for a %r-delimited regex literal" do
61
- it "works for the simple case with escape sequences" do
62
- _('%r[foo\nbar]')
63
- .must_be_parsed_as s(:lit, /foo\nbar/)
64
- end
65
-
66
- it "works with odd delimiters and escape sequences" do
67
- _('%r_foo\nbar_')
68
- .must_be_parsed_as s(:lit, /foo\nbar/)
69
- end
70
- end
71
-
72
- describe "with interpolations" do
73
- it "works for a simple interpolation" do
74
- _('/foo#{bar}baz/')
75
- .must_be_parsed_as s(:dregx,
76
- "foo",
77
- s(:evstr, s(:call, nil, :bar)),
78
- s(:str, "baz"))
79
- end
80
-
81
- it "works for a regex literal with flags and interpolation" do
82
- _('/foo#{bar}/ixm')
83
- .must_be_parsed_as s(:dregx,
84
- "foo",
85
- s(:evstr, s(:call, nil, :bar)),
86
- 7)
87
- end
88
-
89
- it "works with the no-encoding flag" do
90
- _('/foo#{bar}/n')
91
- .must_be_parsed_as s(:dregx,
92
- "foo",
93
- s(:evstr,
94
- s(:call, nil, :bar)), 32)
95
- end
96
-
97
- it "works with the unicode-encoding flag" do
98
- _('/foo#{bar}/u')
99
- .must_be_parsed_as s(:dregx,
100
- "foo",
101
- s(:evstr,
102
- s(:call, nil, :bar)), 16)
103
- end
104
-
105
- it "works with unicode flag plus other flag" do
106
- _('/foo#{bar}/un')
107
- .must_be_parsed_as s(:dregx,
108
- "foo",
109
- s(:evstr,
110
- s(:call, nil, :bar)), 48)
111
- end
112
-
113
- it "works with the euc-encoding flag" do
114
- _('/foo#{bar}/e')
115
- .must_be_parsed_as s(:dregx,
116
- "foo",
117
- s(:evstr,
118
- s(:call, nil, :bar)), 16)
119
- end
120
-
121
- it "works with the sjis-encoding flag" do
122
- _('/foo#{bar}/s')
123
- .must_be_parsed_as s(:dregx,
124
- "foo",
125
- s(:evstr,
126
- s(:call, nil, :bar)), 16)
127
- end
128
-
129
- it "works for a regex literal with interpolate-once flag" do
130
- _('/foo#{bar}/o')
131
- .must_be_parsed_as s(:dregx_once,
132
- "foo",
133
- s(:evstr, s(:call, nil, :bar)))
134
- end
135
-
136
- it "works with an empty interpolation" do
137
- _('/foo#{}bar/')
138
- .must_be_parsed_as s(:dregx,
139
- "foo",
140
- s(:evstr),
141
- s(:str, "bar"))
142
- end
143
-
144
- describe "containing just a literal string" do
145
- it "performs the interpolation when it is at the end" do
146
- _('/foo#{"bar"}/').must_be_parsed_as s(:lit, /foobar/)
147
- end
148
-
149
- it "performs the interpolation when it is in the middle" do
150
- _('/foo#{"bar"}baz/').must_be_parsed_as s(:lit, /foobarbaz/)
151
- end
152
-
153
- it "performs the interpolation when it is at the start" do
154
- _('/#{"foo"}bar/').must_be_parsed_as s(:lit, /foobar/)
155
- end
156
- end
157
- end
158
- end
159
-
160
- describe "for string literals" do
161
- it "works for empty strings" do
162
- _("''")
163
- .must_be_parsed_as s(:str, "")
164
- end
165
-
166
- it "sets the encoding for literal strings to utf8 even if ascii would do" do
167
- parser = RipperRubyParser::Parser.new
168
- result = parser.parse '"foo"'
169
- _(result).must_equal s(:str, "foo")
170
- _(result[1].encoding.to_s).must_equal "UTF-8"
171
- end
172
-
173
- it "handles line breaks within double-quoted strings" do
174
- _("\"foo\nbar\"")
175
- .must_be_parsed_as s(:str, "foo\nbar")
176
- end
177
-
178
- it "handles line continuation with double-quoted strings" do
179
- _("\"foo\\\nbar\"")
180
- .must_be_parsed_as s(:str, "foobar")
181
- end
182
-
183
- it "escapes line continuation with double-quoted strings" do
184
- _("\"foo\\\\\nbar\"")
185
- .must_be_parsed_as s(:str, "foo\\\nbar")
186
- end
187
-
188
- describe "with double-quoted strings with escape sequences" do
189
- it "works for strings with escape sequences" do
190
- _('"\\n"')
191
- .must_be_parsed_as s(:str, "\n")
192
- end
193
-
194
- it "works for strings with useless escape sequences" do
195
- _('"F\\OO"')
196
- .must_be_parsed_as s(:str, "FOO")
197
- end
198
-
199
- it "works for strings with escaped backslashes" do
200
- _('"\\\\n"')
201
- .must_be_parsed_as s(:str, '\\n')
202
- end
203
-
204
- it "works for a representation of a regex literal with escaped right parenthesis" do
205
- _('"/\\\\)/"')
206
- .must_be_parsed_as s(:str, '/\\)/')
207
- end
208
-
209
- it "works for a uselessly escaped right parenthesis" do
210
- _('"/\\)/"')
211
- .must_be_parsed_as s(:str, "/)/")
212
- end
213
-
214
- it "works for a string containing escaped quotes" do
215
- _('"\\""')
216
- .must_be_parsed_as s(:str, '"')
217
- end
218
-
219
- it "works with hex escapes" do
220
- _('"\\x36"').must_be_parsed_as s(:str, "6")
221
- _('"\\x4a"').must_be_parsed_as s(:str, "J")
222
- _('"\\x4A"').must_be_parsed_as s(:str, "J")
223
- _('"\\x3Z"').must_be_parsed_as s(:str, "\x03Z")
224
- end
225
-
226
- it "works with single-letter escapes" do
227
- _('"foo\\abar"').must_be_parsed_as s(:str, "foo\abar")
228
- _('"foo\\bbar"').must_be_parsed_as s(:str, "foo\bbar")
229
- _('"foo\\ebar"').must_be_parsed_as s(:str, "foo\ebar")
230
- _('"foo\\fbar"').must_be_parsed_as s(:str, "foo\fbar")
231
- _('"foo\\nbar"').must_be_parsed_as s(:str, "foo\nbar")
232
- _('"foo\\rbar"').must_be_parsed_as s(:str, "foo\rbar")
233
- _('"foo\\sbar"').must_be_parsed_as s(:str, "foo\sbar")
234
- _('"foo\\tbar"').must_be_parsed_as s(:str, "foo\tbar")
235
- _('"foo\\vbar"').must_be_parsed_as s(:str, "foo\vbar")
236
- end
237
-
238
- it "works with octal number escapes" do
239
- _('"foo\\123bar"').must_be_parsed_as s(:str, "foo\123bar")
240
- _('"foo\\23bar"').must_be_parsed_as s(:str, "foo\023bar")
241
- _('"foo\\3bar"').must_be_parsed_as s(:str, "foo\003bar")
242
-
243
- _('"foo\\118bar"').must_be_parsed_as s(:str, "foo\0118bar")
244
- _('"foo\\18bar"').must_be_parsed_as s(:str, "foo\0018bar")
245
- end
246
-
247
- it "works with simple short hand control sequence escapes" do
248
- _('"foo\\cabar"').must_be_parsed_as s(:str, "foo\cabar")
249
- _('"foo\\cZbar"').must_be_parsed_as s(:str, "foo\cZbar")
250
- end
251
-
252
- it "works with simple regular control sequence escapes" do
253
- _('"foo\\C-abar"').must_be_parsed_as s(:str, "foo\C-abar")
254
- _('"foo\\C-Zbar"').must_be_parsed_as s(:str, "foo\C-Zbar")
255
- end
256
-
257
- it "works with unicode escapes" do
258
- _('"foo\\u273bbar"').must_be_parsed_as s(:str, "foo✻bar")
259
- end
260
-
261
- it "works with unicode escapes with braces" do
262
- _('"foo\\u{273b}bar"').must_be_parsed_as s(:str, "foo✻bar")
263
- end
264
-
265
- it "converts to unicode if possible" do
266
- _('"2\302\275"').must_be_parsed_as s(:str, "2½")
267
- end
268
-
269
- it "does not convert to unicode if result is not valid" do
270
- _('"2\x82\302\275"')
271
- .must_be_parsed_as s(:str,
272
- (+"2\x82\xC2\xBD").force_encoding("ascii-8bit"))
273
- end
274
- end
275
-
276
- describe "with interpolations containing just a literal string" do
277
- it "performs the interpolation when it is at the end" do
278
- _('"foo#{"bar"}"').must_be_parsed_as s(:str, "foobar")
279
- end
280
-
281
- it "performs the interpolation when it is in the middle" do
282
- _('"foo#{"bar"}baz"').must_be_parsed_as s(:str, "foobarbaz")
283
- end
284
-
285
- it "performs the interpolation when it is at the start" do
286
- _('"#{"foo"}bar"').must_be_parsed_as s(:str, "foobar")
287
- end
288
- end
289
-
290
- describe "with interpolations without braces" do
291
- it "works for ivars" do
292
- _("\"foo\#@bar\"").must_be_parsed_as s(:dstr,
293
- "foo",
294
- s(:evstr, s(:ivar, :@bar)))
295
- end
296
-
297
- it "works for gvars" do
298
- _("\"foo\#$bar\"").must_be_parsed_as s(:dstr,
299
- "foo",
300
- s(:evstr, s(:gvar, :$bar)))
301
- end
302
-
303
- it "works for cvars" do
304
- _("\"foo\#@@bar\"").must_be_parsed_as s(:dstr,
305
- "foo",
306
- s(:evstr, s(:cvar, :@@bar)))
307
- end
308
- end
309
-
310
- describe "with interpolations with braces" do
311
- it "works for trivial interpolated strings" do
312
- _('"#{foo}"')
313
- .must_be_parsed_as s(:dstr,
314
- "",
315
- s(:evstr,
316
- s(:call, nil, :foo)))
317
- end
318
-
319
- it "works for basic interpolated strings" do
320
- _('"foo#{bar}"')
321
- .must_be_parsed_as s(:dstr,
322
- "foo",
323
- s(:evstr,
324
- s(:call, nil, :bar)))
325
- end
326
-
327
- it "works for strings with several interpolations" do
328
- _('"foo#{bar}baz#{qux}"')
329
- .must_be_parsed_as s(:dstr,
330
- "foo",
331
- s(:evstr, s(:call, nil, :bar)),
332
- s(:str, "baz"),
333
- s(:evstr, s(:call, nil, :qux)))
334
- end
335
-
336
- it "correctly handles two interpolations in a row" do
337
- _("\"\#{bar}\#{qux}\"")
338
- .must_be_parsed_as s(:dstr,
339
- "",
340
- s(:evstr, s(:call, nil, :bar)),
341
- s(:evstr, s(:call, nil, :qux)))
342
- end
343
-
344
- it "works with an empty interpolation" do
345
- _("\"foo\#{}bar\"")
346
- .must_be_parsed_as s(:dstr,
347
- "foo",
348
- s(:evstr),
349
- s(:str, "bar"))
350
- end
351
-
352
- it "correctly handles interpolation with __FILE__ before another interpolation" do
353
- _("\"foo\#{__FILE__}\#{bar}\"")
354
- .must_be_parsed_as s(:dstr,
355
- "foo(string)",
356
- s(:evstr, s(:call, nil, :bar)))
357
- end
358
-
359
- it "correctly handles interpolation with __FILE__ after another interpolation" do
360
- _("\"\#{bar}foo\#{__FILE__}\"")
361
- .must_be_parsed_as s(:dstr,
362
- "",
363
- s(:evstr, s(:call, nil, :bar)),
364
- s(:str, "foo"),
365
- s(:str, "(string)"))
366
- end
367
-
368
- it "correctly handles nested interpolation" do
369
- _('"foo#{"bar#{baz}"}"')
370
- .must_be_parsed_as s(:dstr,
371
- "foobar",
372
- s(:evstr, s(:call, nil, :baz)))
373
- end
374
-
375
- it "correctly handles consecutive nested interpolation" do
376
- _('"foo#{"bar#{baz}"}foo#{"bar#{baz}"}"')
377
- .must_be_parsed_as s(:dstr,
378
- "foobar",
379
- s(:evstr, s(:call, nil, :baz)),
380
- s(:str, "foo"),
381
- s(:str, "bar"),
382
- s(:evstr, s(:call, nil, :baz)))
383
- end
384
- end
385
-
386
- describe "with interpolations and escape sequences" do
387
- it "works when interpolations are followed by escape sequences" do
388
- _('"#{foo}\\n"')
389
- .must_be_parsed_as s(:dstr,
390
- "",
391
- s(:evstr, s(:call, nil, :foo)),
392
- s(:str, "\n"))
393
- end
394
-
395
- it "works when interpolations contain a mix of other string-like literals" do
396
- _('"#{[:foo, \'bar\']}\\n"')
397
- .must_be_parsed_as s(:dstr,
398
- "",
399
- s(:evstr, s(:array, s(:lit, :foo), s(:str, "bar"))),
400
- s(:str, "\n"))
401
- end
402
-
403
- it "converts to unicode after interpolation" do
404
- _('"#{foo}2\302\275"')
405
- .must_be_parsed_as s(:dstr,
406
- "",
407
- s(:evstr, s(:call, nil, :foo)),
408
- s(:str, "2½"))
409
- end
410
-
411
- it "convert single null byte to unicode after interpolation" do
412
- _('"#{foo}\0"')
413
- .must_be_parsed_as s(:dstr,
414
- "",
415
- s(:evstr, s(:call, nil, :foo)),
416
- s(:str, "\u0000"))
417
- end
418
-
419
- it "converts string with null to unicode after interpolation" do
420
- _('"#{foo}bar\0"')
421
- .must_be_parsed_as s(:dstr,
422
- "",
423
- s(:evstr, s(:call, nil, :foo)),
424
- s(:str, "bar\x00"))
425
- end
426
- end
427
-
428
- describe "with single quoted strings" do
429
- it "works with escaped single quotes" do
430
- _("'foo\\'bar'")
431
- .must_be_parsed_as s(:str, "foo'bar")
432
- end
433
-
434
- it "works with embedded backslashes" do
435
- _("'foo\\abar'")
436
- .must_be_parsed_as s(:str, 'foo\abar')
437
- end
438
-
439
- it "works with escaped embedded backslashes" do
440
- _("'foo\\\\abar'")
441
- .must_be_parsed_as s(:str, 'foo\abar')
442
- end
443
-
444
- it "works with sequences of backslashes" do
445
- _("'foo\\\\\\abar'")
446
- .must_be_parsed_as s(:str, 'foo\\\\abar')
447
- end
448
-
449
- it "does not process line continuation" do
450
- _("'foo\\\nbar'")
451
- .must_be_parsed_as s(:str, "foo\\\nbar")
452
- end
453
- end
454
-
455
- describe "with %Q-delimited strings" do
456
- it "works for the simple case" do
457
- _("%Q[bar]")
458
- .must_be_parsed_as s(:str, "bar")
459
- end
460
-
461
- it "works for escape sequences" do
462
- _('%Q[foo\\nbar]')
463
- .must_be_parsed_as s(:str, "foo\nbar")
464
- end
465
-
466
- it "works for multi-line strings" do
467
- _("%Q[foo\nbar]")
468
- .must_be_parsed_as s(:str, "foo\nbar")
469
- end
470
-
471
- it "handles line continuation" do
472
- _("%Q[foo\\\nbar]")
473
- .must_be_parsed_as s(:str, "foobar")
474
- end
475
- end
476
-
477
- describe "with %q-delimited strings" do
478
- it "works for the simple case" do
479
- _("%q[bar]")
480
- .must_be_parsed_as s(:str, "bar")
481
- end
482
-
483
- it "does not handle for escape sequences" do
484
- _('%q[foo\\nbar]')
485
- .must_be_parsed_as s(:str, 'foo\nbar')
486
- end
487
-
488
- it "works for multi-line strings" do
489
- _("%q[foo\nbar]")
490
- .must_be_parsed_as s(:str, "foo\nbar")
491
- end
492
-
493
- it "handles line continuation" do
494
- _("%q[foo\\\nbar]")
495
- .must_be_parsed_as s(:str, "foo\\\nbar")
496
- end
497
- end
498
-
499
- describe "with %-delimited strings" do
500
- it "works for the simple case" do
501
- _("%(bar)")
502
- .must_be_parsed_as s(:str, "bar")
503
- end
504
-
505
- it "works for escape sequences" do
506
- _('%(foo\nbar)')
507
- .must_be_parsed_as s(:str, "foo\nbar")
508
- end
509
-
510
- it "works for multiple lines" do
511
- _("%(foo\nbar)")
512
- .must_be_parsed_as s(:str, "foo\nbar")
513
- end
514
-
515
- it "works with line continuations" do
516
- _("%(foo\\\nbar)")
517
- .must_be_parsed_as s(:str, "foobar")
518
- end
519
-
520
- it "works for odd delimiters" do
521
- _('%!foo\nbar!')
522
- .must_be_parsed_as s(:str, "foo\nbar")
523
- end
524
- end
525
-
526
- describe "with string concatenation" do
527
- it "performs the concatenation in the case of two simple literal strings" do
528
- _('"foo" "bar"').must_be_parsed_as s(:str, "foobar")
529
- end
530
-
531
- it "performs the concatenation when the right string has interpolations" do
532
- _("\"foo\" \"bar\#{baz}\"")
533
- .must_be_parsed_as s(:dstr,
534
- "foobar",
535
- s(:evstr, s(:call, nil, :baz)))
536
- end
537
-
538
- describe "when the left string has interpolations" do
539
- it "performs the concatenation" do
540
- _("\"foo\#{bar}\" \"baz\"")
541
- .must_be_parsed_as s(:dstr,
542
- "foo",
543
- s(:evstr, s(:call, nil, :bar)),
544
- s(:str, "baz"))
545
- end
546
-
547
- it "performs the concatenation with an empty string" do
548
- _("\"foo\#{bar}\" \"\"")
549
- .must_be_parsed_as s(:dstr,
550
- "foo",
551
- s(:evstr, s(:call, nil, :bar)),
552
- s(:str, ""))
553
- end
554
- end
555
-
556
- describe "when both strings have interpolations" do
557
- it "performs the concatenation" do
558
- _("\"foo\#{bar}\" \"baz\#{qux}\"")
559
- .must_be_parsed_as s(:dstr,
560
- "foo",
561
- s(:evstr, s(:call, nil, :bar)),
562
- s(:str, "baz"),
563
- s(:evstr, s(:call, nil, :qux)))
564
- end
565
-
566
- it "removes empty substrings from the concatenation" do
567
- _("\"foo\#{bar}\" \"\#{qux}\"")
568
- .must_be_parsed_as s(:dstr,
569
- "foo",
570
- s(:evstr, s(:call, nil, :bar)),
571
- s(:evstr, s(:call, nil, :qux)))
572
- end
573
- end
574
- end
575
-
576
- describe "for heredocs" do
577
- it "works for the simple case" do
578
- _("<<FOO\nbar\nFOO")
579
- .must_be_parsed_as s(:str, "bar\n")
580
- end
581
-
582
- it "works with multiple lines" do
583
- _("<<FOO\nbar\nbaz\nFOO")
584
- .must_be_parsed_as s(:str, "bar\nbaz\n")
585
- end
586
-
587
- it "works for the indentable case" do
588
- _("<<-FOO\n bar\n FOO")
589
- .must_be_parsed_as s(:str, " bar\n")
590
- end
591
-
592
- it "works for the automatically outdenting case" do
593
- _(" <<~FOO\n bar\n FOO")
594
- .must_be_parsed_as s(:str, "bar\n")
595
- end
596
-
597
- it "works for escape sequences" do
598
- _("<<FOO\nbar\\tbaz\nFOO")
599
- .must_be_parsed_as s(:str, "bar\tbaz\n")
600
- end
601
-
602
- it 'converts \r to carriage returns' do
603
- _("<<FOO\nbar\\rbaz\\r\nFOO")
604
- .must_be_parsed_as s(:str, "bar\rbaz\r\n")
605
- end
606
-
607
- it "does not unescape with single quoted version" do
608
- _("<<'FOO'\nbar\\tbaz\nFOO")
609
- .must_be_parsed_as s(:str, "bar\\tbaz\n")
610
- end
611
-
612
- it "works with multiple lines with the single quoted version" do
613
- _("<<'FOO'\nbar\nbaz\nFOO")
614
- .must_be_parsed_as s(:str, "bar\nbaz\n")
615
- end
616
-
617
- it "does not unescape with indentable single quoted version" do
618
- _("<<-'FOO'\n bar\\tbaz\n FOO")
619
- .must_be_parsed_as s(:str, " bar\\tbaz\n")
620
- end
621
-
622
- it "does not unescape the automatically outdenting single quoted version" do
623
- _("<<~'FOO'\n bar\\tbaz\n FOO")
624
- .must_be_parsed_as s(:str, "bar\\tbaz\n")
625
- end
626
-
627
- it "handles line continuation" do
628
- _("<<FOO\nbar\\\nbaz\nFOO")
629
- .must_be_parsed_as s(:str, "barbaz\n")
630
- end
631
-
632
- it "escapes line continuation" do
633
- _("<<FOO\nbar\\\\\nbaz\nFOO")
634
- .must_be_parsed_as s(:str, "bar\\\nbaz\n")
635
- end
636
-
637
- it "converts to unicode" do
638
- _("<<FOO\n2\\302\\275\nFOO")
639
- .must_be_parsed_as s(:str, "2½\n")
640
- end
641
-
642
- it "handles interpolation" do
643
- _("<<FOO\n\#{bar}\nFOO")
644
- .must_be_parsed_as s(:dstr, "",
645
- s(:evstr, s(:call, nil, :bar)),
646
- s(:str, "\n"))
647
- end
648
-
649
- it "handles line continuation after interpolation" do
650
- _("<<FOO\n\#{bar}\nbaz\\\nqux\nFOO")
651
- .must_be_parsed_as s(:dstr, "",
652
- s(:evstr, s(:call, nil, :bar)),
653
- s(:str, "\nbazqux\n"))
654
- end
655
-
656
- it "handles line continuation after interpolation for the indentable case" do
657
- _("<<-FOO\n\#{bar}\nbaz\\\nqux\nFOO")
658
- .must_be_parsed_as s(:dstr, "",
659
- s(:evstr, s(:call, nil, :bar)),
660
- s(:str, "\nbazqux\n"))
661
- end
662
- end
663
- end
664
-
665
- describe "for word list literals with %w delimiter" do
666
- it "works for the simple case" do
667
- _("%w(foo bar)")
668
- .must_be_parsed_as s(:array, s(:str, "foo"), s(:str, "bar"))
669
- end
670
-
671
- it "does not perform interpolation" do
672
- _('%w(foo\\nbar baz)')
673
- .must_be_parsed_as s(:array, s(:str, 'foo\\nbar'), s(:str, "baz"))
674
- end
675
-
676
- it "handles line continuation" do
677
- _("%w(foo\\\nbar baz)")
678
- .must_be_parsed_as s(:array, s(:str, "foo\nbar"), s(:str, "baz"))
679
- end
680
-
681
- it "handles escaped spaces" do
682
- _('%w(foo bar\ baz)')
683
- .must_be_parsed_as s(:array, s(:str, "foo"), s(:str, "bar baz"))
684
- end
685
- end
686
-
687
- describe "for word list literals with %W delimiter" do
688
- it "works for the simple case" do
689
- _("%W(foo bar)")
690
- .must_be_parsed_as s(:array, s(:str, "foo"), s(:str, "bar"))
691
- end
692
-
693
- it "handles escaped spaces" do
694
- _('%W(foo bar\ baz)')
695
- .must_be_parsed_as s(:array, s(:str, "foo"), s(:str, "bar baz"))
696
- end
697
-
698
- it "correctly handles interpolation" do
699
- _("%W(foo \#{bar} baz)")
700
- .must_be_parsed_as s(:array,
701
- s(:str, "foo"),
702
- s(:dstr, "", s(:evstr, s(:call, nil, :bar))),
703
- s(:str, "baz"))
704
- end
705
-
706
- it "correctly handles braceless interpolation" do
707
- _("%W(foo \#@bar baz)")
708
- .must_be_parsed_as s(:array,
709
- s(:str, "foo"),
710
- s(:dstr, "", s(:evstr, s(:ivar, :@bar))),
711
- s(:str, "baz"))
712
- end
713
-
714
- it "correctly handles in-word interpolation" do
715
- _("%W(foo \#{bar}baz)")
716
- .must_be_parsed_as s(:array,
717
- s(:str, "foo"),
718
- s(:dstr,
719
- "",
720
- s(:evstr, s(:call, nil, :bar)),
721
- s(:str, "baz")))
722
- end
723
-
724
- it "correctly handles escape sequences" do
725
- _('%W(foo\nbar baz)')
726
- .must_be_parsed_as s(:array,
727
- s(:str, "foo\nbar"),
728
- s(:str, "baz"))
729
- end
730
-
731
- it "converts to unicode if possible" do
732
- _('%W(2\302\275)').must_be_parsed_as s(:array, s(:str, "2½"))
733
- end
734
-
735
- it "correctly handles line continuation" do
736
- _("%W(foo\\\nbar baz)")
737
- .must_be_parsed_as s(:array,
738
- s(:str, "foo\nbar"),
739
- s(:str, "baz"))
740
- end
741
-
742
- it "correctly handles multiple lines" do
743
- _("%W(foo\nbar baz)")
744
- .must_be_parsed_as s(:array,
745
- s(:str, "foo"),
746
- s(:str, "bar"),
747
- s(:str, "baz"))
748
- end
749
- end
750
-
751
- describe "for symbol list literals with %i delimiter" do
752
- it "works for the simple case" do
753
- _("%i(foo bar)")
754
- .must_be_parsed_as s(:array, s(:lit, :foo), s(:lit, :bar))
755
- end
756
-
757
- it "does not perform interpolation" do
758
- _('%i(foo\\nbar baz)')
759
- .must_be_parsed_as s(:array, s(:lit, :"foo\\nbar"), s(:lit, :baz))
760
- end
761
-
762
- it "handles line continuation" do
763
- _("%i(foo\\\nbar baz)")
764
- .must_be_parsed_as s(:array, s(:lit, :"foo\nbar"), s(:lit, :baz))
765
- end
766
- end
767
-
768
- describe "for symbol list literals with %I delimiter" do
769
- it "works for the simple case" do
770
- _("%I(foo bar)")
771
- .must_be_parsed_as s(:array, s(:lit, :foo), s(:lit, :bar))
772
- end
773
-
774
- it "correctly handles escape sequences" do
775
- _('%I(foo\nbar baz)')
776
- .must_be_parsed_as s(:array,
777
- s(:lit, :"foo\nbar"),
778
- s(:lit, :baz))
779
- end
780
-
781
- it "correctly handles interpolation" do
782
- _("%I(foo \#{bar} baz)")
783
- .must_be_parsed_as s(:array,
784
- s(:lit, :foo),
785
- s(:dsym, "", s(:evstr, s(:call, nil, :bar))),
786
- s(:lit, :baz))
787
- end
788
-
789
- it "correctly handles in-word interpolation" do
790
- _("%I(foo \#{bar}baz)")
791
- .must_be_parsed_as s(:array,
792
- s(:lit, :foo),
793
- s(:dsym,
794
- "",
795
- s(:evstr, s(:call, nil, :bar)),
796
- s(:str, "baz")))
797
- end
798
-
799
- it "correctly handles line continuation" do
800
- _("%I(foo\\\nbar baz)")
801
- .must_be_parsed_as s(:array,
802
- s(:lit, :"foo\nbar"),
803
- s(:lit, :baz))
804
- end
805
-
806
- it "correctly handles multiple lines" do
807
- _("%I(foo\nbar baz)")
808
- .must_be_parsed_as s(:array,
809
- s(:lit, :foo),
810
- s(:lit, :bar),
811
- s(:lit, :baz))
812
- end
813
- end
814
-
815
- describe "for character literals" do
816
- it "works for simple character literals" do
817
- _("?a")
818
- .must_be_parsed_as s(:str, "a")
819
- end
820
-
821
- it "works for escaped character literals" do
822
- _('?\\n')
823
- .must_be_parsed_as s(:str, "\n")
824
- end
825
-
826
- it "works for escaped character literals with ctrl" do
827
- _('?\\C-a')
828
- .must_be_parsed_as s(:str, "\u0001")
829
- end
830
-
831
- it "works for escaped character literals with meta" do
832
- _('?\\M-a')
833
- .must_be_parsed_as s(:str, (+"\xE1").force_encoding("ascii-8bit"))
834
- end
835
-
836
- it "works for escaped character literals with meta plus shorthand ctrl" do
837
- _('?\\M-\\ca')
838
- .must_be_parsed_as s(:str, (+"\x81").force_encoding("ascii-8bit"))
839
- end
840
-
841
- it "works for escaped character literals with shorthand ctrl plus meta" do
842
- _('?\\c\\M-a')
843
- .must_be_parsed_as s(:str, (+"\x81").force_encoding("ascii-8bit"))
844
- end
845
-
846
- it "works for escaped character literals with meta plus ctrl" do
847
- _('?\\M-\\C-a')
848
- .must_be_parsed_as s(:str, (+"\x81").force_encoding("ascii-8bit"))
849
- end
850
-
851
- it "works for escaped character literals with ctrl plus meta" do
852
- _('?\\C-\\M-a')
853
- .must_be_parsed_as s(:str, (+"\x81").force_encoding("ascii-8bit"))
854
- end
855
- end
856
-
857
- describe "for symbol literals" do
858
- it "works for simple symbols" do
859
- _(":foo")
860
- .must_be_parsed_as s(:lit, :foo)
861
- end
862
-
863
- it "works for symbols that look like instance variable names" do
864
- _(":@foo")
865
- .must_be_parsed_as s(:lit, :@foo)
866
- end
867
-
868
- it "works for symbols that look like class names" do
869
- _(":Foo")
870
- .must_be_parsed_as s(:lit, :Foo)
871
- end
872
-
873
- it "works for symbols that look like keywords" do
874
- _(":class").must_be_parsed_as s(:lit, :class)
875
- end
876
-
877
- it "works for :__LINE__" do
878
- _(":__LINE__")
879
- .must_be_parsed_as s(:lit, :__LINE__)
880
- end
881
-
882
- it "works for :__FILE__" do
883
- _(":__FILE__")
884
- .must_be_parsed_as s(:lit, :__FILE__)
885
- end
886
-
887
- it "works for a backtick symbol" do
888
- _(":`").must_be_parsed_as s(:lit, :`)
889
- end
890
-
891
- it "works for simple dsyms" do
892
- _(':"foo"')
893
- .must_be_parsed_as s(:lit, :foo)
894
- end
895
-
896
- it "works for dsyms with interpolations" do
897
- _(':"foo#{bar}"')
898
- .must_be_parsed_as s(:dsym,
899
- "foo",
900
- s(:evstr, s(:call, nil, :bar)))
901
- end
902
-
903
- it "works for dsyms with interpolations at the start" do
904
- _(':"#{bar}"')
905
- .must_be_parsed_as s(:dsym,
906
- "",
907
- s(:evstr, s(:call, nil, :bar)))
908
- end
909
-
910
- it "works for dsyms with escape sequences" do
911
- _(':"foo\nbar"')
912
- .must_be_parsed_as s(:lit, :"foo\nbar")
913
- end
914
-
915
- it "works for dsyms with multiple lines" do
916
- _(":\"foo\nbar\"")
917
- .must_be_parsed_as s(:lit, :"foo\nbar")
918
- end
919
-
920
- it "works for dsyms with line continuations" do
921
- _(":\"foo\\\nbar\"")
922
- .must_be_parsed_as s(:lit, :foobar)
923
- end
924
-
925
- it "works with single quoted dsyms" do
926
- _(":'foo'")
927
- .must_be_parsed_as s(:lit, :foo)
928
- end
929
-
930
- it "works with single quoted dsyms with escaped single quotes" do
931
- _(":'foo\\'bar'")
932
- .must_be_parsed_as s(:lit, :'foo\'bar')
933
- end
934
-
935
- it "works with single quoted dsyms with multiple lines" do
936
- _(":'foo\nbar'")
937
- .must_be_parsed_as s(:lit, :"foo\nbar")
938
- end
939
-
940
- it "works with single quoted dsyms with line continuations" do
941
- _(":'foo\\\nbar'")
942
- .must_be_parsed_as s(:lit, :"foo\\\nbar")
943
- end
944
-
945
- it "works with single quoted dsyms with embedded backslashes" do
946
- _(":'foo\\abar'")
947
- .must_be_parsed_as s(:lit, :"foo\\abar")
948
- end
949
-
950
- it "works with barewords that need to be interpreted as symbols" do
951
- _("alias foo bar")
952
- .must_be_parsed_as s(:alias,
953
- s(:lit, :foo), s(:lit, :bar))
954
- end
955
-
956
- it "assigns a line number to the result" do
957
- result = parser.parse ":foo"
958
- _(result.line).must_equal 1
959
- end
960
- end
961
-
962
- describe "for backtick string literals" do
963
- it "works for basic backtick strings" do
964
- _("`foo`")
965
- .must_be_parsed_as s(:xstr, "foo")
966
- end
967
-
968
- it "works for interpolated backtick strings" do
969
- _('`foo#{bar}`')
970
- .must_be_parsed_as s(:dxstr,
971
- "foo",
972
- s(:evstr, s(:call, nil, :bar)))
973
- end
974
-
975
- it "works for backtick strings interpolated at the start" do
976
- _('`#{foo}`')
977
- .must_be_parsed_as s(:dxstr, "",
978
- s(:evstr, s(:call, nil, :foo)))
979
- end
980
-
981
- it "works for backtick strings with escape sequences" do
982
- _('`foo\\n`')
983
- .must_be_parsed_as s(:xstr, "foo\n")
984
- end
985
-
986
- it "works for backtick strings with multiple lines" do
987
- _("`foo\nbar`")
988
- .must_be_parsed_as s(:xstr, "foo\nbar")
989
- end
990
-
991
- it "works for backtick strings with line continuations" do
992
- _("`foo\\\nbar`")
993
- .must_be_parsed_as s(:xstr, "foobar")
994
- end
995
- end
996
-
997
- describe "for array literals" do
998
- it "works for an empty array" do
999
- _("[]")
1000
- .must_be_parsed_as s(:array)
1001
- end
1002
-
1003
- it "works for a simple case with splat" do
1004
- _("[*foo]")
1005
- .must_be_parsed_as s(:array,
1006
- s(:splat, s(:call, nil, :foo)))
1007
- end
1008
-
1009
- it "works for a multi-element case with splat" do
1010
- _("[foo, *bar]")
1011
- .must_be_parsed_as s(:array,
1012
- s(:call, nil, :foo),
1013
- s(:splat, s(:call, nil, :bar)))
1014
- end
1015
- end
1016
-
1017
- describe "for hash literals" do
1018
- it "works for an empty hash" do
1019
- _("{}")
1020
- .must_be_parsed_as s(:hash)
1021
- end
1022
-
1023
- it "works for a hash with one pair" do
1024
- _("{foo => bar}")
1025
- .must_be_parsed_as s(:hash,
1026
- s(:call, nil, :foo),
1027
- s(:call, nil, :bar))
1028
- end
1029
-
1030
- it "works for a hash with multiple pairs" do
1031
- _("{foo => bar, baz => qux}")
1032
- .must_be_parsed_as s(:hash,
1033
- s(:call, nil, :foo),
1034
- s(:call, nil, :bar),
1035
- s(:call, nil, :baz),
1036
- s(:call, nil, :qux))
1037
- end
1038
-
1039
- it "works for a hash with label keys" do
1040
- _("{foo: bar, baz: qux}")
1041
- .must_be_parsed_as s(:hash,
1042
- s(:lit, :foo),
1043
- s(:call, nil, :bar),
1044
- s(:lit, :baz),
1045
- s(:call, nil, :qux))
1046
- end
1047
-
1048
- it "works for a hash with dynamic label keys" do
1049
- _("{'foo': bar}")
1050
- .must_be_parsed_as s(:hash,
1051
- s(:lit, :foo),
1052
- s(:call, nil, :bar))
1053
- end
1054
-
1055
- it "works for a hash with splat" do
1056
- _("{foo: bar, baz: qux, **quux}")
1057
- .must_be_parsed_as s(:hash,
1058
- s(:lit, :foo), s(:call, nil, :bar),
1059
- s(:lit, :baz), s(:call, nil, :qux),
1060
- s(:kwsplat, s(:call, nil, :quux)))
1061
- end
1062
- end
1063
-
1064
- describe "for number literals" do
1065
- it "works for floats" do
1066
- _("3.14")
1067
- .must_be_parsed_as s(:lit, 3.14)
1068
- end
1069
-
1070
- it "works for octal integer literals" do
1071
- _("0700")
1072
- .must_be_parsed_as s(:lit, 448)
1073
- end
1074
-
1075
- it "handles negative sign for integers" do
1076
- _("-1")
1077
- .must_be_parsed_as s(:lit, -1)
1078
- end
1079
-
1080
- it "handles space after negative sign for integers" do
1081
- _("-1 ")
1082
- .must_be_parsed_as s(:lit, -1)
1083
- end
1084
-
1085
- it "handles negative sign for floats" do
1086
- _("-3.14")
1087
- .must_be_parsed_as s(:lit, -3.14)
1088
- end
1089
-
1090
- it "handles space after negative sign for floats" do
1091
- _("-3.14 ")
1092
- .must_be_parsed_as s(:lit, -3.14)
1093
- end
1094
-
1095
- it "handles positive sign" do
1096
- _("+1")
1097
- .must_be_parsed_as s(:lit, 1)
1098
- end
1099
-
1100
- it "works for rationals" do
1101
- _("1000r")
1102
- .must_be_parsed_as s(:lit, 1000r)
1103
- end
1104
- end
1105
- end
1106
- end