synvert-core 1.3.0 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -4
  3. data/CHANGELOG.md +16 -0
  4. data/Gemfile +0 -3
  5. data/Guardfile +0 -9
  6. data/README.md +30 -12
  7. data/Rakefile +1 -15
  8. data/lib/synvert/core/engine/erb.rb +1 -1
  9. data/lib/synvert/core/engine.rb +1 -1
  10. data/lib/synvert/core/node_ext.rb +0 -466
  11. data/lib/synvert/core/rewriter/action/replace_erb_stmt_with_expr_action.rb +20 -17
  12. data/lib/synvert/core/rewriter/condition/if_exist_condition.rb +1 -1
  13. data/lib/synvert/core/rewriter/condition/unless_exist_condition.rb +1 -1
  14. data/lib/synvert/core/rewriter/instance.rb +89 -135
  15. data/lib/synvert/core/rewriter/scope/query_scope.rb +2 -2
  16. data/lib/synvert/core/rewriter/scope/within_scope.rb +4 -4
  17. data/lib/synvert/core/rewriter.rb +0 -10
  18. data/lib/synvert/core/version.rb +1 -1
  19. data/lib/synvert/core.rb +4 -6
  20. data/spec/synvert/core/engine/erb_spec.rb +3 -3
  21. data/spec/synvert/core/node_ext_spec.rb +0 -795
  22. data/spec/synvert/core/rewriter/action/replace_erb_stmt_with_expr_action_spec.rb +21 -1
  23. data/spec/synvert/core/rewriter/instance_spec.rb +49 -112
  24. data/spec/synvert/core/rewriter/scope/goto_scope_spec.rb +1 -4
  25. data/spec/synvert/core/rewriter/scope/query_scope_spec.rb +8 -4
  26. data/spec/synvert/core/rewriter/scope/within_scope_spec.rb +1 -4
  27. data/synvert-core-ruby.gemspec +4 -2
  28. metadata +44 -61
  29. data/lib/synvert/core/array_ext.rb +0 -48
  30. data/lib/synvert/core/node_query/compiler/array.rb +0 -34
  31. data/lib/synvert/core/node_query/compiler/attribute.rb +0 -39
  32. data/lib/synvert/core/node_query/compiler/attribute_list.rb +0 -24
  33. data/lib/synvert/core/node_query/compiler/boolean.rb +0 -23
  34. data/lib/synvert/core/node_query/compiler/comparable.rb +0 -86
  35. data/lib/synvert/core/node_query/compiler/dynamic_attribute.rb +0 -51
  36. data/lib/synvert/core/node_query/compiler/expression.rb +0 -58
  37. data/lib/synvert/core/node_query/compiler/float.rb +0 -23
  38. data/lib/synvert/core/node_query/compiler/identifier.rb +0 -41
  39. data/lib/synvert/core/node_query/compiler/integer.rb +0 -23
  40. data/lib/synvert/core/node_query/compiler/invalid_operator_error.rb +0 -7
  41. data/lib/synvert/core/node_query/compiler/nil.rb +0 -23
  42. data/lib/synvert/core/node_query/compiler/parse_error.rb +0 -7
  43. data/lib/synvert/core/node_query/compiler/regexp.rb +0 -37
  44. data/lib/synvert/core/node_query/compiler/selector.rb +0 -138
  45. data/lib/synvert/core/node_query/compiler/simple_selector.rb +0 -29
  46. data/lib/synvert/core/node_query/compiler/string.rb +0 -23
  47. data/lib/synvert/core/node_query/compiler/symbol.rb +0 -23
  48. data/lib/synvert/core/node_query/compiler.rb +0 -25
  49. data/lib/synvert/core/node_query/lexer.rex +0 -108
  50. data/lib/synvert/core/node_query/lexer.rex.rb +0 -321
  51. data/lib/synvert/core/node_query/parser.racc.rb +0 -322
  52. data/lib/synvert/core/node_query/parser.y +0 -62
  53. data/lib/synvert/core/node_query.rb +0 -37
  54. data/lib/synvert/core/rewriter/action/append_action.rb +0 -28
  55. data/lib/synvert/core/rewriter/action/delete_action.rb +0 -32
  56. data/lib/synvert/core/rewriter/action/insert_action.rb +0 -34
  57. data/lib/synvert/core/rewriter/action/insert_after_action.rb +0 -22
  58. data/lib/synvert/core/rewriter/action/prepend_action.rb +0 -44
  59. data/lib/synvert/core/rewriter/action/remove_action.rb +0 -53
  60. data/lib/synvert/core/rewriter/action/replace_action.rb +0 -33
  61. data/lib/synvert/core/rewriter/action/replace_with_action.rb +0 -36
  62. data/lib/synvert/core/rewriter/action/wrap_action.rb +0 -37
  63. data/lib/synvert/core/rewriter/action.rb +0 -102
  64. data/spec/synvert/core/node_query/lexer_spec.rb +0 -640
  65. data/spec/synvert/core/node_query/parser_spec.rb +0 -382
  66. data/spec/synvert/core/rewriter/action/append_action_spec.rb +0 -70
  67. data/spec/synvert/core/rewriter/action/delete_action_spec.rb +0 -26
  68. data/spec/synvert/core/rewriter/action/insert_action_spec.rb +0 -70
  69. data/spec/synvert/core/rewriter/action/insert_after_action_spec.rb +0 -26
  70. data/spec/synvert/core/rewriter/action/prepend_action_spec.rb +0 -175
  71. data/spec/synvert/core/rewriter/action/remove_action_spec.rb +0 -26
  72. data/spec/synvert/core/rewriter/action/replace_action_spec.rb +0 -28
  73. data/spec/synvert/core/rewriter/action/replace_with_action_spec.rb +0 -59
  74. data/spec/synvert/core/rewriter/action/wrap_action_spec.rb +0 -31
  75. data/spec/synvert/core/rewriter/action_spec.rb +0 -14
@@ -1,640 +0,0 @@
1
- require 'spec_helper'
2
- require 'oedipus_lex'
3
-
4
- module Synvert::Core::NodeQuery
5
- RSpec.describe Lexer do
6
- let(:lexer) { described_class.new }
7
-
8
- def assert_tokens(source, expected_tokens)
9
- lexer.parse(source)
10
- tokens = []
11
- while token = lexer.next_token
12
- tokens << token
13
- end
14
- expect(tokens).to eq expected_tokens
15
- end
16
-
17
- context 'ast node type' do
18
- it 'matches node type' do
19
- source = '.send'
20
- expected_tokens = [[:tNODE_TYPE, "send"]]
21
- assert_tokens source, expected_tokens
22
- end
23
- end
24
-
25
- context 'attribute value' do
26
- it 'matches =' do
27
- source = '.send[message=create]'
28
- expected_tokens = [
29
- [:tNODE_TYPE, "send"],
30
- [:tOPEN_ATTRIBUTE, "["],
31
- [:tKEY, "message"],
32
- [:tOPERATOR, "=="],
33
- [:tIDENTIFIER_VALUE, "create"],
34
- [:tCLOSE_ATTRIBUTE, "]"]
35
- ]
36
- assert_tokens source, expected_tokens
37
- end
38
-
39
- it 'matches nil' do
40
- source = '.send[receiver=nil]'
41
- expected_tokens = [
42
- [:tNODE_TYPE, "send"],
43
- [:tOPEN_ATTRIBUTE, "["],
44
- [:tKEY, "receiver"],
45
- [:tOPERATOR, "=="],
46
- [:tNIL, nil],
47
- [:tCLOSE_ATTRIBUTE, "]"]
48
- ]
49
- assert_tokens source, expected_tokens
50
- end
51
-
52
- it 'matches string' do
53
- source = '.send[message="create"]'
54
- expected_tokens = [
55
- [:tNODE_TYPE, "send"],
56
- [:tOPEN_ATTRIBUTE, "["],
57
- [:tKEY, "message"],
58
- [:tOPERATOR, "=="],
59
- [:tSTRING, "create"],
60
- [:tCLOSE_ATTRIBUTE, "]"]
61
- ]
62
- assert_tokens source, expected_tokens
63
- end
64
-
65
- it 'matches "[]"' do
66
- source = '.send[message="[]"]'
67
- expected_tokens = [
68
- [:tNODE_TYPE, "send"],
69
- [:tOPEN_ATTRIBUTE, "["],
70
- [:tKEY, "message"],
71
- [:tOPERATOR, "=="],
72
- [:tSTRING, "[]"],
73
- [:tCLOSE_ATTRIBUTE, "]"]
74
- ]
75
- assert_tokens source, expected_tokens
76
- end
77
-
78
- it 'matches symbol' do
79
- source = '.send[message=:create]'
80
- expected_tokens = [
81
- [:tNODE_TYPE, "send"],
82
- [:tOPEN_ATTRIBUTE, "["],
83
- [:tKEY, "message"],
84
- [:tOPERATOR, "=="],
85
- [:tSYMBOL, :create],
86
- [:tCLOSE_ATTRIBUTE, "]"]
87
- ]
88
- assert_tokens source, expected_tokens
89
- end
90
-
91
- it 'matches integer' do
92
- source = '[value=1]'
93
- expected_tokens = [
94
- [:tOPEN_ATTRIBUTE, "["],
95
- [:tKEY, "value"],
96
- [:tOPERATOR, "=="],
97
- [:tINTEGER, 1],
98
- [:tCLOSE_ATTRIBUTE, "]"]
99
- ]
100
- assert_tokens source, expected_tokens
101
- end
102
-
103
- it 'matches float' do
104
- source = '.send[value=1.1]'
105
- expected_tokens = [
106
- [:tNODE_TYPE, "send"],
107
- [:tOPEN_ATTRIBUTE, "["],
108
- [:tKEY, "value"],
109
- [:tOPERATOR, "=="],
110
- [:tFLOAT, 1.1],
111
- [:tCLOSE_ATTRIBUTE, "]"]
112
- ]
113
- assert_tokens source, expected_tokens
114
- end
115
-
116
- it 'matches boolean' do
117
- source = '.send[value=true]'
118
- expected_tokens = [
119
- [:tNODE_TYPE, "send"],
120
- [:tOPEN_ATTRIBUTE, "["],
121
- [:tKEY, "value"],
122
- [:tOPERATOR, "=="],
123
- [:tBOOLEAN, true],
124
- [:tCLOSE_ATTRIBUTE, "]"]
125
- ]
126
- assert_tokens source, expected_tokens
127
- end
128
-
129
- it 'identifier can contain !' do
130
- source = '.send[message=create!]'
131
- expected_tokens = [
132
- [:tNODE_TYPE, "send"],
133
- [:tOPEN_ATTRIBUTE, "["],
134
- [:tKEY, "message"],
135
- [:tOPERATOR, "=="],
136
- [:tIDENTIFIER_VALUE, "create!"],
137
- [:tCLOSE_ATTRIBUTE, "]"]
138
- ]
139
- assert_tokens source, expected_tokens
140
- end
141
-
142
- it 'identifier can contain ?' do
143
- source = '.send[message=empty?]'
144
- expected_tokens = [
145
- [:tNODE_TYPE, "send"],
146
- [:tOPEN_ATTRIBUTE, "["],
147
- [:tKEY, "message"],
148
- [:tOPERATOR, "=="],
149
- [:tIDENTIFIER_VALUE, "empty?"],
150
- [:tCLOSE_ATTRIBUTE, "]"]
151
- ]
152
- assert_tokens source, expected_tokens
153
- end
154
-
155
- it 'identifier can contain <, >, =' do
156
- source = '.send[message=<]'
157
- expected_tokens = [
158
- [:tNODE_TYPE, "send"],
159
- [:tOPEN_ATTRIBUTE, "["],
160
- [:tKEY, "message"],
161
- [:tOPERATOR, "=="],
162
- [:tIDENTIFIER_VALUE, "<"],
163
- [:tCLOSE_ATTRIBUTE, "]"]
164
- ]
165
- assert_tokens source, expected_tokens
166
-
167
- source = '.send[message==]'
168
- expected_tokens = [
169
- [:tNODE_TYPE, "send"],
170
- [:tOPEN_ATTRIBUTE, "["],
171
- [:tKEY, "message"],
172
- [:tOPERATOR, "=="],
173
- [:tIDENTIFIER_VALUE, "="],
174
- [:tCLOSE_ATTRIBUTE, "]"]
175
- ]
176
- assert_tokens source, expected_tokens
177
-
178
- source = '.send[message=>]'
179
- expected_tokens = [
180
- [:tNODE_TYPE, "send"],
181
- [:tOPEN_ATTRIBUTE, "["],
182
- [:tKEY, "message"],
183
- [:tOPERATOR, "=="],
184
- [:tIDENTIFIER_VALUE, ">"],
185
- [:tCLOSE_ATTRIBUTE, "]"]
186
- ]
187
- assert_tokens source, expected_tokens
188
- end
189
-
190
- it 'matches empty string' do
191
- source = ".send[arguments.first='']"
192
- expected_tokens = [
193
- [:tNODE_TYPE, "send"],
194
- [:tOPEN_ATTRIBUTE, "["],
195
- [:tKEY, "arguments.first"],
196
- [:tOPERATOR, "=="],
197
- [:tSTRING, ""],
198
- [:tCLOSE_ATTRIBUTE, "]"]
199
- ]
200
- assert_tokens source, expected_tokens
201
- end
202
-
203
- it 'matches :[] message' do
204
- source = ".send[message=[]]"
205
- expected_tokens = [
206
- [:tNODE_TYPE, "send"],
207
- [:tOPEN_ATTRIBUTE, "["],
208
- [:tKEY, "message"],
209
- [:tOPERATOR, "=="],
210
- [:tIDENTIFIER_VALUE, "[]"],
211
- [:tCLOSE_ATTRIBUTE, "]"]
212
- ]
213
- assert_tokens source, expected_tokens
214
- end
215
-
216
- it 'matches :[] message' do
217
- source = ".send[message=:[]=]"
218
- expected_tokens = [
219
- [:tNODE_TYPE, "send"],
220
- [:tOPEN_ATTRIBUTE, "["],
221
- [:tKEY, "message"],
222
- [:tOPERATOR, "=="],
223
- [:tSYMBOL, :[]=],
224
- [:tCLOSE_ATTRIBUTE, "]"]
225
- ]
226
- assert_tokens source, expected_tokens
227
- end
228
-
229
- it 'matches nil?' do
230
- source = ".send[message=nil?]"
231
- expected_tokens = [
232
- [:tNODE_TYPE, "send"],
233
- [:tOPEN_ATTRIBUTE, "["],
234
- [:tKEY, "message"],
235
- [:tOPERATOR, "=="],
236
- [:tIDENTIFIER_VALUE, "nil?"],
237
- [:tCLOSE_ATTRIBUTE, "]"]
238
- ]
239
- assert_tokens source, expected_tokens
240
- end
241
-
242
- it 'matches attribute value' do
243
- source = '.pair[key={{value}}]'
244
- expected_tokens = [
245
- [:tNODE_TYPE, "pair"],
246
- [:tOPEN_ATTRIBUTE, "["],
247
- [:tKEY, "key"],
248
- [:tOPERATOR, "=="],
249
- [:tOPEN_DYNAMIC_ATTRIBUTE, "{{"],
250
- [:tDYNAMIC_ATTRIBUTE, "value"],
251
- [:tCLOSE_DYNAMIC_ATTRIBUTE, "}}"],
252
- [:tCLOSE_ATTRIBUTE, "]"]
253
- ]
254
- assert_tokens source, expected_tokens
255
- end
256
-
257
- it 'matches nested value' do
258
- source = <<~EOS
259
- .send[
260
- receiver=
261
- .send[message=:create]
262
- ]
263
- EOS
264
- expected_tokens = [
265
- [:tNODE_TYPE, "send"],
266
- [:tOPEN_ATTRIBUTE, "["],
267
- [:tKEY, "receiver"],
268
- [:tOPERATOR, "=="],
269
- [:tNODE_TYPE, "send"],
270
- [:tOPEN_ATTRIBUTE, "["],
271
- [:tKEY, "message"],
272
- [:tOPERATOR, "=="],
273
- [:tSYMBOL, :create],
274
- [:tCLOSE_ATTRIBUTE, "]"],
275
- [:tCLOSE_ATTRIBUTE, "]"]
276
- ]
277
- assert_tokens source, expected_tokens
278
- end
279
-
280
- it 'matches deep nested value' do
281
- source = <<~EOS
282
- .send[
283
- arguments=[size=2][first=.str][last=.str]
284
- ]
285
- EOS
286
- expected_tokens = [
287
- [:tNODE_TYPE, "send"],
288
- [:tOPEN_ATTRIBUTE, "["],
289
- [:tKEY, "arguments"],
290
- [:tOPERATOR, "=="],
291
- [:tOPEN_ATTRIBUTE, "["],
292
- [:tKEY, "size"],
293
- [:tOPERATOR, "=="],
294
- [:tINTEGER, 2],
295
- [:tCLOSE_ATTRIBUTE, "]"],
296
- [:tOPEN_ATTRIBUTE, "["],
297
- [:tKEY, "first"],
298
- [:tOPERATOR, "=="],
299
- [:tNODE_TYPE, "str"],
300
- [:tCLOSE_ATTRIBUTE, "]"],
301
- [:tOPEN_ATTRIBUTE, "["],
302
- [:tKEY, "last"],
303
- [:tOPERATOR, "=="],
304
- [:tNODE_TYPE, "str"],
305
- [:tCLOSE_ATTRIBUTE, "]"],
306
- [:tCLOSE_ATTRIBUTE, "]"]
307
- ]
308
- assert_tokens source, expected_tokens
309
- end
310
- end
311
-
312
- context 'attribute condition' do
313
- it 'matches !=' do
314
- source = '.send[message != create]'
315
- expected_tokens = [
316
- [:tNODE_TYPE, "send"],
317
- [:tOPEN_ATTRIBUTE, "["],
318
- [:tKEY, "message"],
319
- [:tOPERATOR, "!="],
320
- [:tIDENTIFIER_VALUE, "create"],
321
- [:tCLOSE_ATTRIBUTE, "]"]
322
- ]
323
- assert_tokens source, expected_tokens
324
- end
325
-
326
- it 'matches >' do
327
- source = '[value > 1]'
328
- expected_tokens = [
329
- [:tOPEN_ATTRIBUTE, "["],
330
- [:tKEY, "value"],
331
- [:tOPERATOR, ">"],
332
- [:tINTEGER, 1],
333
- [:tCLOSE_ATTRIBUTE, "]"]
334
- ]
335
- assert_tokens source, expected_tokens
336
- end
337
-
338
- it 'matches <' do
339
- source = '[value < 1]'
340
- expected_tokens = [
341
- [:tOPEN_ATTRIBUTE, "["],
342
- [:tKEY, "value"],
343
- [:tOPERATOR, "<"],
344
- [:tINTEGER, 1],
345
- [:tCLOSE_ATTRIBUTE, "]"]
346
- ]
347
- assert_tokens source, expected_tokens
348
- end
349
-
350
- it 'matches >=' do
351
- source = '[value >= 1]'
352
- expected_tokens = [
353
- [:tOPEN_ATTRIBUTE, "["],
354
- [:tKEY, "value"],
355
- [:tOPERATOR, ">="],
356
- [:tINTEGER, 1],
357
- [:tCLOSE_ATTRIBUTE, "]"]
358
- ]
359
- assert_tokens source, expected_tokens
360
- end
361
-
362
- it 'matches <=' do
363
- source = '[value <= 1]'
364
- expected_tokens = [
365
- [:tOPEN_ATTRIBUTE, "["],
366
- [:tKEY, "value"],
367
- [:tOPERATOR, "<="],
368
- [:tINTEGER, 1],
369
- [:tCLOSE_ATTRIBUTE, "]"]
370
- ]
371
- assert_tokens source, expected_tokens
372
- end
373
-
374
- it 'matches =~' do
375
- source = '.send[message=~/create/i]'
376
- expected_tokens = [
377
- [:tNODE_TYPE, "send"],
378
- [:tOPEN_ATTRIBUTE, "["],
379
- [:tKEY, "message"],
380
- [:tOPERATOR, "=~"],
381
- [:tREGEXP, /create/i],
382
- [:tCLOSE_ATTRIBUTE, "]"]
383
- ]
384
- assert_tokens source, expected_tokens
385
- end
386
-
387
- it 'matches !~' do
388
- source = '.send[message!~/create/i]'
389
- expected_tokens = [
390
- [:tNODE_TYPE, "send"],
391
- [:tOPEN_ATTRIBUTE, "["],
392
- [:tKEY, "message"],
393
- [:tOPERATOR, "!~"],
394
- [:tREGEXP, /create/i],
395
- [:tCLOSE_ATTRIBUTE, "]"]
396
- ]
397
- assert_tokens source, expected_tokens
398
- end
399
-
400
- it 'matche empty array' do
401
- source = '.send[arguments=()]'
402
- expected_tokens = [
403
- [:tNODE_TYPE, "send"],
404
- [:tOPEN_ATTRIBUTE, "["],
405
- [:tKEY, "arguments"],
406
- [:tOPERATOR, "=="],
407
- [:tOPEN_ARRAY, "("],
408
- [:tCLOSE_ARRAY, ")"],
409
- [:tCLOSE_ATTRIBUTE, "]"]
410
- ]
411
- assert_tokens source, expected_tokens
412
- end
413
-
414
- it 'matche equal array' do
415
- source = '.send[arguments=(:create)]'
416
- expected_tokens = [
417
- [:tNODE_TYPE, "send"],
418
- [:tOPEN_ATTRIBUTE, "["],
419
- [:tKEY, "arguments"],
420
- [:tOPERATOR, "=="],
421
- [:tOPEN_ARRAY, "("],
422
- [:tSYMBOL, :create],
423
- [:tCLOSE_ARRAY, ")"],
424
- [:tCLOSE_ATTRIBUTE, "]"]
425
- ]
426
- assert_tokens source, expected_tokens
427
- end
428
-
429
- it 'matche not equal array' do
430
- source = '.send[arguments!=(:create)]'
431
- expected_tokens = [
432
- [:tNODE_TYPE, "send"],
433
- [:tOPEN_ATTRIBUTE, "["],
434
- [:tKEY, "arguments"],
435
- [:tOPERATOR, "!="],
436
- [:tOPEN_ARRAY, "("],
437
- [:tSYMBOL, :create],
438
- [:tCLOSE_ARRAY, ")"],
439
- [:tCLOSE_ATTRIBUTE, "]"]
440
- ]
441
- assert_tokens source, expected_tokens
442
- end
443
-
444
- it 'matches IN' do
445
- source = '.send[message IN (create build)]'
446
- expected_tokens = [
447
- [:tNODE_TYPE, "send"],
448
- [:tOPEN_ATTRIBUTE, "["],
449
- [:tKEY, "message"],
450
- [:tOPERATOR, "in"],
451
- [:tOPEN_ARRAY, "("],
452
- [:tIDENTIFIER_VALUE, "create"],
453
- [:tIDENTIFIER_VALUE, "build"],
454
- [:tCLOSE_ARRAY, ")"],
455
- [:tCLOSE_ATTRIBUTE, "]"]
456
- ]
457
- assert_tokens source, expected_tokens
458
- end
459
-
460
- it 'matches NOT IN' do
461
- source = '.send[message NOT IN (create build)]'
462
- expected_tokens = [
463
- [:tNODE_TYPE, "send"],
464
- [:tOPEN_ATTRIBUTE, "["],
465
- [:tKEY, "message"],
466
- [:tOPERATOR, "not_in"],
467
- [:tOPEN_ARRAY, "("],
468
- [:tIDENTIFIER_VALUE, "create"],
469
- [:tIDENTIFIER_VALUE, "build"],
470
- [:tCLOSE_ARRAY, ")"],
471
- [:tCLOSE_ATTRIBUTE, "]"]
472
- ]
473
- assert_tokens source, expected_tokens
474
- end
475
-
476
- it 'matches INCLUDES' do
477
- source = '.send[arguments INCLUDES &block]'
478
- expected_tokens = [
479
- [:tNODE_TYPE, "send"],
480
- [:tOPEN_ATTRIBUTE, "["],
481
- [:tKEY, "arguments"],
482
- [:tOPERATOR, "includes"],
483
- [:tIDENTIFIER_VALUE, "&block"],
484
- [:tCLOSE_ATTRIBUTE, "]"]
485
- ]
486
- assert_tokens source, expected_tokens
487
- end
488
- end
489
-
490
- context 'nested attribute' do
491
- it 'matches' do
492
- source = '.send[receiver.message=:create]'
493
- expected_tokens = [
494
- [:tNODE_TYPE, "send"],
495
- [:tOPEN_ATTRIBUTE, "["],
496
- [:tKEY, "receiver.message"],
497
- [:tOPERATOR, "=="],
498
- [:tSYMBOL, :create],
499
- [:tCLOSE_ATTRIBUTE, "]"]
500
- ]
501
- assert_tokens source, expected_tokens
502
- end
503
- end
504
-
505
- context 'position' do
506
- it 'matches :first-child' do
507
- source = '.send[arguments=:create]:first-child'
508
- expected_tokens = [
509
- [:tNODE_TYPE, "send"],
510
- [:tOPEN_ATTRIBUTE, "["],
511
- [:tKEY, "arguments"],
512
- [:tOPERATOR, "=="],
513
- [:tSYMBOL, :create],
514
- [:tCLOSE_ATTRIBUTE, "]"],
515
- [:tINDEX, 0]
516
- ]
517
- assert_tokens source, expected_tokens
518
- end
519
-
520
- it 'matches :last-child' do
521
- source = '.send[arguments=:create]:last-child'
522
- expected_tokens = [
523
- [:tNODE_TYPE, "send"],
524
- [:tOPEN_ATTRIBUTE, "["],
525
- [:tKEY, "arguments"],
526
- [:tOPERATOR, "=="],
527
- [:tSYMBOL, :create],
528
- [:tCLOSE_ATTRIBUTE, "]"],
529
- [:tINDEX, -1]
530
- ]
531
- assert_tokens source, expected_tokens
532
- end
533
-
534
- it 'matches :nth-child(1)' do
535
- source = '.send[arguments=:create]:nth-child(1)'
536
- expected_tokens = [
537
- [:tNODE_TYPE, "send"],
538
- [:tOPEN_ATTRIBUTE, "["],
539
- [:tKEY, "arguments"],
540
- [:tOPERATOR, "=="],
541
- [:tSYMBOL, :create],
542
- [:tCLOSE_ATTRIBUTE, "]"],
543
- [:tINDEX, 0]
544
- ]
545
- assert_tokens source, expected_tokens
546
- end
547
-
548
- it 'matches :nth-last-child(1)' do
549
- source = '.send[arguments=:create]:nth-last-child(1)'
550
- expected_tokens = [
551
- [:tNODE_TYPE, "send"],
552
- [:tOPEN_ATTRIBUTE, "["],
553
- [:tKEY, "arguments"],
554
- [:tOPERATOR, "=="],
555
- [:tSYMBOL, :create],
556
- [:tCLOSE_ATTRIBUTE, "]"],
557
- [:tINDEX, -1]
558
- ]
559
- assert_tokens source, expected_tokens
560
- end
561
- end
562
-
563
- context 'descendant' do
564
- it 'matches' do
565
- source = '.class .send'
566
- expected_tokens = [[:tNODE_TYPE, "class"], [:tNODE_TYPE, "send"]]
567
- assert_tokens source, expected_tokens
568
- end
569
- end
570
-
571
- context 'child' do
572
- it 'matches' do
573
- source = '.def > .send'
574
- expected_tokens = [[:tNODE_TYPE, "def"], [:tRELATIONSHIP, ">"], [:tNODE_TYPE, "send"]]
575
- assert_tokens source, expected_tokens
576
- end
577
- end
578
-
579
- context 'subsequent sibling' do
580
- it 'matches' do
581
- source = '.send ~ .send'
582
- expected_tokens = [[:tNODE_TYPE, "send"], [:tRELATIONSHIP, "~"], [:tNODE_TYPE, "send"]]
583
- assert_tokens source, expected_tokens
584
- end
585
- end
586
-
587
- context 'next sibling' do
588
- it 'matches' do
589
- source = '.send + .send'
590
- expected_tokens = [[:tNODE_TYPE, "send"], [:tRELATIONSHIP, "+"], [:tNODE_TYPE, "send"]]
591
- assert_tokens source, expected_tokens
592
- end
593
- end
594
-
595
- context ':has' do
596
- it 'matches' do
597
- source = '.class:has(> .def)'
598
- expected_tokens = [
599
- [:tNODE_TYPE, "class"],
600
- [:tPSEUDO_CLASS, "has"],
601
- [:tOPEN_SELECTOR, "("],
602
- [:tRELATIONSHIP, ">"],
603
- [:tNODE_TYPE, "def"],
604
- [:tCLOSE_SELECTOR, ")"]
605
- ]
606
- assert_tokens source, expected_tokens
607
- end
608
- end
609
-
610
- context ':not_has' do
611
- it 'matches' do
612
- source = '.class:not_has(> .def)'
613
- expected_tokens = [
614
- [:tNODE_TYPE, "class"],
615
- [:tPSEUDO_CLASS, "not_has"],
616
- [:tOPEN_SELECTOR, "("],
617
- [:tRELATIONSHIP, ">"],
618
- [:tNODE_TYPE, "def"],
619
- [:tCLOSE_SELECTOR, ")"]
620
- ]
621
- assert_tokens source, expected_tokens
622
- end
623
- end
624
-
625
- context 'goto_scope' do
626
- it 'matches' do
627
- source = '.block <body> > .def'
628
- expected_tokens = [
629
- [:tNODE_TYPE, "block"],
630
- [:tOPEN_GOTO_SCOPE, "<"],
631
- [:tIDENTIFIER, "body"],
632
- [:tCLOSE_GOTO_SCOPE, ">"],
633
- [:tRELATIONSHIP, ">"],
634
- [:tNODE_TYPE, "def"]
635
- ]
636
- assert_tokens source, expected_tokens
637
- end
638
- end
639
- end
640
- end