synvert 0.0.9 → 0.0.10
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.
- 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
|
[](http://travis-ci.org/xinminlabs/synvert)
|
4
4
|
[](https://coveralls.io/r/xinminlabs/synvert)
|
5
|
+
[](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
|