parser 2.7.1.5 → 3.0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/lib/parser/all.rb +1 -0
  3. data/lib/parser/ast/processor.rb +3 -0
  4. data/lib/parser/base.rb +1 -0
  5. data/lib/parser/builders/default.rb +126 -13
  6. data/lib/parser/context.rb +4 -0
  7. data/lib/parser/current.rb +16 -7
  8. data/lib/parser/current_arg_stack.rb +5 -2
  9. data/lib/parser/lexer.rb +872 -802
  10. data/lib/parser/max_numparam_stack.rb +12 -4
  11. data/lib/parser/messages.rb +1 -0
  12. data/lib/parser/meta.rb +4 -3
  13. data/lib/parser/ruby18.rb +6 -2
  14. data/lib/parser/ruby27.rb +3763 -3704
  15. data/lib/parser/ruby28.rb +8047 -0
  16. data/lib/parser/ruby30.rb +3657 -3649
  17. data/lib/parser/ruby31.rb +8226 -0
  18. data/lib/parser/runner.rb +6 -1
  19. data/lib/parser/source/buffer.rb +50 -27
  20. data/lib/parser/source/comment.rb +13 -0
  21. data/lib/parser/source/comment/associator.rb +17 -4
  22. data/lib/parser/source/tree_rewriter.rb +27 -0
  23. data/lib/parser/static_environment.rb +4 -0
  24. data/lib/parser/variables_stack.rb +4 -0
  25. data/lib/parser/version.rb +1 -1
  26. data/parser.gemspec +1 -20
  27. metadata +8 -95
  28. data/.travis.yml +0 -41
  29. data/.yardopts +0 -21
  30. data/CHANGELOG.md +0 -1137
  31. data/CONTRIBUTING.md +0 -17
  32. data/Gemfile +0 -10
  33. data/README.md +0 -309
  34. data/Rakefile +0 -167
  35. data/ci/run_rubocop_specs +0 -14
  36. data/doc/AST_FORMAT.md +0 -2284
  37. data/doc/CUSTOMIZATION.md +0 -37
  38. data/doc/INTERNALS.md +0 -21
  39. data/doc/css/.gitkeep +0 -0
  40. data/doc/css/common.css +0 -68
  41. data/lib/parser/lexer.rl +0 -2550
  42. data/lib/parser/macruby.y +0 -2208
  43. data/lib/parser/ruby18.y +0 -1936
  44. data/lib/parser/ruby19.y +0 -2185
  45. data/lib/parser/ruby20.y +0 -2363
  46. data/lib/parser/ruby21.y +0 -2364
  47. data/lib/parser/ruby22.y +0 -2371
  48. data/lib/parser/ruby23.y +0 -2377
  49. data/lib/parser/ruby24.y +0 -2415
  50. data/lib/parser/ruby25.y +0 -2412
  51. data/lib/parser/ruby26.y +0 -2420
  52. data/lib/parser/ruby27.y +0 -2949
  53. data/lib/parser/ruby30.y +0 -3048
  54. data/lib/parser/rubymotion.y +0 -2192
  55. data/test/bug_163/fixtures/input.rb +0 -5
  56. data/test/bug_163/fixtures/output.rb +0 -5
  57. data/test/bug_163/rewriter.rb +0 -20
  58. data/test/helper.rb +0 -103
  59. data/test/parse_helper.rb +0 -328
  60. data/test/racc_coverage_helper.rb +0 -133
  61. data/test/test_ast_processor.rb +0 -32
  62. data/test/test_base.rb +0 -31
  63. data/test/test_current.rb +0 -31
  64. data/test/test_diagnostic.rb +0 -95
  65. data/test/test_diagnostic_engine.rb +0 -59
  66. data/test/test_encoding.rb +0 -99
  67. data/test/test_lexer.rb +0 -3617
  68. data/test/test_lexer_stack_state.rb +0 -78
  69. data/test/test_meta.rb +0 -12
  70. data/test/test_parse_helper.rb +0 -83
  71. data/test/test_parser.rb +0 -9986
  72. data/test/test_runner_parse.rb +0 -56
  73. data/test/test_runner_rewrite.rb +0 -47
  74. data/test/test_source_buffer.rb +0 -165
  75. data/test/test_source_comment.rb +0 -36
  76. data/test/test_source_comment_associator.rb +0 -399
  77. data/test/test_source_map.rb +0 -14
  78. data/test/test_source_range.rb +0 -192
  79. data/test/test_source_rewriter.rb +0 -541
  80. data/test/test_source_rewriter_action.rb +0 -46
  81. data/test/test_source_tree_rewriter.rb +0 -361
  82. data/test/test_static_environment.rb +0 -45
  83. data/test/using_tree_rewriter/fixtures/input.rb +0 -3
  84. data/test/using_tree_rewriter/fixtures/output.rb +0 -3
  85. data/test/using_tree_rewriter/using_tree_rewriter.rb +0 -9
@@ -1,14 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'helper'
4
- require 'parse_helper'
5
-
6
- class TestSourceMap < Minitest::Test
7
- include ParseHelper
8
-
9
- def test_to_hash
10
- buf = Parser::Source::Buffer.new("<input>", source: "1")
11
- ast = parser_for_ruby_version('1.8').parse(buf)
12
- assert_equal [:expression, :operator], ast.loc.to_hash.keys.sort_by(&:to_s)
13
- end
14
- end
@@ -1,192 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'helper'
4
-
5
- class TestSourceRange < Minitest::Test
6
- def setup
7
- @buf = Parser::Source::Buffer.new('(string)',
8
- source: "foobar\nbaz")
9
- @sr1_3 = Parser::Source::Range.new(@buf, 1, 3)
10
- @sr2_2 = Parser::Source::Range.new(@buf, 2, 2)
11
- @sr3_3 = Parser::Source::Range.new(@buf, 3, 3)
12
- @sr2_6 = Parser::Source::Range.new(@buf, 2, 6)
13
- @sr5_8 = Parser::Source::Range.new(@buf, 5, 8)
14
- @sr5_7 = Parser::Source::Range.new(@buf, 5, 7)
15
- @sr6_7 = Parser::Source::Range.new(@buf, 6, 7)
16
- end
17
-
18
- def test_initialize
19
- assert_equal 1, @sr1_3.begin_pos
20
- assert_equal 3, @sr1_3.end_pos
21
- assert @sr1_3.frozen?
22
- end
23
-
24
- def test_size
25
- assert_equal 4, @sr2_6.size
26
- end
27
-
28
- def test_bad_size
29
- assert_raises ArgumentError do
30
- Parser::Source::Range.new(@buf, 2, 1)
31
- end
32
- end
33
-
34
- def test_join
35
- sr = @sr1_3.join(@sr5_8)
36
-
37
- assert_equal 1, sr.begin_pos
38
- assert_equal 8, sr.end_pos
39
- end
40
-
41
- def test_intersect
42
- assert_equal 2, @sr1_3.intersect(@sr2_6).begin_pos
43
- assert_equal 3, @sr1_3.intersect(@sr2_6).end_pos
44
- assert_equal 5, @sr2_6.intersect(@sr5_8).begin_pos
45
- assert_equal 6, @sr2_6.intersect(@sr5_8).end_pos
46
- assert @sr1_3.intersect(@sr5_8) == nil
47
- assert_equal 2, @sr1_3.intersect(@sr2_2).begin_pos
48
- assert_equal 2, @sr1_3.intersect(@sr2_2).end_pos
49
- assert_equal 2, @sr2_2.intersect(@sr2_2).begin_pos
50
- assert_equal 2, @sr2_2.intersect(@sr2_2).end_pos
51
- end
52
-
53
- def test_overlaps
54
- assert !@sr1_3.overlaps?(@sr5_8)
55
- assert @sr1_3.overlaps?(@sr2_6)
56
- assert @sr2_6.overlaps?(@sr5_8)
57
- assert @sr1_3.overlaps?(@sr2_2)
58
- assert !@sr2_6.overlaps?(@sr2_2)
59
- assert @sr2_2.overlaps?(@sr2_2)
60
- end
61
-
62
- def check_relationship(relationship, sr1, sr2, reflexive_relationship = relationship)
63
- # Double check equality
64
- assert_equal true, sr1 == sr1.dup
65
- assert_equal true, sr1 != sr2
66
- # Check relationships and reflexivity
67
- assert_equal true, sr1.send(relationship, sr2)
68
- assert_equal true, sr2.send(reflexive_relationship, sr1)
69
- # Check it's not true for itself
70
- assert_equal false, sr1.send(relationship, sr1)
71
- # Check other relationships return false
72
- others = %i[disjoint? crossing? contains? contained?] - [relationship, reflexive_relationship]
73
- others.each do |other_rel|
74
- assert_equal false, sr1.send(other_rel, sr2), other_rel
75
- assert_equal false, sr2.send(other_rel, sr1), other_rel
76
- end
77
- end
78
-
79
- def test_disjoint
80
- check_relationship(:disjoint?, @sr1_3, @sr5_8)
81
- check_relationship(:disjoint?, @sr2_2, @sr2_6)
82
- check_relationship(:disjoint?, @sr2_2, @sr3_3)
83
- check_relationship(:disjoint?, @sr2_6, @sr6_7)
84
- end
85
-
86
- def test_crossing
87
- check_relationship(:crossing?, @sr1_3, @sr2_6)
88
- end
89
-
90
- def test_containment
91
- check_relationship(:contained?, @sr2_2, @sr1_3, :contains?)
92
- check_relationship(:contained?, @sr5_7, @sr5_8, :contains?)
93
- check_relationship(:contained?, @sr6_7, @sr5_8, :contains?)
94
- end
95
-
96
- def test_order
97
- assert_equal 0, @sr1_3 <=> @sr1_3
98
- assert_equal(-1, @sr1_3 <=> @sr5_8)
99
- assert_equal(-1, @sr2_2 <=> @sr2_6)
100
- assert_equal(+1, @sr2_6 <=> @sr2_2)
101
-
102
- assert_equal(-1, @sr1_3 <=> @sr2_6)
103
-
104
- assert_equal(+1, @sr2_2 <=> @sr1_3)
105
- assert_equal(-1, @sr1_3 <=> @sr2_2)
106
- assert_equal(-1, @sr5_7 <=> @sr5_8)
107
-
108
- assert_nil @sr1_3 <=> Parser::Source::Range.new(@buf.dup, 1, 3)
109
- assert_nil @sr1_3 <=> 4
110
- end
111
-
112
- def test_empty
113
- assert !@sr1_3.empty?
114
- assert @sr2_2.empty?
115
- end
116
-
117
- def test_line
118
- sr = Parser::Source::Range.new(@buf, 7, 8)
119
- assert_equal 2, sr.line
120
- end
121
-
122
- def test_source_line
123
- sr = Parser::Source::Range.new(@buf, 7, 8)
124
- assert_equal 'baz', sr.source_line
125
- end
126
-
127
- def test_columns
128
- sr = Parser::Source::Range.new(@buf, 7, 8)
129
- assert_equal 0, sr.begin.column
130
- assert_equal 1, sr.end.column
131
- assert_equal 0...1, sr.column_range
132
- end
133
-
134
- def test_begin_end
135
- sr_beg = @sr2_6.begin
136
- assert_equal 2, sr_beg.begin_pos
137
- assert_equal 2, sr_beg.end_pos
138
-
139
- sr_end = @sr2_6.end
140
- assert_equal 6, sr_end.begin_pos
141
- assert_equal 6, sr_end.end_pos
142
- end
143
-
144
- def test_source
145
- sr = Parser::Source::Range.new(@buf, 0, 3)
146
- assert_equal 'foo', sr.source
147
-
148
- sr_multi = Parser::Source::Range.new(@buf, 0, 10)
149
- assert_equal "foobar\nbaz", sr_multi.source
150
- end
151
-
152
- def test_is?
153
- sr = Parser::Source::Range.new(@buf, 0, 3)
154
- assert sr.is?('foo')
155
- refute sr.is?('bar')
156
- end
157
-
158
- def test_to_range
159
- sr = Parser::Source::Range.new(@buf, 10, 20)
160
- assert_equal (10...20), sr.to_range
161
- end
162
-
163
- def test_to_s
164
- sr = Parser::Source::Range.new(@buf, 8, 9)
165
- assert_equal '(string):2:2', sr.to_s
166
- end
167
-
168
- def test_with
169
- sr2 = @sr1_3.with(begin_pos: 2)
170
- sr3 = @sr1_3.with(end_pos: 4)
171
-
172
- assert_equal 2, sr2.begin_pos
173
- assert_equal 3, sr2.end_pos
174
- assert_equal 1, sr3.begin_pos
175
- assert_equal 4, sr3.end_pos
176
- end
177
-
178
- def test_eql_and_hash
179
- assert_equal false, @sr1_3.eql?(@sr3_3)
180
- assert @sr1_3.hash != @sr3_3.hash
181
-
182
- also_1_3 = @sr3_3.with(begin_pos: 1)
183
- assert_equal true, @sr1_3.eql?(also_1_3)
184
- assert_equal @sr1_3.hash, also_1_3.hash
185
-
186
- buf2 = Parser::Source::Buffer.new('(string)',
187
- source: "foobar\nbaz")
188
- from_other_buf = Parser::Source::Range.new(buf2, 1, 3)
189
- assert_equal false, @sr1_3.eql?(from_other_buf)
190
- assert @sr1_3.hash != from_other_buf.hash
191
- end
192
- end
@@ -1,541 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'helper'
4
-
5
- class TestSourceRewriter < Minitest::Test
6
- def setup
7
- @buf = Parser::Source::Buffer.new('(rewriter)',
8
- source: 'foo bar baz')
9
- Parser::Source::Rewriter.warned_of_deprecation = true
10
- @rewriter = Parser::Source::Rewriter.new(@buf)
11
- end
12
-
13
- def range(from, len)
14
- Parser::Source::Range.new(@buf, from, from + len)
15
- end
16
-
17
- def test_remove
18
- assert_equal 'foo baz',
19
- @rewriter.
20
- remove(range(4, 3)).
21
- process
22
- end
23
-
24
- def test_insert_before
25
- assert_equal 'foo quux bar baz',
26
- @rewriter.
27
- insert_before(range(4, 3), 'quux ').
28
- process
29
- end
30
-
31
- def test_insert_after
32
- assert_equal 'foo bar quux baz',
33
- @rewriter.
34
- insert_after(range(4, 3), ' quux').
35
- process
36
- end
37
-
38
- def test_replace
39
- assert_equal 'foo quux baz',
40
- @rewriter.
41
- replace(range(4, 3), 'quux').
42
- process
43
- end
44
-
45
- def test_composing_asc
46
- assert_equal 'foo---bar---baz',
47
- @rewriter.
48
- replace(range(3, 1), '---').
49
- replace(range(7, 1), '---').
50
- process
51
- end
52
-
53
- def test_composing_desc
54
- assert_equal 'foo---bar---baz',
55
- @rewriter.
56
- replace(range(7, 1), '---').
57
- replace(range(3, 1), '---').
58
- process
59
- end
60
-
61
- #
62
- # Merging/clobbering of overlapping edits
63
- #
64
-
65
- def test_insertion_just_before_replace
66
- assert_equal 'foostrawberry jam---bar baz',
67
- @rewriter.
68
- replace(range(3, 1), '---').
69
- insert_before(range(3, 1), 'strawberry jam').
70
- process
71
- end
72
-
73
- def test_insertion_just_after_replace
74
- assert_equal 'foo---strawberry jam baz',
75
- @rewriter.
76
- replace(range(3, 4), '---').
77
- insert_after(range(3, 4), 'strawberry jam').
78
- process
79
- end
80
-
81
- def test_insertion_just_before_remove
82
- assert_equal 'foostrawberry jambar baz',
83
- @rewriter.
84
- remove(range(3, 1)).
85
- insert_before(range(3, 1), 'strawberry jam').
86
- process
87
- end
88
-
89
- def test_insertion_just_after_remove
90
- assert_equal 'foostrawberry jam baz',
91
- @rewriter.
92
- remove(range(3, 4)).
93
- insert_after(range(3, 4), 'strawberry jam').
94
- process
95
- end
96
-
97
- def test_insertion_just_before_replace_at_buffer_start
98
- assert_equal 'strawberry jam--- bar baz',
99
- @rewriter.
100
- replace(range(0, 3), '---').
101
- insert_before(range(0, 1), 'strawberry jam').
102
- process
103
- end
104
-
105
- def test_insertion_just_after_replace_at_buffer_end
106
- assert_equal 'foo bar ---strawberry jam',
107
- @rewriter.
108
- replace(range(8, 3), '---').
109
- insert_after(range(9, 2), 'strawberry jam').
110
- process
111
- end
112
-
113
- def test_insertion_just_before_remove_at_buffer_start
114
- assert_equal 'strawberry bar baz',
115
- @rewriter.
116
- remove(range(0, 3)).
117
- insert_before(range(0, 1), 'strawberry').
118
- process
119
- end
120
-
121
- def test_insertion_just_after_remove_at_buffer_end
122
- assert_equal 'foo bar strawberry',
123
- @rewriter.
124
- remove(range(8, 3)).
125
- insert_after(range(10, 1), 'strawberry').
126
- process
127
- end
128
-
129
- def test_multiple_insertions_at_same_location_clobber
130
- silence_diagnostics
131
-
132
- assert_raises Parser::ClobberingError do
133
- @rewriter.
134
- insert_before(range(0, 11), '<').
135
- insert_after( range(0, 11), '>').
136
- insert_before(range(0, 7), '(')
137
- end
138
- end
139
-
140
- def test_intentional_multiple_insertions_at_same_location
141
- assert_equal 'foo [(bar)] baz',
142
- @rewriter.
143
- insert_before_multi(range(4, 0), '(').
144
- insert_after_multi(range(7, 0), ')').
145
- insert_before_multi(range(4, 0), '[').
146
- insert_after_multi(range(7, 0), ']').
147
- process
148
- end
149
-
150
- def test_insertion_within_replace_clobber
151
- silence_diagnostics
152
-
153
- assert_raises Parser::ClobberingError do
154
- @rewriter.
155
- replace(range(3, 2), '<').
156
- insert_after(range(3, 1), '>')
157
- end
158
- end
159
-
160
- def test_insertion_within_remove_clobber
161
- silence_diagnostics
162
-
163
- assert_raises Parser::ClobberingError do
164
- @rewriter.
165
- remove(range(3, 2)).
166
- insert_after(range(3, 1), '>')
167
- end
168
- end
169
-
170
- def test_replace_overlapping_insertion_clobber
171
- silence_diagnostics
172
-
173
- assert_raises Parser::ClobberingError do
174
- @rewriter.
175
- insert_after(range(3, 1), '>').
176
- replace(range(3, 2), '<')
177
- end
178
- end
179
-
180
- def test_remove_overlapping_insertion_clobber
181
- silence_diagnostics
182
-
183
- assert_raises Parser::ClobberingError do
184
- @rewriter.
185
- insert_after(range(3, 1), '>').
186
- remove(range(3, 2))
187
- end
188
- end
189
-
190
- def test_multi_insertion_within_replace_clobber
191
- silence_diagnostics
192
-
193
- assert_raises Parser::ClobberingError do
194
- @rewriter.
195
- replace(range(3, 2), '<').
196
- insert_after_multi(range(3, 1), '>')
197
- end
198
- end
199
-
200
- def test_multi_insertion_within_remove_clobber
201
- silence_diagnostics
202
-
203
- assert_raises Parser::ClobberingError do
204
- @rewriter.
205
- remove(range(3, 2)).
206
- insert_after_multi(range(3, 1), '>')
207
- end
208
- end
209
-
210
- def test_replace_overlapping_multi_insertion_clobber
211
- silence_diagnostics
212
-
213
- assert_raises Parser::ClobberingError do
214
- @rewriter.
215
- insert_after_multi(range(3, 1), '>').
216
- replace(range(3, 2), '<')
217
- end
218
- end
219
-
220
- def test_remove_overlapping_multi_insertion_clobber
221
- silence_diagnostics
222
-
223
- assert_raises Parser::ClobberingError do
224
- @rewriter.
225
- insert_after_multi(range(3, 1), '>').
226
- remove(range(3, 2))
227
- end
228
- end
229
-
230
- def test_insertion_on_merged_insertion_clobber
231
- # 2 insertions at the same point clobber each other, even if the 1st one
232
- # was merged with an adjacent edit, and even if the same text is being
233
- # inserted
234
-
235
- silence_diagnostics
236
-
237
- assert_raises Parser::ClobberingError do
238
- @rewriter.
239
- insert_before(range(3, 1), '>').
240
- remove(range(3, 2)).
241
- insert_after(range(2, 1), '>')
242
- end
243
- end
244
-
245
- def test_insertion_merge_with_overlapping_replace
246
- assert_equal 'fo abc bar baz',
247
- @rewriter.
248
- insert_before(range(3, 1), 'abc').
249
- replace(range(2, 2), ' abc ').
250
- process
251
- end
252
-
253
- def test_replace_merge_with_overlapped_insertion
254
- assert_equal 'fo abc bar baz',
255
- @rewriter.
256
- replace(range(2, 2), ' abc ').
257
- insert_before(range(3, 1), 'abc').
258
- process
259
- end
260
-
261
- def test_replace_same_begin_larger_than_replaced_range_matching
262
- assert_equal 'foo supercalifragilistic baz',
263
- @rewriter.
264
- replace(range(4, 3), 'super').
265
- replace(range(4, 3), 'supercalifragilistic').
266
- process
267
- end
268
-
269
- def test_replace_same_begin_larger_than_replaced_range_non_matching
270
- silence_diagnostics
271
-
272
- assert_raises Parser::ClobberingError do
273
- @rewriter.
274
- replace(range(4, 3), 'super!').
275
- replace(range(4, 3), 'supercalifragilistic')
276
- end
277
- end
278
-
279
- def test_overlapping_replace_left_smaller_than_replaced_matching
280
- assert_equal 'superbaz',
281
- @rewriter.
282
- replace(range(0, 7), 'super').
283
- replace(range(2, 6), 'per').
284
- process
285
- end
286
-
287
- def test_overlapping_replace_left_smaller_than_replaced_non_matching
288
- silence_diagnostics
289
-
290
- assert_raises Parser::ClobberingError do
291
- @rewriter.
292
- replace(range(0, 7), 'super').
293
- replace(range(2, 8), 'perk')
294
- end
295
- end
296
-
297
- def test_overlapping_replace_left_larger_right_smaller_matching
298
- assert_equal 'foods baz',
299
- @rewriter.
300
- replace(range(1, 3), 'oods ').
301
- replace(range(3, 6), 'ds b').
302
- process
303
- end
304
-
305
- def test_overlapping_replace_left_larger_right_larger_matching
306
- assert_equal 'foods abcdefghijklm',
307
- @rewriter.
308
- replace(range(1, 3), 'oods ').
309
- replace(range(3, 8), 'ds abcdefghijklm').
310
- process
311
- end
312
-
313
- def test_overlapping_replace_left_larger_right_smaller_non_matching
314
- silence_diagnostics
315
-
316
- assert_raises Parser::ClobberingError do
317
- @rewriter.
318
- replace(range(1, 3), 'oods ').
319
- replace(range(3, 6), 'ds')
320
- end
321
- end
322
-
323
- def test_overlapping_replace_left_larger_right_larger_non_matching
324
- silence_diagnostics
325
-
326
- assert_raises Parser::ClobberingError do
327
- @rewriter.
328
- replace(range(1, 3), 'oods b').
329
- replace(range(3, 8), 'ds abcdefghijklm')
330
- end
331
- end
332
-
333
- def test_subsuming_replace_both_smaller_matching
334
- assert_equal 'food baz',
335
- @rewriter.
336
- replace(range(0, 7), 'food').
337
- replace(range(3, 3), 'd').
338
- process
339
- end
340
-
341
- def test_subsuming_replace_both_smaller_non_matching
342
- silence_diagnostics
343
-
344
- assert_raises Parser::ClobberingError do
345
- @rewriter.
346
- replace(range(0, 7), 'foo').
347
- replace(range(3, 3), 'd')
348
- end
349
- end
350
-
351
- def test_subsuming_replace_both_larger_matching
352
- assert_equal 'foo barr baz',
353
- @rewriter.
354
- replace(range(0, 7), 'foo barr').
355
- replace(range(3, 3), ' bar').
356
- process
357
- end
358
-
359
- def test_subsuming_replace_both_larger_non_matching
360
- silence_diagnostics
361
-
362
- assert_raises Parser::ClobberingError do
363
- @rewriter.
364
- replace(range(0, 7), 'foo barr').
365
- replace(range(3, 3), ' bar ')
366
- end
367
- end
368
-
369
- def test_replaced_ranges_merge_when_furthest_right_range_is_not_furthest_left
370
- # regression test; previously, when actions were merged, the resulting
371
- # replaced range could be too small sometimes
372
- assert_equal 'foo_***_***',
373
- @rewriter.
374
- replace(range(3, 1), '_').
375
- replace(range(7, 1), '_').
376
- replace(range(4, 7), '***_***').
377
- process
378
- end
379
-
380
- def test_clobber
381
- diagnostics = []
382
- @rewriter.diagnostics.consumer = lambda do |diag|
383
- diagnostics << diag
384
- end
385
-
386
- assert_raises Parser::ClobberingError do
387
- @rewriter.
388
- replace(range(3, 1), '---').
389
- remove(range(3, 1))
390
- end
391
-
392
- assert_equal 2, diagnostics.count
393
-
394
- assert_equal :error, diagnostics.first.level
395
- assert_equal 'cannot remove 1 character(s)',
396
- diagnostics.first.message
397
- assert_equal range(3, 1), diagnostics.first.location
398
-
399
- assert_equal :note, diagnostics.last.level
400
- assert_equal "clobbered by: replace 1 character(s) with \"---\"",
401
- diagnostics.last.message
402
- assert_equal range(3, 1), diagnostics.last.location
403
- end
404
-
405
- def test_clobbering_error_backward_compatibility
406
- silence_diagnostics
407
-
408
- rescued = false
409
-
410
- # We use begin..rescue..end here rather than #assert_raises
411
- # since #assert_raises expects exact error class.
412
- begin
413
- @rewriter.
414
- replace(range(3, 1), '---').
415
- remove(range(3, 1))
416
- rescue RuntimeError => error
417
- rescued = true if error.message.include?('clobber')
418
- end
419
-
420
- assert rescued
421
- end
422
-
423
-
424
- def test_crossing_delete
425
- assert_equal 'faz',
426
- @rewriter.
427
- remove(range(1, 4)).
428
- remove(range(6, 3)).
429
- remove(range(4, 3)).
430
- process
431
- end
432
-
433
- def test_overlapping_replace
434
- assert_equal 'flippin flyin flapjackz',
435
- @rewriter.
436
- replace(range(1, 4), 'lippin f').
437
- replace(range(4, 4), 'pin flyin flap').
438
- replace(range(7, 3), ' flyin flapjack').
439
- process
440
- end
441
-
442
- def test_subsuming_delete
443
- assert_equal 'foo',
444
- @rewriter.
445
- remove(range(6, 3)).
446
- remove(range(7, 2)).
447
- remove(range(3, 8)).
448
- process
449
- end
450
-
451
- def test_subsuming_replace
452
- assert_equal 'freebie',
453
- @rewriter.
454
- replace(range(3, 3), 'ebi').
455
- replace(range(1, 10), 'reebie').
456
- replace(range(5, 2), 'ie').
457
- process
458
- end
459
-
460
- def test_equivalent_delete_insert_replace
461
- # A deletion + insertion just before or after the deleted range is
462
- # identical in every way to a replacement! So logically, they shouldn't
463
- # conflict.
464
- assert_equal 'tin bar baz',
465
- @rewriter.
466
- remove(range(0, 3)). # ' bar baz'
467
- insert_before(range(0, 1), 'tin'). # 'tin bar baz'
468
- replace(range(0, 3), 'tin').
469
- process
470
- end
471
-
472
- def test_transaction_returns_self
473
- assert_equal @rewriter, @rewriter.transaction {}
474
- end
475
-
476
- def test_transaction_commit
477
- silence_diagnostics
478
-
479
- # Original: 'foo bar baz'
480
-
481
- # Rewrite as 'foo BAR baz'
482
- @rewriter.replace(range(4, 3), 'BAR')
483
-
484
- # Rewrite as '( bar )'
485
- @rewriter.transaction do
486
- @rewriter.replace(range(0, 3), '(')
487
- @rewriter.replace(range(8, 3), ')')
488
- end
489
-
490
- @rewriter.replace(range(3, 1), '_')
491
- @rewriter.replace(range(7, 1), '_')
492
-
493
- assert_equal '(_BAR_)', @rewriter.process
494
- end
495
-
496
- def test_transaction_rollback
497
- silence_diagnostics
498
-
499
- # Original: 'foo bar baz'
500
-
501
- # Rewrite as 'foo bar BAZ'
502
- @rewriter.replace(range(8, 3), 'BAZ')
503
-
504
- assert_raises Parser::ClobberingError do
505
- # Trying to rewrite as '( bar )', but it fails
506
- @rewriter.transaction do
507
- @rewriter.replace(range(0, 3), '(')
508
- @rewriter.replace(range(8, 3), ')')
509
- end
510
- end
511
-
512
- @rewriter.replace(range(0, 3), 'FOO')
513
-
514
- assert_equal 'FOO bar BAZ', @rewriter.process
515
- end
516
-
517
- def test_nested_transaction_raises_error
518
- error = assert_raises RuntimeError do
519
- @rewriter.transaction do
520
- @rewriter.transaction do
521
- end
522
- end
523
- end
524
-
525
- assert_match(/nested/i, error.message)
526
- end
527
-
528
- def test_process_in_transaction_raises_error
529
- error = assert_raises RuntimeError do
530
- @rewriter.transaction do
531
- @rewriter.process
532
- end
533
- end
534
-
535
- assert_match(/transaction/, error.message)
536
- end
537
-
538
- def silence_diagnostics
539
- @rewriter.diagnostics.consumer = proc {}
540
- end
541
- end