parser 2.4.0.2 → 2.5.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +5 -6
- data/CHANGELOG.md +35 -1
- data/Gemfile +2 -0
- data/README.md +1 -2
- data/Rakefile +2 -1
- data/bin/ruby-parse +2 -1
- data/bin/ruby-rewrite +2 -1
- data/lib/gauntlet_parser.rb +2 -0
- data/lib/parser.rb +16 -17
- data/lib/parser/all.rb +2 -0
- data/lib/parser/ast/node.rb +2 -0
- data/lib/parser/ast/processor.rb +2 -0
- data/lib/parser/base.rb +6 -12
- data/lib/parser/builders/default.rb +28 -47
- data/lib/parser/clobbering_error.rb +2 -0
- data/lib/parser/context.rb +42 -0
- data/lib/parser/current.rb +4 -20
- data/lib/parser/deprecation.rb +13 -0
- data/lib/parser/diagnostic.rb +3 -3
- data/lib/parser/diagnostic/engine.rb +2 -0
- data/lib/parser/lexer.rl +122 -60
- data/lib/parser/lexer/dedenter.rb +2 -0
- data/lib/parser/lexer/explanation.rb +2 -0
- data/lib/parser/lexer/literal.rb +4 -9
- data/lib/parser/lexer/stack_state.rb +4 -1
- data/lib/parser/macruby.y +32 -17
- data/lib/parser/messages.rb +14 -0
- data/lib/parser/meta.rb +2 -0
- data/lib/parser/rewriter.rb +30 -44
- data/lib/parser/ruby18.y +20 -13
- data/lib/parser/ruby19.y +32 -17
- data/lib/parser/ruby20.y +33 -18
- data/lib/parser/ruby21.y +32 -17
- data/lib/parser/ruby22.y +32 -17
- data/lib/parser/ruby23.y +32 -17
- data/lib/parser/ruby24.y +63 -46
- data/lib/parser/ruby25.y +72 -48
- data/lib/parser/rubymotion.y +33 -18
- data/lib/parser/runner.rb +4 -7
- data/lib/parser/runner/ruby_parse.rb +10 -0
- data/lib/parser/runner/ruby_rewrite.rb +2 -0
- data/lib/parser/source/buffer.rb +19 -24
- data/lib/parser/source/comment.rb +2 -0
- data/lib/parser/source/comment/associator.rb +2 -0
- data/lib/parser/source/map.rb +2 -0
- data/lib/parser/source/map/collection.rb +2 -0
- data/lib/parser/source/map/condition.rb +2 -0
- data/lib/parser/source/map/constant.rb +2 -0
- data/lib/parser/source/map/definition.rb +2 -0
- data/lib/parser/source/map/for.rb +2 -0
- data/lib/parser/source/map/heredoc.rb +2 -0
- data/lib/parser/source/map/keyword.rb +2 -0
- data/lib/parser/source/map/objc_kwarg.rb +2 -0
- data/lib/parser/source/map/operator.rb +2 -0
- data/lib/parser/source/map/rescue_body.rb +2 -0
- data/lib/parser/source/map/send.rb +2 -0
- data/lib/parser/source/map/ternary.rb +2 -0
- data/lib/parser/source/map/variable.rb +2 -0
- data/lib/parser/source/range.rb +81 -13
- data/lib/parser/source/rewriter.rb +48 -10
- data/lib/parser/source/rewriter/action.rb +2 -0
- data/lib/parser/source/tree_rewriter.rb +301 -0
- data/lib/parser/source/tree_rewriter/action.rb +133 -0
- data/lib/parser/static_environment.rb +2 -0
- data/lib/parser/syntax_error.rb +2 -0
- data/lib/parser/tree_rewriter.rb +133 -0
- data/lib/parser/version.rb +3 -1
- data/parser.gemspec +4 -1
- data/test/bug_163/fixtures/input.rb +2 -0
- data/test/bug_163/fixtures/output.rb +2 -0
- data/test/bug_163/rewriter.rb +2 -0
- data/test/helper.rb +7 -7
- data/test/parse_helper.rb +57 -10
- data/test/racc_coverage_helper.rb +2 -0
- data/test/test_base.rb +2 -0
- data/test/test_current.rb +2 -4
- data/test/test_diagnostic.rb +3 -1
- data/test/test_diagnostic_engine.rb +2 -0
- data/test/test_encoding.rb +61 -49
- data/test/test_lexer.rb +164 -77
- data/test/test_lexer_stack_state.rb +2 -0
- data/test/test_parse_helper.rb +8 -8
- data/test/test_parser.rb +613 -51
- data/test/test_runner_rewrite.rb +47 -0
- data/test/test_source_buffer.rb +22 -10
- data/test/test_source_comment.rb +2 -0
- data/test/test_source_comment_associator.rb +2 -0
- data/test/test_source_map.rb +2 -0
- data/test/test_source_range.rb +92 -45
- data/test/test_source_rewriter.rb +3 -1
- data/test/test_source_rewriter_action.rb +2 -0
- data/test/test_source_tree_rewriter.rb +177 -0
- data/test/test_static_environment.rb +2 -0
- data/test/using_tree_rewriter/fixtures/input.rb +3 -0
- data/test/using_tree_rewriter/fixtures/output.rb +3 -0
- data/test/using_tree_rewriter/using_tree_rewriter.rb +9 -0
- metadata +21 -10
- data/lib/parser/compatibility/ruby1_8.rb +0 -20
- data/lib/parser/compatibility/ruby1_9.rb +0 -32
- data/test/bug_163/test_runner_rewrite.rb +0 -35
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'pathname'
|
4
|
+
require 'fileutils'
|
5
|
+
require 'shellwords'
|
6
|
+
require 'open3'
|
7
|
+
|
8
|
+
BASE_DIR = Pathname.new(__FILE__) + '..'
|
9
|
+
require (BASE_DIR + 'helper').expand_path
|
10
|
+
|
11
|
+
class TestRunnerRewrite < Minitest::Test
|
12
|
+
def assert_rewriter_output(path, args, input: 'input.rb', output: 'output.rb', expected_output: '', expected_error: '')
|
13
|
+
@ruby_rewrite = BASE_DIR.expand_path + '../bin/ruby-rewrite'
|
14
|
+
@test_dir = BASE_DIR + path
|
15
|
+
@fixtures_dir = @test_dir + 'fixtures'
|
16
|
+
|
17
|
+
Dir.mktmpdir("parser", BASE_DIR.expand_path.to_s) do |tmp_dir|
|
18
|
+
tmp_dir = Pathname.new(tmp_dir)
|
19
|
+
sample_file = tmp_dir + "#{path}.rb"
|
20
|
+
sample_file_expanded = sample_file.expand_path
|
21
|
+
expected_file = @fixtures_dir + output
|
22
|
+
|
23
|
+
FileUtils.cp(@fixtures_dir + input, sample_file_expanded)
|
24
|
+
stdout, stderr, exit_code = Dir.chdir @test_dir do
|
25
|
+
Open3.capture3 %Q{
|
26
|
+
#{Shellwords.escape(@ruby_rewrite.to_s)} #{args} \
|
27
|
+
#{Shellwords.escape(sample_file_expanded.to_s)}
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
assert_equal expected_output.chomp, stdout.chomp
|
32
|
+
assert_match expected_error.chomp, stderr.chomp
|
33
|
+
assert_equal File.read(expected_file.expand_path), File.read(sample_file)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_rewriter_bug_163
|
38
|
+
assert_rewriter_output('bug_163',
|
39
|
+
'--modify -l rewriter.rb',
|
40
|
+
expected_error: Parser::Rewriter::DEPRECATION_WARNING
|
41
|
+
)
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_tree_rewriter
|
45
|
+
assert_rewriter_output('using_tree_rewriter', '-l using_tree_rewriter.rb --modify')
|
46
|
+
end
|
47
|
+
end
|
data/test/test_source_buffer.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'helper'
|
2
4
|
|
3
5
|
class TestSourceBuffer < Minitest::Test
|
@@ -29,17 +31,15 @@ class TestSourceBuffer < Minitest::Test
|
|
29
31
|
end
|
30
32
|
end
|
31
33
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
].join("\n")
|
39
|
-
end
|
40
|
-
|
41
|
-
assert_match /invalid byte sequence in UTF\-8/, error.message
|
34
|
+
def test_source_setter_encoding_error
|
35
|
+
error = assert_raises EncodingError do
|
36
|
+
@buffer.source = [
|
37
|
+
'# encoding: utf-8',
|
38
|
+
"# \xf9"
|
39
|
+
].join("\n")
|
42
40
|
end
|
41
|
+
|
42
|
+
assert_match /invalid byte sequence in UTF\-8/, error.message
|
43
43
|
end
|
44
44
|
|
45
45
|
def test_read
|
@@ -117,6 +117,18 @@ class TestSourceBuffer < Minitest::Test
|
|
117
117
|
end
|
118
118
|
end
|
119
119
|
|
120
|
+
def test_source_range
|
121
|
+
@buffer = Parser::Source::Buffer.new('(string)', 5)
|
122
|
+
|
123
|
+
assert_raises RuntimeError do
|
124
|
+
@buffer.source_range
|
125
|
+
end
|
126
|
+
|
127
|
+
@buffer.source = "abc\ndef\nghi\n"
|
128
|
+
|
129
|
+
assert_equal Parser::Source::Range.new(@buffer, 0, @buffer.source.size), @buffer.source_range
|
130
|
+
end
|
131
|
+
|
120
132
|
def test_last_line
|
121
133
|
@buffer.source = "1\nfoo\nbar"
|
122
134
|
assert_equal 3, @buffer.last_line
|
data/test/test_source_comment.rb
CHANGED
data/test/test_source_map.rb
CHANGED
data/test/test_source_range.rb
CHANGED
@@ -1,21 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'helper'
|
2
4
|
|
3
5
|
class TestSourceRange < Minitest::Test
|
4
6
|
def setup
|
5
7
|
@buf = Parser::Source::Buffer.new('(string)')
|
6
8
|
@buf.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)
|
7
16
|
end
|
8
17
|
|
9
18
|
def test_initialize
|
10
|
-
|
11
|
-
assert_equal
|
12
|
-
|
13
|
-
assert sr.frozen?
|
19
|
+
assert_equal 1, @sr1_3.begin_pos
|
20
|
+
assert_equal 3, @sr1_3.end_pos
|
21
|
+
assert @sr1_3.frozen?
|
14
22
|
end
|
15
23
|
|
16
24
|
def test_size
|
17
|
-
|
18
|
-
assert_equal 2, sr.size
|
25
|
+
assert_equal 4, @sr2_6.size
|
19
26
|
end
|
20
27
|
|
21
28
|
def test_bad_size
|
@@ -25,54 +32,86 @@ class TestSourceRange < Minitest::Test
|
|
25
32
|
end
|
26
33
|
|
27
34
|
def test_join
|
28
|
-
|
29
|
-
sr2 = Parser::Source::Range.new(@buf, 5, 8)
|
30
|
-
sr = sr1.join(sr2)
|
35
|
+
sr = @sr1_3.join(@sr5_8)
|
31
36
|
|
32
37
|
assert_equal 1, sr.begin_pos
|
33
38
|
assert_equal 8, sr.end_pos
|
34
39
|
end
|
35
40
|
|
36
41
|
def test_intersect
|
37
|
-
|
38
|
-
|
39
|
-
|
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
|
40
52
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
assert
|
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
|
46
77
|
end
|
47
78
|
|
48
79
|
def test_disjoint
|
49
|
-
|
50
|
-
|
51
|
-
|
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
|
52
85
|
|
53
|
-
|
54
|
-
|
55
|
-
assert !sr2.disjoint?(sr3)
|
86
|
+
def test_crossing
|
87
|
+
check_relationship(:crossing?, @sr1_3, @sr2_6)
|
56
88
|
end
|
57
89
|
|
58
|
-
def
|
59
|
-
|
60
|
-
|
61
|
-
|
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
|
62
95
|
|
63
|
-
|
64
|
-
|
65
|
-
|
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
|
66
110
|
end
|
67
111
|
|
68
112
|
def test_empty
|
69
|
-
|
70
|
-
|
71
|
-
sr3 = Parser::Source::Range.new(@buf, 7, 8)
|
72
|
-
|
73
|
-
assert !sr1.empty?
|
74
|
-
assert sr2.empty?
|
75
|
-
assert !sr3.empty?
|
113
|
+
assert !@sr1_3.empty?
|
114
|
+
assert @sr2_2.empty?
|
76
115
|
end
|
77
116
|
|
78
117
|
def test_line
|
@@ -93,15 +132,13 @@ class TestSourceRange < Minitest::Test
|
|
93
132
|
end
|
94
133
|
|
95
134
|
def test_begin_end
|
96
|
-
|
135
|
+
sr_beg = @sr2_6.begin
|
136
|
+
assert_equal 2, sr_beg.begin_pos
|
137
|
+
assert_equal 2, sr_beg.end_pos
|
97
138
|
|
98
|
-
|
99
|
-
assert_equal
|
100
|
-
assert_equal
|
101
|
-
|
102
|
-
sr_end = sr.end
|
103
|
-
assert_equal 5, sr_end.begin_pos
|
104
|
-
assert_equal 5, sr_end.end_pos
|
139
|
+
sr_end = @sr2_6.end
|
140
|
+
assert_equal 6, sr_end.begin_pos
|
141
|
+
assert_equal 6, sr_end.end_pos
|
105
142
|
end
|
106
143
|
|
107
144
|
def test_source
|
@@ -122,4 +159,14 @@ class TestSourceRange < Minitest::Test
|
|
122
159
|
sr = Parser::Source::Range.new(@buf, 8, 9)
|
123
160
|
assert_equal '(string):2:2', sr.to_s
|
124
161
|
end
|
162
|
+
|
163
|
+
def test_with
|
164
|
+
sr2 = @sr1_3.with(begin_pos: 2)
|
165
|
+
sr3 = @sr1_3.with(end_pos: 4)
|
166
|
+
|
167
|
+
assert_equal 2, sr2.begin_pos
|
168
|
+
assert_equal 3, sr2.end_pos
|
169
|
+
assert_equal 1, sr3.begin_pos
|
170
|
+
assert_equal 4, sr3.end_pos
|
171
|
+
end
|
125
172
|
end
|
@@ -1,10 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'helper'
|
2
4
|
|
3
5
|
class TestSourceRewriter < Minitest::Test
|
4
6
|
def setup
|
5
7
|
@buf = Parser::Source::Buffer.new('(rewriter)')
|
6
8
|
@buf.source = 'foo bar baz'
|
7
|
-
|
9
|
+
Parser::Source::Rewriter.warned_of_deprecation = true
|
8
10
|
@rewriter = Parser::Source::Rewriter.new(@buf)
|
9
11
|
end
|
10
12
|
|
@@ -0,0 +1,177 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'helper'
|
4
|
+
|
5
|
+
class TestSourceTreeRewriter < Minitest::Test
|
6
|
+
def setup
|
7
|
+
@buf = Parser::Source::Buffer.new('(rewriter)')
|
8
|
+
@buf.source = 'puts(:hello, :world)'
|
9
|
+
|
10
|
+
@hello = range(5, 6)
|
11
|
+
@comma_space = range(11,2)
|
12
|
+
@world = range(13,6)
|
13
|
+
end
|
14
|
+
|
15
|
+
def range(from, len)
|
16
|
+
Parser::Source::Range.new(@buf, from, from + len)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Returns either:
|
20
|
+
# - String (Normal operation)
|
21
|
+
# - [diagnostic, ...] (Diagnostics)
|
22
|
+
# - Parser::ClobberingError
|
23
|
+
#
|
24
|
+
def apply(actions, **policy)
|
25
|
+
diagnostics = []
|
26
|
+
diags = -> { diagnostics.flatten.map(&:strip).join("\n") }
|
27
|
+
rewriter = Parser::Source::TreeRewriter.new(@buf, **policy)
|
28
|
+
rewriter.diagnostics.consumer = -> diag { diagnostics << diag.render }
|
29
|
+
actions.each do |action, range, *args|
|
30
|
+
rewriter.public_send(action, range, *args)
|
31
|
+
end
|
32
|
+
if diagnostics.empty?
|
33
|
+
rewriter.process
|
34
|
+
else
|
35
|
+
diags.call
|
36
|
+
end
|
37
|
+
rescue ::Parser::ClobberingError => e
|
38
|
+
[::Parser::ClobberingError, diags.call]
|
39
|
+
end
|
40
|
+
|
41
|
+
# Expects ordered actions to be grouped together
|
42
|
+
def check_actions(expected, grouped_actions, **policy)
|
43
|
+
grouped_actions.permutation do |sequence|
|
44
|
+
# [action, [action, action]] => [action, action, action]
|
45
|
+
# except we can't use flatten because "action" are arrays themselves
|
46
|
+
actions = sequence.flat_map { |group| group.first.is_a?(Array) ? group : [group] }
|
47
|
+
assert_equal(expected, apply(actions, **policy))
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def assert_actions_result(expected, *actions, **rest)
|
52
|
+
if expected == :raise
|
53
|
+
diagnostic = rest.values.first
|
54
|
+
check_actions([::Parser::ClobberingError, diagnostic], actions)
|
55
|
+
elsif rest.empty?
|
56
|
+
check_actions(expected, actions)
|
57
|
+
else
|
58
|
+
policy, diagnostic = rest.first
|
59
|
+
check_actions(expected, actions, policy => :accept)
|
60
|
+
check_actions(diagnostic, actions, policy => :warn)
|
61
|
+
diagnostic.gsub!(/warning: /, 'error: ')
|
62
|
+
check_actions([::Parser::ClobberingError, diagnostic], actions, policy => :raise)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
### Simple cases
|
67
|
+
|
68
|
+
def test_remove
|
69
|
+
assert_actions_result 'puts(, :world)', [:remove, @hello]
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_insert_before
|
73
|
+
assert_actions_result 'puts(:hello, 42, :world)', [:insert_before, @world, '42, ']
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_insert_after
|
77
|
+
assert_actions_result 'puts(:hello, 42, :world)', [:insert_after, @hello, ', 42']
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_wrap
|
81
|
+
assert_actions_result 'puts([:hello], :world)', [:wrap, @hello, '[', ']']
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_replace
|
85
|
+
assert_actions_result 'puts(:hi, :world)', [:replace, @hello, ':hi']
|
86
|
+
end
|
87
|
+
|
88
|
+
#
|
89
|
+
# All other cases, as per doc
|
90
|
+
#
|
91
|
+
|
92
|
+
def test_crossing_non_deletions
|
93
|
+
check = [
|
94
|
+
[:wrap, '(', ')'],
|
95
|
+
[:remove],
|
96
|
+
[:replace, 'xx'],
|
97
|
+
]
|
98
|
+
check.combination(2) do |(action, *args), (action_b, *args_b)|
|
99
|
+
next if action == :remove && action_b == :remove
|
100
|
+
assert_actions_result :raise,
|
101
|
+
[[action, @hello.join(@comma_space), *args],
|
102
|
+
[action_b, @world.join(@comma_space), *args_b]],
|
103
|
+
diagnostic: <<-DIAGNOSTIC.chomp
|
104
|
+
(rewriter):1:12: error: the rewriting action on:
|
105
|
+
(rewriter):1: puts(:hello, :world)
|
106
|
+
(rewriter):1: ^~~~~~~~
|
107
|
+
(rewriter):1:6: error: is crossing that on:
|
108
|
+
(rewriter):1: puts(:hello, :world)
|
109
|
+
(rewriter):1: ^~~~~~~~
|
110
|
+
DIAGNOSTIC
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
|
115
|
+
def test_crossing_deletions
|
116
|
+
assert_actions_result 'puts()',
|
117
|
+
[[:remove, @hello.join(@comma_space)],
|
118
|
+
[:remove, @world.join(@comma_space)]],
|
119
|
+
crossing_deletions: <<-DIAGNOSTIC.chomp
|
120
|
+
(rewriter):1:12: warning: the deletion of:
|
121
|
+
(rewriter):1: puts(:hello, :world)
|
122
|
+
(rewriter):1: ^~~~~~~~
|
123
|
+
(rewriter):1:6: warning: is crossing:
|
124
|
+
(rewriter):1: puts(:hello, :world)
|
125
|
+
(rewriter):1: ^~~~~~~~
|
126
|
+
DIAGNOSTIC
|
127
|
+
end
|
128
|
+
|
129
|
+
def test_multiple_actions
|
130
|
+
assert_actions_result 'puts({:hello => [:everybody]})',
|
131
|
+
[:replace, @comma_space, ' => '],
|
132
|
+
[:wrap, @hello.join(@world), '{', '}'],
|
133
|
+
[:replace, @world, ':everybody'],
|
134
|
+
[:wrap, @world, '[', ']']
|
135
|
+
end
|
136
|
+
|
137
|
+
|
138
|
+
def test_multiple_actions
|
139
|
+
assert_actions_result 'puts({:hello => [:everybody]})',
|
140
|
+
[:replace, @comma_space, ' => '],
|
141
|
+
[:wrap, @hello.join(@world), '{', '}'],
|
142
|
+
[:replace, @world, ':everybody'],
|
143
|
+
[:wrap, @world, '[', ']']
|
144
|
+
end
|
145
|
+
|
146
|
+
def test_wraps_same_range
|
147
|
+
assert_actions_result 'puts([(:hello)], :world)',
|
148
|
+
[[:wrap, @hello, '(', ')'],
|
149
|
+
[:wrap, @hello, '[', ']']]
|
150
|
+
end
|
151
|
+
|
152
|
+
def test_replace_same_range
|
153
|
+
assert_actions_result 'puts(:hey, :world)',
|
154
|
+
[[:replace, @hello, ':hi'],
|
155
|
+
[:replace, @hello, ':hey']],
|
156
|
+
different_replacements: <<-DIAGNOSTIC.chomp
|
157
|
+
(rewriter):1:6: warning: different replacements: :hey vs :hi
|
158
|
+
(rewriter):1: puts(:hello, :world)
|
159
|
+
(rewriter):1: ^~~~~~
|
160
|
+
DIAGNOSTIC
|
161
|
+
end
|
162
|
+
|
163
|
+
def test_swallowed_insertions
|
164
|
+
assert_actions_result 'puts(:hi)',
|
165
|
+
[[:wrap, @hello.adjust(begin_pos: 1), '__', '__'],
|
166
|
+
[:replace, @world.adjust(end_pos: -2), 'xx'],
|
167
|
+
[:replace, @hello.join(@world), ':hi']],
|
168
|
+
swallowed_insertions: <<-DIAGNOSTIC.chomp
|
169
|
+
(rewriter):1:6: warning: this replacement:
|
170
|
+
(rewriter):1: puts(:hello, :world)
|
171
|
+
(rewriter):1: ^~~~~~~~~~~~~~
|
172
|
+
(rewriter):1:7: warning: swallows some inner rewriting actions:
|
173
|
+
(rewriter):1: puts(:hello, :world)
|
174
|
+
(rewriter):1: ^~~~~ ~~~~
|
175
|
+
DIAGNOSTIC
|
176
|
+
end
|
177
|
+
end
|