synvert 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -1,5 +1,5 @@
1
1
  # coding: utf-8
2
2
 
3
3
  module Synvert
4
- VERSION = "0.0.1"
4
+ VERSION = "0.0.2"
5
5
  end
@@ -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,5 @@
1
+ module ParserHelper
2
+ def parse(code)
3
+ Parser::CurrentRuby.parse code
4
+ end
5
+ end
@@ -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