ripper_ruby_parser 1.7.1 → 1.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -17,25 +17,11 @@ module RipperRubyParser
17
17
  def initialize(filename: nil, extra_compatible: nil)
18
18
  super()
19
19
 
20
- @processors[:@int] = :process_at_int
21
- @processors[:@float] = :process_at_float
22
- @processors[:@rational] = :process_at_rational
23
- @processors[:@CHAR] = :process_at_CHAR
24
- @processors[:@label] = :process_at_label
25
-
26
- @processors[:@const] = :process_at_const
27
- @processors[:@ident] = :process_at_ident
28
- @processors[:@cvar] = :process_at_cvar
29
- @processors[:@gvar] = :process_at_gvar
30
- @processors[:@ivar] = :process_at_ivar
31
- @processors[:@kw] = :process_at_kw
32
- @processors[:@op] = :process_at_op
33
- @processors[:@backref] = :process_at_backref
34
-
35
- @processors[:@backtick] = :process_at_backtick
36
- @processors[:@period] = :process_at_period
37
-
38
- @processors[:@tstring_content] = :process_at_tstring_content
20
+ public_methods.each do |name|
21
+ if name =~ /^process_at_(.*)/
22
+ @processors["@#{Regexp.last_match(1)}".to_sym] = name.to_sym
23
+ end
24
+ end
39
25
 
40
26
  @filename = filename
41
27
  @extra_compatible = extra_compatible
@@ -172,25 +158,6 @@ module RipperRubyParser
172
158
  with_position pos, s(:iter, s(:postexe), 0, *body)
173
159
  end
174
160
 
175
- # number literals
176
- def process_at_int(exp)
177
- make_literal(exp) { |val| Integer(val) }
178
- end
179
-
180
- def process_at_float(exp)
181
- make_literal(exp, &:to_f)
182
- end
183
-
184
- def process_at_rational(exp)
185
- make_literal(exp, &:to_r)
186
- end
187
-
188
- # character literals
189
- def process_at_CHAR(exp)
190
- _, val, pos = exp.shift 3
191
- with_position(pos, s(:str, unescape(val[1..-1])))
192
- end
193
-
194
161
  def process_at_label(exp)
195
162
  make_literal(exp) { |val| val.chop.to_sym }
196
163
  end
@@ -9,7 +9,7 @@ module RipperRubyParser
9
9
  /\\(
10
10
  [0-7]{1,3} | # octal character
11
11
  x[0-9a-fA-F]{1,2} | # hex byte
12
- u[0-9a-fA-F]+ | # unicode character
12
+ u[0-9a-fA-F]{4} | # unicode character
13
13
  u{[0-9a-fA-F]{4,6}} | # unicode character
14
14
  M-\\C-. | # meta-ctrl
15
15
  C-\\M-. | # ctrl-meta
@@ -18,8 +18,8 @@ module RipperRubyParser
18
18
  C-. | # control (regular)
19
19
  c. | # control (shorthand)
20
20
  M-. | # meta
21
- \n | # line continuation
22
- . # single-character
21
+ \n | # line break
22
+ . # other single character
23
23
  )/x.freeze
24
24
 
25
25
  SINGLE_LETTER_ESCAPES = {
@@ -38,23 +38,28 @@ module RipperRubyParser
38
38
  Regexp.new("^[#{SINGLE_LETTER_ESCAPES.keys.join}]$")
39
39
 
40
40
  def simple_unescape(string)
41
- string.gsub(/\\(
42
- ' | # single quote
43
- \\ # backslash
44
- )/x) do
45
- Regexp.last_match[1]
46
- end
41
+ string.gsub(/
42
+ \\ # a backslash
43
+ ( # followed by a
44
+ ' | # single quote or
45
+ \\ # backslash
46
+ )/x) do
47
+ Regexp.last_match[1]
48
+ end
47
49
  end
48
50
 
49
51
  def simple_unescape_wordlist_word(string)
50
- string.gsub(/\\(
51
- ' | # single quote
52
- \\ | # backslash
53
- [ ] | # space
54
- \n # newline
55
- )/x) do
56
- Regexp.last_match[1]
57
- end
52
+ string.gsub(/
53
+ \\ # a backslash
54
+ ( # followed by a
55
+ ' | # single quote or
56
+ \\ | # backslash or
57
+ [ ] | # space or
58
+ \n # newline
59
+ )
60
+ /x) do
61
+ Regexp.last_match[1]
62
+ end
58
63
  end
59
64
 
60
65
  def unescape(string)
@@ -106,7 +111,7 @@ module RipperRubyParser
106
111
  when /^u\{/
107
112
  hex_to_unicode_char(bare[2..-2])
108
113
  when /^u/
109
- hex_to_unicode_char(bare[1..4]) + bare[5..-1]
114
+ hex_to_unicode_char(bare[1..4])
110
115
  when /^(c|C-).$/
111
116
  control(bare[-1].ord).chr
112
117
  when /^M-.$/
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RipperRubyParser
4
- VERSION = "1.7.1"
4
+ VERSION = "1.7.2"
5
5
  end
@@ -4,14 +4,6 @@ require File.expand_path("../test_helper.rb", File.dirname(__FILE__))
4
4
  require "ruby_parser"
5
5
 
6
6
  describe "Using RipperRubyParser and RubyParser" do
7
- let :newparser do
8
- RipperRubyParser::Parser.new
9
- end
10
-
11
- let :oldparser do
12
- RubyParser.for_current_ruby
13
- end
14
-
15
7
  Dir.glob("lib/**/*.rb").each do |file|
16
8
  describe "for #{file}" do
17
9
  let :program do
@@ -19,10 +11,7 @@ describe "Using RipperRubyParser and RubyParser" do
19
11
  end
20
12
 
21
13
  it "gives the same result" do
22
- original = oldparser.parse program
23
- imitation = newparser.parse program
24
-
25
- _(formatted(imitation)).must_equal formatted(original)
14
+ _(program).must_be_parsed_as_before
26
15
  end
27
16
  end
28
17
  end
@@ -4,14 +4,6 @@ require File.expand_path("../test_helper.rb", File.dirname(__FILE__))
4
4
  require "ruby_parser"
5
5
 
6
6
  describe "Using RipperRubyParser and RubyParser" do
7
- let :newparser do
8
- RipperRubyParser::Parser.new
9
- end
10
-
11
- let :oldparser do
12
- RubyParser.for_current_ruby
13
- end
14
-
15
7
  Dir.glob("test/ripper_ruby_parser/**/*.rb").each do |file|
16
8
  describe "for #{file}" do
17
9
  let :program do
@@ -19,13 +11,7 @@ describe "Using RipperRubyParser and RubyParser" do
19
11
  end
20
12
 
21
13
  it "gives the same result" do
22
- # Clone string because ruby_parser destroys it when there's a heredoc
23
- # inside.
24
- copy = program.clone
25
- original = oldparser.parse program
26
- imitation = newparser.parse copy
27
-
28
- _(formatted(imitation)).must_equal formatted(original)
14
+ _(program).must_be_parsed_as_before
29
15
  end
30
16
  end
31
17
  end
@@ -324,6 +324,15 @@ describe RipperRubyParser::Parser do
324
324
  _(result[4].comments).must_equal "# bar\n"
325
325
  end
326
326
 
327
+ it "handles the use of symbols that are keywords" do
328
+ result = parser.parse "# Foo\ndef bar\n:class\nend"
329
+ _(result).must_equal s(:defn,
330
+ :bar,
331
+ s(:args),
332
+ s(:lit, :class))
333
+ _(result.comments).must_equal "# Foo\n"
334
+ end
335
+
327
336
  it "handles use of singleton class inside methods" do
328
337
  result = parser.parse "# Foo\ndef bar\nclass << self\nbaz\nend\nend"
329
338
  _(result).must_equal s(:defn,
@@ -336,13 +345,11 @@ describe RipperRubyParser::Parser do
336
345
 
337
346
  # TODO: Prefer assigning comment to the BEGIN instead
338
347
  it "assigns comments on BEGIN blocks to the following item" do
339
- result = parser.parse "# Bar\nBEGIN { }\n# Foo\nclass Bar\n# foo\ndef foo; end\nend"
348
+ result = parser.parse "# Bar\nBEGIN { }\n# Foo\ndef foo; end"
340
349
  _(result).must_equal s(:block,
341
350
  s(:iter, s(:preexe), 0),
342
- s(:class, :Bar, nil,
343
- s(:defn, :foo, s(:args), s(:nil))))
351
+ s(:defn, :foo, s(:args), s(:nil)))
344
352
  _(result[2].comments).must_equal "# Bar\n# Foo\n"
345
- _(result[2][3].comments).must_equal "# foo\n"
346
353
  end
347
354
 
348
355
  it "assigns comments on multiple BEGIN blocks to the following item" do
@@ -355,12 +362,13 @@ describe RipperRubyParser::Parser do
355
362
  end
356
363
 
357
364
  it "assigns comments on BEGIN blocks to the first following item" do
358
- result = parser.parse "# Bar\nBEGIN { }\n# Baz\nBEGIN { }\n# Foo\ndef foo; end"
365
+ result = parser.parse "# Bar\nBEGIN { }\n# Foo\nclass Bar\n# foo\ndef foo; end\nend"
359
366
  _(result).must_equal s(:block,
360
367
  s(:iter, s(:preexe), 0),
361
- s(:iter, s(:preexe), 0),
362
- s(:defn, :foo, s(:args), s(:nil)))
363
- _(result[3].comments).must_equal "# Bar\n# Baz\n# Foo\n"
368
+ s(:class, :Bar, nil,
369
+ s(:defn, :foo, s(:args), s(:nil))))
370
+ _(result[2].comments).must_equal "# Bar\n# Foo\n"
371
+ _(result[2][3].comments).must_equal "# foo\n"
364
372
  end
365
373
  end
366
374
 
@@ -493,6 +501,11 @@ describe RipperRubyParser::Parser do
493
501
  _(result.line).must_equal 1
494
502
  end
495
503
 
504
+ it "works for a symbol literal" do
505
+ result = parser.parse ":foo"
506
+ _(result.line).must_equal 1
507
+ end
508
+
496
509
  it "works for a class definition" do
497
510
  result = parser.parse "class Foo; end"
498
511
  _(result.line).must_equal 1
@@ -508,6 +521,16 @@ describe RipperRubyParser::Parser do
508
521
  _(result.line).must_equal 1
509
522
  end
510
523
 
524
+ it "works for assignment of the empty hash" do
525
+ result = parser.parse "foo = {}"
526
+ _(result.line).must_equal 1
527
+ end
528
+
529
+ it "works for multiple assignment of empty hashes" do
530
+ result = parser.parse "foo, bar = {}, {}"
531
+ _(result.line).must_equal 1
532
+ end
533
+
511
534
  it "assigns line numbers to nested sexps without their own line numbers" do
512
535
  _("foo(bar) do\nnext baz\nend\n")
513
536
  .must_be_parsed_as s(:iter,
@@ -205,22 +205,6 @@ describe RipperRubyParser::Parser do
205
205
  s(:call, s(:const, :Bar), :baz, s(:call, nil, :qux)),
206
206
  s(:resbody, s(:array), s(:call, nil, :quuz))))
207
207
  end
208
-
209
- it "works with a method call with argument without brackets" do
210
- _("foo = bar baz rescue qux")
211
- .must_be_parsed_as s(:lasgn, :foo,
212
- s(:rescue,
213
- s(:call, nil, :bar, s(:call, nil, :baz)),
214
- s(:resbody, s(:array), s(:call, nil, :qux))))
215
- end
216
-
217
- it "works with a class method call with argument without brackets" do
218
- _("foo = Bar.baz qux rescue quuz")
219
- .must_be_parsed_as s(:lasgn, :foo,
220
- s(:rescue,
221
- s(:call, s(:const, :Bar), :baz, s(:call, nil, :qux)),
222
- s(:resbody, s(:array), s(:call, nil, :quuz))))
223
- end
224
208
  end
225
209
 
226
210
  it "sets the correct line numbers" do
@@ -448,7 +432,10 @@ describe RipperRubyParser::Parser do
448
432
  it "handles safe-assigning to an attribute of the collection element" do
449
433
  _("foo[bar]&.baz = qux")
450
434
  .must_be_parsed_as s(:safe_attrasgn,
451
- s(:call, s(:call, nil, :foo), :[], s(:call, nil, :bar)),
435
+ s(:call,
436
+ s(:call, nil, :foo),
437
+ :[],
438
+ s(:call, nil, :bar)),
452
439
  :baz=,
453
440
  s(:call, nil, :qux))
454
441
  end
@@ -170,6 +170,14 @@ describe RipperRubyParser::Parser do
170
170
  s(:lvar, :bar)))
171
171
  end
172
172
 
173
+ it "works with a nameless kwrest argument" do
174
+ _("foo do |**|; bar; end")
175
+ .must_be_parsed_as s(:iter,
176
+ s(:call, nil, :foo),
177
+ s(:args, :**),
178
+ s(:call, nil, :bar))
179
+ end
180
+
173
181
  it "works with a regular argument after a splat argument" do
174
182
  _("foo do |*bar, baz|; end")
175
183
  .must_be_parsed_as s(:iter,
@@ -186,6 +194,15 @@ describe RipperRubyParser::Parser do
186
194
  s(:lvar, :bar),
187
195
  s(:lvar, :baz)))
188
196
  end
197
+
198
+ it "works with a combination of regular arguments and an anonymous kwrest argument" do
199
+ _("foo do |bar, **|; qux bar; end")
200
+ .must_be_parsed_as s(:iter,
201
+ s(:call, nil, :foo),
202
+ s(:args, :bar, :"**"),
203
+ s(:call, nil, :qux,
204
+ s(:lvar, :bar)))
205
+ end
189
206
  end
190
207
 
191
208
  describe "for begin" do
@@ -219,6 +236,11 @@ describe RipperRubyParser::Parser do
219
236
  nil,
220
237
  s(:begin, s(:call, nil, :foo)))
221
238
  end
239
+
240
+ it "removes :begin for a method receiver" do
241
+ _("begin; foo; end.bar")
242
+ .must_be_parsed_as s(:call, s(:call, nil, :foo), :bar)
243
+ end
222
244
  end
223
245
 
224
246
  describe "for rescue/else" do
@@ -6,820 +6,6 @@ describe RipperRubyParser::Parser do
6
6
  let(:parser) { RipperRubyParser::Parser.new }
7
7
 
8
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 "works with unicode escapes with braces with 5 hex chars" do
266
- _('"foo\\u{101D1}bar"').must_be_parsed_as s(:str, "foo𐇑bar")
267
- end
268
-
269
- it "works with unicode escapes with braces with 6 hex chars" do
270
- _('"foo\\u{10FFFF}bar"').must_be_parsed_as s(:str, "foo\u{10FFFF}bar")
271
- end
272
-
273
- it "converts to unicode if possible" do
274
- _('"2\302\275"').must_be_parsed_as s(:str, "2½")
275
- end
276
-
277
- it "does not convert to unicode if result is not valid" do
278
- _('"2\x82\302\275"')
279
- .must_be_parsed_as s(:str,
280
- (+"2\x82\xC2\xBD").force_encoding("ascii-8bit"))
281
- end
282
- end
283
-
284
- describe "with interpolations containing just a literal string" do
285
- it "performs the interpolation when it is at the end" do
286
- _('"foo#{"bar"}"').must_be_parsed_as s(:str, "foobar")
287
- end
288
-
289
- it "performs the interpolation when it is in the middle" do
290
- _('"foo#{"bar"}baz"').must_be_parsed_as s(:str, "foobarbaz")
291
- end
292
-
293
- it "performs the interpolation when it is at the start" do
294
- _('"#{"foo"}bar"').must_be_parsed_as s(:str, "foobar")
295
- end
296
- end
297
-
298
- describe "with interpolations without braces" do
299
- it "works for ivars" do
300
- _("\"foo\#@bar\"").must_be_parsed_as s(:dstr,
301
- "foo",
302
- s(:evstr, s(:ivar, :@bar)))
303
- end
304
-
305
- it "works for gvars" do
306
- _("\"foo\#$bar\"").must_be_parsed_as s(:dstr,
307
- "foo",
308
- s(:evstr, s(:gvar, :$bar)))
309
- end
310
-
311
- it "works for cvars" do
312
- _("\"foo\#@@bar\"").must_be_parsed_as s(:dstr,
313
- "foo",
314
- s(:evstr, s(:cvar, :@@bar)))
315
- end
316
- end
317
-
318
- describe "with interpolations with braces" do
319
- it "works for trivial interpolated strings" do
320
- _('"#{foo}"')
321
- .must_be_parsed_as s(:dstr,
322
- "",
323
- s(:evstr,
324
- s(:call, nil, :foo)))
325
- end
326
-
327
- it "works for basic interpolated strings" do
328
- _('"foo#{bar}"')
329
- .must_be_parsed_as s(:dstr,
330
- "foo",
331
- s(:evstr,
332
- s(:call, nil, :bar)))
333
- end
334
-
335
- it "works for strings with several interpolations" do
336
- _('"foo#{bar}baz#{qux}"')
337
- .must_be_parsed_as s(:dstr,
338
- "foo",
339
- s(:evstr, s(:call, nil, :bar)),
340
- s(:str, "baz"),
341
- s(:evstr, s(:call, nil, :qux)))
342
- end
343
-
344
- it "correctly handles two interpolations in a row" do
345
- _("\"\#{bar}\#{qux}\"")
346
- .must_be_parsed_as s(:dstr,
347
- "",
348
- s(:evstr, s(:call, nil, :bar)),
349
- s(:evstr, s(:call, nil, :qux)))
350
- end
351
-
352
- it "works with an empty interpolation" do
353
- _("\"foo\#{}bar\"")
354
- .must_be_parsed_as s(:dstr,
355
- "foo",
356
- s(:evstr),
357
- s(:str, "bar"))
358
- end
359
-
360
- it "correctly handles interpolation with __FILE__ before another interpolation" do
361
- _("\"foo\#{__FILE__}\#{bar}\"")
362
- .must_be_parsed_as s(:dstr,
363
- "foo(string)",
364
- s(:evstr, s(:call, nil, :bar)))
365
- end
366
-
367
- it "correctly handles interpolation with __FILE__ after another interpolation" do
368
- _("\"\#{bar}foo\#{__FILE__}\"")
369
- .must_be_parsed_as s(:dstr,
370
- "",
371
- s(:evstr, s(:call, nil, :bar)),
372
- s(:str, "foo"),
373
- s(:str, "(string)"))
374
- end
375
-
376
- it "correctly handles nested interpolation" do
377
- _('"foo#{"bar#{baz}"}"')
378
- .must_be_parsed_as s(:dstr,
379
- "foobar",
380
- s(:evstr, s(:call, nil, :baz)))
381
- end
382
-
383
- it "correctly handles consecutive nested interpolation" do
384
- _('"foo#{"bar#{baz}"}foo#{"bar#{baz}"}"')
385
- .must_be_parsed_as s(:dstr,
386
- "foobar",
387
- s(:evstr, s(:call, nil, :baz)),
388
- s(:str, "foo"),
389
- s(:str, "bar"),
390
- s(:evstr, s(:call, nil, :baz)))
391
- end
392
- end
393
-
394
- describe "with interpolations and escape sequences" do
395
- it "works when interpolations are followed by escape sequences" do
396
- _('"#{foo}\\n"')
397
- .must_be_parsed_as s(:dstr,
398
- "",
399
- s(:evstr, s(:call, nil, :foo)),
400
- s(:str, "\n"))
401
- end
402
-
403
- it "works when interpolations contain a mix of other string-like literals" do
404
- _('"#{[:foo, \'bar\']}\\n"')
405
- .must_be_parsed_as s(:dstr,
406
- "",
407
- s(:evstr, s(:array, s(:lit, :foo), s(:str, "bar"))),
408
- s(:str, "\n"))
409
- end
410
-
411
- it "converts to unicode after interpolation" do
412
- _('"#{foo}2\302\275"')
413
- .must_be_parsed_as s(:dstr,
414
- "",
415
- s(:evstr, s(:call, nil, :foo)),
416
- s(:str, "2½"))
417
- end
418
-
419
- it "convert single null byte to unicode after interpolation" do
420
- _('"#{foo}\0"')
421
- .must_be_parsed_as s(:dstr,
422
- "",
423
- s(:evstr, s(:call, nil, :foo)),
424
- s(:str, "\u0000"))
425
- end
426
-
427
- it "converts string with null to unicode after interpolation" do
428
- _('"#{foo}bar\0"')
429
- .must_be_parsed_as s(:dstr,
430
- "",
431
- s(:evstr, s(:call, nil, :foo)),
432
- s(:str, "bar\x00"))
433
- end
434
- end
435
-
436
- describe "with single quoted strings" do
437
- it "works with escaped single quotes" do
438
- _("'foo\\'bar'")
439
- .must_be_parsed_as s(:str, "foo'bar")
440
- end
441
-
442
- it "works with embedded backslashes" do
443
- _("'foo\\abar'")
444
- .must_be_parsed_as s(:str, 'foo\abar')
445
- end
446
-
447
- it "works with escaped embedded backslashes" do
448
- _("'foo\\\\abar'")
449
- .must_be_parsed_as s(:str, 'foo\abar')
450
- end
451
-
452
- it "works with sequences of backslashes" do
453
- _("'foo\\\\\\abar'")
454
- .must_be_parsed_as s(:str, 'foo\\\\abar')
455
- end
456
-
457
- it "does not process line continuation" do
458
- _("'foo\\\nbar'")
459
- .must_be_parsed_as s(:str, "foo\\\nbar")
460
- end
461
- end
462
-
463
- describe "with %Q-delimited strings" do
464
- it "works for the simple case" do
465
- _("%Q[bar]")
466
- .must_be_parsed_as s(:str, "bar")
467
- end
468
-
469
- it "works for escape sequences" do
470
- _('%Q[foo\\nbar]')
471
- .must_be_parsed_as s(:str, "foo\nbar")
472
- end
473
-
474
- it "works for multi-line strings" do
475
- _("%Q[foo\nbar]")
476
- .must_be_parsed_as s(:str, "foo\nbar")
477
- end
478
-
479
- it "handles line continuation" do
480
- _("%Q[foo\\\nbar]")
481
- .must_be_parsed_as s(:str, "foobar")
482
- end
483
- end
484
-
485
- describe "with %q-delimited strings" do
486
- it "works for the simple case" do
487
- _("%q[bar]")
488
- .must_be_parsed_as s(:str, "bar")
489
- end
490
-
491
- it "does not handle for escape sequences" do
492
- _('%q[foo\\nbar]')
493
- .must_be_parsed_as s(:str, 'foo\nbar')
494
- end
495
-
496
- it "works for multi-line strings" do
497
- _("%q[foo\nbar]")
498
- .must_be_parsed_as s(:str, "foo\nbar")
499
- end
500
-
501
- it "handles line continuation" do
502
- _("%q[foo\\\nbar]")
503
- .must_be_parsed_as s(:str, "foo\\\nbar")
504
- end
505
- end
506
-
507
- describe "with %-delimited strings" do
508
- it "works for the simple case" do
509
- _("%(bar)")
510
- .must_be_parsed_as s(:str, "bar")
511
- end
512
-
513
- it "works for escape sequences" do
514
- _('%(foo\nbar)')
515
- .must_be_parsed_as s(:str, "foo\nbar")
516
- end
517
-
518
- it "works for multiple lines" do
519
- _("%(foo\nbar)")
520
- .must_be_parsed_as s(:str, "foo\nbar")
521
- end
522
-
523
- it "works with line continuations" do
524
- _("%(foo\\\nbar)")
525
- .must_be_parsed_as s(:str, "foobar")
526
- end
527
-
528
- it "works for odd delimiters" do
529
- _('%!foo\nbar!')
530
- .must_be_parsed_as s(:str, "foo\nbar")
531
- end
532
- end
533
-
534
- describe "with string concatenation" do
535
- it "performs the concatenation in the case of two simple literal strings" do
536
- _('"foo" "bar"').must_be_parsed_as s(:str, "foobar")
537
- end
538
-
539
- it "performs the concatenation when the right string has interpolations" do
540
- _("\"foo\" \"bar\#{baz}\"")
541
- .must_be_parsed_as s(:dstr,
542
- "foobar",
543
- s(:evstr, s(:call, nil, :baz)))
544
- end
545
-
546
- describe "when the left string has interpolations" do
547
- it "performs the concatenation" do
548
- _("\"foo\#{bar}\" \"baz\"")
549
- .must_be_parsed_as s(:dstr,
550
- "foo",
551
- s(:evstr, s(:call, nil, :bar)),
552
- s(:str, "baz"))
553
- end
554
-
555
- it "performs the concatenation with an empty string" do
556
- _("\"foo\#{bar}\" \"\"")
557
- .must_be_parsed_as s(:dstr,
558
- "foo",
559
- s(:evstr, s(:call, nil, :bar)),
560
- s(:str, ""))
561
- end
562
- end
563
-
564
- describe "when both strings have interpolations" do
565
- it "performs the concatenation" do
566
- _("\"foo\#{bar}\" \"baz\#{qux}\"")
567
- .must_be_parsed_as s(:dstr,
568
- "foo",
569
- s(:evstr, s(:call, nil, :bar)),
570
- s(:str, "baz"),
571
- s(:evstr, s(:call, nil, :qux)))
572
- end
573
-
574
- it "removes empty substrings from the concatenation" do
575
- _("\"foo\#{bar}\" \"\#{qux}\"")
576
- .must_be_parsed_as s(:dstr,
577
- "foo",
578
- s(:evstr, s(:call, nil, :bar)),
579
- s(:evstr, s(:call, nil, :qux)))
580
- end
581
- end
582
- end
583
-
584
- describe "for heredocs" do
585
- it "works for the simple case" do
586
- _("<<FOO\nbar\nFOO")
587
- .must_be_parsed_as s(:str, "bar\n")
588
- end
589
-
590
- it "works with multiple lines" do
591
- _("<<FOO\nbar\nbaz\nFOO")
592
- .must_be_parsed_as s(:str, "bar\nbaz\n")
593
- end
594
-
595
- it "works for the indentable case" do
596
- _("<<-FOO\n bar\n FOO")
597
- .must_be_parsed_as s(:str, " bar\n")
598
- end
599
-
600
- it "works for the automatically outdenting case" do
601
- _(" <<~FOO\n bar\n FOO")
602
- .must_be_parsed_as s(:str, "bar\n")
603
- end
604
-
605
- it "works for escape sequences" do
606
- _("<<FOO\nbar\\tbaz\nFOO")
607
- .must_be_parsed_as s(:str, "bar\tbaz\n")
608
- end
609
-
610
- it 'converts \r to carriage returns' do
611
- _("<<FOO\nbar\\rbaz\\r\nFOO")
612
- .must_be_parsed_as s(:str, "bar\rbaz\r\n")
613
- end
614
-
615
- it "does not unescape with single quoted version" do
616
- _("<<'FOO'\nbar\\tbaz\nFOO")
617
- .must_be_parsed_as s(:str, "bar\\tbaz\n")
618
- end
619
-
620
- it "works with multiple lines with the single quoted version" do
621
- _("<<'FOO'\nbar\nbaz\nFOO")
622
- .must_be_parsed_as s(:str, "bar\nbaz\n")
623
- end
624
-
625
- it "does not unescape with indentable single quoted version" do
626
- _("<<-'FOO'\n bar\\tbaz\n FOO")
627
- .must_be_parsed_as s(:str, " bar\\tbaz\n")
628
- end
629
-
630
- it "does not unescape the automatically outdenting single quoted version" do
631
- _("<<~'FOO'\n bar\\tbaz\n FOO")
632
- .must_be_parsed_as s(:str, "bar\\tbaz\n")
633
- end
634
-
635
- it "handles line continuation" do
636
- _("<<FOO\nbar\\\nbaz\nFOO")
637
- .must_be_parsed_as s(:str, "barbaz\n")
638
- end
639
-
640
- it "escapes line continuation" do
641
- _("<<FOO\nbar\\\\\nbaz\nFOO")
642
- .must_be_parsed_as s(:str, "bar\\\nbaz\n")
643
- end
644
-
645
- it "converts to unicode" do
646
- _("<<FOO\n2\\302\\275\nFOO")
647
- .must_be_parsed_as s(:str, "2½\n")
648
- end
649
-
650
- it "handles interpolation" do
651
- _("<<FOO\n\#{bar}\nFOO")
652
- .must_be_parsed_as s(:dstr, "",
653
- s(:evstr, s(:call, nil, :bar)),
654
- s(:str, "\n"))
655
- end
656
-
657
- it "handles line continuation after interpolation" do
658
- _("<<FOO\n\#{bar}\nbaz\\\nqux\nFOO")
659
- .must_be_parsed_as s(:dstr, "",
660
- s(:evstr, s(:call, nil, :bar)),
661
- s(:str, "\nbazqux\n"))
662
- end
663
-
664
- it "handles line continuation after interpolation for the indentable case" do
665
- _("<<-FOO\n\#{bar}\nbaz\\\nqux\nFOO")
666
- .must_be_parsed_as s(:dstr, "",
667
- s(:evstr, s(:call, nil, :bar)),
668
- s(:str, "\nbazqux\n"))
669
- end
670
- end
671
- end
672
-
673
- describe "for word list literals with %w delimiter" do
674
- it "works for the simple case" do
675
- _("%w(foo bar)")
676
- .must_be_parsed_as s(:array, s(:str, "foo"), s(:str, "bar"))
677
- end
678
-
679
- it "does not perform interpolation" do
680
- _('%w(foo\\nbar baz)')
681
- .must_be_parsed_as s(:array, s(:str, 'foo\\nbar'), s(:str, "baz"))
682
- end
683
-
684
- it "handles line continuation" do
685
- _("%w(foo\\\nbar baz)")
686
- .must_be_parsed_as s(:array, s(:str, "foo\nbar"), s(:str, "baz"))
687
- end
688
-
689
- it "handles escaped spaces" do
690
- _('%w(foo bar\ baz)')
691
- .must_be_parsed_as s(:array, s(:str, "foo"), s(:str, "bar baz"))
692
- end
693
- end
694
-
695
- describe "for word list literals with %W delimiter" do
696
- it "works for the simple case" do
697
- _("%W(foo bar)")
698
- .must_be_parsed_as s(:array, s(:str, "foo"), s(:str, "bar"))
699
- end
700
-
701
- it "handles escaped spaces" do
702
- _('%W(foo bar\ baz)')
703
- .must_be_parsed_as s(:array, s(:str, "foo"), s(:str, "bar baz"))
704
- end
705
-
706
- it "correctly handles interpolation" do
707
- _("%W(foo \#{bar} baz)")
708
- .must_be_parsed_as s(:array,
709
- s(:str, "foo"),
710
- s(:dstr, "", s(:evstr, s(:call, nil, :bar))),
711
- s(:str, "baz"))
712
- end
713
-
714
- it "correctly handles braceless interpolation" do
715
- _("%W(foo \#@bar baz)")
716
- .must_be_parsed_as s(:array,
717
- s(:str, "foo"),
718
- s(:dstr, "", s(:evstr, s(:ivar, :@bar))),
719
- s(:str, "baz"))
720
- end
721
-
722
- it "correctly handles in-word interpolation" do
723
- _("%W(foo \#{bar}baz)")
724
- .must_be_parsed_as s(:array,
725
- s(:str, "foo"),
726
- s(:dstr,
727
- "",
728
- s(:evstr, s(:call, nil, :bar)),
729
- s(:str, "baz")))
730
- end
731
-
732
- it "correctly handles escape sequences" do
733
- _('%W(foo\nbar baz)')
734
- .must_be_parsed_as s(:array,
735
- s(:str, "foo\nbar"),
736
- s(:str, "baz"))
737
- end
738
-
739
- it "converts to unicode if possible" do
740
- _('%W(2\302\275)').must_be_parsed_as s(:array, s(:str, "2½"))
741
- end
742
-
743
- it "correctly handles line continuation" do
744
- _("%W(foo\\\nbar baz)")
745
- .must_be_parsed_as s(:array,
746
- s(:str, "foo\nbar"),
747
- s(:str, "baz"))
748
- end
749
-
750
- it "correctly handles multiple lines" do
751
- _("%W(foo\nbar baz)")
752
- .must_be_parsed_as s(:array,
753
- s(:str, "foo"),
754
- s(:str, "bar"),
755
- s(:str, "baz"))
756
- end
757
- end
758
-
759
- describe "for symbol list literals with %i delimiter" do
760
- it "works for the simple case" do
761
- _("%i(foo bar)")
762
- .must_be_parsed_as s(:array, s(:lit, :foo), s(:lit, :bar))
763
- end
764
-
765
- it "does not perform interpolation" do
766
- _('%i(foo\\nbar baz)')
767
- .must_be_parsed_as s(:array, s(:lit, :"foo\\nbar"), s(:lit, :baz))
768
- end
769
-
770
- it "handles line continuation" do
771
- _("%i(foo\\\nbar baz)")
772
- .must_be_parsed_as s(:array, s(:lit, :"foo\nbar"), s(:lit, :baz))
773
- end
774
- end
775
-
776
- describe "for symbol list literals with %I delimiter" do
777
- it "works for the simple case" do
778
- _("%I(foo bar)")
779
- .must_be_parsed_as s(:array, s(:lit, :foo), s(:lit, :bar))
780
- end
781
-
782
- it "correctly handles escape sequences" do
783
- _('%I(foo\nbar baz)')
784
- .must_be_parsed_as s(:array,
785
- s(:lit, :"foo\nbar"),
786
- s(:lit, :baz))
787
- end
788
-
789
- it "correctly handles interpolation" do
790
- _("%I(foo \#{bar} baz)")
791
- .must_be_parsed_as s(:array,
792
- s(:lit, :foo),
793
- s(:dsym, "", s(:evstr, s(:call, nil, :bar))),
794
- s(:lit, :baz))
795
- end
796
-
797
- it "correctly handles in-word interpolation" do
798
- _("%I(foo \#{bar}baz)")
799
- .must_be_parsed_as s(:array,
800
- s(:lit, :foo),
801
- s(:dsym,
802
- "",
803
- s(:evstr, s(:call, nil, :bar)),
804
- s(:str, "baz")))
805
- end
806
-
807
- it "correctly handles line continuation" do
808
- _("%I(foo\\\nbar baz)")
809
- .must_be_parsed_as s(:array,
810
- s(:lit, :"foo\nbar"),
811
- s(:lit, :baz))
812
- end
813
-
814
- it "correctly handles multiple lines" do
815
- _("%I(foo\nbar baz)")
816
- .must_be_parsed_as s(:array,
817
- s(:lit, :foo),
818
- s(:lit, :bar),
819
- s(:lit, :baz))
820
- end
821
- end
822
-
823
9
  describe "for character literals" do
824
10
  it "works for simple character literals" do
825
11
  _("?a")
@@ -862,146 +48,6 @@ describe RipperRubyParser::Parser do
862
48
  end
863
49
  end
864
50
 
865
- describe "for symbol literals" do
866
- it "works for simple symbols" do
867
- _(":foo")
868
- .must_be_parsed_as s(:lit, :foo)
869
- end
870
-
871
- it "works for symbols that look like instance variable names" do
872
- _(":@foo")
873
- .must_be_parsed_as s(:lit, :@foo)
874
- end
875
-
876
- it "works for symbols that look like class names" do
877
- _(":Foo")
878
- .must_be_parsed_as s(:lit, :Foo)
879
- end
880
-
881
- it "works for symbols that look like keywords" do
882
- _(":class").must_be_parsed_as s(:lit, :class)
883
- end
884
-
885
- it "works for :__LINE__" do
886
- _(":__LINE__")
887
- .must_be_parsed_as s(:lit, :__LINE__)
888
- end
889
-
890
- it "works for :__FILE__" do
891
- _(":__FILE__")
892
- .must_be_parsed_as s(:lit, :__FILE__)
893
- end
894
-
895
- it "works for a backtick symbol" do
896
- _(":`").must_be_parsed_as s(:lit, :`)
897
- end
898
-
899
- it "works for simple dsyms" do
900
- _(':"foo"')
901
- .must_be_parsed_as s(:lit, :foo)
902
- end
903
-
904
- it "works for dsyms with interpolations" do
905
- _(':"foo#{bar}"')
906
- .must_be_parsed_as s(:dsym,
907
- "foo",
908
- s(:evstr, s(:call, nil, :bar)))
909
- end
910
-
911
- it "works for dsyms with interpolations at the start" do
912
- _(':"#{bar}"')
913
- .must_be_parsed_as s(:dsym,
914
- "",
915
- s(:evstr, s(:call, nil, :bar)))
916
- end
917
-
918
- it "works for dsyms with escape sequences" do
919
- _(':"foo\nbar"')
920
- .must_be_parsed_as s(:lit, :"foo\nbar")
921
- end
922
-
923
- it "works for dsyms with multiple lines" do
924
- _(":\"foo\nbar\"")
925
- .must_be_parsed_as s(:lit, :"foo\nbar")
926
- end
927
-
928
- it "works for dsyms with line continuations" do
929
- _(":\"foo\\\nbar\"")
930
- .must_be_parsed_as s(:lit, :foobar)
931
- end
932
-
933
- it "works with single quoted dsyms" do
934
- _(":'foo'")
935
- .must_be_parsed_as s(:lit, :foo)
936
- end
937
-
938
- it "works with single quoted dsyms with escaped single quotes" do
939
- _(":'foo\\'bar'")
940
- .must_be_parsed_as s(:lit, :'foo\'bar')
941
- end
942
-
943
- it "works with single quoted dsyms with multiple lines" do
944
- _(":'foo\nbar'")
945
- .must_be_parsed_as s(:lit, :"foo\nbar")
946
- end
947
-
948
- it "works with single quoted dsyms with line continuations" do
949
- _(":'foo\\\nbar'")
950
- .must_be_parsed_as s(:lit, :"foo\\\nbar")
951
- end
952
-
953
- it "works with single quoted dsyms with embedded backslashes" do
954
- _(":'foo\\abar'")
955
- .must_be_parsed_as s(:lit, :"foo\\abar")
956
- end
957
-
958
- it "works with barewords that need to be interpreted as symbols" do
959
- _("alias foo bar")
960
- .must_be_parsed_as s(:alias,
961
- s(:lit, :foo), s(:lit, :bar))
962
- end
963
-
964
- it "assigns a line number to the result" do
965
- result = parser.parse ":foo"
966
- _(result.line).must_equal 1
967
- end
968
- end
969
-
970
- describe "for backtick string literals" do
971
- it "works for basic backtick strings" do
972
- _("`foo`")
973
- .must_be_parsed_as s(:xstr, "foo")
974
- end
975
-
976
- it "works for interpolated backtick strings" do
977
- _('`foo#{bar}`')
978
- .must_be_parsed_as s(:dxstr,
979
- "foo",
980
- s(:evstr, s(:call, nil, :bar)))
981
- end
982
-
983
- it "works for backtick strings interpolated at the start" do
984
- _('`#{foo}`')
985
- .must_be_parsed_as s(:dxstr, "",
986
- s(:evstr, s(:call, nil, :foo)))
987
- end
988
-
989
- it "works for backtick strings with escape sequences" do
990
- _('`foo\\n`')
991
- .must_be_parsed_as s(:xstr, "foo\n")
992
- end
993
-
994
- it "works for backtick strings with multiple lines" do
995
- _("`foo\nbar`")
996
- .must_be_parsed_as s(:xstr, "foo\nbar")
997
- end
998
-
999
- it "works for backtick strings with line continuations" do
1000
- _("`foo\\\nbar`")
1001
- .must_be_parsed_as s(:xstr, "foobar")
1002
- end
1003
- end
1004
-
1005
51
  describe "for array literals" do
1006
52
  it "works for an empty array" do
1007
53
  _("[]")
@@ -1109,6 +155,11 @@ describe RipperRubyParser::Parser do
1109
155
  _("1000r")
1110
156
  .must_be_parsed_as s(:lit, 1000r)
1111
157
  end
158
+
159
+ it "works for imaginary numbers" do
160
+ _("1i")
161
+ .must_be_parsed_as s(:lit, 1i)
162
+ end
1112
163
  end
1113
164
  end
1114
165
  end