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