synvert-core 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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