synvert-core 0.58.3 → 0.61.1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +18 -5
- data/lib/synvert/core/node_ext.rb +50 -6
- data/lib/synvert/core/rewriter/action/append_action.rb +1 -1
- data/lib/synvert/core/rewriter/action/prepend_action.rb +5 -1
- data/lib/synvert/core/rewriter/instance.rb +38 -37
- data/lib/synvert/core/rewriter/scope/within_scope.rb +3 -3
- data/lib/synvert/core/rewriter.rb +3 -3
- data/lib/synvert/core/version.rb +1 -1
- data/lib/synvert/core.rb +31 -0
- data/spec/synvert/core/node_ext_spec.rb +84 -0
- data/spec/synvert/core/rewriter/action/append_action_spec.rb +21 -0
- data/spec/synvert/core/rewriter/action/prepend_action_spec.rb +84 -0
- data/spec/synvert/core/rewriter/instance_spec.rb +11 -11
- data/spec/synvert/core/rewriter/scope/within_scope_spec.rb +2 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f2496379cf2e2ab4bfd7df1466e0780965830a34601ce0e4dce0a8d23975e9a9
|
4
|
+
data.tar.gz: a59a23e473d98e05415aeb053202a4334e0527c6055b9f5f32415c0e29b3224c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 90a027ececec24e20efd6f9e35517e1557393f2f3d1831da52cac012cc953d1f387ab1cdbba779f559f48e73643d8774013b418da40d3c3ae5f33b8a361d4edc
|
7
|
+
data.tar.gz: ffa1b43ec24296c9fd3f0b684b25f80de7459f0007dd3fb157df899ecc6610b4f22a83624ad2fc5da964a685bcaef3c697e28dade547587816b4d1b010b05149
|
data/CHANGELOG.md
CHANGED
@@ -1,13 +1,26 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
-
## 0.
|
3
|
+
## 0.61.1 (2021-12-12)
|
4
4
|
|
5
|
-
*
|
6
|
-
*
|
5
|
+
* Fix prepend action for def and defs nodes
|
6
|
+
* Fix append action for def and defs nodes
|
7
|
+
|
8
|
+
## 0.61.0 (2021-12-10)
|
9
|
+
|
10
|
+
* Add `Node#child_node_by_name`
|
11
|
+
* Fix `Node#child_node_range` for array
|
7
12
|
|
8
|
-
## 0.
|
13
|
+
## 0.60.0 (2021-12-02)
|
9
14
|
|
10
|
-
*
|
15
|
+
* Add `to_string` to `sym` node
|
16
|
+
|
17
|
+
## 0.59.0 (2021-11-17)
|
18
|
+
|
19
|
+
* Use option `stop_when_match` instead of `recursive`
|
20
|
+
* Add file pattern constants
|
21
|
+
* Instance supports array of file patterns
|
22
|
+
* Return block value by `next`
|
23
|
+
* Add `Node#filename` method
|
11
24
|
|
12
25
|
## 0.58.0 (2021-10-23)
|
13
26
|
|
@@ -343,6 +343,43 @@ module Parser::AST
|
|
343
343
|
loc.expression.line
|
344
344
|
end
|
345
345
|
|
346
|
+
# Get child node by child name.
|
347
|
+
#
|
348
|
+
# @param [String] name of child node.
|
349
|
+
# @return [Parser::AST::Node] the child node.
|
350
|
+
def child_node_by_name(child_name)
|
351
|
+
direct_child_name, nested_child_name = child_name.to_s.split('.', 2)
|
352
|
+
if respond_to?(direct_child_name)
|
353
|
+
child_node = send(direct_child_name)
|
354
|
+
|
355
|
+
if nested_child_name
|
356
|
+
if child_node.is_a?(Array)
|
357
|
+
child_direct_child_name, child_nested_child_name = nested_child_name.split('.', 2)
|
358
|
+
child_direct_child_node = child_direct_child_name =~ /\A\d+\z/ ? child_node[child_direct_child_name.to_i - 1] : child_node.send(child_direct_child_name)
|
359
|
+
return child_direct_child_node.child_node_by_name(child_nested_child_name) if child_nested_child_name
|
360
|
+
return child_direct_child_node if child_direct_child_node
|
361
|
+
|
362
|
+
raise Synvert::Core::MethodNotSupported,
|
363
|
+
"child_node_by_name is not handled for #{debug_info}, child_name: #{child_name}"
|
364
|
+
end
|
365
|
+
|
366
|
+
return child_node.child_node_by_name(nested_child_name)
|
367
|
+
end
|
368
|
+
|
369
|
+
return nil if child_node.nil?
|
370
|
+
|
371
|
+
return child_node if child_node.is_a?(Parser::AST::Node)
|
372
|
+
|
373
|
+
# arguments
|
374
|
+
return nil if child_node.empty?
|
375
|
+
|
376
|
+
return child_node
|
377
|
+
end
|
378
|
+
|
379
|
+
raise Synvert::Core::MethodNotSupported,
|
380
|
+
"child_node_by_name is not handled for #{debug_info}, child_name: #{child_name}"
|
381
|
+
end
|
382
|
+
|
346
383
|
# Get the source range of child node.
|
347
384
|
#
|
348
385
|
# @param [String] name of child node.
|
@@ -382,10 +419,10 @@ module Parser::AST
|
|
382
419
|
|
383
420
|
if nested_child_name
|
384
421
|
if child_node.is_a?(Array)
|
385
|
-
child_direct_child_name,
|
386
|
-
child_direct_child_node = child_direct_child_name =~ /\A\d+\z/ ? child_node[child_direct_child_name] : child_node.send(child_direct_child_name)
|
387
|
-
if child_nested_child_name
|
388
|
-
return child_direct_child_node.child_node_range(child_nested_child_name
|
422
|
+
child_direct_child_name, child_nested_child_name = nested_child_name.split('.', 2)
|
423
|
+
child_direct_child_node = child_direct_child_name =~ /\A\d+\z/ ? child_node[child_direct_child_name.to_i - 1] : child_node.send(child_direct_child_name)
|
424
|
+
if child_nested_child_name
|
425
|
+
return child_direct_child_node.child_node_range(child_nested_child_name)
|
389
426
|
elsif child_direct_child_node
|
390
427
|
return (
|
391
428
|
Parser::Source::Range.new(
|
@@ -486,8 +523,8 @@ module Parser::AST
|
|
486
523
|
def rewritten_source(code)
|
487
524
|
code.gsub(/{{(.*?)}}/m) do
|
488
525
|
old_code = Regexp.last_match(1)
|
489
|
-
if respond_to?
|
490
|
-
evaluated =
|
526
|
+
if respond_to?(old_code.split('.').first)
|
527
|
+
evaluated = child_node_by_name(old_code)
|
491
528
|
case evaluated
|
492
529
|
when Parser::AST::Node
|
493
530
|
if evaluated.type == :args
|
@@ -552,6 +589,13 @@ module Parser::AST
|
|
552
589
|
":#{to_value}"
|
553
590
|
end
|
554
591
|
|
592
|
+
# convert symbol to string
|
593
|
+
def to_string
|
594
|
+
return to_source unless type == :sym
|
595
|
+
|
596
|
+
"#{to_value}"
|
597
|
+
end
|
598
|
+
|
555
599
|
# convert lambda {} to -> {}
|
556
600
|
def to_lambda_literal
|
557
601
|
if type == :block && caller.type == :send && caller.receiver.nil? && caller.message == :lambda
|
@@ -17,7 +17,7 @@ module Synvert::Core
|
|
17
17
|
# @param node [Parser::AST::Node]
|
18
18
|
# @return [String] n times whitesphace
|
19
19
|
def indent(node)
|
20
|
-
if %i[block class].include? node.type
|
20
|
+
if %i[block class def defs].include? node.type
|
21
21
|
' ' * (node.column + DEFAULT_INDENT)
|
22
22
|
else
|
23
23
|
' ' * node.column
|
@@ -16,6 +16,10 @@ module Synvert::Core
|
|
16
16
|
end
|
17
17
|
when :class
|
18
18
|
@node.children[1] ? @node.children[1].loc.expression.end_pos : @node.children[0].loc.expression.end_pos
|
19
|
+
when :def
|
20
|
+
@node.children[1].empty? ? @node.loc.name.end_pos : @node.children[1].loc.expression.end_pos
|
21
|
+
when :defs
|
22
|
+
@node.children[2].empty? ? @node.loc.name.end_pos : @node.children[2].loc.expression.end_pos
|
19
23
|
else
|
20
24
|
@node.children.last.loc.expression.end_pos
|
21
25
|
end
|
@@ -29,7 +33,7 @@ module Synvert::Core
|
|
29
33
|
# @param node [Parser::AST::Node]
|
30
34
|
# @return [String] n times whitesphace
|
31
35
|
def indent(node)
|
32
|
-
if %i[block class].include?
|
36
|
+
if %i[block class def defs].include?(node.type)
|
33
37
|
' ' * (node.column + DEFAULT_INDENT)
|
34
38
|
else
|
35
39
|
' ' * node.column
|
@@ -72,13 +72,13 @@ module Synvert::Core
|
|
72
72
|
# Initialize an instance.
|
73
73
|
#
|
74
74
|
# @param rewriter [Synvert::Core::Rewriter]
|
75
|
-
# @param
|
75
|
+
# @param file_patterns [Array<String>] pattern list to find files, e.g. ['spec/**/*_spec.rb']
|
76
76
|
# @param block [Block] block code to find nodes, match conditions and rewrite code.
|
77
77
|
# @return [Synvert::Core::Rewriter::Instance]
|
78
|
-
def initialize(rewriter,
|
78
|
+
def initialize(rewriter, file_patterns, &block)
|
79
79
|
@rewriter = rewriter
|
80
80
|
@actions = []
|
81
|
-
@
|
81
|
+
@file_patterns = file_patterns
|
82
82
|
@block = block
|
83
83
|
rewriter.helpers.each { |helper| singleton_class.send(:define_method, helper[:name], &helper[:block]) }
|
84
84
|
end
|
@@ -87,41 +87,42 @@ module Synvert::Core
|
|
87
87
|
# It finds all files, for each file, it executes the block code, gets all rewrite actions,
|
88
88
|
# and rewrite source code back to original file.
|
89
89
|
def process
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
begin
|
95
|
-
puts file_path if Configuration.show_run_process
|
96
|
-
conflict_actions = []
|
97
|
-
source = +self.class.file_source(file_path)
|
98
|
-
ast = self.class.file_ast(file_path)
|
99
|
-
|
100
|
-
@current_file = file_path
|
101
|
-
|
102
|
-
process_with_node ast do
|
103
|
-
begin
|
104
|
-
instance_eval(&@block)
|
105
|
-
rescue NoMethodError
|
106
|
-
puts @current_node.debug_info
|
107
|
-
raise
|
108
|
-
end
|
109
|
-
end
|
90
|
+
@file_patterns.each do |file_pattern|
|
91
|
+
Dir.glob(File.join(Configuration.path, file_pattern)).each do |file_path|
|
92
|
+
next if Configuration.skip_files.include? file_path
|
110
93
|
|
111
|
-
|
112
|
-
|
113
|
-
conflict_actions =
|
114
|
-
|
115
|
-
|
94
|
+
begin
|
95
|
+
puts file_path if Configuration.show_run_process
|
96
|
+
conflict_actions = []
|
97
|
+
source = +self.class.file_source(file_path)
|
98
|
+
ast = self.class.file_ast(file_path)
|
99
|
+
|
100
|
+
@current_file = file_path
|
101
|
+
|
102
|
+
process_with_node ast do
|
103
|
+
begin
|
104
|
+
instance_eval(&@block)
|
105
|
+
rescue NoMethodError
|
106
|
+
puts @current_node.debug_info
|
107
|
+
raise
|
108
|
+
end
|
116
109
|
end
|
117
|
-
@actions = []
|
118
110
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
111
|
+
if @actions.length > 0
|
112
|
+
@actions.sort_by! { |action| [action.begin_pos, action.end_pos] }
|
113
|
+
conflict_actions = get_conflict_actions
|
114
|
+
@actions.reverse_each do |action|
|
115
|
+
source[action.begin_pos...action.end_pos] = action.rewritten_code
|
116
|
+
end
|
117
|
+
@actions = []
|
118
|
+
|
119
|
+
update_file(file_path, source)
|
120
|
+
end
|
121
|
+
rescue Parser::SyntaxError
|
122
|
+
puts "[Warn] file #{file_path} was not parsed correctly."
|
123
|
+
# do nothing, iterate next file
|
124
|
+
end while !conflict_actions.empty?
|
125
|
+
end
|
125
126
|
end
|
126
127
|
end
|
127
128
|
|
@@ -161,10 +162,10 @@ module Synvert::Core
|
|
161
162
|
# then continue operating on each matching ast node.
|
162
163
|
#
|
163
164
|
# @param rules [Hash] rules to find mathing ast nodes.
|
164
|
-
# @param options [Hash] optional, set if
|
165
|
+
# @param options [Hash] optional, set if stop_when_match or not.
|
165
166
|
# @param block [Block] block code to continue operating on the matching nodes.
|
166
167
|
def within_node(rules, options = nil, &block)
|
167
|
-
options ||= {
|
168
|
+
options ||= { stop_when_match: false }
|
168
169
|
Rewriter::WithinScope.new(self, rules, options, &block).process
|
169
170
|
end
|
170
171
|
|
@@ -26,10 +26,10 @@ module Synvert::Core
|
|
26
26
|
matching_nodes =
|
27
27
|
if @options[:direct]
|
28
28
|
find_direct_matching_nodes(current_node)
|
29
|
-
elsif @options[:
|
30
|
-
find_recursive_matching_nodes(current_node)
|
31
|
-
else
|
29
|
+
elsif @options[:stop_when_match]
|
32
30
|
find_matching_nodes(current_node)
|
31
|
+
else
|
32
|
+
find_recursive_matching_nodes(current_node)
|
33
33
|
end
|
34
34
|
@instance.process_with_node current_node do
|
35
35
|
matching_nodes.each do |matching_node|
|
@@ -231,13 +231,13 @@ module Synvert::Core
|
|
231
231
|
# Parse within_files dsl, it finds specified files.
|
232
232
|
# It creates a [Synvert::Core::Rewriter::Instance] to rewrite code.
|
233
233
|
#
|
234
|
-
# @param
|
234
|
+
# @param file_patterns [String|Array<String>] string pattern or list of string pattern to find files, e.g. ['spec/**/*_spec.rb']
|
235
235
|
# @param block [Block] the block to rewrite code in the matching files.
|
236
|
-
def within_files(
|
236
|
+
def within_files(file_patterns, &block)
|
237
237
|
return if @sandbox
|
238
238
|
|
239
239
|
if (!@ruby_version || @ruby_version.match?) && (!@gem_spec || @gem_spec.match?)
|
240
|
-
Rewriter::Instance.new(self,
|
240
|
+
Rewriter::Instance.new(self, Array(file_patterns), &block).process
|
241
241
|
end
|
242
242
|
end
|
243
243
|
|
data/lib/synvert/core/version.rb
CHANGED
data/lib/synvert/core.rb
CHANGED
@@ -24,4 +24,35 @@ end
|
|
24
24
|
|
25
25
|
module Synvert
|
26
26
|
Rewriter = Core::Rewriter
|
27
|
+
|
28
|
+
ALL_RUBY_FILES = %w[**/*.rb]
|
29
|
+
ALL_RAKE_FILES = %w[**/*.rake]
|
30
|
+
|
31
|
+
RAILS_APP_FILES = %w[app/**/*.rb engines/*/app/**/*.rb]
|
32
|
+
RAILS_CONTROLLER_FILES = %w[app/controllers/**/*.rb engines/*/app/controllers/**/*.rb]
|
33
|
+
RAILS_JOB_FILES = %w[app/jobs/**/*.rb engines/*/app/jobs/**/*.rb]
|
34
|
+
RAILS_OBSERVER_FILES = %w[app/observers/**/*.rb engines/*/app/observers/**/*.rb]
|
35
|
+
RAILS_HELPER_FILES = %w[app/helpers/**/*.rb]
|
36
|
+
RAILS_LIB_FILES = %w[lib/**/*.rb engines/*/lib/**/*.rb]
|
37
|
+
RAILS_MAILER_FILES = %w[app/mailers/**/*.rb engines/*/app/mailers/**/*.rb]
|
38
|
+
RAILS_MIGRATION_FILES = %w[db/migrate/**/*.rb engines/*/db/migrate/**/*.rb]
|
39
|
+
RAILS_MODEL_FILES = %w[app/models/**/*.rb engines/*/app/models/**/*.rb]
|
40
|
+
RAILS_ROUTE_FILES = %w[config/routes.rb config/routes/**/*.rb engines/*/config/routes.rb engines/*/config/routes/**/*.rb]
|
41
|
+
RAILS_VIEW_FILES = %w[app/views/**/*.html.{erb,haml,slim}]
|
42
|
+
|
43
|
+
RAILS_CONTROLLER_TEST_FILES = %w[
|
44
|
+
test/functional/**/*.rb test/controllers/**/*.rb engines/*/test/functional/**/*.rb engines/*/test/controllers/**/*.rb
|
45
|
+
spec/functional/**/*.rb spec/controllers/**/*.rb engines/*/spec/functional/**/*.rb engines/*/spec/controllers/**/*.rb
|
46
|
+
]
|
47
|
+
RAILS_INTEGRATION_TEST_FILES = %w[test/integration/**/*.rb spec/integration/**/*.rb]
|
48
|
+
RAILS_MODEL_TEST_FILES = %w[
|
49
|
+
test/unit/**/*.rb engines/*/test/unit/**/*.rb test/models/**/*.rb engines/*/test/models/**/*.rb
|
50
|
+
spec/models/**/*.rb engines/*/spec/models/**/*.rb
|
51
|
+
]
|
52
|
+
|
53
|
+
RAILS_FACTORY_FILES = %w[test/factories/**/*.rb spec/factories/**/*.rb]
|
54
|
+
RAILS_RSPEC_FILES = %w[spec/**/*.rb engines/*/spec/**/*.rb]
|
55
|
+
RAILS_MINITEST_FILES = %w[test/**/*.rb engines/*/test/**/*.rb]
|
56
|
+
RAILS_CUCUMBER_FILES = %w[features/**/*.rb]
|
57
|
+
RAILS_TEST_FILES = RAILS_MINITEST_FILES + RAILS_RSPEC_FILES + RAILS_CUCUMBER_FILES
|
27
58
|
end
|
@@ -554,6 +554,54 @@ describe Parser::AST::Node do
|
|
554
554
|
end
|
555
555
|
end
|
556
556
|
|
557
|
+
describe '#child_node_by_name' do
|
558
|
+
context 'block node' do
|
559
|
+
it 'checks caller' do
|
560
|
+
node = parse('Factory.define :user do |user|; end')
|
561
|
+
child_node = node.child_node_by_name(:caller)
|
562
|
+
expect(child_node).to eq node.caller
|
563
|
+
end
|
564
|
+
|
565
|
+
it 'checks arguments' do
|
566
|
+
node = parse('Factory.define :user do |user|; end')
|
567
|
+
child_node = node.child_node_by_name(:arguments)
|
568
|
+
expect(child_node).to eq node.arguments
|
569
|
+
end
|
570
|
+
|
571
|
+
it 'checks caller.receiver' do
|
572
|
+
node = parse('Factory.define :user do |user|; end')
|
573
|
+
child_node = node.child_node_by_name('caller.receiver')
|
574
|
+
expect(child_node).to eq node.caller.receiver
|
575
|
+
end
|
576
|
+
|
577
|
+
it 'checks caller.message' do
|
578
|
+
node = parse('Factory.define :user do |user|; end')
|
579
|
+
child_node = node.child_node_by_name('caller.message')
|
580
|
+
expect(child_node).to eq node.caller.message
|
581
|
+
end
|
582
|
+
end
|
583
|
+
|
584
|
+
context 'array' do
|
585
|
+
it 'checks array by index' do
|
586
|
+
node = parse('factory :admin, class: User do; end')
|
587
|
+
child_node = node.child_node_by_name('caller.arguments.2')
|
588
|
+
expect(child_node).to eq node.caller.arguments[1]
|
589
|
+
end
|
590
|
+
|
591
|
+
it 'checks array by method' do
|
592
|
+
node = parse('factory :admin, class: User do; end')
|
593
|
+
child_node = node.child_node_by_name('caller.arguments.second')
|
594
|
+
expect(child_node).to eq node.caller.arguments[1]
|
595
|
+
end
|
596
|
+
|
597
|
+
it "checks array' value" do
|
598
|
+
node = parse('factory :admin, class: User do; end')
|
599
|
+
child_node = node.child_node_by_name('caller.arguments.second.class_value')
|
600
|
+
expect(child_node).to eq node.caller.arguments[1].class_value
|
601
|
+
end
|
602
|
+
end
|
603
|
+
end
|
604
|
+
|
557
605
|
describe '#child_node_range' do
|
558
606
|
context 'block node' do
|
559
607
|
it 'checks caller' do
|
@@ -720,6 +768,26 @@ describe Parser::AST::Node do
|
|
720
768
|
expect(range).to be_nil
|
721
769
|
end
|
722
770
|
end
|
771
|
+
|
772
|
+
context 'array' do
|
773
|
+
it 'checks array by index' do
|
774
|
+
node = parse('factory :admin, class: User do; end')
|
775
|
+
range = node.child_node_range('caller.arguments.2')
|
776
|
+
expect(range.to_range).to eq(16...27)
|
777
|
+
end
|
778
|
+
|
779
|
+
it 'checks array by method' do
|
780
|
+
node = parse('factory :admin, class: User do; end')
|
781
|
+
range = node.child_node_range('caller.arguments.second')
|
782
|
+
expect(range.to_range).to eq(16...27)
|
783
|
+
end
|
784
|
+
|
785
|
+
it "checks array' value" do
|
786
|
+
node = parse('factory :admin, class: User do; end')
|
787
|
+
range = node.child_node_range('caller.arguments.second.class_value')
|
788
|
+
expect(range.to_range).to eq(23...27)
|
789
|
+
end
|
790
|
+
end
|
723
791
|
end
|
724
792
|
|
725
793
|
describe '#rewritten_source' do
|
@@ -827,6 +895,22 @@ describe Parser::AST::Node do
|
|
827
895
|
end
|
828
896
|
end
|
829
897
|
|
898
|
+
describe '#to_string' do
|
899
|
+
context 'sym node' do
|
900
|
+
it 'converts symbol to string' do
|
901
|
+
node = parse(':foobar')
|
902
|
+
expect(node.to_string).to eq 'foobar'
|
903
|
+
end
|
904
|
+
end
|
905
|
+
|
906
|
+
context 'other node' do
|
907
|
+
it 'does nothing' do
|
908
|
+
node = parse("'foobar'")
|
909
|
+
expect(node.to_string).to eq "'foobar'"
|
910
|
+
end
|
911
|
+
end
|
912
|
+
end
|
913
|
+
|
830
914
|
describe '#to_lambda_literal' do
|
831
915
|
context 'lambda node' do
|
832
916
|
it 'converts to lambda literal without arguments' do
|
@@ -45,5 +45,26 @@ module Synvert::Core
|
|
45
45
|
expect(subject.rewritten_code).to eq "\ngem 'twitter'"
|
46
46
|
end
|
47
47
|
end
|
48
|
+
|
49
|
+
describe 'def node' do
|
50
|
+
subject do
|
51
|
+
source = "def teardown\n do_something\nend"
|
52
|
+
class_node = Parser::CurrentRuby.parse(source)
|
53
|
+
instance = double(current_node: class_node)
|
54
|
+
Rewriter::AppendAction.new(instance, 'super').process
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'gets begin_pos' do
|
58
|
+
expect(subject.begin_pos).to eq "def teardown\n do_something".length
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'gets end_pos' do
|
62
|
+
expect(subject.end_pos).to eq "def teardown\n do_something".length
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'gets rewritten_code' do
|
66
|
+
expect(subject.rewritten_code).to eq "\n super"
|
67
|
+
end
|
68
|
+
end
|
48
69
|
end
|
49
70
|
end
|
@@ -87,5 +87,89 @@ module Synvert::Core
|
|
87
87
|
expect(subject.rewritten_code).to eq "\n include Deletable"
|
88
88
|
end
|
89
89
|
end
|
90
|
+
|
91
|
+
describe 'def node without args' do
|
92
|
+
subject do
|
93
|
+
source = "def setup\n do_something\nend"
|
94
|
+
def_node = Parser::CurrentRuby.parse(source)
|
95
|
+
instance = double(current_node: def_node)
|
96
|
+
Rewriter::PrependAction.new(instance, 'super').process
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'gets begin_pos' do
|
100
|
+
expect(subject.begin_pos).to eq 'def setup'.length
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'gets end_pos' do
|
104
|
+
expect(subject.end_pos).to eq 'def setup'.length
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'gets rewritten_code' do
|
108
|
+
expect(subject.rewritten_code).to eq "\n super"
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
describe 'def node with args' do
|
113
|
+
subject do
|
114
|
+
source = "def setup(foobar)\n do_something\nend"
|
115
|
+
def_node = Parser::CurrentRuby.parse(source)
|
116
|
+
instance = double(current_node: def_node)
|
117
|
+
Rewriter::PrependAction.new(instance, 'super').process
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'gets begin_pos' do
|
121
|
+
expect(subject.begin_pos).to eq 'def setup(foobar)'.length
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'gets end_pos' do
|
125
|
+
expect(subject.end_pos).to eq 'def setup(foobar)'.length
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'gets rewritten_code' do
|
129
|
+
expect(subject.rewritten_code).to eq "\n super"
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
describe 'defs node without args' do
|
134
|
+
subject do
|
135
|
+
source = "def self.foo\n do_something\nend"
|
136
|
+
def_node = Parser::CurrentRuby.parse(source)
|
137
|
+
instance = double(current_node: def_node)
|
138
|
+
Rewriter::PrependAction.new(instance, 'do_something_first').process
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'gets begin_pos' do
|
142
|
+
expect(subject.begin_pos).to eq 'def self.foo'.length
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'gets end_pos' do
|
146
|
+
expect(subject.end_pos).to eq 'def self.foo'.length
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'gets rewritten_code' do
|
150
|
+
expect(subject.rewritten_code).to eq "\n do_something_first"
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
describe 'defs node with args' do
|
155
|
+
subject do
|
156
|
+
source = "def self.foo(bar)\n do_something\nend"
|
157
|
+
def_node = Parser::CurrentRuby.parse(source)
|
158
|
+
instance = double(current_node: def_node)
|
159
|
+
Rewriter::PrependAction.new(instance, 'do_something_first').process
|
160
|
+
end
|
161
|
+
|
162
|
+
it 'gets begin_pos' do
|
163
|
+
expect(subject.begin_pos).to eq 'def self.foo(bar)'.length
|
164
|
+
end
|
165
|
+
|
166
|
+
it 'gets end_pos' do
|
167
|
+
expect(subject.end_pos).to eq 'def self.foo(bar)'.length
|
168
|
+
end
|
169
|
+
|
170
|
+
it 'gets rewritten_code' do
|
171
|
+
expect(subject.rewritten_code).to eq "\n do_something_first"
|
172
|
+
end
|
173
|
+
end
|
90
174
|
end
|
91
175
|
end
|
@@ -8,14 +8,14 @@ module Synvert::Core
|
|
8
8
|
|
9
9
|
let(:instance) {
|
10
10
|
rewriter = Rewriter.new('foo', 'bar')
|
11
|
-
Rewriter::Instance.new(rewriter, 'file pattern')
|
11
|
+
Rewriter::Instance.new(rewriter, ['file pattern'])
|
12
12
|
}
|
13
13
|
|
14
14
|
it 'parses within_node' do
|
15
15
|
scope = double
|
16
16
|
block = proc {}
|
17
17
|
expect(Rewriter::WithinScope).to receive(:new)
|
18
|
-
.with(instance, { type: 'send', message: 'create' }, {
|
18
|
+
.with(instance, { type: 'send', message: 'create' }, { stop_when_match: false }, &block)
|
19
19
|
.and_return(scope)
|
20
20
|
expect(scope).to receive(:process)
|
21
21
|
instance.within_node(type: 'send', message: 'create', &block)
|
@@ -25,7 +25,7 @@ module Synvert::Core
|
|
25
25
|
scope = double
|
26
26
|
block = proc {}
|
27
27
|
expect(Rewriter::WithinScope).to receive(:new)
|
28
|
-
.with(instance, { type: 'send', message: 'create' }, {
|
28
|
+
.with(instance, { type: 'send', message: 'create' }, { stop_when_match: false }, &block)
|
29
29
|
.and_return(scope)
|
30
30
|
expect(scope).to receive(:process)
|
31
31
|
instance.with_node(type: 'send', message: 'create', &block)
|
@@ -35,10 +35,10 @@ module Synvert::Core
|
|
35
35
|
scope = double
|
36
36
|
block = proc {}
|
37
37
|
expect(Rewriter::WithinScope).to receive(:new)
|
38
|
-
.with(instance, { type: 'send', message: 'create' }, {
|
38
|
+
.with(instance, { type: 'send', message: 'create' }, { stop_when_match: true }, &block)
|
39
39
|
.and_return(scope)
|
40
40
|
expect(scope).to receive(:process)
|
41
|
-
instance.within_node({ type: 'send', message: 'create' }, {
|
41
|
+
instance.within_node({ type: 'send', message: 'create' }, { stop_when_match: true }, &block)
|
42
42
|
end
|
43
43
|
|
44
44
|
it 'parses within_direct_node' do
|
@@ -185,7 +185,7 @@ module Synvert::Core
|
|
185
185
|
|
186
186
|
it 'writes new code to file' do
|
187
187
|
instance =
|
188
|
-
Rewriter::Instance.new rewriter, 'spec/**/*_spec.rb' do
|
188
|
+
Rewriter::Instance.new rewriter, ['spec/**/*_spec.rb'] do
|
189
189
|
with_node type: 'send', receiver: 'FactoryGirl', message: 'create' do
|
190
190
|
replace_with 'create {{arguments}}'
|
191
191
|
end
|
@@ -212,7 +212,7 @@ module Synvert::Core
|
|
212
212
|
|
213
213
|
it 'does not write if file content is not changed' do
|
214
214
|
instance =
|
215
|
-
Rewriter::Instance.new rewriter, 'spec/spec_helper.rb' do
|
215
|
+
Rewriter::Instance.new rewriter, ['spec/spec_helper.rb'] do
|
216
216
|
with_node type: 'block', caller: { receiver: 'RSpec', message: 'configure' } do
|
217
217
|
unless_exist_node type: 'send', message: 'include', arguments: ['FactoryGirl::Syntax::Methods'] do
|
218
218
|
insert '{{arguments.first}}.include FactoryGirl::Syntax::Methods'
|
@@ -237,7 +237,7 @@ module Synvert::Core
|
|
237
237
|
|
238
238
|
it 'does not read file if already read' do
|
239
239
|
instance =
|
240
|
-
Rewriter::Instance.new rewriter, 'spec/spec_helper.rb' do
|
240
|
+
Rewriter::Instance.new rewriter, ['spec/spec_helper.rb'] do
|
241
241
|
with_node type: 'block', caller: { receiver: 'RSpec', message: 'configure' } do
|
242
242
|
unless_exist_node type: 'send', message: 'include', arguments: ['FactoryGirl::Syntax::Methods'] do
|
243
243
|
insert '{{arguments.first}}.include FactoryGirl::Syntax::Methods'
|
@@ -263,7 +263,7 @@ module Synvert::Core
|
|
263
263
|
|
264
264
|
it 'updates file_source and file_ast when writing a file' do
|
265
265
|
instance =
|
266
|
-
Rewriter::Instance.new rewriter, 'spec/**/*_spec.rb' do
|
266
|
+
Rewriter::Instance.new rewriter, ['spec/**/*_spec.rb'] do
|
267
267
|
with_node type: 'send', receiver: 'FactoryGirl', message: 'create' do
|
268
268
|
replace_with 'create {{arguments}}'
|
269
269
|
end
|
@@ -299,7 +299,7 @@ module Synvert::Core
|
|
299
299
|
action1 = double(begin_pos: 10, end_pos: 20)
|
300
300
|
action2 = double(begin_pos: 30, end_pos: 40)
|
301
301
|
action3 = double(begin_pos: 50, end_pos: 60)
|
302
|
-
instance = Rewriter::Instance.new rewriter, 'spec/spec_helper.rb'
|
302
|
+
instance = Rewriter::Instance.new rewriter, ['spec/spec_helper.rb']
|
303
303
|
instance.instance_variable_set :@actions, [action1, action2, action3]
|
304
304
|
conflict_actions = instance.send(:get_conflict_actions)
|
305
305
|
expect(conflict_actions).to eq []
|
@@ -310,7 +310,7 @@ module Synvert::Core
|
|
310
310
|
action1 = double(begin_pos: 30, end_pos: 40)
|
311
311
|
action2 = double(begin_pos: 50, end_pos: 60)
|
312
312
|
action3 = double(begin_pos: 10, end_pos: 20)
|
313
|
-
instance = Rewriter::Instance.new rewriter, 'spec/spec_helper.rb'
|
313
|
+
instance = Rewriter::Instance.new rewriter, ['spec/spec_helper.rb']
|
314
314
|
instance.instance_variable_set :@actions, [action1, action2, action3]
|
315
315
|
conflict_actions = instance.send(:get_conflict_actions)
|
316
316
|
expect(conflict_actions).to eq [action2, action1]
|
@@ -54,7 +54,7 @@ module Synvert::Core
|
|
54
54
|
|
55
55
|
it 'matches multiple block nodes' do
|
56
56
|
block_nodes = []
|
57
|
-
scope = Rewriter::WithinScope.new(instance, { type: 'block' }, {
|
57
|
+
scope = Rewriter::WithinScope.new(instance, { type: 'block' }, { stop_when_match: false }) do
|
58
58
|
block_nodes << node
|
59
59
|
end
|
60
60
|
scope.process
|
@@ -63,7 +63,7 @@ module Synvert::Core
|
|
63
63
|
|
64
64
|
it 'matches only one block node if no recursive' do
|
65
65
|
block_nodes = []
|
66
|
-
scope = Rewriter::WithinScope.new(instance, { type: 'block' } , {
|
66
|
+
scope = Rewriter::WithinScope.new(instance, { type: 'block' } , { stop_when_match: true }) do
|
67
67
|
block_nodes << node
|
68
68
|
end
|
69
69
|
scope.process
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: synvert-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.61.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Richard Huang
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-12-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|