ripper_ruby_parser 1.7.0 → 1.9.0

Sign up to get free protection for your applications and to get access to all the features.
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