synvert 0.0.9 → 0.0.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +19 -6
- data/lib/synvert/node_ext.rb +21 -4
- data/lib/synvert/rewriter/action.rb +13 -1
- data/lib/synvert/rewriter/condition.rb +2 -2
- data/lib/synvert/snippets/rails/upgrade_3_0_to_3_1.rb +1 -1
- data/lib/synvert/snippets/rspec/be_close_to_be_within.rb +12 -0
- data/lib/synvert/snippets/rspec/block_to_expect.rb +14 -0
- data/lib/synvert/snippets/rspec/boolean_matcher.rb +13 -0
- data/lib/synvert/snippets/rspec/collection_matcher.rb +23 -0
- data/lib/synvert/snippets/rspec/its_to_it.rb +56 -0
- data/lib/synvert/snippets/rspec/message_expectation.rb +28 -0
- data/lib/synvert/snippets/rspec/method_stub.rb +71 -0
- data/lib/synvert/snippets/rspec/negative_error_expectation.rb +14 -0
- data/lib/synvert/snippets/rspec/new_syntax.rb +14 -0
- data/lib/synvert/snippets/rspec/one_liner_expectation.rb +51 -0
- data/lib/synvert/snippets/rspec/should_to_expect.rb +40 -0
- data/lib/synvert/snippets/rspec/stub_and_mock_to_double.rb +15 -0
- data/lib/synvert/version.rb +1 -1
- data/spec/synvert/node_ext_spec.rb +26 -2
- data/spec/synvert/rewriter/action_spec.rb +42 -13
- data/spec/synvert/snippets/rspec/new_syntax_spec.rb +183 -0
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 614d00dc632a03aa4e33b46e9abd3632e3cd1192
|
4
|
+
data.tar.gz: cda16861b6998679c265db36fa32c094ca391417
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dc0094150dfdc672a9f4cbe95ba484cedf065d778a988b60790c2a417748b1e7b07c50e74df7fe3b44835f32313c4ac7708e0928b5cac4db41f5fd9ad59c8f24
|
7
|
+
data.tar.gz: 2531c8a731dcfcf741634f23450abd0415b630197c64845958a3f81dd3f7d7b43b3d07ef706c31c1bf7d650beb04e9b4c7c768ad05fdb22694212f1fe90ed781
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
[![Build Status](https://secure.travis-ci.org/xinminlabs/synvert.png)](http://travis-ci.org/xinminlabs/synvert)
|
4
4
|
[![Coverage Status](https://coveralls.io/repos/xinminlabs/synvert/badge.png?branch=master)](https://coveralls.io/r/xinminlabs/synvert)
|
5
|
+
[![Gem Version](https://badge.fury.io/rb/synvert.png)](http://badge.fury.io/rb/synvert)
|
5
6
|
|
6
7
|
synvert = syntax + convert, makes it easy to rewrite ruby code
|
7
8
|
automatically.
|
@@ -41,12 +42,24 @@ $ synvert --run-snippets factory_girl_short_syntax,upgrade_rails_3_2_to_4_0 ~/Si
|
|
41
42
|
|
42
43
|
name | description
|
43
44
|
--- | ---
|
44
|
-
factory_girl_short_syntax
|
45
|
-
convert_dynamic_finders
|
46
|
-
strong_parameters
|
47
|
-
|
48
|
-
upgrade_rails_3_1_to_3_2
|
49
|
-
|
45
|
+
factory_girl_short_syntax | FactoryGirl uses short syntax
|
46
|
+
convert_dynamic_finders | Convert dynamic finders
|
47
|
+
strong_parameters | Use strong_parameters syntax
|
48
|
+
upgrade_rails_3_0_to_3_1 | Upgrade rails from 3.0 to 3.1
|
49
|
+
upgrade_rails_3_1_to_3_2 | Upgrade rails from 3.1 to 3.2
|
50
|
+
upgrade_rails_3_2_to_4_0 | Upgrade rails from 3.2 to 4.0, it contains convert_dynamic_finder and strong_parameters snippets
|
51
|
+
convert_rspec_be_close_to_be_within | RSpec converts be_close to be_within
|
52
|
+
convert_rspec_block_to_expect | RSpec converts block to expect
|
53
|
+
convert_rspec_boolean_matcher | RSpec converts boolean matcher
|
54
|
+
convert_rspec_collection_matcher | RSpec converts collection matcher
|
55
|
+
convert_rspec_its_to_it | RSpec converts its to it
|
56
|
+
convert_rspec_message_expectation | RSpec converts message expectation
|
57
|
+
convert_rspec_method_stub | RSpec converts method stub
|
58
|
+
convert_rspec_negative_error_expectation | RSpec converts negative error expectation
|
59
|
+
rspec_new_syntax | Use RSpec new syntax
|
60
|
+
convert_rspec_one_liner_expectation | RSpec converts one liner expectation
|
61
|
+
convert_rspec_should_to_expect | RSpec converts should to expect
|
62
|
+
convert_rspec_stub_and_mock_to_double | RSpec converts stub and mock to double
|
50
63
|
|
51
64
|
## Documentation
|
52
65
|
|
data/lib/synvert/node_ext.rb
CHANGED
@@ -48,8 +48,11 @@ class Parser::AST::Node
|
|
48
48
|
end
|
49
49
|
|
50
50
|
def body
|
51
|
-
|
52
|
-
|
51
|
+
case self.type
|
52
|
+
when :begin
|
53
|
+
self.children
|
54
|
+
when :block
|
55
|
+
:begin == self.children[2].type ? self.children[2].children : [self.children[2]]
|
53
56
|
else
|
54
57
|
raise NotImplementedError.new "body is not handled for #{self.inspect}"
|
55
58
|
end
|
@@ -88,6 +91,10 @@ class Parser::AST::Node
|
|
88
91
|
actual_values = actual_value(self, instance, multi_keys[0...-1])
|
89
92
|
expected = expected_value(rules, multi_keys)
|
90
93
|
actual_values.any? { |actual| match_value?(instance, actual, expected) }
|
94
|
+
elsif multi_keys.last == :not
|
95
|
+
actual = actual_value(self, instance, multi_keys[0...-1])
|
96
|
+
expected = expected_value(rules, multi_keys)
|
97
|
+
!match_value?(instance, actual, expected)
|
91
98
|
else
|
92
99
|
actual = actual_value(self, instance, multi_keys)
|
93
100
|
expected = expected_value(rules, multi_keys)
|
@@ -104,10 +111,14 @@ class Parser::AST::Node
|
|
104
111
|
source = evaluated.loc.expression.source_buffer.source
|
105
112
|
source[evaluated.loc.expression.begin_pos...evaluated.loc.expression.end_pos]
|
106
113
|
when Array
|
107
|
-
|
108
|
-
|
114
|
+
if evaluated.size > 0
|
115
|
+
source = evaluated.first.loc.expression.source_buffer.source
|
116
|
+
source[evaluated.first.loc.expression.begin_pos...evaluated.last.loc.expression.end_pos]
|
117
|
+
end
|
109
118
|
when String
|
110
119
|
evaluated
|
120
|
+
when NilClass
|
121
|
+
'nil'
|
111
122
|
else
|
112
123
|
raise NotImplementedError.new "rewritten_source is not handled for #{evaluated.inspect}"
|
113
124
|
end
|
@@ -140,6 +151,12 @@ private
|
|
140
151
|
actual.zip(expected).all? { |a, e| match_value?(instance, a, e) }
|
141
152
|
when NilClass
|
142
153
|
actual.nil?
|
154
|
+
when Numeric
|
155
|
+
if Parser::AST::Node === actual
|
156
|
+
actual.children[0] == expected
|
157
|
+
else
|
158
|
+
actual == expected
|
159
|
+
end
|
143
160
|
when TrueClass
|
144
161
|
:true == actual.type
|
145
162
|
when FalseClass
|
@@ -41,7 +41,19 @@ module Synvert
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def rewritten_code
|
44
|
-
|
44
|
+
if rewritten_source.split("\n").length > 1
|
45
|
+
"\n\n" + rewritten_source.split("\n").map { |line|
|
46
|
+
indent(@node) + line
|
47
|
+
}.join("\n")
|
48
|
+
else
|
49
|
+
rewritten_source
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def indent(node)
|
56
|
+
' ' * node.indent
|
45
57
|
end
|
46
58
|
end
|
47
59
|
|
@@ -35,8 +35,8 @@ module Synvert
|
|
35
35
|
|
36
36
|
class Rewriter::IfOnlyExistCondition < Rewriter::Condition
|
37
37
|
def match?
|
38
|
-
|
39
|
-
@instance.current_node.body.match?(@instance, @rules)
|
38
|
+
@instance.current_node.body.size == 1 &&
|
39
|
+
@instance.current_node.body.first.match?(@instance, @rules)
|
40
40
|
end
|
41
41
|
end
|
42
42
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
Synvert::Rewriter.new "convert_rspec_be_close_to_be_within", "RSpec converts be_close to be_within" do
|
2
|
+
gem_spec 'rspec', '2.1.0'
|
3
|
+
|
4
|
+
within_files 'spec/**/*.rb' do
|
5
|
+
# expect(1.0 / 3.0).to be_close(0.333, 0.001) => expect(1.0 / 3.0).to be_within(0.001).of(0.333)
|
6
|
+
with_node type: 'send', message: 'to', arguments: {first: {type: 'send', message: 'be_close'}} do
|
7
|
+
within_arg = node.arguments.first.arguments.last.source(self)
|
8
|
+
of_arg = node.arguments.first.arguments.first.source(self)
|
9
|
+
replace_with "{{receiver}}.to be_within(#{within_arg}).of(#{of_arg})"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
Synvert::Rewriter.new "convert_rspec_block_to_expect", "RSpec converts block to expect" do
|
2
|
+
gem_spec 'rspec', '2.11.0'
|
3
|
+
|
4
|
+
{should: 'to', should_not: 'not_to'}.each do |old_message, new_message|
|
5
|
+
within_files 'spec/**/*.rb' do
|
6
|
+
# lambda { do_something }.should raise_error => expect { do_something }.to raise_error
|
7
|
+
# proc { do_something }.should raise_error => expect { do_something }.to raise_error
|
8
|
+
# -> { do_something }.should raise_error => expect { do_something }.to raise_error
|
9
|
+
with_node type: 'send', receiver: {type: 'block'}, message: old_message do
|
10
|
+
replace_with "expect { {{receiver.body}} }.#{new_message} {{arguments}}"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
Synvert::Rewriter.new "convert_rspec_boolean_matcher", "RSpec converts boolean matcher" do
|
2
|
+
gem_spec 'rspec', '2.99.0'
|
3
|
+
|
4
|
+
{be_true: 'be_truthy', be_false: 'be_falsey'}.each do |old_matcher, new_matcher|
|
5
|
+
within_files 'spec/**/*_spec.rb' do
|
6
|
+
# be_true => be_truthy
|
7
|
+
# be_false => be_falsey
|
8
|
+
with_node type: 'send', receiver: nil, message: old_matcher do
|
9
|
+
replace_with new_matcher
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
Synvert::Rewriter.new "convert_rspec_collection_matcher", "RSpec converts collection matcher" do
|
2
|
+
gem_spec 'rspec', '2.99.0'
|
3
|
+
|
4
|
+
{have: 'eq', have_exactly: 'eq', have_at_least: 'be >=', have_at_most: 'be <='}.each do |old_matcher, new_matcher|
|
5
|
+
within_files 'spec/**/*_spec.rb' do
|
6
|
+
# expect(collection).to have(3).items => expect(collection.size).to eq(3)
|
7
|
+
# expect(collection).to have_exactly(3).items => expect(collection.size).to eq(3)
|
8
|
+
# expect(collection).to have_at_least(3).items => expect(collection.size).to be >= 3
|
9
|
+
# expect(collection).to have_at_most(3).items => expect(collection.size).to be <= 3
|
10
|
+
#
|
11
|
+
# expect(team).to have(3).players => expect(team.players.size).to eq 3
|
12
|
+
with_node type: 'send', message: 'to', arguments: {first: {type: 'send', receiver: {type: 'send', message: old_matcher}}} do
|
13
|
+
times = node.arguments.first.receiver.arguments.first.source(self)
|
14
|
+
items_name = node.arguments.first.message
|
15
|
+
if :items == items_name
|
16
|
+
replace_with "expect({{receiver.arguments}}.size).to #{new_matcher} #{times}"
|
17
|
+
else
|
18
|
+
replace_with "expect({{receiver.arguments}}.#{items_name}.size).to #{new_matcher} #{times}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
Synvert::Rewriter.new "convert_rspec_its_to_it", "RSpec converts its to it" do
|
2
|
+
gem_spec 'rspec', '2.99.0'
|
3
|
+
|
4
|
+
[:should, :should_not].each do |message|
|
5
|
+
within_files 'spec/**/*.rb' do
|
6
|
+
# describe 'example' do
|
7
|
+
# subject { { foo: 1, bar: 2 } }
|
8
|
+
# its(:size) { should == 2 }
|
9
|
+
# its([:foo]) { should == 1 }
|
10
|
+
# its('keys.first') { should == :foo }
|
11
|
+
# end
|
12
|
+
# =>
|
13
|
+
# describe 'example' do
|
14
|
+
# subject { { foo: 1, bar: 2 } }
|
15
|
+
#
|
16
|
+
# describe '#size' do
|
17
|
+
# subject { super().size }
|
18
|
+
# it { should == 2 }
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# describe '[:foo]' do
|
22
|
+
# subject { super()[:foo] }
|
23
|
+
# it { should == 1 }
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# describe '#keys' do
|
27
|
+
# subject { super().keys }
|
28
|
+
# describe '#first' do
|
29
|
+
# subject { super().first }
|
30
|
+
# it { should == :foo }
|
31
|
+
# end
|
32
|
+
# end
|
33
|
+
# end
|
34
|
+
with_node type: 'block', caller: {message: 'its'} do
|
35
|
+
if node.body.length == 1
|
36
|
+
its_arg = node.caller.arguments.first.source(self)
|
37
|
+
its_arg = its_arg[1...-1] if its_arg =~ /^['"].*['"]$/
|
38
|
+
its_arg = its_arg[1..-1] if its_arg[0] == ':'
|
39
|
+
rewritten_code = ""
|
40
|
+
args = its_arg.split(".")
|
41
|
+
args.each_with_index do |arg, index|
|
42
|
+
describe_name = arg[0] =~ /^[a-z]/ ? '#' + arg : arg
|
43
|
+
message_name = arg[0] =~ /^[a-z]/ ? '.' + arg : arg
|
44
|
+
rewritten_code << "#{' ' * index}describe '#{describe_name}' do\n"
|
45
|
+
rewritten_code << "#{' ' * (index + 1)}subject { super()#{message_name} }\n"
|
46
|
+
rewritten_code << "#{' ' * (index + 1)}it { {{body}} }\n" if index + 1 == args.length
|
47
|
+
end
|
48
|
+
args.length.times do |i|
|
49
|
+
rewritten_code << "#{' ' * (args.length - 1 - i)}end\n"
|
50
|
+
end
|
51
|
+
replace_with rewritten_code
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
Synvert::Rewriter.new "convert_rspec_message_expectation", "RSpec converts message expectation" do
|
2
|
+
gem_spec 'rspec', '2.14.0'
|
3
|
+
|
4
|
+
within_files 'spec/**/*.rb' do
|
5
|
+
# obj.should_receive(:message) => expect(obj).to receive(:message)
|
6
|
+
# Klass.any_instance.should_receive(:message) => expect_any_instance_of(Klass).to receive(:message)
|
7
|
+
with_node type: 'send', message: 'should_receive' do
|
8
|
+
if_exist_node type: 'send', message: 'any_instance' do
|
9
|
+
replace_with "expect_any_instance_of({{receiver.receiver}}).to receive({{arguments}})"
|
10
|
+
end
|
11
|
+
unless_exist_node type: 'send', message: 'any_instance' do
|
12
|
+
replace_with "expect({{receiver}}).to receive({{arguments}})"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
within_files 'spec/**/*.rb' do
|
18
|
+
# expect(obj).to receive(:message).and_return { 1 } => expect(obj).to receive(:message) { 1 }
|
19
|
+
with_node type: 'send', receiver: {type: 'send', message: 'expect'}, arguments: {first: {type: 'block', caller: {type: 'send', message: 'and_return', arguments: []}}} do
|
20
|
+
replace_with "{{receiver}}.to {{arguments.first.caller.receiver}} { {{arguments.first.body}} }"
|
21
|
+
end
|
22
|
+
|
23
|
+
# expect(obj).to receive(:message).and_return => expect(obj).to receive(:message)
|
24
|
+
with_node type: 'send', receiver: {type: 'send', message: 'expect'}, arguments: {first: {type: 'send', message: 'and_return', arguments: []}} do
|
25
|
+
replace_with "{{receiver}}.to {{arguments.first.receiver}}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
Synvert::Rewriter.new "convert_rspec_method_stub", "RSpec converts method stub" do
|
2
|
+
gem_spec 'rspec', '2.14.0'
|
3
|
+
|
4
|
+
within_files 'spec/**/*.rb' do
|
5
|
+
# obj.stub!(:message) => obj.stub(:message)
|
6
|
+
# obj.unstub!(:message) => obj.unstub(:message)
|
7
|
+
{stub!: 'stub', unstub!: 'unstub'}.each do |old_message, new_message|
|
8
|
+
with_node type: 'send', message: old_message do
|
9
|
+
replace_with "{{receiver}}.#{new_message}({{arguments}})"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
within_files 'spec/**/*.rb' do
|
15
|
+
# obj.stub(:message).any_number_of_times => allow(obj).to receive(:message)
|
16
|
+
# obj.stub(:message).at_least(0) => allow(obj).to receive(:message)
|
17
|
+
with_node type: 'send', message: 'any_number_of_times' do
|
18
|
+
replace_with "{{receiver}}"
|
19
|
+
end
|
20
|
+
|
21
|
+
with_node type: 'send', message: 'at_least', arguments: [0] do
|
22
|
+
replace_with "{{receiver}}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
within_files 'spec/**/*.rb' do
|
27
|
+
# obj.stub(:message) => allow(obj).to receive(:message)
|
28
|
+
# Klass.any_instance.stub(:message) => allow_any_instance_of(Klass).to receive(:message)
|
29
|
+
with_node type: 'send', message: 'stub', arguments: {first: {type: {not: 'hash'}}} do
|
30
|
+
if_exist_node type: 'send', message: 'any_instance' do
|
31
|
+
replace_with "allow_any_instance_of({{receiver.receiver}}).to receive({{arguments}})"
|
32
|
+
end
|
33
|
+
unless_exist_node type: 'send', message: 'any_instance' do
|
34
|
+
replace_with "allow({{receiver}}).to receive({{arguments}})"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
gem_spec 'rspec', '3.0.0'
|
40
|
+
|
41
|
+
within_files 'spec/**/*.rb' do
|
42
|
+
# obj.stub_chain(:foo, :bar, :baz) => allow(obj).to receive_message_chain(:foo, :bar, :baz)
|
43
|
+
with_node type: 'send', message: 'stub_chain' do
|
44
|
+
if_exist_node type: 'send', message: 'any_instance' do
|
45
|
+
replace_with "allow_any_instance_of({{receiver.receiver}}).to receive_message_chain({{arguments}})"
|
46
|
+
end
|
47
|
+
unless_exist_node type: 'send', message: 'any_instance' do
|
48
|
+
replace_with "allow({{receiver}}).to receive_message_chain({{arguments}})"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
within_files 'spec/**/*.rb' do
|
54
|
+
# obj.stub(:foo => 1, :bar => 2) => allow(obj).to receive_messages(:foo => 1, :bar => 2)
|
55
|
+
with_node type: 'send', message: 'stub', arguments: {first: {type: 'hash'}} do
|
56
|
+
replace_with "allow({{receiver}}).to receive_messages({{arguments}})"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
within_files 'spec/**/*.rb' do
|
61
|
+
# allow(obj).to receive(:message).and_return { 1 } => allow(obj).to receive(:message) { 1 }
|
62
|
+
with_node type: 'send', receiver: {type: 'send', message: 'allow'}, arguments: {first: {type: 'block', caller: {type: 'send', message: 'and_return', arguments: []}}} do
|
63
|
+
replace_with "{{receiver}}.to {{arguments.first.caller.receiver}} { {{arguments.first.body}} }"
|
64
|
+
end
|
65
|
+
|
66
|
+
# allow(obj).to receive(:message).and_return => allow(obj).to receive(:message)
|
67
|
+
with_node type: 'send', receiver: {type: 'send', message: 'allow'}, arguments: {first: {type: 'send', message: 'and_return', arguments: []}} do
|
68
|
+
replace_with "{{receiver}}.to {{arguments.first.receiver}}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
Synvert::Rewriter.new "convert_rspec_negative_error_expectation", "RSpec converts negative error expectation" do
|
2
|
+
gem_spec 'rspec', '2.14.0'
|
3
|
+
|
4
|
+
within_files 'spec/**/*.rb' do
|
5
|
+
# expect { do_something }.not_to raise_error(SomeErrorClass) => expect { do_something }.not_to raise_error
|
6
|
+
# expect { do_something }.not_to raise_error('message') => expect { do_something }.not_to raise_error
|
7
|
+
# expect { do_something }.not_to raise_error(SomeErrorClass, 'message') => expect { do_something }.not_to raise_error
|
8
|
+
within_node type: 'send', receiver: {type: 'block'}, message: 'not_to' do
|
9
|
+
with_node type: 'send', message: 'raise_error' do
|
10
|
+
replace_with "raise_error"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
Synvert::Rewriter.new "rspec_new_syntax", "Use RSpec new syntax" do
|
2
|
+
add_snippet "convert_rspec_should_to_expect"
|
3
|
+
add_snippet "convert_rspec_block_to_expect"
|
4
|
+
add_snippet "convert_rspec_one_liner_expectation"
|
5
|
+
add_snippet "convert_rspec_boolean_matcher"
|
6
|
+
add_snippet "convert_rspec_be_close_to_be_within"
|
7
|
+
add_snippet "convert_rspec_collection_matcher"
|
8
|
+
add_snippet "convert_rspec_negative_error_expectation"
|
9
|
+
add_snippet "convert_rspec_its_to_it"
|
10
|
+
|
11
|
+
add_snippet "convert_rspec_stub_and_mock_to_double"
|
12
|
+
add_snippet "convert_rspec_message_expectation"
|
13
|
+
add_snippet "convert_rspec_method_stub"
|
14
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
Synvert::Rewriter.new "convert_rspec_one_liner_expectation", "RSpec converts one liner expectation" do
|
2
|
+
gem_spec 'rspec', '2.99.0'
|
3
|
+
|
4
|
+
{should: 'to', should_not: 'not_to'}.each do |old_message, new_message|
|
5
|
+
matcher_converters = {have: 'eq', have_exactly: 'eq', have_at_least: 'be >=', have_at_most: 'be <='}
|
6
|
+
matcher_converters.each do |old_matcher, new_matcher|
|
7
|
+
within_files 'spec/**/*.rb' do
|
8
|
+
# it { should have(3).items }
|
9
|
+
# =>
|
10
|
+
# it 'has 3 items' do
|
11
|
+
# expect(subject.size).to eq(3)
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# it { should have_at_least(3).players }
|
15
|
+
# =>
|
16
|
+
# it 'has at least 3 players' do
|
17
|
+
# expect(subject.players.size).to be >= 3
|
18
|
+
# end
|
19
|
+
with_node type: 'block', caller: {message: 'it'} do
|
20
|
+
if_only_exist_node type: 'send', receiver: nil, message: old_message, arguments: {first: {type: 'send', receiver: {type: 'send', message: old_matcher}}} do
|
21
|
+
times = node.body.first.arguments.first.receiver.arguments.first.source(self)
|
22
|
+
items_name = node.body.first.arguments.first.message
|
23
|
+
if :items == items_name
|
24
|
+
replace_with """it 'has #{times} items' do
|
25
|
+
expect(subject.size).#{new_message} #{new_matcher}(#{times})
|
26
|
+
end"""
|
27
|
+
else
|
28
|
+
it_message = "#{old_matcher.to_s.sub('have', 'has').gsub('_', ' ')} #{times} #{items_name}"
|
29
|
+
replace_with """it '#{it_message}' do
|
30
|
+
expect(subject.#{items_name}.size).#{new_message} #{new_matcher} #{times}
|
31
|
+
end"""
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
{should: 'to', should_not: 'not_to'}.each do |old_message, new_message|
|
40
|
+
within_files 'spec/**/*.rb' do
|
41
|
+
# it { should matcher } => it { is_expected.to matcher }
|
42
|
+
# it { should_not matcher } => it { is_expected.not_to matcher }
|
43
|
+
with_node type: 'block', caller: {message: 'it'} do
|
44
|
+
if_only_exist_node type: 'send', receiver: nil, message: old_message do
|
45
|
+
matcher = node.body.first.arguments.first.source(self)
|
46
|
+
replace_with "it { is_expected.#{new_message} #{matcher} }"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
Synvert::Rewriter.new "convert_rspec_should_to_expect", "RSpec converts should to expect" do
|
2
|
+
gem_spec 'rspec', '2.11.0'
|
3
|
+
|
4
|
+
{should: 'to', should_not: 'not_to'}.each do |old_message, new_message|
|
5
|
+
within_files 'spec/**/*.rb' do
|
6
|
+
# obj.should matcher => expect(obj).to matcher
|
7
|
+
# obj.should_not matcher => expect(obj).not_to matcher
|
8
|
+
with_node type: 'send', receiver: {type: {not: 'block'}}, message: old_message do
|
9
|
+
if node.receiver && node.arguments.size > 0
|
10
|
+
replace_with "expect({{receiver}}).#{new_message} {{arguments}}"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
{'==' => 'eq', '<' => 'be <', '>' => 'be >', '<=' => 'be <=', '>=' => 'be >=', '===' => 'be ==='}.each do |old_matcher, new_matcher|
|
16
|
+
within_files 'spec/**/*.rb' do
|
17
|
+
# 1.should == 1 => expect(1).to eq 1
|
18
|
+
# 1.should < 1 => expect(1).to be < 2
|
19
|
+
# Integer.should === 1 => expect(Integer).to be === 1
|
20
|
+
with_node type: 'send', receiver: {type: 'send', message: old_message}, message: old_matcher do
|
21
|
+
if node.receiver.receiver
|
22
|
+
replace_with "expect({{receiver.receiver}}).#{new_message} #{new_matcher} {{arguments}}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
within_files 'spec/**/*.rb' do
|
29
|
+
# 'string'.should =~ /^str/ => expect('string').to match /^str/
|
30
|
+
# [1, 2, 3].should =~ [2, 1, 3] => expect([1, 2, 3]).to match_array [2, 1, 3]
|
31
|
+
with_node type: 'send', receiver: {type: 'send', message: old_message}, message: '=~' do
|
32
|
+
if :regexp == node.arguments.first.type
|
33
|
+
replace_with "expect({{receiver.receiver}}).#{new_message} match {{arguments}}"
|
34
|
+
else
|
35
|
+
replace_with "expect({{receiver.receiver}}).#{new_message} match_array {{arguments}}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
Synvert::Rewriter.new "convert_rspec_stub_and_mock_to_double", "RSpec converts stub and mock to double" do
|
2
|
+
gem_spec 'rspec', '2.14.0'
|
3
|
+
|
4
|
+
within_files 'spec/**/*.rb' do
|
5
|
+
# stub('something') => double('something')
|
6
|
+
# mock('something') => double('something')
|
7
|
+
with_node type: 'send', receiver: nil, message: 'stub' do
|
8
|
+
replace_with "double({{arguments}})"
|
9
|
+
end
|
10
|
+
|
11
|
+
with_node type: 'send', receiver: nil, message: 'mock' do
|
12
|
+
replace_with "double({{arguments}})"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/synvert/version.rb
CHANGED
@@ -67,9 +67,19 @@ describe Parser::AST::Node do
|
|
67
67
|
end
|
68
68
|
|
69
69
|
describe '#body' do
|
70
|
-
it 'gets for block node' do
|
70
|
+
it 'gets one line for block node' do
|
71
71
|
node = parse('RSpec.configure do |config|; include EmailSpec::Helpers; end')
|
72
|
-
expect(node.body).to eq parse('include EmailSpec::Helpers')
|
72
|
+
expect(node.body).to eq [parse('include EmailSpec::Helpers')]
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'gets multiple lines for block node' do
|
76
|
+
node = parse('RSpec.configure do |config|; include EmailSpec::Helpers; include EmailSpec::Matchers; end')
|
77
|
+
expect(node.body).to eq [parse('include EmailSpec::Helpers'), parse('include EmailSpec::Matchers')]
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'gets for begin node' do
|
81
|
+
node = parse('foo; bar')
|
82
|
+
expect(node.body).to eq [parse('foo'), parse('bar')]
|
73
83
|
end
|
74
84
|
end
|
75
85
|
|
@@ -132,6 +142,13 @@ describe Parser::AST::Node do
|
|
132
142
|
expect(node).to be_match(instance, type: 'send', receiver: 'params', message: '[]', arguments: [:user])
|
133
143
|
end
|
134
144
|
|
145
|
+
it 'matches assign number' do
|
146
|
+
source = 'at_least(0)'
|
147
|
+
instance.current_source = source
|
148
|
+
node = parse(source)
|
149
|
+
expect(node).to be_match(instance, type: 'send', arguments: [0])
|
150
|
+
end
|
151
|
+
|
135
152
|
it 'matches arguments with string' do
|
136
153
|
source = 'params["user"]'
|
137
154
|
instance.current_source = source
|
@@ -145,5 +162,12 @@ describe Parser::AST::Node do
|
|
145
162
|
node = parse(source)
|
146
163
|
expect(node).to be_match(instance, type: 'send', arguments: {any: 'Lifo::Cache'})
|
147
164
|
end
|
165
|
+
|
166
|
+
it 'matches not' do
|
167
|
+
source = 'class Synvert; end'
|
168
|
+
instance.current_source = source
|
169
|
+
node = parse(source)
|
170
|
+
expect(node).not_to be_match(instance, type: 'class', name: {not: 'Synvert'})
|
171
|
+
end
|
148
172
|
end
|
149
173
|
end
|
@@ -2,23 +2,52 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
module Synvert
|
4
4
|
describe Rewriter::ReplaceWithAction do
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
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
|
+
}
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
13
|
+
it 'gets begin_pos' do
|
14
|
+
expect(subject.begin_pos).to eq "post = ".length
|
15
|
+
end
|
15
16
|
|
16
|
-
|
17
|
-
|
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
|
18
24
|
end
|
19
25
|
|
20
|
-
|
21
|
-
|
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
|
22
51
|
end
|
23
52
|
end
|
24
53
|
|
@@ -0,0 +1,183 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Use RSpec new syntax' do
|
4
|
+
before do
|
5
|
+
Synvert::Configuration.instance.set :path, '.'
|
6
|
+
allow_any_instance_of(Synvert::Rewriter::GemSpec).to receive(:match?).and_return(true)
|
7
|
+
Dir.glob File.join(File.dirname(__FILE__), '../../../../lib/synvert/snippets/rspec/*') do |file|
|
8
|
+
if file =~ /new_syntax.rb$/
|
9
|
+
@rewriter = eval(File.read(file))
|
10
|
+
else
|
11
|
+
eval(File.read(file))
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe 'rspec', fakefs: true do
|
17
|
+
let(:post_spec_content) {"""
|
18
|
+
it 'case' do
|
19
|
+
obj.should matcher
|
20
|
+
obj.should_not matcher
|
21
|
+
|
22
|
+
1.should == 1
|
23
|
+
1.should < 2
|
24
|
+
Integer.should === 1
|
25
|
+
'string'.should =~ /^str/
|
26
|
+
[1, 2, 3].should =~ [2, 1, 3]
|
27
|
+
|
28
|
+
expect(obj).to be_true
|
29
|
+
expect(obj).to be_false
|
30
|
+
|
31
|
+
expect(1.0 / 3.0).to be_close(0.333, 0.001)
|
32
|
+
|
33
|
+
expect(collection).to have(3).items
|
34
|
+
expect(collection).to have_exactly(3).items
|
35
|
+
expect(collection).to have_at_least(3).items
|
36
|
+
expect(collection).to have_at_most(3).items
|
37
|
+
|
38
|
+
expect(team).to have(3).players
|
39
|
+
|
40
|
+
lambda { do_something }.should raise_error
|
41
|
+
proc { do_something }.should raise_error
|
42
|
+
-> { do_something }.should raise_error
|
43
|
+
|
44
|
+
expect { do_something }.not_to raise_error(SomeErrorClass)
|
45
|
+
expect { do_something }.not_to raise_error('message')
|
46
|
+
expect { do_something }.not_to raise_error(SomeErrorClass, 'message')
|
47
|
+
|
48
|
+
obj.should_receive(:message)
|
49
|
+
Klass.any_instance.should_receive(:message)
|
50
|
+
|
51
|
+
obj.stub(:message)
|
52
|
+
obj.stub!(:message)
|
53
|
+
obj.stub_chain(:foo, :bar, :baz)
|
54
|
+
Klass.any_instance.stub(:message)
|
55
|
+
|
56
|
+
obj.stub(:foo => 1, :bar => 2)
|
57
|
+
|
58
|
+
obj.unstub!(:message)
|
59
|
+
|
60
|
+
obj.stub(:message).any_number_of_times
|
61
|
+
obj.stub(:message).at_least(0)
|
62
|
+
|
63
|
+
expect(obj).to receive(:message).and_return { 1 }
|
64
|
+
allow(obj).to receive(:message).and_return { 1 }
|
65
|
+
|
66
|
+
expect(obj).to receive(:message).and_return
|
67
|
+
allow(obj).to receive(:message).and_return
|
68
|
+
|
69
|
+
stub('something')
|
70
|
+
mock('something')
|
71
|
+
end
|
72
|
+
|
73
|
+
it { should matcher }
|
74
|
+
it { should_not matcher }
|
75
|
+
|
76
|
+
it { should have(3).items }
|
77
|
+
it { should have_at_least(3).players }
|
78
|
+
|
79
|
+
describe 'example' do
|
80
|
+
subject { { foo: 1, bar: 2 } }
|
81
|
+
its(:size) { should == 2 }
|
82
|
+
its([:foo]) { should == 1 }
|
83
|
+
its('keys.first') { should == :foo }
|
84
|
+
end
|
85
|
+
"""}
|
86
|
+
let(:post_spec_rewritten_content) {"""
|
87
|
+
it 'case' do
|
88
|
+
expect(obj).to matcher
|
89
|
+
expect(obj).not_to matcher
|
90
|
+
|
91
|
+
expect(1).to eq 1
|
92
|
+
expect(1).to be < 2
|
93
|
+
expect(Integer).to be === 1
|
94
|
+
expect('string').to match /^str/
|
95
|
+
expect([1, 2, 3]).to match_array [2, 1, 3]
|
96
|
+
|
97
|
+
expect(obj).to be_truthy
|
98
|
+
expect(obj).to be_falsey
|
99
|
+
|
100
|
+
expect(1.0 / 3.0).to be_within(0.001).of(0.333)
|
101
|
+
|
102
|
+
expect(collection.size).to eq 3
|
103
|
+
expect(collection.size).to eq 3
|
104
|
+
expect(collection.size).to be >= 3
|
105
|
+
expect(collection.size).to be <= 3
|
106
|
+
|
107
|
+
expect(team.players.size).to eq 3
|
108
|
+
|
109
|
+
expect { do_something }.to raise_error
|
110
|
+
expect { do_something }.to raise_error
|
111
|
+
expect { do_something }.to raise_error
|
112
|
+
|
113
|
+
expect { do_something }.not_to raise_error
|
114
|
+
expect { do_something }.not_to raise_error
|
115
|
+
expect { do_something }.not_to raise_error
|
116
|
+
|
117
|
+
expect(obj).to receive(:message)
|
118
|
+
expect_any_instance_of(Klass).to receive(:message)
|
119
|
+
|
120
|
+
allow(obj).to receive(:message)
|
121
|
+
allow(obj).to receive(:message)
|
122
|
+
allow(obj).to receive_message_chain(:foo, :bar, :baz)
|
123
|
+
allow_any_instance_of(Klass).to receive(:message)
|
124
|
+
|
125
|
+
allow(obj).to receive_messages(:foo => 1, :bar => 2)
|
126
|
+
|
127
|
+
obj.unstub(:message)
|
128
|
+
|
129
|
+
allow(obj).to receive(:message)
|
130
|
+
allow(obj).to receive(:message)
|
131
|
+
|
132
|
+
expect(obj).to receive(:message) { 1 }
|
133
|
+
allow(obj).to receive(:message) { 1 }
|
134
|
+
|
135
|
+
expect(obj).to receive(:message)
|
136
|
+
allow(obj).to receive(:message)
|
137
|
+
|
138
|
+
double('something')
|
139
|
+
double('something')
|
140
|
+
end
|
141
|
+
|
142
|
+
it { is_expected.to matcher }
|
143
|
+
it { is_expected.not_to matcher }
|
144
|
+
|
145
|
+
it 'has 3 items' do
|
146
|
+
expect(subject.size).to eq(3)
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'has at least 3 players' do
|
150
|
+
expect(subject.players.size).to be >= 3
|
151
|
+
end
|
152
|
+
|
153
|
+
describe 'example' do
|
154
|
+
subject { { foo: 1, bar: 2 } }
|
155
|
+
|
156
|
+
describe '#size' do
|
157
|
+
subject { super().size }
|
158
|
+
it { should == 2 }
|
159
|
+
end
|
160
|
+
|
161
|
+
describe '[:foo]' do
|
162
|
+
subject { super()[:foo] }
|
163
|
+
it { should == 1 }
|
164
|
+
end
|
165
|
+
|
166
|
+
describe '#keys' do
|
167
|
+
subject { super().keys }
|
168
|
+
describe '#first' do
|
169
|
+
subject { super().first }
|
170
|
+
it { should == :foo }
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
"""}
|
175
|
+
|
176
|
+
it 'process' do
|
177
|
+
FileUtils.mkdir_p 'spec/models'
|
178
|
+
File.write 'spec/models/post_spec.rb', post_spec_content
|
179
|
+
@rewriter.process
|
180
|
+
expect(File.read 'spec/models/post_spec.rb').to eq post_spec_rewritten_content
|
181
|
+
end
|
182
|
+
end
|
183
|
+
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.10
|
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-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parser
|
@@ -128,6 +128,18 @@ files:
|
|
128
128
|
- lib/synvert/snippets/rails/upgrade_3_0_to_3_1.rb
|
129
129
|
- lib/synvert/snippets/rails/upgrade_3_1_to_3_2.rb
|
130
130
|
- lib/synvert/snippets/rails/upgrade_3_2_to_4_0.rb
|
131
|
+
- lib/synvert/snippets/rspec/be_close_to_be_within.rb
|
132
|
+
- lib/synvert/snippets/rspec/block_to_expect.rb
|
133
|
+
- lib/synvert/snippets/rspec/boolean_matcher.rb
|
134
|
+
- lib/synvert/snippets/rspec/collection_matcher.rb
|
135
|
+
- lib/synvert/snippets/rspec/its_to_it.rb
|
136
|
+
- lib/synvert/snippets/rspec/message_expectation.rb
|
137
|
+
- lib/synvert/snippets/rspec/method_stub.rb
|
138
|
+
- lib/synvert/snippets/rspec/negative_error_expectation.rb
|
139
|
+
- lib/synvert/snippets/rspec/new_syntax.rb
|
140
|
+
- lib/synvert/snippets/rspec/one_liner_expectation.rb
|
141
|
+
- lib/synvert/snippets/rspec/should_to_expect.rb
|
142
|
+
- lib/synvert/snippets/rspec/stub_and_mock_to_double.rb
|
131
143
|
- lib/synvert/version.rb
|
132
144
|
- spec/spec_helper.rb
|
133
145
|
- spec/support/parser_helper.rb
|
@@ -144,6 +156,7 @@ files:
|
|
144
156
|
- spec/synvert/snippets/rails/upgrade_3_0_to_3_1_spec.rb
|
145
157
|
- spec/synvert/snippets/rails/upgrade_3_1_to_3_2_spec.rb
|
146
158
|
- spec/synvert/snippets/rails/upgrade_3_2_to_4_0_spec.rb
|
159
|
+
- spec/synvert/snippets/rspec/new_syntax_spec.rb
|
147
160
|
- synvert.gemspec
|
148
161
|
homepage: ''
|
149
162
|
licenses:
|
@@ -185,3 +198,4 @@ test_files:
|
|
185
198
|
- spec/synvert/snippets/rails/upgrade_3_0_to_3_1_spec.rb
|
186
199
|
- spec/synvert/snippets/rails/upgrade_3_1_to_3_2_spec.rb
|
187
200
|
- spec/synvert/snippets/rails/upgrade_3_2_to_4_0_spec.rb
|
201
|
+
- spec/synvert/snippets/rspec/new_syntax_spec.rb
|