synvert 0.0.2 → 0.0.3
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 +4 -0
- data/README.md +2 -1
- data/lib/synvert.rb +1 -1
- data/lib/synvert/cli.rb +2 -4
- data/lib/synvert/node_ext.rb +60 -18
- data/lib/synvert/rewriter.rb +22 -33
- data/lib/synvert/rewriter/action.rb +36 -0
- data/lib/synvert/rewriter/{conditions.rb → condition.rb} +8 -18
- data/lib/synvert/rewriter/gem_spec.rb +20 -0
- data/lib/synvert/rewriter/{instances.rb → instance.rb} +20 -22
- data/lib/synvert/rewriter/{scopes.rb → scope.rb} +0 -19
- data/lib/synvert/{factory_girl → snippets/factory_girl}/syntax_methods.rb +4 -4
- data/lib/synvert/snippets/rails/upgrade_3_2_to_4_0.rb +157 -0
- data/lib/synvert/version.rb +1 -1
- data/spec/synvert/node_ext_spec.rb +30 -1
- data/spec/synvert/rewriter/action_spec.rb +26 -2
- data/spec/synvert/rewriter/condition_spec.rb +56 -0
- data/spec/synvert/rewriter/gem_spec_spec.rb +45 -0
- data/spec/synvert/rewriter/{instances_spec.rb → instance_spec.rb} +30 -21
- data/spec/synvert/rewriter/scope_spec.rb +38 -0
- data/spec/synvert/rewriter_spec.rb +21 -13
- metadata +16 -12
- data/spec/synvert/rewriter/conditions_spec.rb +0 -31
- data/spec/synvert/rewriter/scopes_spec.rb +0 -79
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ee5d52cf95df07b26f5bb50cbee385209ce3b59d
|
4
|
+
data.tar.gz: b077dd95e2e34be6c39af959ca9d9a7fc3352ecb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e3b9411dc8752fada8cd1a86eebb995d38e82fcdcc4169f6ef69941b743bbb025c3bf2e29015af3827f6d9116e7564b235f6d32ced48728ad30762e8380e389d
|
7
|
+
data.tar.gz: 372f93f527fa4d6a22c07f5b8c1bca2b178d9589df2155f1ec67b67486ea8abacd47a269ffecc9dbe931d2a45f56df2c2532fae4f2c2f78ade50cc18bbc49b5e
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
data/lib/synvert.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
require "synvert/version"
|
3
|
+
require 'bundler'
|
3
4
|
require 'parser'
|
4
5
|
require 'parser/current'
|
5
6
|
require 'ast'
|
6
7
|
require 'synvert/node_ext'
|
7
8
|
|
8
9
|
module Synvert
|
9
|
-
autoload :BaseConverter, 'synvert/base_converter'
|
10
10
|
autoload :CheckingVisitor, 'synvert/checking_visitor'
|
11
11
|
autoload :Configuration, 'synvert/configuration'
|
12
12
|
autoload :Rewriter, 'synvert/rewriter'
|
data/lib/synvert/cli.rb
CHANGED
@@ -15,10 +15,8 @@ module Synvert
|
|
15
15
|
paths = optparse.parse(args)
|
16
16
|
Configuration.instance.set :path, paths.first || Dir.pwd
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
ObjectSpace.each_object Synvert::Rewriter do |rewriter|
|
21
|
-
rewriter.process
|
18
|
+
Dir.glob(File.join(File.dirname(__FILE__), 'snippets/**/*.rb')).each do |file|
|
19
|
+
eval(File.read(file)).process
|
22
20
|
end
|
23
21
|
end
|
24
22
|
end
|
data/lib/synvert/node_ext.rb
CHANGED
@@ -29,6 +29,8 @@ class Parser::AST::Node
|
|
29
29
|
self.children[2..-1]
|
30
30
|
when :block
|
31
31
|
self.children[1].children
|
32
|
+
when :defined?
|
33
|
+
self.children
|
32
34
|
else
|
33
35
|
raise NotImplementedError.new "arguments is not handled for #{self.inspect}"
|
34
36
|
end
|
@@ -42,14 +44,40 @@ class Parser::AST::Node
|
|
42
44
|
end
|
43
45
|
end
|
44
46
|
|
47
|
+
def body
|
48
|
+
if :block == self.type
|
49
|
+
self.children[2]
|
50
|
+
else
|
51
|
+
raise NotImplementedError.new "body is not handled for #{self.inspect}"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def condition
|
56
|
+
if :if == self.type
|
57
|
+
self.children[0]
|
58
|
+
else
|
59
|
+
raise NotImplementedError.new "condition is not handled for #{self.inspect}"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def to_ast
|
64
|
+
self
|
65
|
+
end
|
66
|
+
|
45
67
|
def to_s
|
46
68
|
case self.type
|
47
69
|
when :const
|
48
70
|
self.children.compact.map(&:to_s).join('::')
|
49
71
|
when :sym
|
50
72
|
':' + self.children[0].to_s
|
51
|
-
when :str
|
73
|
+
when :str
|
74
|
+
"'" + self.children[0].to_s + "'"
|
75
|
+
when :arg, :lvar, :ivar
|
52
76
|
self.children[0].to_s
|
77
|
+
when :self
|
78
|
+
'self'
|
79
|
+
when :send
|
80
|
+
self.children[1].to_s
|
53
81
|
else
|
54
82
|
end
|
55
83
|
end
|
@@ -74,23 +102,33 @@ class Parser::AST::Node
|
|
74
102
|
end
|
75
103
|
|
76
104
|
def match?(options)
|
77
|
-
flat_hash(options).keys.all? do |
|
78
|
-
|
79
|
-
|
80
|
-
|
105
|
+
flat_hash(options).keys.all? do |multi_keys|
|
106
|
+
if multi_keys.last == :any
|
107
|
+
actual_values = actual_value(self, multi_keys[0...-1])
|
108
|
+
expected = expected_value(options, multi_keys)
|
109
|
+
actual_values.any? { |actual| match_value?(actual, expected) }
|
110
|
+
else
|
111
|
+
actual = actual_value(self, multi_keys)
|
112
|
+
expected = expected_value(options, multi_keys)
|
113
|
+
match_value?(actual, expected)
|
114
|
+
end
|
81
115
|
end
|
82
116
|
end
|
83
117
|
|
84
118
|
def to_source(code)
|
85
|
-
code.gsub(/{{(
|
86
|
-
|
87
|
-
evaluated
|
88
|
-
|
119
|
+
code.gsub(/{{(.*?)}}/m) do
|
120
|
+
evaluated = self.instance_eval $1
|
121
|
+
case evaluated
|
122
|
+
when Parser::AST::Node
|
89
123
|
source = evaluated.loc.expression.source_buffer.source
|
90
124
|
source[evaluated.loc.expression.begin_pos...evaluated.loc.expression.end_pos]
|
91
|
-
|
125
|
+
when Array
|
92
126
|
source = evaluated.first.loc.expression.source_buffer.source
|
93
127
|
source[evaluated.first.loc.expression.begin_pos...evaluated.last.loc.expression.end_pos]
|
128
|
+
when String
|
129
|
+
evaluated
|
130
|
+
else
|
131
|
+
raise NotImplementedError.new "to_source is not handled for #{evaluated.inspect}"
|
94
132
|
end
|
95
133
|
end
|
96
134
|
end
|
@@ -98,13 +136,21 @@ class Parser::AST::Node
|
|
98
136
|
private
|
99
137
|
|
100
138
|
def match_value?(actual, expected)
|
101
|
-
case
|
139
|
+
case expected
|
102
140
|
when Symbol
|
103
|
-
actual == expected
|
141
|
+
actual.to_sym == expected
|
142
|
+
when String
|
143
|
+
actual.to_s == expected || actual.to_s == "'#{expected}'"
|
144
|
+
when Regexp
|
145
|
+
actual.to_s =~ Regexp.new(expected.to_s, Regexp::MULTILINE)
|
104
146
|
when Array
|
105
147
|
actual.zip(expected).all? { |a, e| match_value?(a, e) }
|
148
|
+
when NilClass
|
149
|
+
actual.nil?
|
150
|
+
when Parser::AST::Node
|
151
|
+
actual == expected
|
106
152
|
else
|
107
|
-
|
153
|
+
raise NotImplementedError.new "#{expected.class} is not handled for match_value?"
|
108
154
|
end
|
109
155
|
end
|
110
156
|
|
@@ -121,14 +167,10 @@ private
|
|
121
167
|
end
|
122
168
|
|
123
169
|
def actual_value(node, multi_keys)
|
124
|
-
multi_keys.inject(node) { |n, key| n.send(key) }
|
170
|
+
multi_keys.inject(node) { |n, key| n.send(key) if n }
|
125
171
|
end
|
126
172
|
|
127
173
|
def expected_value(options, multi_keys)
|
128
174
|
multi_keys.inject(options) { |o, key| o[key] }
|
129
175
|
end
|
130
|
-
|
131
|
-
#def to_ast(str)
|
132
|
-
#Parser::CurrentRuby.parse(str)
|
133
|
-
#end
|
134
176
|
end
|
data/lib/synvert/rewriter.rb
CHANGED
@@ -1,56 +1,45 @@
|
|
1
1
|
module Synvert
|
2
2
|
class Rewriter
|
3
3
|
autoload :Action, 'synvert/rewriter/action'
|
4
|
-
autoload :ReplaceWithAction, 'synvert/rewriter/action'
|
5
4
|
autoload :InsertAction, 'synvert/rewriter/action'
|
5
|
+
autoload :InsertAfterAction, 'synvert/rewriter/action'
|
6
|
+
autoload :ReplaceWithAction, 'synvert/rewriter/action'
|
7
|
+
autoload :RemoveAction, 'synvert/rewriter/action'
|
8
|
+
|
9
|
+
autoload :Instance, 'synvert/rewriter/instance'
|
6
10
|
|
7
|
-
autoload :
|
11
|
+
autoload :Scope, 'synvert/rewriter/scope'
|
8
12
|
|
9
|
-
autoload :
|
10
|
-
autoload :
|
13
|
+
autoload :Condition, 'synvert/rewriter/condition'
|
14
|
+
autoload :UnlessExistCondition, 'synvert/rewriter/condition'
|
15
|
+
autoload :IfOnlyExistCondition, 'synvert/rewriter/condition'
|
11
16
|
|
12
|
-
autoload :
|
13
|
-
autoload :Condition, 'synvert/rewriter/conditions'
|
14
|
-
autoload :UnlessExistCondition, 'synvert/rewriter/conditions'
|
17
|
+
autoload :GemSpec, 'synvert/rewriter/gem_spec'
|
15
18
|
|
16
|
-
attr_reader :description
|
19
|
+
attr_reader :description
|
17
20
|
|
18
21
|
def initialize(description, &block)
|
19
22
|
@description = description
|
20
|
-
@instances =
|
23
|
+
@instances = []
|
21
24
|
instance_eval &block if block_given?
|
22
25
|
end
|
23
26
|
|
24
27
|
def process
|
25
|
-
@
|
26
|
-
|
27
|
-
|
28
|
-
def from_version(version)
|
29
|
-
@version = Version.from_string(version)
|
28
|
+
if @gem_spec.match?
|
29
|
+
@instances.each { |instance| instance.process }
|
30
|
+
end
|
30
31
|
end
|
31
32
|
|
32
|
-
def
|
33
|
-
@
|
33
|
+
def gem_spec(name, version)
|
34
|
+
@gem_spec = Rewriter::GemSpec.new(name, version)
|
34
35
|
end
|
35
36
|
|
36
|
-
def
|
37
|
-
|
37
|
+
def within_file(file_pattern, &block)
|
38
|
+
instance = Rewriter::Instance.new(file_pattern)
|
39
|
+
instance.instance_eval &block if block_given?
|
40
|
+
@instances << instance
|
38
41
|
end
|
39
42
|
|
40
|
-
|
41
|
-
def self.from_string(version)
|
42
|
-
self.new *version.split('.')
|
43
|
-
end
|
44
|
-
|
45
|
-
def initialize(major, minor, patch)
|
46
|
-
@major = major
|
47
|
-
@minor = minor
|
48
|
-
@patch = patch
|
49
|
-
end
|
50
|
-
|
51
|
-
def to_s
|
52
|
-
[@major, @minor, @patch].join('.')
|
53
|
-
end
|
54
|
-
end
|
43
|
+
alias within_files within_file
|
55
44
|
end
|
56
45
|
end
|
@@ -45,4 +45,40 @@ module Synvert
|
|
45
45
|
end
|
46
46
|
end
|
47
47
|
end
|
48
|
+
|
49
|
+
class Rewriter::InsertAfterAction < Rewriter::Action
|
50
|
+
def rewrite(source, node)
|
51
|
+
source[node.loc.expression.end_pos, 0] = "\n" + insert_indent(node) + node.to_source(@code)
|
52
|
+
source
|
53
|
+
end
|
54
|
+
|
55
|
+
def insert_indent(node)
|
56
|
+
' ' * node.indent
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
class Rewriter::RemoveAction < Rewriter::Action
|
61
|
+
def initialize
|
62
|
+
end
|
63
|
+
|
64
|
+
def rewrite(source, node)
|
65
|
+
begin_pos = node.loc.expression.begin_pos
|
66
|
+
end_pos = node.loc.expression.end_pos
|
67
|
+
line = node.loc.expression.line
|
68
|
+
source[begin_pos...end_pos] = ''
|
69
|
+
remove_code_or_whole_line(source, line)
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
def remove_code_or_whole_line(source, line)
|
74
|
+
newline_at_end_of_line = source[-1] == "\n"
|
75
|
+
source_arr = source.split("\n")
|
76
|
+
if source_arr[line - 1] && source_arr[line - 1].strip.empty?
|
77
|
+
source_arr.delete_at(line - 1)
|
78
|
+
source_arr.join("\n") + (newline_at_end_of_line ? "\n" : '')
|
79
|
+
else
|
80
|
+
source
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
48
84
|
end
|
@@ -1,24 +1,6 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
module Synvert
|
4
|
-
class Rewriter::Conditions
|
5
|
-
def initialize
|
6
|
-
@conditions = []
|
7
|
-
end
|
8
|
-
|
9
|
-
def add(condition)
|
10
|
-
@conditions << condition
|
11
|
-
end
|
12
|
-
|
13
|
-
def matching_nodes(nodes)
|
14
|
-
@conditions.each do |condition|
|
15
|
-
break if nodes.empty?
|
16
|
-
nodes = condition.matching_nodes(nodes)
|
17
|
-
end
|
18
|
-
nodes
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
4
|
class Rewriter::Condition
|
23
5
|
def initialize(options)
|
24
6
|
@options = options
|
@@ -36,4 +18,12 @@ module Synvert
|
|
36
18
|
}
|
37
19
|
end
|
38
20
|
end
|
21
|
+
|
22
|
+
class Rewriter::IfOnlyExistCondition < Rewriter::Condition
|
23
|
+
def matching_nodes(nodes)
|
24
|
+
nodes.find_all { |node|
|
25
|
+
:begin != node.body.type && node.body.match?(@options)
|
26
|
+
}
|
27
|
+
end
|
28
|
+
end
|
39
29
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Synvert
|
4
|
+
class Rewriter::GemSpec
|
5
|
+
def initialize(name, version)
|
6
|
+
@name = name
|
7
|
+
@version = Gem::Version.new version
|
8
|
+
end
|
9
|
+
|
10
|
+
def match?
|
11
|
+
gemfile_lock_path = File.join(Configuration.instance.get(:path), 'Gemfile.lock')
|
12
|
+
if File.exists? gemfile_lock_path
|
13
|
+
parser = Bundler::LockfileParser.new(File.read(gemfile_lock_path))
|
14
|
+
Gem::Version.new(parser.specs.find { |spec| spec.name == @name }.version) >= @version
|
15
|
+
else
|
16
|
+
raise LoadError.new 'Gemfile.lock does not exist'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -1,27 +1,10 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
module Synvert
|
4
|
-
class Rewriter::Instances
|
5
|
-
def initialize
|
6
|
-
@instances = []
|
7
|
-
end
|
8
|
-
|
9
|
-
def add(file_pattern, &block)
|
10
|
-
instance = Rewriter::Instance.new(file_pattern)
|
11
|
-
instance.instance_eval &block if block_given?
|
12
|
-
@instances << instance
|
13
|
-
end
|
14
|
-
|
15
|
-
def process
|
16
|
-
@instances.each { |instance| instance.process }
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
4
|
class Rewriter::Instance
|
21
5
|
def initialize(file_pattern)
|
22
6
|
@file_pattern = file_pattern
|
23
|
-
@
|
24
|
-
@conditions = Rewriter::Conditions.new
|
7
|
+
@scopes_or_conditions = []
|
25
8
|
end
|
26
9
|
|
27
10
|
def process
|
@@ -35,8 +18,10 @@ module Synvert
|
|
35
18
|
parser.reset
|
36
19
|
ast = parser.parse buffer
|
37
20
|
|
38
|
-
|
39
|
-
|
21
|
+
matching_nodes = [ast]
|
22
|
+
@scopes_or_conditions.each do |scope_or_condition|
|
23
|
+
matching_nodes = scope_or_condition.matching_nodes(matching_nodes)
|
24
|
+
end
|
40
25
|
matching_nodes.reverse.each do |node|
|
41
26
|
source = @action.rewrite(source, node)
|
42
27
|
end
|
@@ -45,14 +30,19 @@ module Synvert
|
|
45
30
|
end
|
46
31
|
|
47
32
|
def within_node(options, &block)
|
48
|
-
@
|
33
|
+
@scopes_or_conditions << Rewriter::Scope.new(options)
|
49
34
|
instance_eval &block if block_given?
|
50
35
|
end
|
51
36
|
|
52
37
|
alias with_node within_node
|
53
38
|
|
54
39
|
def unless_exist_node(options, &block)
|
55
|
-
@
|
40
|
+
@scopes_or_conditions << Rewriter::UnlessExistCondition.new(options)
|
41
|
+
instance_eval &block if block_given?
|
42
|
+
end
|
43
|
+
|
44
|
+
def if_only_exist_node(options, &block)
|
45
|
+
@scopes_or_conditions << Rewriter::IfOnlyExistCondition.new(options)
|
56
46
|
instance_eval &block if block_given?
|
57
47
|
end
|
58
48
|
|
@@ -60,8 +50,16 @@ module Synvert
|
|
60
50
|
@action = Rewriter::InsertAction.new(code)
|
61
51
|
end
|
62
52
|
|
53
|
+
def insert_after(node)
|
54
|
+
@action = Rewriter::InsertAfterAction.new(node)
|
55
|
+
end
|
56
|
+
|
63
57
|
def replace_with(code)
|
64
58
|
@action = Rewriter::ReplaceWithAction.new(code)
|
65
59
|
end
|
60
|
+
|
61
|
+
def remove
|
62
|
+
@action = Rewriter::RemoveAction.new
|
63
|
+
end
|
66
64
|
end
|
67
65
|
end
|
@@ -1,25 +1,6 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
module Synvert
|
4
|
-
class Rewriter::Scopes
|
5
|
-
def initialize
|
6
|
-
@scopes = []
|
7
|
-
end
|
8
|
-
|
9
|
-
def add(options)
|
10
|
-
@scopes << Rewriter::Scope.new(options)
|
11
|
-
end
|
12
|
-
|
13
|
-
def matching_nodes(node)
|
14
|
-
nodes = [node]
|
15
|
-
@scopes.each do |scope|
|
16
|
-
break if nodes.empty?
|
17
|
-
nodes = scope.matching_nodes(nodes)
|
18
|
-
end
|
19
|
-
nodes
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
4
|
class Rewriter::Scope
|
24
5
|
def initialize(options)
|
25
6
|
@options = options
|
@@ -1,10 +1,10 @@
|
|
1
|
-
Synvert::Rewriter.new "
|
2
|
-
|
1
|
+
Synvert::Rewriter.new "FactoryGirl uses short syntax" do
|
2
|
+
gem_spec 'factory_girl', '2.0.0'
|
3
3
|
|
4
4
|
within_file 'spec/spec_helper.rb' do
|
5
5
|
within_node type: 'block', caller: {receiver: 'RSpec', message: 'configure'} do
|
6
6
|
unless_exist_node type: 'send', message: 'include', arguments: {first: {to_s: 'FactoryGirl::Syntax::Methods'}} do
|
7
|
-
insert "{{
|
7
|
+
insert "{{self.arguments.first}}.include FactoryGirl::Syntax::Methods"
|
8
8
|
end
|
9
9
|
end
|
10
10
|
end
|
@@ -29,7 +29,7 @@ Synvert::Rewriter.new "use short syntax" do
|
|
29
29
|
%w(create build attributes_for build_stubbed create_list build_list ccreate_pair build_pair).each do |message|
|
30
30
|
within_files file_pattern do
|
31
31
|
with_node type: 'send', receiver: 'FactoryGirl', message: message do
|
32
|
-
replace_with "#{message}({{
|
32
|
+
replace_with "#{message}({{self.arguments}})"
|
33
33
|
end
|
34
34
|
end
|
35
35
|
end
|
@@ -0,0 +1,157 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
|
3
|
+
def dynamic_finder_to_hash(node, prefix)
|
4
|
+
fields = node.message.to_s[prefix.length..-1].split("_and_")
|
5
|
+
fields.length.times.map { |i|
|
6
|
+
fields[i] + ": " + node.arguments[i].to_s
|
7
|
+
}.join(", ")
|
8
|
+
end
|
9
|
+
|
10
|
+
Synvert::Rewriter.new "Upgrade from rails 3.2 to rails 4.0" do
|
11
|
+
gem_spec 'rails', '3.2.0'
|
12
|
+
|
13
|
+
within_file 'config/application.rb' do
|
14
|
+
# if defined?(Bundler)
|
15
|
+
# Bundler.require(*Rails.groups(:assets => %w(development test)))
|
16
|
+
# end
|
17
|
+
# => Bundler.require(:default, Rails.env)
|
18
|
+
with_node type: 'if', condition: {type: 'defined?', arguments: {first: 'Bundler'}} do
|
19
|
+
replace_with 'Bundler.require(:default, Rails.env)'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
within_file 'config/environments/production.rb' do
|
24
|
+
# remove config.active_record.identity_map = true
|
25
|
+
with_node type: 'send', receiver: {type: 'send', receiver: {type: 'send', message: 'config'}, message: 'active_record'}, message: 'identity_map=' do
|
26
|
+
remove
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
within_file 'app/models/**/*.rb' do
|
31
|
+
# self.serialized_attributes => self.class.serialized_attributes
|
32
|
+
with_node type: 'send', receiver: 'self', message: 'serialized_attributes' do
|
33
|
+
replace_with 'self.class.serialized_attributes'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
within_file 'app/models/**/*.rb' do
|
38
|
+
# scope :active, where(active: true) => scope :active, -> { where(active: true) }
|
39
|
+
with_node type: 'send', receiver: nil, message: 'scope' do
|
40
|
+
replace_with 'scope {{self.arguments.first}}, -> { {{self.arguments.last}} }'
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
within_file 'test/unit/**/*.rb' do
|
45
|
+
# ActiveRecord::TestCase => ActiveSupport::TestCase
|
46
|
+
with_node type: 'const', to_s: 'ActiveRecord::TestCase' do
|
47
|
+
replace_with 'ActiveSupport::TestCase'
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
within_file 'app/**/*.rb' do
|
52
|
+
# find_all_by_... => where(...)
|
53
|
+
with_node type: 'send', message: /find_all_by_(.*)/ do
|
54
|
+
hash_params = '{{find_all_by(self, "find_last_by_")}}'
|
55
|
+
replace_with "{{self.receiver}}.where(#{hash_params})"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
within_file 'app/**/*.rb' do
|
60
|
+
# find_last_by_... => where(...).last
|
61
|
+
with_node type: 'send', message: /find_last_by_(.*)/ do
|
62
|
+
hash_params = '{{dynamic_finder_to_hash(self, "find_last_by_")}}'
|
63
|
+
replace_with "{{self.receiver}}.where(#{hash_params}).last"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
within_file 'app/**/*.rb' do
|
68
|
+
# scoped_by_... => where(...)
|
69
|
+
with_node type: 'send', message: /scoped_by_(.*)/ do
|
70
|
+
hash_params = '{{dynamic_finder_to_hash(self, "scoped_by_")}}'
|
71
|
+
replace_with "{{self.receiver}}.where(#{hash_params})"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
within_file 'app/**/*.rb' do
|
76
|
+
# find_or_initialize_by_... => find_or_initialize_by(...)
|
77
|
+
with_node type: 'send', message: /find_or_initialize_by_(.*)/ do
|
78
|
+
hash_params = '{{dynamic_finder_to_hash(self, "find_or_initialize_by_")}}'
|
79
|
+
replace_with "{{self.receiver}}.find_or_initialize_by(#{hash_params})"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
within_file 'app/**/*.rb' do
|
84
|
+
# find_or_create_by_... => find_or_create_by(...)
|
85
|
+
with_node type: 'send', message: /find_or_create_by_(.*)/ do
|
86
|
+
hash_params = '{{dynamic_finder_to_hash(self, "find_or_create_by_")}}'
|
87
|
+
replace_with "{{self.receiver}}.find_or_create_by(#{hash_params})"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
within_file 'config/initializers/wrap_parameters.rb' do
|
92
|
+
# remove self.include_root_in_json = false
|
93
|
+
with_node type: 'block', caller: {receiver: 'ActiveSupport', message: 'on_load', arguments: {first: ':active_record'}} do
|
94
|
+
if_only_exist_node to_ast: Parser::CurrentRuby.parse('self.include_root_in_json = false') do
|
95
|
+
remove
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
within_file 'config/initializers/secret_token.rb' do
|
101
|
+
# insert Application.config.secret_key_base = '...'
|
102
|
+
unless_exist_node type: 'send', message: 'secret_key_base=' do
|
103
|
+
with_node type: 'send', message: 'secret_token=' do
|
104
|
+
secret = SecureRandom.hex(64)
|
105
|
+
insert_after "{{self.receiver}}.secret_key_base = '#{secret}'"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
within_file 'config/**/*.rb' do
|
111
|
+
# remove ActionController::Base.page_cache_extension => ActionController::Base.default_static_extension
|
112
|
+
with_node type: 'send', message: 'page_cache_extension=' do
|
113
|
+
replace_with 'ActionController::Base.default_static_extension = {{self.arguments}}'
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
within_file 'config/routes.rb' do
|
118
|
+
# Rack::Utils.escape('こんにちは') => 'こんにちは'
|
119
|
+
with_node type: 'send', receiver: 'Rack::Utils', message: 'escape' do
|
120
|
+
replace_with '{{self.arguments}}'
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
within_file 'config/routes.rb' do
|
125
|
+
# match "/" => "root#index" => get "/" => "root#index"
|
126
|
+
with_node type: 'send', message: 'match' do
|
127
|
+
replace_with 'get {{self.arguments}}'
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
within_file 'config/**/*.rb' do
|
132
|
+
with_node type: 'send', arguments: {any: 'ActionDispatch::BestStandardsSupport'} do
|
133
|
+
remove
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
within_file 'config/**/*.rb' do
|
138
|
+
with_node type: 'send', message: 'best_standards_support=' do
|
139
|
+
remove
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
{'ActionController::Integration' => 'ActionDispatch::Integration',
|
144
|
+
'ActionController::IntegrationTest' => 'ActionDispatch::IntegrationTest',
|
145
|
+
'ActionController::PerformanceTest' => 'ActionDispatch::PerformanceTest',
|
146
|
+
'ActionController::AbstractRequest' => 'ActionDispatch::Request',
|
147
|
+
'ActionController::Request' => 'ActionDispatch::Request',
|
148
|
+
'ActionController::AbstractResponse' => 'ActionDispatch::Response',
|
149
|
+
'ActionController::Response' => 'ActionDispatch::Response',
|
150
|
+
'ActionController::Routing' => 'ActionDispatch::Routing'}.each do |deprecated, favor|
|
151
|
+
within_file '**/*.rb' do
|
152
|
+
with_node to_s: deprecated do
|
153
|
+
replace_with favor
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
data/lib/synvert/version.rb
CHANGED
@@ -35,6 +35,11 @@ describe Parser::AST::Node do
|
|
35
35
|
node = parse('RSpec.configure do |config|; end')
|
36
36
|
expect(node.arguments.map(&:to_s)).to eq ['config']
|
37
37
|
end
|
38
|
+
|
39
|
+
it 'gets for defined? node' do
|
40
|
+
node = parse('defined?(Bundler)')
|
41
|
+
expect(node.arguments).to eq [parse('Bundler')]
|
42
|
+
end
|
38
43
|
end
|
39
44
|
|
40
45
|
describe '#caller' do
|
@@ -44,6 +49,20 @@ describe Parser::AST::Node do
|
|
44
49
|
end
|
45
50
|
end
|
46
51
|
|
52
|
+
describe '#body' do
|
53
|
+
it 'gets for block node' do
|
54
|
+
node = parse('RSpec.configure do |config|; include EmailSpec::Helpers; end')
|
55
|
+
expect(node.body).to eq parse('include EmailSpec::Helpers')
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "#condition" do
|
60
|
+
it 'gets for if node' do
|
61
|
+
node = parse('if defined?(Bundler); end')
|
62
|
+
expect(node.condition).to eq parse('defined?(Bundler)')
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
47
66
|
describe '#to_s' do
|
48
67
|
it 'gets for const node' do
|
49
68
|
node = parse('Synvert')
|
@@ -60,7 +79,7 @@ describe Parser::AST::Node do
|
|
60
79
|
|
61
80
|
it 'gets for str node' do
|
62
81
|
node = parse("'synvert'")
|
63
|
-
expect(node.to_s).to eq 'synvert'
|
82
|
+
expect(node.to_s).to eq "'synvert'"
|
64
83
|
end
|
65
84
|
|
66
85
|
it 'gets for lvar node' do
|
@@ -77,6 +96,16 @@ describe Parser::AST::Node do
|
|
77
96
|
node = parse("RSpec.configure do |config|; end").grep_node(type: 'arg')
|
78
97
|
expect(node.to_s).to eq 'config'
|
79
98
|
end
|
99
|
+
|
100
|
+
it 'gets for self node' do
|
101
|
+
node = parse('self')
|
102
|
+
expect(node.to_s).to eq 'self'
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'gets for send node' do
|
106
|
+
node = parse('email')
|
107
|
+
expect(node.to_s).to eq 'email'
|
108
|
+
end
|
80
109
|
end
|
81
110
|
|
82
111
|
describe '#indent' do
|
@@ -4,7 +4,7 @@ module Synvert
|
|
4
4
|
describe Rewriter::ReplaceWithAction do
|
5
5
|
describe '#rewrite' do
|
6
6
|
it 'replaces code' do
|
7
|
-
action = Rewriter::ReplaceWithAction.new('create_list {{
|
7
|
+
action = Rewriter::ReplaceWithAction.new('create_list {{self.arguments}}')
|
8
8
|
source = "post = FactoryGirl.create_list :post, 2"
|
9
9
|
send_node = Parser::CurrentRuby.parse(source).children[1]
|
10
10
|
output = action.rewrite(source, send_node)
|
@@ -16,7 +16,7 @@ module Synvert
|
|
16
16
|
describe Rewriter::InsertAction do
|
17
17
|
describe '#rewrite' do
|
18
18
|
it 'insert code to block node' do
|
19
|
-
action = Rewriter::InsertAction.new('{{
|
19
|
+
action = Rewriter::InsertAction.new('{{self.arguments.first}}.include FactoryGirl::Syntax::Methods')
|
20
20
|
source = "RSpec.configure do |config|\nend"
|
21
21
|
block_node = Parser::CurrentRuby.parse(source)
|
22
22
|
output = action.rewrite(source, block_node)
|
@@ -48,4 +48,28 @@ module Synvert
|
|
48
48
|
end
|
49
49
|
end
|
50
50
|
end
|
51
|
+
|
52
|
+
describe Rewriter::InsertAfterAction do
|
53
|
+
describe '#rewrite' do
|
54
|
+
it 'insert_after code' do
|
55
|
+
action = Rewriter::InsertAfterAction.new('include Bar')
|
56
|
+
source = " include Foo"
|
57
|
+
node = Parser::CurrentRuby.parse(source)
|
58
|
+
output = action.rewrite(source, node)
|
59
|
+
expect(output).to eq " include Foo\n include Bar"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe Rewriter::RemoveAction do
|
65
|
+
describe '#rewrite' do
|
66
|
+
it 'remove code' do
|
67
|
+
action = Rewriter::RemoveAction.new
|
68
|
+
source = "user = User.new params[:user]\nuser.save\nrender\n"
|
69
|
+
send_node = Parser::CurrentRuby.parse(source).children[1]
|
70
|
+
output = action.rewrite(source, send_node)
|
71
|
+
expect(output).to eq "user = User.new params[:user]\nrender\n"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
51
75
|
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Synvert
|
4
|
+
describe Rewriter::UnlessExistCondition do
|
5
|
+
let(:source) {
|
6
|
+
"""
|
7
|
+
RSpec.configure do |config|
|
8
|
+
config.include EmailSpec::Helpers
|
9
|
+
config.include EmailSpec::Methods
|
10
|
+
end
|
11
|
+
"""
|
12
|
+
}
|
13
|
+
let(:node) { Parser::CurrentRuby.parse(source) }
|
14
|
+
|
15
|
+
describe '#matching_nodes' do
|
16
|
+
it 'gets empty array if does not matchi anything' do
|
17
|
+
condition = Rewriter::UnlessExistCondition.new type: 'send', message: 'include', arguments: {first: {to_s: 'FactoryGirl::Syntax::Methods'} }
|
18
|
+
expect(condition.matching_nodes([node]).size).to eq 1
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'gets matching nodes' do
|
22
|
+
condition = Rewriter::UnlessExistCondition.new type: 'send', message: 'include', arguments: {first: {to_s: 'EmailSpec::Helpers'} }
|
23
|
+
expect(condition.matching_nodes([node])).to eq []
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe Rewriter::IfOnlyExistCondition do
|
29
|
+
describe '#matching_nodes' do
|
30
|
+
it 'gets matching nodes' do
|
31
|
+
source = """
|
32
|
+
RSpec.configure do |config|
|
33
|
+
config.include EmailSpec::Helpers
|
34
|
+
end
|
35
|
+
"""
|
36
|
+
node = Parser::CurrentRuby.parse(source)
|
37
|
+
|
38
|
+
condition = Rewriter::IfOnlyExistCondition.new type: 'send', message: 'include', arguments: {first: 'EmailSpec::Helpers'}
|
39
|
+
expect(condition.matching_nodes([node])).to eq [node]
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'gets empty array if does not match' do
|
43
|
+
source = """
|
44
|
+
RSpec.configure do |config|
|
45
|
+
config.include EmailSpec::Helpers
|
46
|
+
config.include EmailSpec::Methods
|
47
|
+
end
|
48
|
+
"""
|
49
|
+
node = Parser::CurrentRuby.parse(source)
|
50
|
+
|
51
|
+
condition = Rewriter::IfOnlyExistCondition.new type: 'send', message: 'include', arguments: {first: {to_s: 'EmailSpec::Helpers'} }
|
52
|
+
expect(condition.matching_nodes([node])).to eq []
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Synvert
|
4
|
+
describe Rewriter::GemSpec do
|
5
|
+
before { Configuration.instance.set :path, '.' }
|
6
|
+
let(:gemfile_lock_content) { """
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
ast (1.1.0)
|
11
|
+
parser (2.1.7)
|
12
|
+
ast (~> 1.1)
|
13
|
+
slop (~> 3.4, >= 3.4.5)
|
14
|
+
rake (10.1.1)
|
15
|
+
slop (3.4.7)
|
16
|
+
"""}
|
17
|
+
|
18
|
+
it 'returns true if version in Gemfile.lock is greater than definition' do
|
19
|
+
expect(File).to receive(:exists?).with('./Gemfile.lock').and_return(true)
|
20
|
+
expect(File).to receive(:read).with('./Gemfile.lock').and_return(gemfile_lock_content)
|
21
|
+
gem_spec = Rewriter::GemSpec.new('ast', '1.0.0')
|
22
|
+
expect(gem_spec).to be_match
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'returns true if version in Gemfile.lock is equal to definition' do
|
26
|
+
expect(File).to receive(:exists?).with('./Gemfile.lock').and_return(true)
|
27
|
+
expect(File).to receive(:read).with('./Gemfile.lock').and_return(gemfile_lock_content)
|
28
|
+
gem_spec = Rewriter::GemSpec.new('ast', '1.1.0')
|
29
|
+
expect(gem_spec).to be_match
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'returns false if version in Gemfile.lock is less than definition' do
|
33
|
+
expect(File).to receive(:exists?).with('./Gemfile.lock').and_return(true)
|
34
|
+
expect(File).to receive(:read).with('./Gemfile.lock').and_return(gemfile_lock_content)
|
35
|
+
gem_spec = Rewriter::GemSpec.new('ast', '1.2.0')
|
36
|
+
expect(gem_spec).not_to be_match
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'raise LoadError if Gemfile.lock does not exist' do
|
40
|
+
expect(File).to receive(:exists?).with('./Gemfile.lock').and_return(false)
|
41
|
+
gem_spec = Rewriter::GemSpec.new('ast', '1.1.0')
|
42
|
+
expect { gem_spec.match? }.to raise_error(LoadError)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -1,38 +1,34 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
module Synvert
|
4
|
-
describe Rewriter::Instances do
|
5
|
-
|
6
|
-
end
|
7
|
-
|
8
4
|
describe Rewriter::Instance do
|
9
5
|
let(:instance) { Rewriter::Instance.new('file pattern') }
|
10
6
|
|
11
|
-
describe '#
|
12
|
-
it '
|
13
|
-
|
14
|
-
instance.
|
7
|
+
describe '#insert' do
|
8
|
+
it 'sets an action' do
|
9
|
+
expect(Rewriter::InsertAction).to receive(:new).with('{{self.arguments.first}}.include FactoryGirl::Syntax::Methods')
|
10
|
+
instance.insert "{{self.arguments.first}}.include FactoryGirl::Syntax::Methods"
|
15
11
|
end
|
16
12
|
end
|
17
13
|
|
18
|
-
describe '#
|
19
|
-
it '
|
20
|
-
|
21
|
-
instance.
|
14
|
+
describe '#insert_after' do
|
15
|
+
it 'sets an action' do
|
16
|
+
expect(Rewriter::InsertAfterAction).to receive(:new).with('{{self.arguments.first}}.include FactoryGirl::Syntax::Methods')
|
17
|
+
instance.insert_after "{{self.arguments.first}}.include FactoryGirl::Syntax::Methods"
|
22
18
|
end
|
23
19
|
end
|
24
20
|
|
25
|
-
describe '#
|
21
|
+
describe '#replace_with' do
|
26
22
|
it 'sets an action' do
|
27
|
-
expect(Rewriter::
|
28
|
-
instance.
|
23
|
+
expect(Rewriter::ReplaceWithAction).to receive(:new).with('create {{self.arguments}}')
|
24
|
+
instance.replace_with 'create {{self.arguments}}'
|
29
25
|
end
|
30
26
|
end
|
31
27
|
|
32
|
-
describe '#
|
28
|
+
describe '#remove' do
|
33
29
|
it 'sets an action' do
|
34
|
-
expect(Rewriter::
|
35
|
-
instance.
|
30
|
+
expect(Rewriter::RemoveAction).to receive(:new)
|
31
|
+
instance.remove
|
36
32
|
end
|
37
33
|
end
|
38
34
|
|
@@ -42,7 +38,7 @@ module Synvert
|
|
42
38
|
it 'FactoryGirl uses short syntax' do
|
43
39
|
instance = Rewriter::Instance.new('spec/**/*_spec.rb')
|
44
40
|
instance.with_node type: 'send', receiver: 'FactoryGirl', message: 'create' do
|
45
|
-
replace_with 'create {{
|
41
|
+
replace_with 'create {{self.arguments}}'
|
46
42
|
end
|
47
43
|
input = """
|
48
44
|
it 'uses factory_girl' do
|
@@ -68,7 +64,7 @@ end
|
|
68
64
|
instance = Rewriter::Instance.new('spec/spec_helper.rb')
|
69
65
|
instance.with_node type: 'block', caller: {receiver: 'RSpec', message: 'configure'} do
|
70
66
|
unless_exist_node type: 'send', message: 'include', arguments: {first: {to_s: 'FactoryGirl::Syntax::Methods'}} do
|
71
|
-
insert "{{
|
67
|
+
insert "{{self.arguments.first}}.include FactoryGirl::Syntax::Methods"
|
72
68
|
end
|
73
69
|
end
|
74
70
|
input = """
|
@@ -90,7 +86,7 @@ end
|
|
90
86
|
instance = Rewriter::Instance.new('spec/spec_helper.rb')
|
91
87
|
instance.with_node type: 'block', caller: {receiver: 'RSpec', message: 'configure'} do
|
92
88
|
unless_exist_node type: 'send', message: 'include', arguments: {first: {to_s: 'FactoryGirl::Syntax::Methods'}} do
|
93
|
-
insert "{{
|
89
|
+
insert "{{self.arguments.first}}.include FactoryGirl::Syntax::Methods"
|
94
90
|
end
|
95
91
|
end
|
96
92
|
input = """
|
@@ -108,6 +104,19 @@ end
|
|
108
104
|
expect(File).to receive(:write).with('spec/spec_helper.rb', output)
|
109
105
|
instance.process
|
110
106
|
end
|
107
|
+
|
108
|
+
it 'process nested send nodes' do
|
109
|
+
instance = Rewriter::Instance.new('config/*.rb')
|
110
|
+
instance.with_node type: 'send', receiver: {type: 'send', receiver: {type: 'send', message: 'config'}, message: 'active_record'}, message: 'identity_map=' do
|
111
|
+
remove
|
112
|
+
end
|
113
|
+
input = 'config.active_record.identity_map = true'
|
114
|
+
output = ''
|
115
|
+
expect(Dir).to receive(:glob).with('./config/*.rb').and_return(['config/environments/production.rb'])
|
116
|
+
expect(File).to receive(:read).with('config/environments/production.rb').and_return(input)
|
117
|
+
expect(File).to receive(:write).with('config/environments/production.rb', output)
|
118
|
+
instance.process
|
119
|
+
end
|
111
120
|
end
|
112
121
|
end
|
113
122
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Synvert
|
4
|
+
describe Rewriter::Scope do
|
5
|
+
let(:source) {
|
6
|
+
"""
|
7
|
+
describe Post do
|
8
|
+
before :each do
|
9
|
+
@user = FactoryGirl.create :user
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'gets posts' do
|
13
|
+
post1 = FactoryGirl.create :post
|
14
|
+
post2 = FactoryGirl.create :post
|
15
|
+
end
|
16
|
+
end
|
17
|
+
"""
|
18
|
+
}
|
19
|
+
let(:node) { Parser::CurrentRuby.parse(source) }
|
20
|
+
|
21
|
+
describe '#matching_nodes' do
|
22
|
+
it 'gets empty array if does not match anything' do
|
23
|
+
scope = Rewriter::Scope.new type: 'send', message: 'missing'
|
24
|
+
expect(scope.matching_nodes([node])).to eq []
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'gets matching nodes' do
|
28
|
+
scope = Rewriter::Scope.new type: 'send', receiver: 'FactoryGirl', message: 'create', arguments: [':post']
|
29
|
+
expect(scope.matching_nodes([node]).size).to eq 2
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'gets matching nodes witch block caller' do
|
33
|
+
scope = Rewriter::Scope.new type: 'block', caller: {message: 'it', arguments: ['gets posts']}
|
34
|
+
expect(scope.matching_nodes([node]).size).to eq 1
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -7,24 +7,32 @@ module Synvert
|
|
7
7
|
expect(rewriter.description).to eq 'this is description'
|
8
8
|
end
|
9
9
|
|
10
|
-
it 'parses
|
11
|
-
|
12
|
-
|
10
|
+
it 'parses gem_spec' do
|
11
|
+
expect(Rewriter::GemSpec).to receive(:new).with('synvert', '1.0.0')
|
12
|
+
Rewriter.new 'description' do
|
13
|
+
gem_spec 'synvert', '1.0.0'
|
13
14
|
end
|
14
|
-
expect(rewriter.version.to_s).to eq '1.0.0'
|
15
15
|
end
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
17
|
+
describe '#process' do
|
18
|
+
it 'does nothing if gem_spec not match' do
|
19
|
+
expect_any_instance_of(Rewriter::GemSpec).to receive(:match?).and_return(false)
|
20
|
+
expect_any_instance_of(Rewriter::Instance).not_to receive(:process)
|
21
|
+
rewriter = Rewriter.new 'description' do
|
22
|
+
gem_spec 'synvert', '1.0.0'
|
23
|
+
within_file 'config/routes.rb' do; end
|
24
|
+
end
|
25
|
+
rewriter.process
|
21
26
|
end
|
22
|
-
end
|
23
27
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
+
it 'delegates process to instances' do
|
29
|
+
expect_any_instance_of(Rewriter::GemSpec).to receive(:match?).and_return(true)
|
30
|
+
expect_any_instance_of(Rewriter::Instance).to receive(:process)
|
31
|
+
rewriter = Rewriter.new 'description' do
|
32
|
+
gem_spec 'synvert', '1.0.0'
|
33
|
+
within_file 'config/routes.rb' do; end
|
34
|
+
end
|
35
|
+
rewriter.process
|
28
36
|
end
|
29
37
|
end
|
30
38
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: synvert
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Richard Huang
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-03-
|
11
|
+
date: 2014-03-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parser
|
@@ -85,21 +85,24 @@ files:
|
|
85
85
|
- lib/synvert.rb
|
86
86
|
- lib/synvert/cli.rb
|
87
87
|
- lib/synvert/configuration.rb
|
88
|
-
- lib/synvert/factory_girl/syntax_methods.rb
|
89
88
|
- lib/synvert/node_ext.rb
|
90
89
|
- lib/synvert/rewriter.rb
|
91
90
|
- lib/synvert/rewriter/action.rb
|
92
|
-
- lib/synvert/rewriter/
|
93
|
-
- lib/synvert/rewriter/
|
94
|
-
- lib/synvert/rewriter/
|
91
|
+
- lib/synvert/rewriter/condition.rb
|
92
|
+
- lib/synvert/rewriter/gem_spec.rb
|
93
|
+
- lib/synvert/rewriter/instance.rb
|
94
|
+
- lib/synvert/rewriter/scope.rb
|
95
|
+
- lib/synvert/snippets/factory_girl/syntax_methods.rb
|
96
|
+
- lib/synvert/snippets/rails/upgrade_3_2_to_4_0.rb
|
95
97
|
- lib/synvert/version.rb
|
96
98
|
- spec/spec_helper.rb
|
97
99
|
- spec/support/parser_helper.rb
|
98
100
|
- spec/synvert/node_ext_spec.rb
|
99
101
|
- spec/synvert/rewriter/action_spec.rb
|
100
|
-
- spec/synvert/rewriter/
|
101
|
-
- spec/synvert/rewriter/
|
102
|
-
- spec/synvert/rewriter/
|
102
|
+
- spec/synvert/rewriter/condition_spec.rb
|
103
|
+
- spec/synvert/rewriter/gem_spec_spec.rb
|
104
|
+
- spec/synvert/rewriter/instance_spec.rb
|
105
|
+
- spec/synvert/rewriter/scope_spec.rb
|
103
106
|
- spec/synvert/rewriter_spec.rb
|
104
107
|
- synvert.gemspec
|
105
108
|
homepage: ''
|
@@ -131,7 +134,8 @@ test_files:
|
|
131
134
|
- spec/support/parser_helper.rb
|
132
135
|
- spec/synvert/node_ext_spec.rb
|
133
136
|
- spec/synvert/rewriter/action_spec.rb
|
134
|
-
- spec/synvert/rewriter/
|
135
|
-
- spec/synvert/rewriter/
|
136
|
-
- spec/synvert/rewriter/
|
137
|
+
- spec/synvert/rewriter/condition_spec.rb
|
138
|
+
- spec/synvert/rewriter/gem_spec_spec.rb
|
139
|
+
- spec/synvert/rewriter/instance_spec.rb
|
140
|
+
- spec/synvert/rewriter/scope_spec.rb
|
137
141
|
- spec/synvert/rewriter_spec.rb
|
@@ -1,31 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module Synvert
|
4
|
-
describe Rewriter::Conditions do
|
5
|
-
|
6
|
-
end
|
7
|
-
|
8
|
-
describe Rewriter::UnlessExistCondition do
|
9
|
-
let(:source) {
|
10
|
-
"""
|
11
|
-
RSpec.configure do |config|
|
12
|
-
config.include EmailSpec::Helpers
|
13
|
-
config.include EmailSpec::Methods
|
14
|
-
end
|
15
|
-
"""
|
16
|
-
}
|
17
|
-
let(:node) { Parser::CurrentRuby.parse(source) }
|
18
|
-
|
19
|
-
describe '#matching_nodes' do
|
20
|
-
it 'gets empty array if does not matchi anything' do
|
21
|
-
condition = Rewriter::UnlessExistCondition.new type: 'send', message: 'include', arguments: {first: {to_s: 'FactoryGirl::Syntax::Methods'} }
|
22
|
-
expect(condition.matching_nodes([node]).size).to eq 1
|
23
|
-
end
|
24
|
-
|
25
|
-
it 'gets matching nodes' do
|
26
|
-
condition = Rewriter::UnlessExistCondition.new type: 'send', message: 'include', arguments: {first: {to_s: 'EmailSpec::Helpers'} }
|
27
|
-
expect(condition.matching_nodes([node])).to eq []
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
@@ -1,79 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module Synvert
|
4
|
-
describe Rewriter::Scopes do
|
5
|
-
let(:source) {
|
6
|
-
"""
|
7
|
-
describe Post do
|
8
|
-
before :each do
|
9
|
-
@user = FactoryGirl.create :user
|
10
|
-
end
|
11
|
-
|
12
|
-
it 'gets posts' do
|
13
|
-
post1 = FactoryGirl.create :post
|
14
|
-
post2 = FactoryGirl.create :post
|
15
|
-
end
|
16
|
-
end
|
17
|
-
"""
|
18
|
-
}
|
19
|
-
let(:node) { Parser::CurrentRuby.parse(source) }
|
20
|
-
|
21
|
-
before(:each) { @scopes = Rewriter::Scopes.new }
|
22
|
-
|
23
|
-
describe '#matching_nodes' do
|
24
|
-
it 'gets original node if scopes are empty' do
|
25
|
-
scoped_nodes = @scopes.matching_nodes(node)
|
26
|
-
expect(scoped_nodes).to eq [node]
|
27
|
-
end
|
28
|
-
|
29
|
-
it 'gets all matching nodes with one scope' do
|
30
|
-
@scopes.add type: 'send', receiver: 'FactoryGirl', message: 'create'
|
31
|
-
scoped_nodes = @scopes.matching_nodes(node)
|
32
|
-
expect(scoped_nodes.size).to eq 3
|
33
|
-
end
|
34
|
-
|
35
|
-
it 'gets all matching nodes with multi scopes' do
|
36
|
-
@scopes.add type: 'block', caller: {message: 'describe', arguments: ['Post']}
|
37
|
-
@scopes.add type: 'block', caller: {message: 'before', arguments: [':each']}
|
38
|
-
@scopes.add type: 'send', receiver: 'FactoryGirl', message: 'create'
|
39
|
-
scoped_nodes = @scopes.matching_nodes(node)
|
40
|
-
expect(scoped_nodes.size).to eq 1
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
describe Rewriter::Scope do
|
46
|
-
let(:source) {
|
47
|
-
"""
|
48
|
-
describe Post do
|
49
|
-
before :each do
|
50
|
-
@user = FactoryGirl.create :user
|
51
|
-
end
|
52
|
-
|
53
|
-
it 'gets posts' do
|
54
|
-
post1 = FactoryGirl.create :post
|
55
|
-
post2 = FactoryGirl.create :post
|
56
|
-
end
|
57
|
-
end
|
58
|
-
"""
|
59
|
-
}
|
60
|
-
let(:node) { Parser::CurrentRuby.parse(source) }
|
61
|
-
|
62
|
-
describe '#matching_nodes' do
|
63
|
-
it 'gets empty array if does not match anything' do
|
64
|
-
scope = Rewriter::Scope.new type: 'send', message: 'missing'
|
65
|
-
expect(scope.matching_nodes([node])).to eq []
|
66
|
-
end
|
67
|
-
|
68
|
-
it 'gets matching nodes' do
|
69
|
-
scope = Rewriter::Scope.new type: 'send', receiver: 'FactoryGirl', message: 'create', arguments: [':post']
|
70
|
-
expect(scope.matching_nodes([node]).size).to eq 2
|
71
|
-
end
|
72
|
-
|
73
|
-
it 'gets matching nodes witch block caller' do
|
74
|
-
scope = Rewriter::Scope.new type: 'block', caller: {message: 'it', arguments: ['gets posts']}
|
75
|
-
expect(scope.matching_nodes([node]).size).to eq 1
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|