synvert 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/README.md +9 -2
- data/lib/synvert.rb +3 -4
- data/lib/synvert/cli.rb +13 -12
- data/lib/synvert/configuration.rb +16 -0
- data/lib/synvert/factory_girl/syntax_methods.rb +37 -0
- data/lib/synvert/node_ext.rb +134 -0
- data/lib/synvert/rewriter.rb +56 -0
- data/lib/synvert/rewriter/action.rb +48 -0
- data/lib/synvert/rewriter/conditions.rb +39 -0
- data/lib/synvert/rewriter/instances.rb +67 -0
- data/lib/synvert/rewriter/scopes.rb +39 -0
- data/lib/synvert/version.rb +1 -1
- data/spec/spec_helper.rb +2 -2
- data/spec/support/parser_helper.rb +5 -0
- data/spec/synvert/node_ext_spec.rb +88 -0
- data/spec/synvert/rewriter/action_spec.rb +51 -0
- data/spec/synvert/rewriter/conditions_spec.rb +31 -0
- data/spec/synvert/rewriter/instances_spec.rb +113 -0
- data/spec/synvert/rewriter/scopes_spec.rb +79 -0
- data/spec/synvert/rewriter_spec.rb +31 -0
- data/synvert.gemspec +0 -1
- metadata +25 -28
- data/lib/synvert/base_converter.rb +0 -36
- data/lib/synvert/checking_visitor.rb +0 -37
- data/lib/synvert/factory_girl/syntax_methods_converter.rb +0 -49
- data/lib/synvert/sexp_helper.rb +0 -51
- data/spec/support/shared_context.rb +0 -41
- data/spec/synvert/base_converter_spec.rb +0 -0
- data/spec/synvert/checking_visitor_spec.rb +0 -42
- data/spec/synvert/factory_girl/syntax_methods_converter_spec.rb +0 -148
@@ -0,0 +1,39 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
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
|
+
class Rewriter::Scope
|
24
|
+
def initialize(options)
|
25
|
+
@options = options
|
26
|
+
end
|
27
|
+
|
28
|
+
def matching_nodes(nodes)
|
29
|
+
matching_nodes = []
|
30
|
+
while node = nodes.shift
|
31
|
+
matching_nodes << node if node.match?(@options)
|
32
|
+
node.recursive_children do |child_node|
|
33
|
+
matching_nodes << child_node if child_node.match?(@options)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
matching_nodes
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/synvert/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -6,9 +6,9 @@ Dir[File.join(File.dirname(__FILE__), 'support', '*')].each do |path|
|
|
6
6
|
require path
|
7
7
|
end
|
8
8
|
|
9
|
-
require 'mocha/api'
|
10
|
-
|
11
9
|
RSpec.configure do |config|
|
10
|
+
config.include ParserHelper
|
11
|
+
|
12
12
|
config.treat_symbols_as_metadata_keys_with_true_values = true
|
13
13
|
config.run_all_when_everything_filtered = true
|
14
14
|
config.filter_run :focus
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Parser::AST::Node do
|
4
|
+
describe '#name' do
|
5
|
+
it 'gets for class node' do
|
6
|
+
node = parse('class Synvert; end')
|
7
|
+
expect(node.name).to eq parse('Synvert')
|
8
|
+
|
9
|
+
node = parse('class Synvert::Rewriter::Instance; end')
|
10
|
+
expect(node.name).to eq parse('Synvert::Rewriter::Instance')
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '#receiver' do
|
15
|
+
it 'gets for send node' do
|
16
|
+
node = parse('FactoryGirl.create :post')
|
17
|
+
expect(node.receiver).to eq parse('FactoryGirl')
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '#message' do
|
22
|
+
it 'gets for send node' do
|
23
|
+
node = parse('FactoryGirl.create :post')
|
24
|
+
expect(node.message).to eq :create
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe '#arguments' do
|
29
|
+
it 'gets for send node' do
|
30
|
+
node = parse("FactoryGirl.create :post, title: 'post'")
|
31
|
+
expect(node.arguments).to eq parse("[:post, title: 'post']").children
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'gets for block node' do
|
35
|
+
node = parse('RSpec.configure do |config|; end')
|
36
|
+
expect(node.arguments.map(&:to_s)).to eq ['config']
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe '#caller' do
|
41
|
+
it 'gets for block node' do
|
42
|
+
node = parse('RSpec.configure do |config|; end')
|
43
|
+
expect(node.caller).to eq parse('RSpec.configure')
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '#to_s' do
|
48
|
+
it 'gets for const node' do
|
49
|
+
node = parse('Synvert')
|
50
|
+
expect(node.to_s).to eq 'Synvert'
|
51
|
+
|
52
|
+
node = parse('Synvert::Rewriter::Instance')
|
53
|
+
expect(node.to_s).to eq 'Synvert::Rewriter::Instance'
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'gets for sym node' do
|
57
|
+
node = parse(':synvert')
|
58
|
+
expect(node.to_s).to eq ':synvert'
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'gets for str node' do
|
62
|
+
node = parse("'synvert'")
|
63
|
+
expect(node.to_s).to eq 'synvert'
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'gets for lvar node' do
|
67
|
+
node = parse("user = User.find 1; user.valid?").grep_node(type: 'lvar')
|
68
|
+
expect(node.to_s).to eq 'user'
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'gets for ivar node' do
|
72
|
+
node = parse('@user')
|
73
|
+
expect(node.to_s).to eq '@user'
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'gets for arg node' do
|
77
|
+
node = parse("RSpec.configure do |config|; end").grep_node(type: 'arg')
|
78
|
+
expect(node.to_s).to eq 'config'
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe '#indent' do
|
83
|
+
it 'gets column number' do
|
84
|
+
node = parse(' FactoryGirl.create :post')
|
85
|
+
expect(node.indent).to eq 2
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Synvert
|
4
|
+
describe Rewriter::ReplaceWithAction do
|
5
|
+
describe '#rewrite' do
|
6
|
+
it 'replaces code' do
|
7
|
+
action = Rewriter::ReplaceWithAction.new('create_list {{node.arguments}}')
|
8
|
+
source = "post = FactoryGirl.create_list :post, 2"
|
9
|
+
send_node = Parser::CurrentRuby.parse(source).children[1]
|
10
|
+
output = action.rewrite(source, send_node)
|
11
|
+
expect(output).to eq "post = create_list :post, 2"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe Rewriter::InsertAction do
|
17
|
+
describe '#rewrite' do
|
18
|
+
it 'insert code to block node' do
|
19
|
+
action = Rewriter::InsertAction.new('{{node.arguments.first}}.include FactoryGirl::Syntax::Methods')
|
20
|
+
source = "RSpec.configure do |config|\nend"
|
21
|
+
block_node = Parser::CurrentRuby.parse(source)
|
22
|
+
output = action.rewrite(source, block_node)
|
23
|
+
expect(output).to eq "RSpec.configure do |config|\n config.include FactoryGirl::Syntax::Methods\nend"
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'insert code to class node' do
|
27
|
+
action = Rewriter::InsertAction.new('include FactoryGirl::Syntax::Methods')
|
28
|
+
source = "class Test::Unit::TestCase\nend"
|
29
|
+
block_node = Parser::CurrentRuby.parse(source)
|
30
|
+
output = action.rewrite(source, block_node)
|
31
|
+
expect(output).to eq "class Test::Unit::TestCase\n include FactoryGirl::Syntax::Methods\nend"
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'insert code to begin node' do
|
35
|
+
action = Rewriter::InsertAction.new('World(FactoryGirl::Syntax::Methods)')
|
36
|
+
source = "require 'cucumber/rails'\nActionController::Base.allow_rescue = false"
|
37
|
+
block_node = Parser::CurrentRuby.parse(source)
|
38
|
+
output = action.rewrite(source, block_node)
|
39
|
+
expect(output).to eq "require 'cucumber/rails'\nActionController::Base.allow_rescue = false\nWorld(FactoryGirl::Syntax::Methods)"
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'insert code to other node' do
|
43
|
+
action = Rewriter::InsertAction.new('World(FactoryGirl::Syntax::Methods)')
|
44
|
+
source = "require 'cucumber/rails'"
|
45
|
+
block_node = Parser::CurrentRuby.parse(source)
|
46
|
+
output = action.rewrite(source, block_node)
|
47
|
+
expect(output).to eq "require 'cucumber/rails'\nWorld(FactoryGirl::Syntax::Methods)"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,31 @@
|
|
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
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Synvert
|
4
|
+
describe Rewriter::Instances do
|
5
|
+
|
6
|
+
end
|
7
|
+
|
8
|
+
describe Rewriter::Instance do
|
9
|
+
let(:instance) { Rewriter::Instance.new('file pattern') }
|
10
|
+
|
11
|
+
describe '#within_node' do
|
12
|
+
it 'adds a scope'do
|
13
|
+
expect_any_instance_of(Rewriter::Scopes).to receive(:add).with(type: 'block', caller: {receiver: 'RSpec', message: 'configure'})
|
14
|
+
instance.within_node type: 'block', caller: {receiver: 'RSpec', message: 'configure'} do; end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#with_node' do
|
19
|
+
it 'adds a scope' do
|
20
|
+
expect_any_instance_of(Rewriter::Scopes).to receive(:add).with(type: 'send', receiver: 'FactoryGirl', message: 'create')
|
21
|
+
instance.with_node type: 'send', receiver: 'FactoryGirl', message: 'create' do; end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '#insert' do
|
26
|
+
it 'sets an action' do
|
27
|
+
expect(Rewriter::InsertAction).to receive(:new).with('{{node.arguments.first}}.include FactoryGirl::Syntax::Methods')
|
28
|
+
instance.insert "{{node.arguments.first}}.include FactoryGirl::Syntax::Methods"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe '#replace_with' do
|
33
|
+
it 'sets an action' do
|
34
|
+
expect(Rewriter::ReplaceWithAction).to receive(:new).with('create {{node.arguments}}')
|
35
|
+
instance.replace_with 'create {{node.arguments}}'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe '#process' do
|
40
|
+
before { Configuration.instance.set :path, '.' }
|
41
|
+
|
42
|
+
it 'FactoryGirl uses short syntax' do
|
43
|
+
instance = Rewriter::Instance.new('spec/**/*_spec.rb')
|
44
|
+
instance.with_node type: 'send', receiver: 'FactoryGirl', message: 'create' do
|
45
|
+
replace_with 'create {{node.arguments}}'
|
46
|
+
end
|
47
|
+
input = """
|
48
|
+
it 'uses factory_girl' do
|
49
|
+
user = FactoryGirl.create :user
|
50
|
+
post = FactoryGirl.create :post, user: user
|
51
|
+
assert post.valid?
|
52
|
+
end
|
53
|
+
"""
|
54
|
+
output = """
|
55
|
+
it 'uses factory_girl' do
|
56
|
+
user = create :user
|
57
|
+
post = create :post, user: user
|
58
|
+
assert post.valid?
|
59
|
+
end
|
60
|
+
"""
|
61
|
+
expect(Dir).to receive(:glob).with('./spec/**/*_spec.rb').and_return(['spec/models/post_spec.rb'])
|
62
|
+
expect(File).to receive(:read).with('spec/models/post_spec.rb').and_return(input)
|
63
|
+
expect(File).to receive(:write).with('spec/models/post_spec.rb', output)
|
64
|
+
instance.process
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'includes FactoryGirl::Syntax::Methods' do
|
68
|
+
instance = Rewriter::Instance.new('spec/spec_helper.rb')
|
69
|
+
instance.with_node type: 'block', caller: {receiver: 'RSpec', message: 'configure'} do
|
70
|
+
unless_exist_node type: 'send', message: 'include', arguments: {first: {to_s: 'FactoryGirl::Syntax::Methods'}} do
|
71
|
+
insert "{{node.arguments.first}}.include FactoryGirl::Syntax::Methods"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
input = """
|
75
|
+
RSpec.configure do |config|
|
76
|
+
end
|
77
|
+
"""
|
78
|
+
output = """
|
79
|
+
RSpec.configure do |config|
|
80
|
+
config.include FactoryGirl::Syntax::Methods
|
81
|
+
end
|
82
|
+
"""
|
83
|
+
expect(Dir).to receive(:glob).with('./spec/spec_helper.rb').and_return(['spec/spec_helper.rb'])
|
84
|
+
expect(File).to receive(:read).with('spec/spec_helper.rb').and_return(input)
|
85
|
+
expect(File).to receive(:write).with('spec/spec_helper.rb', output)
|
86
|
+
instance.process
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'does not include FactoryGirl::Syntax::Methods' do
|
90
|
+
instance = Rewriter::Instance.new('spec/spec_helper.rb')
|
91
|
+
instance.with_node type: 'block', caller: {receiver: 'RSpec', message: 'configure'} do
|
92
|
+
unless_exist_node type: 'send', message: 'include', arguments: {first: {to_s: 'FactoryGirl::Syntax::Methods'}} do
|
93
|
+
insert "{{node.arguments.first}}.include FactoryGirl::Syntax::Methods"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
input = """
|
97
|
+
RSpec.configure do |config|
|
98
|
+
config.include FactoryGirl::Syntax::Methods
|
99
|
+
end
|
100
|
+
"""
|
101
|
+
output = """
|
102
|
+
RSpec.configure do |config|
|
103
|
+
config.include FactoryGirl::Syntax::Methods
|
104
|
+
end
|
105
|
+
"""
|
106
|
+
expect(Dir).to receive(:glob).with('./spec/spec_helper.rb').and_return(['spec/spec_helper.rb'])
|
107
|
+
expect(File).to receive(:read).with('spec/spec_helper.rb').and_return(input)
|
108
|
+
expect(File).to receive(:write).with('spec/spec_helper.rb', output)
|
109
|
+
instance.process
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,79 @@
|
|
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
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Synvert
|
4
|
+
describe Rewriter do
|
5
|
+
it 'sets description' do
|
6
|
+
rewriter = Rewriter.new 'this is description' do; end
|
7
|
+
expect(rewriter.description).to eq 'this is description'
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'parses from_version' do
|
11
|
+
rewriter = Rewriter.new 'description' do
|
12
|
+
from_version '1.0.0'
|
13
|
+
end
|
14
|
+
expect(rewriter.version.to_s).to eq '1.0.0'
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'parses within_file' do
|
18
|
+
expect_any_instance_of(Rewriter::Instances).to receive(:add).with('spec/spec_helper.rb')
|
19
|
+
Rewriter.new 'description' do
|
20
|
+
within_file 'spec/spec_helper.rb' do; end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'parses within_files' do
|
25
|
+
expect_any_instance_of(Rewriter::Instances).to receive(:add).with('spec/**/*_spec.rb')
|
26
|
+
Rewriter.new 'description' do
|
27
|
+
within_files 'spec/**/*_spec.rb' do; end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|