synvert-core 0.1.0

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.
@@ -0,0 +1,225 @@
1
+ require 'spec_helper'
2
+
3
+ module Synvert::Core
4
+ describe Rewriter::ReplaceWithAction do
5
+ context "replace with single line" do
6
+ subject {
7
+ source = "post = FactoryGirl.create_list :post, 2"
8
+ send_node = Parser::CurrentRuby.parse(source).children[1]
9
+ instance = double(:current_node => send_node)
10
+ Rewriter::ReplaceWithAction.new(instance, 'create_list {{arguments}}')
11
+ }
12
+
13
+ it 'gets begin_pos' do
14
+ expect(subject.begin_pos).to eq "post = ".length
15
+ end
16
+
17
+ it 'gets end_pos' do
18
+ expect(subject.end_pos).to eq "post = FactoryGirl.create_list :post, 2".length
19
+ end
20
+
21
+ it 'gets rewritten_code' do
22
+ expect(subject.rewritten_code).to eq 'create_list :post, 2'
23
+ end
24
+ end
25
+
26
+ context "#replace with multiple line" do
27
+ subject {
28
+ source = " its(:size) { should == 1 }"
29
+ send_node = Parser::CurrentRuby.parse(source)
30
+ instance = double(:current_node => send_node)
31
+ Rewriter::ReplaceWithAction.new(instance, """describe '#size' do
32
+ subject { super().size }
33
+ it { {{body}} }
34
+ end""")
35
+ }
36
+
37
+ it 'gets begin_pos' do
38
+ expect(subject.begin_pos).to eq 2
39
+ end
40
+
41
+ it 'gets end_pos' do
42
+ expect(subject.end_pos).to eq " its(:size) { should == 1 }".length
43
+ end
44
+
45
+ it 'gets rewritten_code' do
46
+ expect(subject.rewritten_code).to eq """\n\n describe '#size' do
47
+ subject { super().size }
48
+ it { should == 1 }
49
+ end"""
50
+ end
51
+ end
52
+ end
53
+
54
+ describe Rewriter::AppendAction < Rewriter::Action do
55
+ describe 'class node' do
56
+ subject do
57
+ source = "class User\n has_many :posts\nend"
58
+ class_node = Parser::CurrentRuby.parse(source)
59
+ instance = double(:current_node => class_node)
60
+ Rewriter::AppendAction.new(instance, "def as_json\n super\nend")
61
+ end
62
+
63
+ it 'gets begin_pos' do
64
+ expect(subject.begin_pos).to eq "calss User\n has_many :posts".length
65
+ end
66
+
67
+ it 'gets end_pos' do
68
+ expect(subject.end_pos).to eq "class User\n has_many :posts".length
69
+ end
70
+
71
+ it 'gets rewritten_code' do
72
+ expect(subject.rewritten_code).to eq "\n\n def as_json\n super\n end"
73
+ end
74
+ end
75
+
76
+ describe 'begin node' do
77
+ subject do
78
+ source = "gem 'rails'\ngem 'mysql2'"
79
+ begin_node = Parser::CurrentRuby.parse(source)
80
+ instance = double(:current_node => begin_node)
81
+ Rewriter::AppendAction.new(instance, "gem 'twitter'")
82
+ end
83
+
84
+ it 'gets begin_pos' do
85
+ expect(subject.begin_pos).to eq "gem 'rails'\ngem 'mysql2'".length
86
+ end
87
+
88
+ it 'gets end_pos' do
89
+ expect(subject.end_pos).to eq "gem 'rails'\ngem 'mysql2'".length
90
+ end
91
+
92
+ it 'gets rewritten_code' do
93
+ expect(subject.rewritten_code).to eq "\ngem 'twitter'"
94
+ end
95
+ end
96
+ end
97
+
98
+ describe Rewriter::InsertAction do
99
+ describe 'block node without args' do
100
+ subject {
101
+ source = "Synvert::Application.configure do\nend"
102
+ block_node = Parser::CurrentRuby.parse(source)
103
+ instance = double(:current_node => block_node)
104
+ Rewriter::InsertAction.new(instance, 'config.eager_load = true')
105
+ }
106
+
107
+ it 'gets begin_pos' do
108
+ expect(subject.begin_pos).to eq "Synvert::Application.configure do".length
109
+ end
110
+
111
+ it 'gets end_pos' do
112
+ expect(subject.end_pos).to eq "Synvert::Application.configure do".length
113
+ end
114
+
115
+ it 'gets rewritten_code' do
116
+ expect(subject.rewritten_code).to eq "\n config.eager_load = true"
117
+ end
118
+ end
119
+
120
+ describe 'block node with args' do
121
+ subject {
122
+ source = "RSpec.configure do |config|\nend"
123
+ block_node = Parser::CurrentRuby.parse(source)
124
+ instance = double(:current_node => block_node)
125
+ Rewriter::InsertAction.new(instance, '{{arguments.first}}.include FactoryGirl::Syntax::Methods')
126
+ }
127
+
128
+ it 'gets begin_pos' do
129
+ expect(subject.begin_pos).to eq "RSpec.configure do |config|".length
130
+ end
131
+
132
+ it 'gets end_pos' do
133
+ expect(subject.end_pos).to eq "RSpec.configure do |config|".length
134
+ end
135
+
136
+ it 'gets rewritten_code' do
137
+ expect(subject.rewritten_code).to eq "\n config.include FactoryGirl::Syntax::Methods"
138
+ end
139
+ end
140
+
141
+ describe 'class node without superclass' do
142
+ subject {
143
+ source = "class User\n has_many :posts\nend"
144
+ class_node = Parser::CurrentRuby.parse(source)
145
+ instance = double(:current_node => class_node)
146
+ Rewriter::InsertAction.new(instance, 'include Deletable')
147
+ }
148
+
149
+ it 'gets begin_pos' do
150
+ expect(subject.begin_pos).to eq "class User".length
151
+ end
152
+
153
+ it 'gets end_pos' do
154
+ expect(subject.end_pos).to eq "class User".length
155
+ end
156
+
157
+ it 'gets rewritten_code' do
158
+ expect(subject.rewritten_code).to eq "\n include Deletable"
159
+ end
160
+ end
161
+
162
+ describe 'class node with superclass' do
163
+ subject {
164
+ source = "class User < ActiveRecord::Base\n has_many :posts\nend"
165
+ class_node = Parser::CurrentRuby.parse(source)
166
+ instance = double(:current_node => class_node)
167
+ Rewriter::InsertAction.new(instance, 'include Deletable')
168
+ }
169
+
170
+ it 'gets begin_pos' do
171
+ expect(subject.begin_pos).to eq "class User < ActionRecord::Base".length
172
+ end
173
+
174
+ it 'gets end_pos' do
175
+ expect(subject.end_pos).to eq "class User < ActionRecord::Base".length
176
+ end
177
+
178
+ it 'gets rewritten_code' do
179
+ expect(subject.rewritten_code).to eq "\n include Deletable"
180
+ end
181
+ end
182
+ end
183
+
184
+ describe Rewriter::InsertAfterAction do
185
+ subject {
186
+ source = " include Foo"
187
+ node = Parser::CurrentRuby.parse(source)
188
+ instance = double(:current_node => node)
189
+ Rewriter::InsertAfterAction.new(instance, 'include Bar')
190
+ }
191
+
192
+ it 'gets begin_pos' do
193
+ expect(subject.begin_pos).to eq " include Foo".length
194
+ end
195
+
196
+ it 'gets end_pos' do
197
+ expect(subject.end_pos).to eq " include Foo".length
198
+ end
199
+
200
+ it 'gets rewritten_code' do
201
+ expect(subject.rewritten_code).to eq "\n include Bar"
202
+ end
203
+ end
204
+
205
+ describe Rewriter::RemoveAction do
206
+ subject {
207
+ source = "user = User.new params[:user]\nuser.save\nrender\n"
208
+ send_node = Parser::CurrentRuby.parse(source).children[1]
209
+ instance = double(:current_node => send_node)
210
+ Rewriter::RemoveAction.new(instance)
211
+ }
212
+
213
+ it 'gets begin_pos' do
214
+ expect(subject.begin_pos).to eq "user = User.new params[:user]\n".length
215
+ end
216
+
217
+ it 'gets end_pos' do
218
+ expect(subject.end_pos).to eq "user = User.new params[:user]\nuser.save".length
219
+ end
220
+
221
+ it 'gets rewritten_code' do
222
+ expect(subject.rewritten_code).to eq ""
223
+ end
224
+ end
225
+ end
@@ -0,0 +1,106 @@
1
+ require 'spec_helper'
2
+
3
+ module Synvert::Core
4
+ describe Rewriter::IfExistCondition 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
+ let(:instance) { double(:current_node => node, :current_source => source) }
15
+
16
+ describe '#process' do
17
+ it 'call block if match anything' do
18
+ run = false
19
+ condition = Rewriter::IfExistCondition.new instance, type: 'send', message: 'include', arguments: ['EmailSpec::Helpers'] do
20
+ run = true
21
+ end
22
+ condition.process
23
+ expect(run).to be_true
24
+ end
25
+
26
+ it 'not call block if not match anything' do
27
+ run = false
28
+ condition = Rewriter::IfExistCondition.new instance, type: 'send', message: 'include', arguments: ['FactoryGirl::SyntaxMethods'] do
29
+ run = true
30
+ end
31
+ condition.process
32
+ expect(run).to be_false
33
+ end
34
+ end
35
+ end
36
+
37
+ describe Rewriter::UnlessExistCondition do
38
+ let(:source) {
39
+ """
40
+ RSpec.configure do |config|
41
+ config.include EmailSpec::Helpers
42
+ config.include EmailSpec::Methods
43
+ end
44
+ """
45
+ }
46
+ let(:node) { Parser::CurrentRuby.parse(source) }
47
+ let(:instance) { double(:current_node => node, :current_source => source) }
48
+
49
+ describe '#process' do
50
+ it 'call block if match anything' do
51
+ run = false
52
+ condition = Rewriter::UnlessExistCondition.new instance, type: 'send', message: 'include', arguments: ['FactoryGirl::Syntax::Methods'] do
53
+ run = true
54
+ end
55
+ condition.process
56
+ expect(run).to be_true
57
+ end
58
+
59
+ it 'not call block if not match anything' do
60
+ run = false
61
+ condition = Rewriter::UnlessExistCondition.new instance, type: 'send', message: 'include', arguments: ['EmailSpec::Helpers'] do
62
+ run = true
63
+ end
64
+ condition.process
65
+ expect(run).to be_false
66
+ end
67
+ end
68
+ end
69
+
70
+ describe Rewriter::IfOnlyExistCondition do
71
+ describe '#process' do
72
+ it 'gets matching nodes' do
73
+ source = """
74
+ RSpec.configure do |config|
75
+ config.include EmailSpec::Helpers
76
+ end
77
+ """
78
+ node = Parser::CurrentRuby.parse(source)
79
+ instance = double(:current_node => node, :current_source => source)
80
+ run = false
81
+ condition = Rewriter::IfOnlyExistCondition.new instance, type: 'send', message: 'include', arguments: ['EmailSpec::Helpers'] do
82
+ run = true
83
+ end
84
+ condition.process
85
+ expect(run).to be_true
86
+ end
87
+
88
+ it 'not call block if does not match' do
89
+ source = """
90
+ RSpec.configure do |config|
91
+ config.include EmailSpec::Helpers
92
+ config.include EmailSpec::Methods
93
+ end
94
+ """
95
+ node = Parser::CurrentRuby.parse(source)
96
+ instance = double(:current_node => node, :current_source => source)
97
+ run = false
98
+ condition = Rewriter::IfOnlyExistCondition.new instance, type: 'send', message: 'include', arguments: ['EmailSpec::Helpers'] do
99
+ run = true
100
+ end
101
+ condition.process
102
+ expect(run).to be_false
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,52 @@
1
+ require 'spec_helper'
2
+
3
+ module Synvert::Core
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', {gte: '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', {gt: '1.2.0'})
36
+ expect(gem_spec).not_to be_match
37
+ end
38
+
39
+ it 'returns false if gem does not exist in Gemfile.lock' do
40
+ expect(File).to receive(:exists?).with('./Gemfile.lock').and_return(true)
41
+ expect(File).to receive(:read).with('./Gemfile.lock').and_return(gemfile_lock_content)
42
+ gem_spec = Rewriter::GemSpec.new('synvert', '1.0.0')
43
+ expect(gem_spec).not_to be_match
44
+ end
45
+
46
+ it 'raise Synvert::Core::GemfileLockNotFound if Gemfile.lock does not exist' do
47
+ expect(File).to receive(:exists?).with('./Gemfile.lock').and_return(false)
48
+ gem_spec = Rewriter::GemSpec.new('ast', '1.1.0')
49
+ expect { gem_spec.match? }.to raise_error(Synvert::Core::GemfileLockNotFound)
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,163 @@
1
+ require 'spec_helper'
2
+
3
+ module Synvert::Core
4
+ describe Rewriter::Instance do
5
+ let(:instance) { Rewriter::Instance.new('file pattern') }
6
+
7
+ it 'parses within_node' do
8
+ scope = double()
9
+ block = Proc.new {}
10
+ expect(Rewriter::Scope).to receive(:new).with(instance, type: 'send', message: 'create', &block).and_return(scope)
11
+ expect(scope).to receive(:process)
12
+ instance.within_node(type: 'send', message: 'create', &block)
13
+ end
14
+
15
+ it 'parses with_node' do
16
+ scope = double()
17
+ block = Proc.new {}
18
+ expect(Rewriter::Scope).to receive(:new).with(instance, type: 'send', message: 'create', &block).and_return(scope)
19
+ expect(scope).to receive(:process)
20
+ instance.with_node(type: 'send', message: 'create', &block)
21
+ end
22
+
23
+ it 'parses if_exist_node' do
24
+ condition = double()
25
+ block = Proc.new {}
26
+ expect(Rewriter::IfExistCondition).to receive(:new).with(instance, type: 'send', message: 'create', &block).and_return(condition)
27
+ expect(condition).to receive(:process)
28
+ instance.if_exist_node(type: 'send', message: 'create', &block)
29
+ end
30
+
31
+ it 'parses unless_exist_node' do
32
+ condition = double()
33
+ block = Proc.new {}
34
+ expect(Rewriter::UnlessExistCondition).to receive(:new).with(instance, type: 'send', message: 'create', &block).and_return(condition)
35
+ expect(condition).to receive(:process)
36
+ instance.unless_exist_node(type: 'send', message: 'create', &block)
37
+ end
38
+
39
+ it 'parses if_only_exist_node' do
40
+ condition = double()
41
+ block = Proc.new {}
42
+ expect(Rewriter::IfOnlyExistCondition).to receive(:new).with(instance, type: 'send', message: 'create', &block).and_return(condition)
43
+ expect(condition).to receive(:process)
44
+ instance.if_only_exist_node(type: 'send', message: 'create', &block)
45
+ end
46
+
47
+ it 'parses append' do
48
+ expect(Rewriter::AppendAction).to receive(:new).with(instance, 'include FactoryGirl::Syntax::Methods')
49
+ instance.append "include FactoryGirl::Syntax::Methods"
50
+ end
51
+
52
+ it 'parses insert' do
53
+ expect(Rewriter::InsertAction).to receive(:new).with(instance, '{{arguments.first}}.include FactoryGirl::Syntax::Methods')
54
+ instance.insert "{{arguments.first}}.include FactoryGirl::Syntax::Methods"
55
+ end
56
+
57
+ it 'parses insert_after' do
58
+ expect(Rewriter::InsertAfterAction).to receive(:new).with(instance, '{{arguments.first}}.include FactoryGirl::Syntax::Methods')
59
+ instance.insert_after "{{arguments.first}}.include FactoryGirl::Syntax::Methods"
60
+ end
61
+
62
+ it 'parses replace_with' do
63
+ expect(Rewriter::ReplaceWithAction).to receive(:new).with(instance, 'create {{arguments}}')
64
+ instance.replace_with 'create {{arguments}}'
65
+ end
66
+
67
+ it 'parses remove' do
68
+ expect(Rewriter::RemoveAction).to receive(:new).with(instance)
69
+ instance.remove
70
+ end
71
+
72
+ describe '#process' do
73
+ before { Configuration.instance.set :path, '.' }
74
+
75
+ it 'FactoryGirl uses short syntax' do
76
+ instance = Rewriter::Instance.new 'spec/**/*_spec.rb' do
77
+ with_node type: 'send', receiver: 'FactoryGirl', message: 'create' do
78
+ replace_with 'create {{arguments}}'
79
+ end
80
+ end
81
+ input = """
82
+ it 'uses factory_girl' do
83
+ user = FactoryGirl.create :user
84
+ post = FactoryGirl.create :post, user: user
85
+ assert post.valid?
86
+ end
87
+ """
88
+ output = """
89
+ it 'uses factory_girl' do
90
+ user = create :user
91
+ post = create :post, user: user
92
+ assert post.valid?
93
+ end
94
+ """
95
+ expect(Dir).to receive(:glob).with('./spec/**/*_spec.rb').and_return(['spec/models/post_spec.rb'])
96
+ expect(File).to receive(:read).with('spec/models/post_spec.rb').and_return(input)
97
+ expect(File).to receive(:write).with('spec/models/post_spec.rb', output)
98
+ instance.process
99
+ end
100
+
101
+ it 'includes FactoryGirl::Syntax::Methods' do
102
+ instance = Rewriter::Instance.new 'spec/spec_helper.rb' do
103
+ with_node type: 'block', caller: {receiver: 'RSpec', message: 'configure'} do
104
+ unless_exist_node type: 'send', message: 'include', arguments: ['FactoryGirl::Syntax::Methods'] do
105
+ insert "{{arguments.first}}.include FactoryGirl::Syntax::Methods"
106
+ end
107
+ end
108
+ end
109
+ input = """
110
+ RSpec.configure do |config|
111
+ end
112
+ """
113
+ output = """
114
+ RSpec.configure do |config|
115
+ config.include FactoryGirl::Syntax::Methods
116
+ end
117
+ """
118
+ expect(Dir).to receive(:glob).with('./spec/spec_helper.rb').and_return(['spec/spec_helper.rb'])
119
+ expect(File).to receive(:read).with('spec/spec_helper.rb').and_return(input)
120
+ expect(File).to receive(:write).with('spec/spec_helper.rb', output)
121
+ instance.process
122
+ end
123
+
124
+ it 'does not include FactoryGirl::Syntax::Methods' do
125
+ instance = Rewriter::Instance.new 'spec/spec_helper.rb' do
126
+ with_node type: 'block', caller: {receiver: 'RSpec', message: 'configure'} do
127
+ unless_exist_node type: 'send', message: 'include', arguments: ['FactoryGirl::Syntax::Methods'] do
128
+ insert "{{arguments.first}}.include FactoryGirl::Syntax::Methods"
129
+ end
130
+ end
131
+ end
132
+ input = """
133
+ RSpec.configure do |config|
134
+ config.include FactoryGirl::Syntax::Methods
135
+ end
136
+ """
137
+ output = """
138
+ RSpec.configure do |config|
139
+ config.include FactoryGirl::Syntax::Methods
140
+ end
141
+ """
142
+ expect(Dir).to receive(:glob).with('./spec/spec_helper.rb').and_return(['spec/spec_helper.rb'])
143
+ expect(File).to receive(:read).with('spec/spec_helper.rb').and_return(input)
144
+ expect(File).to receive(:write).with('spec/spec_helper.rb', output)
145
+ instance.process
146
+ end
147
+
148
+ it 'process nested send nodes' do
149
+ instance = Rewriter::Instance.new 'config/*.rb' do
150
+ with_node type: 'send', receiver: {type: 'send', receiver: {type: 'send', message: 'config'}, message: 'active_record'}, message: 'identity_map=' do
151
+ remove
152
+ end
153
+ end
154
+ input = 'config.active_record.identity_map = true'
155
+ output = ''
156
+ expect(Dir).to receive(:glob).with('./config/*.rb').and_return(['config/environments/production.rb'])
157
+ expect(File).to receive(:read).with('config/environments/production.rb').and_return(input)
158
+ expect(File).to receive(:write).with('config/environments/production.rb', output)
159
+ instance.process
160
+ end
161
+ end
162
+ end
163
+ end