syntax 0.5.0 → 0.7.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.
@@ -1,518 +1,666 @@
1
- $:.unshift "../../lib"
1
+ $:.unshift File.dirname(__FILE__) +"/../../lib"
2
2
 
3
3
  require 'test/unit'
4
- require 'syntax/ruby'
4
+ require 'syntax/lang/ruby'
5
5
 
6
6
  class TC_Syntax_Ruby < Test::Unit::TestCase
7
7
 
8
+ def tokenize( string )
9
+ @tokens = []
10
+ @ruby.tokenize( string ) { |tok| @tokens << tok }
11
+ end
12
+
13
+ def assert_next_token(group, lexeme, instruction=:none)
14
+ assert false, "no tokens in stack" if @tokens.nil? or @tokens.empty?
15
+ assert_equal [group, lexeme, instruction],
16
+ [@tokens.first.group, @tokens.first, @tokens.shift.instruction]
17
+ end
18
+
19
+ def assert_no_next_token
20
+ assert @tokens.empty?
21
+ end
22
+
23
+ def skip_token( n=1 )
24
+ n.times { @tokens.shift } unless @tokens.nil? || @tokens.empty?
25
+ end
26
+
8
27
  def setup
9
28
  @ruby = Syntax::Ruby.new
10
29
  end
11
30
 
12
31
  def test_empty
13
- called = false
14
- @ruby.tokenize( "" ) { |tok| called = true }
15
- assert !called
32
+ tokenize( "" )
33
+ assert_no_next_token
16
34
  end
17
35
 
18
36
  def test_constant
19
- called = false
20
- @ruby.tokenize( "Foo" ) do |tok|
21
- called = true
22
- assert_equal :constant, tok.group
23
- assert_equal "Foo", tok
24
- end
25
- assert called
37
+ tokenize( "Foo" )
38
+ assert_next_token :constant, "Foo"
26
39
  end
27
40
 
28
41
  def test_ident
29
- called = false
30
- @ruby.tokenize( "foo" ) do |tok|
31
- called = true
32
- assert_equal :ident, tok.group
33
- assert_equal "foo", tok
34
- end
35
- assert called
42
+ tokenize( "foo" )
43
+ assert_next_token :ident, "foo"
36
44
  end
37
45
 
38
46
  def test_comment_eol
39
- called = false
40
- @ruby.tokenize( "# a comment" ) do |tok|
41
- called = true
42
- assert_equal :comment, tok.group
43
- assert_equal "# a comment", tok
44
- end
45
- assert called
47
+ tokenize( "# a comment\nfoo" )
48
+ assert_next_token :comment, "# a comment"
49
+ assert_next_token :normal, "\n"
50
+ assert_next_token :ident, "foo"
46
51
  end
47
52
 
48
53
  def test_comment_block
49
- called = false
50
- @ruby.tokenize( "=begin\nthis is a comment\n=end" ) do |tok|
51
- called = true
52
- assert_equal :comment, tok.group
53
- assert_equal "=begin\nthis is a comment\n=end", tok
54
- end
55
- assert called
54
+ tokenize( "=begin\nthis is a comment\n=end\nnoncomment" )
55
+ assert_next_token :comment, "=begin\nthis is a comment\n=end"
56
+ assert_next_token :normal, "\n"
57
+ assert_next_token :ident, "noncomment"
56
58
  end
57
59
 
58
60
  def test_keyword
59
61
  Syntax::Ruby::KEYWORDS.each do |word|
60
- tok = []
61
- @ruby.tokenize( word ) { |t| tok << t }
62
- assert_equal [ :keyword, word ], [ tok.first.group, tok.first ]
62
+ tokenize( word )
63
+ assert_next_token :keyword, word
63
64
  end
64
65
  Syntax::Ruby::KEYWORDS.each do |word|
65
- tok = []
66
- @ruby.tokenize( "foo.#{word}" ) { |t| tok << t }
67
- tok.shift
68
- tok.shift
69
- assert_equal [ :ident, word ], [ tok.first.group, tok.first ]
66
+ tokenize( "foo.#{word}" )
67
+ skip_token 2
68
+ assert_next_token :ident, word
70
69
  end
71
70
  end
72
71
 
73
72
  def test__END__
74
- called = false
75
- @ruby.tokenize( "__END__\n\nblah blah blah" ) do |tok|
76
- called = true
77
- assert_equal :comment, tok.group
78
- assert_equal "__END__\n\nblah blah blah", tok
79
- end
80
- assert called
73
+ tokenize( "__END__\n\nblah blah blah" )
74
+ assert_next_token :comment, "__END__\n\nblah blah blah"
81
75
  end
82
76
 
83
77
  def test_def_paren
84
- tok = nil
85
- @ruby.start( "def foo(bar)" ) { |t| tok = t }
86
- @ruby.step
87
- assert_equal "def ", tok
88
- assert_equal :keyword, tok.group
89
- @ruby.step
90
- assert_equal "foo", tok
91
- assert_equal :method, tok.group
78
+ tokenize( "def foo(bar)" )
79
+ assert_next_token :keyword, "def "
80
+ assert_next_token :method, "foo"
81
+ assert_next_token :punct, "("
82
+ assert_next_token :ident, "bar"
83
+ assert_next_token :punct, ")"
92
84
  end
93
85
 
94
86
  def test_def_space
95
- tok = nil
96
- @ruby.start( "def foo bar" ) { |t| tok = t }
97
- @ruby.step
98
- assert_equal "def ", tok
99
- assert_equal :keyword, tok.group
100
- @ruby.step
101
- assert_equal "foo", tok
102
- assert_equal :method, tok.group
87
+ tokenize( "def foo bar" )
88
+ assert_next_token :keyword, "def "
89
+ assert_next_token :method, "foo"
90
+ assert_next_token :normal, " "
91
+ assert_next_token :ident, "bar"
103
92
  end
104
93
 
105
94
  def test_def_semicolon
106
- tok = nil
107
- @ruby.start( "def foo;" ) { |t| tok = t }
108
- @ruby.step
109
- assert_equal "def ", tok
110
- assert_equal :keyword, tok.group
111
- @ruby.step
112
- assert_equal "foo", tok
113
- assert_equal :method, tok.group
95
+ tokenize( "def foo;" )
96
+ assert_next_token :keyword, "def "
97
+ assert_next_token :method, "foo"
98
+ assert_next_token :punct, ";"
114
99
  end
115
100
 
116
101
  def test_class_space
117
- tok = nil
118
- @ruby.start( "class Foo\n" ) { |t| tok = t }
119
- @ruby.step
120
- assert_equal "class ", tok
121
- assert_equal :keyword, tok.group
122
- @ruby.step
123
- assert_equal "Foo", tok
124
- assert_equal :class, tok.group
102
+ tokenize( "class Foo\n" )
103
+ assert_next_token :keyword, "class "
104
+ assert_next_token :class, "Foo"
105
+ assert_next_token :normal, "\n"
125
106
  end
126
107
 
127
108
  def test_class_semicolon
128
- tok = nil
129
- @ruby.start( "class Foo;" ) { |t| tok = t }
130
- @ruby.step
131
- assert_equal "class ", tok
132
- assert_equal :keyword, tok.group
133
- @ruby.step
134
- assert_equal "Foo", tok
135
- assert_equal :class, tok.group
109
+ tokenize( "class Foo;" )
110
+ assert_next_token :keyword, "class "
111
+ assert_next_token :class, "Foo"
112
+ assert_next_token :punct, ";"
136
113
  end
137
114
 
138
115
  def test_class_extend
139
- tok = nil
140
- @ruby.start( "class Foo< Bang" ) { |t| tok = t }
141
- @ruby.step
142
- assert_equal "class ", tok
143
- assert_equal :keyword, tok.group
144
- @ruby.step
145
- assert_equal "Foo", tok
146
- assert_equal :class, tok.group
116
+ tokenize( "class Foo< Bang" )
117
+ assert_next_token :keyword, "class "
118
+ assert_next_token :class, "Foo"
119
+ assert_next_token :punct, "<"
120
+ assert_next_token :normal, " "
121
+ assert_next_token :constant, "Bang"
147
122
  end
148
123
 
149
124
  def test_module_space
150
- tok = nil
151
- @ruby.start( "module Foo\n" ) { |t| tok = t }
152
- @ruby.step
153
- assert_equal "module ", tok
154
- assert_equal :keyword, tok.group
155
- @ruby.step
156
- assert_equal "Foo", tok
157
- assert_equal :module, tok.group
125
+ tokenize( "module Foo\n" )
126
+ assert_next_token :keyword, "module "
127
+ assert_next_token :module, "Foo"
128
+ assert_next_token :normal, "\n"
158
129
  end
159
130
 
160
131
  def test_module_semicolon
161
- tok = nil
162
- @ruby.start( "module Foo;" ) { |t| tok = t }
163
- @ruby.step
164
- assert_equal "module ", tok
165
- assert_equal :keyword, tok.group
166
- @ruby.step
167
- assert_equal "Foo", tok
168
- assert_equal :module, tok.group
132
+ tokenize( "module Foo;" )
133
+ assert_next_token :keyword, "module "
134
+ assert_next_token :module, "Foo"
135
+ assert_next_token :punct, ";"
169
136
  end
170
137
 
171
138
  def test_module_other
172
- tok = nil
173
- @ruby.start( "module Foo!\n" ) { |t| tok = t }
174
- @ruby.step
175
- assert_equal "module ", tok
176
- assert_equal :keyword, tok.group
177
- @ruby.step
178
- assert_equal "Foo!", tok
179
- assert_equal :module, tok.group
139
+ tokenize( "module Foo!\n" )
140
+ assert_next_token :keyword, "module "
141
+ assert_next_token :module, "Foo!"
180
142
  end
181
143
 
182
144
  def test_scope_operator
183
- tok = []
184
- @ruby.tokenize( "Foo::Bar" ) { |t| tok << t }
185
- assert_equal "Foo", tok.shift
186
- assert_equal "::", tok.first
187
- assert_equal :punct, tok.shift.group
188
- assert_equal "Bar", tok.first
145
+ tokenize( "Foo::Bar" )
146
+ assert_next_token :constant, "Foo"
147
+ assert_next_token :punct, "::"
148
+ assert_next_token :constant, "Bar"
189
149
  end
190
150
 
191
151
  def test_symbol_dquote
192
- tok = []
193
- @ruby.tokenize( ':"foo"' ) { |t| tok << t }
194
- assert_equal ':"foo"', tok.first
195
- assert_equal :symbol, tok.first.group
152
+ tokenize( ':"foo"' )
153
+ assert_next_token :symbol, ':"'
154
+ assert_next_token :symbol, '', :region_open
155
+ assert_next_token :symbol, 'foo'
156
+ assert_next_token :symbol, '', :region_close
157
+ assert_next_token :symbol, '"'
158
+ assert_no_next_token
196
159
  end
197
160
 
198
161
  def test_symbol_squote
199
- tok = []
200
- @ruby.tokenize( ":'foo'" ) { |t| tok << t }
201
- assert_equal ":'foo'", tok.first
202
- assert_equal :symbol, tok.first.group
162
+ tokenize( ":'foo'" )
163
+ assert_next_token :symbol, ":'"
164
+ assert_next_token :symbol, "", :region_open
165
+ assert_next_token :symbol, "foo"
166
+ assert_next_token :symbol, "", :region_close
167
+ assert_next_token :symbol, "'"
168
+ assert_no_next_token
203
169
  end
204
170
 
205
171
  def test_symbol
206
- tok = []
207
- @ruby.tokenize( ":foo_bar?" ) { |t| tok << t }
208
- assert_equal ":foo_bar?", tok.first
209
- assert_equal :symbol, tok.first.group
172
+ tokenize( ":foo_bar?" )
173
+ assert_next_token :symbol, ":foo_bar?"
210
174
  end
211
175
 
212
176
  def test_char
213
- tok = []
214
- @ruby.tokenize( "?." ) { |t| tok << t }
215
- assert_equal "?.", tok.first
216
- assert_equal :char, tok.first.group
177
+ tokenize( "?." )
178
+ assert_next_token :char, "?."
217
179
 
218
- tok.clear
219
- @ruby.tokenize( '?\n' ) { |t| tok << t }
220
- assert_equal '?\n', tok.first
221
- assert_equal :char, tok.first.group
180
+ tokenize( '?\n' )
181
+ assert_next_token :char, '?\n'
222
182
  end
223
183
 
224
184
  def test_specials
225
185
  %w{__FILE__ __LINE__ true false nil self}.each do |word|
226
- tok = []
227
- @ruby.tokenize( word ) { |t| tok << t }
228
- assert_equal word, tok.first
229
- assert_equal :constant, tok.first.group
186
+ tokenize( word )
187
+ assert_next_token :constant, word
230
188
  end
231
189
 
232
190
  %w{__FILE__ __LINE__ true false nil self}.each do |word|
233
- tok = []
234
- @ruby.tokenize( "#{word}?" ) { |t| tok << t }
235
- assert_equal "#{word}?", tok.first
236
- assert_equal :ident, tok.first.group
191
+ tokenize( "#{word}?" )
192
+ assert_next_token :ident, "#{word}?"
237
193
  end
238
194
 
239
195
  %w{__FILE__ __LINE__ true false nil self}.each do |word|
240
- tok = []
241
- @ruby.tokenize( "#{word}!" ) { |t| tok << t }
242
- assert_equal "#{word}!", tok.first
243
- assert_equal :ident, tok.first.group
196
+ tokenize( "#{word}!" )
197
+ assert_next_token :ident, "#{word}!"
244
198
  end
245
199
 
246
200
  %w{__FILE__ __LINE__ true false nil self}.each do |word|
247
- tok = []
248
- @ruby.tokenize( "x.#{word}" ) { |t| tok << t }
249
- tok.shift
250
- tok.shift
251
- assert_equal word, tok.first
252
- assert_equal :ident, tok.first.group
201
+ tokenize( "x.#{word}" )
202
+ skip_token 2
203
+ assert_next_token :ident, word
253
204
  end
254
205
  end
255
206
 
256
207
  def test_pct_r
257
- tok = []
258
- @ruby.tokenize( '%r{foo#{x}bar}' ) { |t| tok << t }
259
- assert_equal [ :punct, "%r{" ], [ tok.first.group, tok.shift ]
260
- assert_equal [ :regex, "foo" ], [ tok.first.group, tok.shift ]
261
- assert_equal [ :expr, '#{x}' ], [ tok.first.group, tok.shift ]
262
- assert_equal [ :regex, "bar" ], [ tok.first.group, tok.shift ]
263
- assert_equal [ :punct, "}" ], [ tok.first.group, tok.shift ]
264
-
265
- tok = []
266
- @ruby.tokenize( '%r-foo#{x}bar-' ) { |t| tok << t }
267
- assert_equal [ :punct, "%r-" ], [ tok.first.group, tok.shift ]
268
- assert_equal [ :regex, "foo" ], [ tok.first.group, tok.shift ]
269
- assert_equal [ :expr, '#{x}' ], [ tok.first.group, tok.shift ]
270
- assert_equal [ :regex, "bar" ], [ tok.first.group, tok.shift ]
271
- assert_equal [ :punct, "-" ], [ tok.first.group, tok.shift ]
208
+ tokenize( '%r{foo#{x}bar}' )
209
+ assert_next_token :punct, "%r{"
210
+ assert_next_token :regex, "", :region_open
211
+ assert_next_token :regex, "foo"
212
+ assert_next_token :expr, '#{x}'
213
+ assert_next_token :regex, "bar"
214
+ assert_next_token :regex, "", :region_close
215
+ assert_next_token :punct, "}"
216
+
217
+ tokenize( '%r-foo#{x}bar-' )
218
+ assert_next_token :punct, "%r-"
219
+ assert_next_token :regex, "", :region_open
220
+ assert_next_token :regex, "foo"
221
+ assert_next_token :expr, '#{x}'
222
+ assert_next_token :regex, "bar"
223
+ assert_next_token :regex, "", :region_close
224
+ assert_next_token :punct, "-"
225
+ end
226
+
227
+ def test_pct_r_with_wakas
228
+ tokenize '%r<foo#{x}bar> foo'
229
+ assert_next_token :punct, "%r<"
230
+ assert_next_token :regex, "", :region_open
231
+ assert_next_token :regex, "foo"
232
+ assert_next_token :expr, '#{x}'
233
+ assert_next_token :regex, "bar"
234
+ assert_next_token :regex, "", :region_close
235
+ assert_next_token :punct, ">"
236
+ assert_next_token :normal, " "
237
+ assert_next_token :ident, "foo"
238
+ end
239
+
240
+ def test_pct_w_brace
241
+ tokenize( '%w{foo bar baz}' )
242
+ assert_next_token :punct, "%w{"
243
+ assert_next_token :string, '', :region_open
244
+ assert_next_token :string, 'foo bar baz'
245
+ assert_next_token :string, '', :region_close
246
+ assert_next_token :punct, "}"
272
247
  end
273
248
 
274
249
  def test_pct_w
275
- tok = []
276
- @ruby.tokenize( '%w-foo#{x} bar baz-' ) { |t| tok << t }
277
- assert_equal [ :punct, "%w-" ], [ tok.first.group, tok.shift ]
278
- assert_equal [ :string, 'foo#{x} bar baz' ], [ tok.first.group, tok.shift ]
279
- assert_equal [ :punct, "-" ], [ tok.first.group, tok.shift ]
250
+ tokenize( '%w-foo#{x} bar baz-' )
251
+ assert_next_token :punct, "%w-"
252
+ assert_next_token :string, '', :region_open
253
+ assert_next_token :string, 'foo#{x} bar baz'
254
+ assert_next_token :string, '', :region_close
255
+ assert_next_token :punct, "-"
280
256
  end
281
257
 
282
258
  def test_pct_q
283
- tok = []
284
- @ruby.tokenize( '%q-hello #{world}-' ) { |t| tok << t }
285
- assert_equal [ :punct, "%q-" ], [ tok.first.group, tok.shift ]
286
- assert_equal [ :string, 'hello #{world}' ], [ tok.first.group, tok.shift ]
287
- assert_equal [ :punct, "-" ], [ tok.first.group, tok.shift ]
259
+ tokenize( '%q-hello #{world}-' )
260
+ assert_next_token :punct, "%q-"
261
+ assert_next_token :string, '', :region_open
262
+ assert_next_token :string, 'hello #{world}'
263
+ assert_next_token :string, '', :region_close
264
+ assert_next_token :punct, "-"
288
265
  end
289
266
 
290
267
  def test_pct_s
291
- tok = []
292
- @ruby.tokenize( '%s-hello #{world}-' ) { |t| tok << t }
293
- assert_equal [ :punct, "%s-" ], [ tok.first.group, tok.shift ]
294
- assert_equal [ :symbol, 'hello #{world}' ], [ tok.first.group, tok.shift ]
295
- assert_equal [ :punct, "-" ], [ tok.first.group, tok.shift ]
268
+ tokenize( '%s-hello #{world}-' )
269
+ assert_next_token :punct, "%s-"
270
+ assert_next_token :symbol, '', :region_open
271
+ assert_next_token :symbol, 'hello #{world}'
272
+ assert_next_token :symbol, '', :region_close
273
+ assert_next_token :punct, "-"
296
274
  end
297
275
 
298
276
  def test_pct_W
299
- tok = []
300
- @ruby.tokenize( '%W-foo#{x} bar baz-' ) { |t| tok << t }
301
- assert_equal [ :punct, "%W-" ], [ tok.first.group, tok.shift ]
302
- assert_equal [ :string, 'foo' ], [ tok.first.group, tok.shift ]
303
- assert_equal [ :expr, '#{x}' ], [ tok.first.group, tok.shift ]
304
- assert_equal [ :string, ' bar baz' ], [ tok.first.group, tok.shift ]
305
- assert_equal [ :punct, "-" ], [ tok.first.group, tok.shift ]
277
+ tokenize( '%W-foo#{x} bar baz-' )
278
+ assert_next_token :punct, "%W-"
279
+ assert_next_token :string, '', :region_open
280
+ assert_next_token :string, 'foo'
281
+ assert_next_token :expr, '#{x}'
282
+ assert_next_token :string, ' bar baz'
283
+ assert_next_token :string, '', :region_close
284
+ assert_next_token :punct, "-"
306
285
  end
307
286
 
308
287
  def test_pct_Q
309
- tok = []
310
- @ruby.tokenize( '%Q-hello #{world}-' ) { |t| tok << t }
311
- assert_equal [ :punct, "%Q-" ], [ tok.first.group, tok.shift ]
312
- assert_equal [ :string, 'hello ' ], [ tok.first.group, tok.shift ]
313
- assert_equal [ :expr, '#{world}' ], [ tok.first.group, tok.shift ]
314
- assert_equal [ :punct, "-" ], [ tok.first.group, tok.shift ]
288
+ tokenize( '%Q-hello #{world}-' )
289
+ assert_next_token :punct, "%Q-"
290
+ assert_next_token :string, '', :region_open
291
+ assert_next_token :string, 'hello '
292
+ assert_next_token :expr, '#{world}'
293
+ assert_next_token :string, '', :region_close
294
+ assert_next_token :punct, "-"
315
295
  end
316
296
 
317
297
  def test_pct_x
318
- tok = []
319
- @ruby.tokenize( '%x-ls /blah/#{foo}-' ) { |t| tok << t }
320
- assert_equal [ :punct, "%x-" ], [ tok.first.group, tok.shift ]
321
- assert_equal [ :string, 'ls /blah/' ], [ tok.first.group, tok.shift ]
322
- assert_equal [ :expr, '#{foo}' ], [ tok.first.group, tok.shift ]
323
- assert_equal [ :punct, "-" ], [ tok.first.group, tok.shift ]
298
+ tokenize( '%x-ls /blah/#{foo}-' )
299
+ assert_next_token :punct, "%x-"
300
+ assert_next_token :string, '', :region_open
301
+ assert_next_token :string, 'ls /blah/'
302
+ assert_next_token :expr, '#{foo}'
303
+ assert_next_token :string, '', :region_close
304
+ assert_next_token :punct, "-"
324
305
  end
325
306
 
326
307
  def test_pct_string
327
- tok = []
328
- @ruby.tokenize( '%-hello #{world}-' ) { |t| tok << t }
329
- assert_equal [ :punct, "%-" ], [ tok.first.group, tok.shift ]
330
- assert_equal [ :string, 'hello ' ], [ tok.first.group, tok.shift ]
331
- assert_equal [ :expr, '#{world}' ], [ tok.first.group, tok.shift ]
332
- assert_equal [ :punct, "-" ], [ tok.first.group, tok.shift ]
308
+ tokenize( '%-hello #{world}-' )
309
+ assert_next_token :punct, "%-"
310
+ assert_next_token :string, '', :region_open
311
+ assert_next_token :string, 'hello '
312
+ assert_next_token :expr, '#{world}'
313
+ assert_next_token :string, '', :region_close
314
+ assert_next_token :punct, "-"
333
315
  end
334
316
 
335
317
  def test_bad_pct_string
336
- tok = []
337
- @ruby.tokenize( '%0hello #{world}0' ) { |t| tok << t }
338
- assert_equal [ :punct, "%" ], [ tok.first.group, tok.shift ]
339
- assert_equal [ :number, '0' ], [ tok.first.group, tok.shift ]
340
- assert_equal [ :ident, 'hello' ], [ tok.first.group, tok.shift ]
341
- assert_equal [ :normal, ' ' ], [ tok.first.group, tok.shift ]
342
- assert_equal [ :comment, '#{world}0' ], [ tok.first.group, tok.shift ]
318
+ tokenize( '%0hello #{world}0' )
319
+ assert_next_token :punct, "%"
320
+ assert_next_token :number, '0'
321
+ assert_next_token :ident, 'hello'
322
+ assert_next_token :normal, ' '
323
+ assert_next_token :comment, '#{world}0'
343
324
  end
344
325
 
345
326
  def test_shift_left
346
- tok = []
347
- @ruby.tokenize( 'foo << 5' ) { |t| tok << t }
348
- assert_equal [ :ident, "foo" ], [ tok.first.group, tok.shift ]
349
- assert_equal [ :normal, " " ], [ tok.first.group, tok.shift ]
350
- assert_equal [ :punct, "<<" ], [ tok.first.group, tok.shift ]
351
- assert_equal [ :normal, " " ], [ tok.first.group, tok.shift ]
352
- assert_equal [ :number, "5" ], [ tok.first.group, tok.shift ]
327
+ tokenize( 'foo << 5' )
328
+ assert_next_token :ident, "foo"
329
+ assert_next_token :normal, " "
330
+ assert_next_token :punct, "<<"
331
+ assert_next_token :normal, " "
332
+ assert_next_token :number, "5"
333
+ end
334
+
335
+ def test_shift_left_no_white
336
+ tokenize( 'foo<<5' )
337
+ assert_next_token :ident, "foo"
338
+ assert_next_token :punct, "<<"
339
+ assert_next_token :number, "5"
353
340
  end
354
341
 
355
342
  def test_here_doc_no_opts
356
- tok = []
357
- @ruby.tokenize( "foo <<EOF\n foo\n bar\n baz\nEOF" ) { |t| tok << t }
358
- assert_equal [ :ident, "foo" ], [ tok.first.group, tok.shift ]
359
- assert_equal [ :normal, " " ], [ tok.first.group, tok.shift ]
360
- assert_equal [ :punct, "<<" ], [ tok.first.group, tok.shift ]
361
- assert_equal [ :constant, "EOF" ], [ tok.first.group, tok.shift ]
362
- assert_equal [ :string, "\n foo\n bar\n baz\n" ], [ tok.first.group, tok.shift ]
363
- assert_equal [ :constant, "EOF" ], [ tok.first.group, tok.shift ]
343
+ tokenize( "foo <<EOF\n foo\n bar\n baz\nEOF" )
344
+ assert_next_token :ident, "foo"
345
+ assert_next_token :normal, " "
346
+ assert_next_token :punct, "<<"
347
+ assert_next_token :constant, "EOF"
348
+ assert_next_token :string, "", :region_open
349
+ assert_next_token :string, "\n foo\n bar\n baz\n"
350
+ assert_next_token :string, "", :region_close
351
+ assert_next_token :constant, "EOF"
364
352
  end
365
353
 
366
354
  def test_here_doc_no_opts_missing_end
367
- tok = []
368
- @ruby.tokenize( "foo <<EOF\n foo\n bar\n baz\n EOF" ) { |t| tok << t }
369
- assert_equal [ :ident, "foo" ], [ tok.first.group, tok.shift ]
370
- assert_equal [ :normal, " " ], [ tok.first.group, tok.shift ]
371
- assert_equal [ :punct, "<<" ], [ tok.first.group, tok.shift ]
372
- assert_equal [ :constant, "EOF" ], [ tok.first.group, tok.shift ]
373
- assert_equal [ :string, "\n foo\n bar\n baz\n EOF" ], [ tok.first.group, tok.shift ]
355
+ tokenize( "foo <<EOF\n foo\n bar\n baz\n EOF" )
356
+ assert_next_token :ident, "foo"
357
+ assert_next_token :normal, " "
358
+ assert_next_token :punct, "<<"
359
+ assert_next_token :constant, "EOF"
360
+ assert_next_token :string, "", :region_open
361
+ assert_next_token :string, "\n foo\n bar\n baz\n EOF"
362
+ assert_no_next_token
374
363
  end
375
364
 
376
365
  def test_here_doc_float_right
377
- tok = []
378
- @ruby.tokenize( "foo <<-EOF\n foo\n bar\n baz\n EOF" ) { |t| tok << t }
379
- assert_equal [ :ident, "foo" ], [ tok.first.group, tok.shift ]
380
- assert_equal [ :normal, " " ], [ tok.first.group, tok.shift ]
381
- assert_equal [ :punct, "<<-" ], [ tok.first.group, tok.shift ]
382
- assert_equal [ :constant, "EOF" ], [ tok.first.group, tok.shift ]
383
- assert_equal [ :string, "\n foo\n bar\n baz\n" ], [ tok.first.group, tok.shift ]
384
- assert_equal [ :constant, " EOF" ], [ tok.first.group, tok.shift ]
366
+ tokenize( "foo <<-EOF\n foo\n bar\n baz\n EOF" )
367
+ assert_next_token :ident, "foo"
368
+ assert_next_token :normal, " "
369
+ assert_next_token :punct, "<<-"
370
+ assert_next_token :constant, "EOF"
371
+ assert_next_token :string, "", :region_open
372
+ assert_next_token :string, "\n foo\n bar\n baz\n"
373
+ assert_next_token :string, "", :region_close
374
+ assert_next_token :constant, " EOF"
385
375
  end
386
376
 
387
377
  def test_here_doc_single_quotes
388
- tok = []
389
- @ruby.tokenize( "foo <<'EOF'\n foo\#{x}\n bar\n baz\nEOF" ) { |t| tok << t }
390
- assert_equal [ :ident, "foo" ], [ tok.first.group, tok.shift ]
391
- assert_equal [ :normal, " " ], [ tok.first.group, tok.shift ]
392
- assert_equal [ :punct, "<<'" ], [ tok.first.group, tok.shift ]
393
- assert_equal [ :constant, "EOF" ], [ tok.first.group, tok.shift ]
394
- assert_equal [ :punct, "'" ], [ tok.first.group, tok.shift ]
395
- assert_equal [ :string, "\n foo\#{x}\n bar\n baz\n" ], [ tok.first.group, tok.shift ]
396
- assert_equal [ :constant, "EOF" ], [ tok.first.group, tok.shift ]
378
+ tokenize( "foo <<'EOF'\n foo\#{x}\n bar\n baz\nEOF" )
379
+ assert_next_token :ident, "foo"
380
+ assert_next_token :normal, " "
381
+ assert_next_token :punct, "<<'"
382
+ assert_next_token :constant, "EOF"
383
+ assert_next_token :punct, "'"
384
+ assert_next_token :string, "", :region_open
385
+ assert_next_token :string, "\n foo\#{x}\n bar\n baz\n"
386
+ assert_next_token :string, "", :region_close
387
+ assert_next_token :constant, "EOF"
397
388
  end
398
389
 
399
390
  def test_here_doc_double_quotes
400
- tok = []
401
- @ruby.tokenize( "foo <<\"EOF\"\n foo\#{x}\n bar\n baz\nEOF" ) { |t| tok << t }
402
- assert_equal [ :ident, "foo" ], [ tok.first.group, tok.shift ]
403
- assert_equal [ :normal, " " ], [ tok.first.group, tok.shift ]
404
- assert_equal [ :punct, "<<\"" ], [ tok.first.group, tok.shift ]
405
- assert_equal [ :constant, "EOF" ], [ tok.first.group, tok.shift ]
406
- assert_equal [ :punct, "\"" ], [ tok.first.group, tok.shift ]
407
- assert_equal [ :string, "\n foo" ], [ tok.first.group, tok.shift ]
408
- assert_equal [ :expr, '#{x}' ], [ tok.first.group, tok.shift ]
409
- assert_equal [ :string, "\n bar\n baz\n" ], [ tok.first.group, tok.shift ]
410
- assert_equal [ :constant, "EOF" ], [ tok.first.group, tok.shift ]
391
+ tokenize( "foo <<\"EOF\"\n foo\#{x}\n bar\n baz\nEOF" )
392
+ assert_next_token :ident, "foo"
393
+ assert_next_token :normal, " "
394
+ assert_next_token :punct, "<<\""
395
+ assert_next_token :constant, "EOF"
396
+ assert_next_token :punct, "\""
397
+ assert_next_token :string, "", :region_open
398
+ assert_next_token :string, "\n foo"
399
+ assert_next_token :expr, '#{x}'
400
+ assert_next_token :string, "\n bar\n baz\n"
401
+ assert_next_token :string, "", :region_close
402
+ assert_next_token :constant, "EOF"
411
403
  end
412
404
 
413
405
  def test_space
414
- tok = []
415
- @ruby.tokenize( "\n \t\t\n\n\r\n" ) { |t| tok << t }
416
- assert_equal [ :normal, "\n \t\t\n\n\r\n" ], [ tok.first.group, tok.shift ]
406
+ tokenize( "\n \t\t\n\n\r\n" )
407
+ assert_next_token :normal, "\n \t\t\n\n\r\n"
417
408
  end
418
409
 
419
410
  def test_number
420
- tok = []
421
- @ruby.tokenize( "1 1.0 1e5 1.0e5 1_2.5 1_2.5_2 1_2.5_2e3_2" ) { |t| tok << t }
422
- assert_equal [ :number, "1" ], [ tok.first.group, tok.shift ]
423
- tok.shift
424
- assert_equal [ :number, "1.0" ], [ tok.first.group, tok.shift ]
425
- tok.shift
426
- assert_equal [ :number, "1e5" ], [ tok.first.group, tok.shift ]
427
- tok.shift
428
- assert_equal [ :number, "1.0e5" ], [ tok.first.group, tok.shift ]
429
- tok.shift
430
- assert_equal [ :number, "1_2.5" ], [ tok.first.group, tok.shift ]
431
- tok.shift
432
- assert_equal [ :number, "1_2.5_2" ], [ tok.first.group, tok.shift ]
433
- tok.shift
434
- assert_equal [ :number, "1_2.5_2e3_2" ], [ tok.first.group, tok.shift ]
411
+ tokenize( "1 1.0 1e5 1.0e5 1_2.5 1_2.5_2 1_2.5_2e3_2" )
412
+ assert_next_token :number, "1"
413
+ skip_token
414
+ assert_next_token :number, "1.0"
415
+ skip_token
416
+ assert_next_token :number, "1e5"
417
+ skip_token
418
+ assert_next_token :number, "1.0e5"
419
+ skip_token
420
+ assert_next_token :number, "1_2.5"
421
+ skip_token
422
+ assert_next_token :number, "1_2.5_2"
423
+ skip_token
424
+ assert_next_token :number, "1_2.5_2e3_2"
435
425
  end
436
426
 
437
427
  def test_dquoted_string
438
- tok = []
439
- @ruby.tokenize( '"foo #{x} bar\"\n\tbaz\xA5b\5\1234"' ) { |t| tok << t }
440
- assert_equal [ :punct, '"' ], [ tok.first.group, tok.shift ]
441
- assert_equal [ :string, 'foo ' ], [ tok.first.group, tok.shift ]
442
- assert_equal [ :expr, '#{x}' ], [ tok.first.group, tok.shift ]
443
- assert_equal [ :string, ' bar' ], [ tok.first.group, tok.shift ]
444
- assert_equal [ :expr, '\"\n\t' ], [ tok.first.group, tok.shift ]
445
- assert_equal [ :string, 'baz' ], [ tok.first.group, tok.shift ]
446
- assert_equal [ :expr, '\xA5' ], [ tok.first.group, tok.shift ]
447
- assert_equal [ :string, 'b' ], [ tok.first.group, tok.shift ]
448
- assert_equal [ :expr, '\5\123' ], [ tok.first.group, tok.shift ]
449
- assert_equal [ :string, '4' ], [ tok.first.group, tok.shift ]
450
- assert_equal [ :punct, '"' ], [ tok.first.group, tok.shift ]
428
+ tokenize( '"foo #{x} bar\"\n\tbaz\xA5b\5\1234"' )
429
+ assert_next_token :punct, '"'
430
+ assert_next_token :string, '', :region_open
431
+ assert_next_token :string, 'foo '
432
+ assert_next_token :expr, '#{x}'
433
+ assert_next_token :string, ' bar'
434
+ assert_next_token :escape, '\"\n\t'
435
+ assert_next_token :string, 'baz'
436
+ assert_next_token :escape, '\xA5'
437
+ assert_next_token :string, 'b'
438
+ assert_next_token :escape, '\5\123'
439
+ assert_next_token :string, '4'
440
+ assert_next_token :string, '', :region_close
441
+ assert_next_token :punct, '"'
451
442
  end
452
443
 
453
444
  def test_squoted_string
454
- tok = []
455
- @ruby.tokenize( '\'foo #{x} bar\\\'\n\tbaz\\\\\xA5b\5\1234\'' ) { |t| tok << t }
456
- assert_equal [ :punct, "'" ], [ tok.first.group, tok.shift ]
457
- assert_equal [ :string, 'foo #{x} bar' ], [ tok.first.group, tok.shift ]
458
- assert_equal [ :expr, '\\\'' ], [ tok.first.group, tok.shift ]
459
- assert_equal [ :string, '\n\tbaz' ], [ tok.first.group, tok.shift ]
460
- assert_equal [ :expr, '\\\\' ], [ tok.first.group, tok.shift ]
461
- assert_equal [ :string, '\xA5b\5\1234' ], [ tok.first.group, tok.shift ]
462
- assert_equal [ :punct, "'" ], [ tok.first.group, tok.shift ]
445
+ tokenize( '\'foo #{x} bar\\\'\n\tbaz\\\\\xA5b\5\1234\'' )
446
+ assert_next_token :punct, "'"
447
+ assert_next_token :string, "", :region_open
448
+ assert_next_token :string, 'foo #{x} bar'
449
+ assert_next_token :escape, '\\\''
450
+ assert_next_token :string, '\n\tbaz'
451
+ assert_next_token :escape, '\\\\'
452
+ assert_next_token :string, '\xA5b\5\1234'
453
+ assert_next_token :string, "", :region_close
454
+ assert_next_token :punct, "'"
463
455
  end
464
456
 
465
457
  def test_dot_selector
466
- tok = []
467
- @ruby.tokenize( 'foo.nil' ) { |t| tok << t }
468
- tok.shift
469
- assert_equal [ :punct, "." ], [ tok.first.group, tok.shift ]
470
- assert_equal [ :ident, "nil" ], [ tok.first.group, tok.shift ]
458
+ tokenize( 'foo.nil' )
459
+ skip_token
460
+ assert_next_token :punct, "."
461
+ assert_next_token :ident, "nil"
471
462
  end
472
463
 
473
464
  def test_dot_range_inclusive
474
- tok = []
475
- @ruby.tokenize( 'foo..nil' ) { |t| tok << t }
476
- tok.shift
477
- assert_equal [ :punct, ".." ], [ tok.first.group, tok.shift ]
478
- assert_equal [ :constant, "nil" ], [ tok.first.group, tok.shift ]
465
+ tokenize( 'foo..nil' )
466
+ skip_token
467
+ assert_next_token :punct, ".."
468
+ assert_next_token :constant, "nil"
479
469
  end
480
470
 
481
471
  def test_dot_range_exclusive
482
- tok = []
483
- @ruby.tokenize( 'foo...nil' ) { |t| tok << t }
484
- tok.shift
485
- assert_equal [ :punct, "..." ], [ tok.first.group, tok.shift ]
486
- assert_equal [ :constant, "nil" ], [ tok.first.group, tok.shift ]
472
+ tokenize( 'foo...nil' )
473
+ skip_token
474
+ assert_next_token :punct, "..."
475
+ assert_next_token :constant, "nil"
487
476
  end
488
477
 
489
478
  def test_dot_range_many
490
- tok = []
491
- @ruby.tokenize( 'foo.....nil' ) { |t| tok << t }
492
- tok.shift
493
- assert_equal [ :punct, "....." ], [ tok.first.group, tok.shift ]
494
- assert_equal [ :constant, "nil" ], [ tok.first.group, tok.shift ]
479
+ tokenize( 'foo.....nil' )
480
+ skip_token
481
+ assert_next_token :punct, "....."
482
+ assert_next_token :constant, "nil"
495
483
  end
496
484
 
497
485
  def test_attribute
498
- tok = []
499
- @ruby.tokenize( '@var_foo' ) { |t| tok << t }
500
- assert_equal [ :attribute, "@var_foo" ], [ tok.first.group, tok.shift ]
486
+ tokenize( '@var_foo' )
487
+ assert_next_token :attribute, "@var_foo"
501
488
  end
502
489
 
503
490
  def test_global
504
- tok = []
505
- @ruby.tokenize( '$var_foo' ) { |t| tok << t }
506
- assert_equal [ :global, "$var_foo" ], [ tok.first.group, tok.shift ]
507
- tok = []
508
- @ruby.tokenize( '$12' ) { |t| tok << t }
509
- assert_equal [ :global, "$12" ], [ tok.first.group, tok.shift ]
510
- tok = []
511
- @ruby.tokenize( '$/f' ) { |t| tok << t }
512
- assert_equal [ :global, "$/" ], [ tok.first.group, tok.shift ]
513
- tok = []
514
- @ruby.tokenize( "$\n" ) { |t| tok << t }
515
- assert_equal [ :global, "$" ], [ tok.first.group, tok.shift ]
491
+ tokenize( '$var_foo' )
492
+ assert_next_token :global, "$var_foo"
493
+ tokenize( '$12' )
494
+ assert_next_token :global, "$12"
495
+ tokenize( '$/f' )
496
+ assert_next_token :global, "$/"
497
+ tokenize( "$\n" )
498
+ assert_next_token :global, "$"
499
+ end
500
+
501
+ def test_paren_delimiter
502
+ tokenize( '%w(a)' )
503
+ assert_next_token :punct, "%w("
504
+ assert_next_token :string, "", :region_open
505
+ assert_next_token :string, "a"
506
+ assert_next_token :string, "", :region_close
507
+ assert_next_token :punct, ")"
508
+ end
509
+
510
+ def test_division
511
+ tokenize( 'm / 3' )
512
+ assert_next_token :ident, "m"
513
+ assert_next_token :normal, " "
514
+ assert_next_token :punct, "/"
515
+ assert_next_token :normal, " "
516
+ assert_next_token :number, "3"
517
+ end
518
+
519
+ def test_regex
520
+ tokenize( 'm =~ /3/' )
521
+ assert_next_token :ident, "m"
522
+ assert_next_token :normal, " "
523
+ assert_next_token :punct, "=~"
524
+ assert_next_token :normal, " "
525
+ assert_next_token :punct, "/"
526
+ assert_next_token :regex, "", :region_open
527
+ assert_next_token :regex, "3"
528
+ assert_next_token :regex, "", :region_close
529
+ assert_next_token :punct, "/"
530
+ end
531
+
532
+ def test_heredoc_with_trailing_text
533
+ tokenize( "foo('here', <<EOF)\n A heredoc.\nEOF\nfoo" )
534
+ assert_next_token :ident, "foo"
535
+ assert_next_token :punct, "('"
536
+ assert_next_token :string, '', :region_open
537
+ assert_next_token :string, 'here'
538
+ assert_next_token :string, '', :region_close
539
+ assert_next_token :punct, "',"
540
+ assert_next_token :normal, ' '
541
+ assert_next_token :punct, '<<'
542
+ assert_next_token :constant, "EOF"
543
+ assert_next_token :punct, ')'
544
+ assert_next_token :string, "", :region_open
545
+ assert_next_token :string, "\n A heredoc.\n"
546
+ assert_next_token :string, "", :region_close
547
+ assert_next_token :constant, "EOF"
548
+ assert_next_token :normal, "\n"
549
+ assert_next_token :ident, "foo"
550
+ end
551
+
552
+ def test_multiple_heredocs
553
+ tokenize( <<'TEST' )
554
+ foo('here', <<EOF, 'there', <<-'FOO', 'blah')
555
+ First heredoc, right here.
556
+ Expressions are #{allowed}
557
+ EOF
558
+ Another heredoc, immediately after the first.
559
+ Expressions are not #{allowed}
560
+ FOO
561
+ TEST
562
+ assert_next_token :ident, "foo"
563
+ assert_next_token :punct, "('"
564
+ assert_next_token :string, '', :region_open
565
+ assert_next_token :string, 'here'
566
+ assert_next_token :string, '', :region_close
567
+ assert_next_token :punct, "',"
568
+ assert_next_token :normal, ' '
569
+ assert_next_token :punct, '<<'
570
+ assert_next_token :constant, "EOF"
571
+ assert_next_token :punct, ','
572
+ assert_next_token :normal, ' '
573
+ assert_next_token :punct, "'"
574
+ assert_next_token :string, '', :region_open
575
+ assert_next_token :string, 'there'
576
+ assert_next_token :string, '', :region_close
577
+ assert_next_token :punct, "',"
578
+ assert_next_token :normal, ' '
579
+ assert_next_token :punct, "<<-'"
580
+ assert_next_token :constant, "FOO"
581
+ assert_next_token :punct, "',"
582
+ assert_next_token :normal, ' '
583
+ assert_next_token :punct, "'"
584
+ assert_next_token :string, '', :region_open
585
+ assert_next_token :string, 'blah'
586
+ assert_next_token :string, '', :region_close
587
+ assert_next_token :punct, "')"
588
+ assert_next_token :string, "", :region_open
589
+ assert_next_token :string, "\nFirst heredoc, right here.\nExpressions are "
590
+ assert_next_token :expr, '#{allowed}'
591
+ assert_next_token :string, "\n"
592
+ assert_next_token :string, "", :region_close
593
+ assert_next_token :constant, "EOF"
594
+ assert_next_token :string, "", :region_open
595
+ assert_next_token :string, "\n Another heredoc, immediately after the first.\n Expressions are not \#{allowed}\n"
596
+ assert_next_token :string, "", :region_close
597
+ assert_next_token :constant, " FOO"
598
+ end
599
+
600
+ def test_carldr_bad_heredoc_001
601
+ tokenize( <<'TEST' )
602
+ str = <<END
603
+ here document #{1 + 1}
604
+ END
605
+
606
+ if str
607
+ TEST
608
+
609
+ assert_next_token :ident, "str"
610
+ assert_next_token :normal, " "
611
+ assert_next_token :punct, "="
612
+ assert_next_token :normal, " "
613
+ assert_next_token :punct, "<<"
614
+ assert_next_token :constant, "END"
615
+ assert_next_token :string, "", :region_open
616
+ assert_next_token :string, "\nhere document "
617
+ assert_next_token :expr, '#{1 + 1}'
618
+ assert_next_token :string, "\n"
619
+ assert_next_token :string, "", :region_close
620
+ assert_next_token :constant, "END"
621
+ assert_next_token :normal, "\n\n"
622
+ assert_next_token :keyword, "if"
623
+ assert_next_token :normal, " "
624
+ assert_next_token :ident, "str"
625
+ end
626
+
627
+ def test_regex_after_keyword
628
+ tokenize "when /[0-7]/\nfoo"
629
+ assert_next_token :keyword, "when"
630
+ assert_next_token :normal, " "
631
+ assert_next_token :punct, "/"
632
+ assert_next_token :regex, "", :region_open
633
+ assert_next_token :regex, "[0-7]"
634
+ assert_next_token :regex, "", :region_close
635
+ assert_next_token :punct, "/"
636
+ assert_next_token :normal, "\n"
637
+ assert_next_token :ident, "foo"
638
+ end
639
+
640
+ def test_heredoc_after_lparen
641
+ tokenize "foo(<<SRC, obj)\nblah blah\nSRC\nfoo"
642
+ assert_next_token :ident, "foo"
643
+ assert_next_token :punct, "(<<"
644
+ assert_next_token :constant, "SRC"
645
+ assert_next_token :punct, ","
646
+ assert_next_token :normal, " "
647
+ assert_next_token :ident, "obj"
648
+ assert_next_token :punct, ")"
649
+ assert_next_token :string, "", :region_open
650
+ assert_next_token :string, "\nblah blah\n"
651
+ assert_next_token :string, "", :region_close
652
+ assert_next_token :constant, "SRC"
653
+ assert_next_token :normal, "\n"
654
+ assert_next_token :ident, "foo"
655
+ end
656
+
657
+ def test_division_after_parens
658
+ tokenize "(a+b)/2"
659
+ assert_next_token :punct, "("
660
+ assert_next_token :ident, "a"
661
+ assert_next_token :punct, "+"
662
+ assert_next_token :ident, "b"
663
+ assert_next_token :punct, ")/"
664
+ assert_next_token :number, "2"
516
665
  end
517
-
518
666
  end