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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 15b18499a48bc225d4ae1c3bda5b9cb1c1040a49
4
- data.tar.gz: 378b683c0d0844c5c7d6b6b00ad4be92abf5da25
3
+ metadata.gz: 614d00dc632a03aa4e33b46e9abd3632e3cd1192
4
+ data.tar.gz: cda16861b6998679c265db36fa32c094ca391417
5
5
  SHA512:
6
- metadata.gz: 564b0445b50d28b9a14ed805320e68821f3dbaa87923519f6014c1e64bb0c9fdf6576585c9d52c05df38a9312c720393802bce2b365e2867f63aa5cb95be905c
7
- data.tar.gz: 3a64f525fec4d10f99fa39243e369373e37e453ce90bc2f81f527b0c4ea62bdd4b41f28859d8275d84fa8ebdd91f2b4e0ce800717586d244cb2c38a008aec834
6
+ metadata.gz: dc0094150dfdc672a9f4cbe95ba484cedf065d778a988b60790c2a417748b1e7b07c50e74df7fe3b44835f32313c4ac7708e0928b5cac4db41f5fd9ad59c8f24
7
+ data.tar.gz: 2531c8a731dcfcf741634f23450abd0415b630197c64845958a3f81dd3f7d7b43b3d07ef706c31c1bf7d650beb04e9b4c7c768ad05fdb22694212f1fe90ed781
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 0.0.10
4
+
5
+ * Add not ast node operator
6
+ * Replace with multipe line code
7
+ * Add RSpec new syntax snippet
8
+
3
9
  ## 0.0.9
4
10
 
5
11
  * Add add_file dsl
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 | FactoryGirl uses short syntax
45
- convert_dynamic_finders | Convert dynamic finders
46
- strong_parameters | Use strong_parameters syntax
47
- upgrade_rails_3_2_to_4_0 | Upgrade rails from 3.2 to 4.0, it contains convert_dynamic_finder and strong_parameters snippets
48
- upgrade_rails_3_1_to_3_2 | Upgrade rails from 3.1 to 3.2
49
- upgrade_rails_3_0_to_3_1 | Upgrade rails from 3.0 to 3.1
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
 
@@ -48,8 +48,11 @@ class Parser::AST::Node
48
48
  end
49
49
 
50
50
  def body
51
- if :block == self.type
52
- self.children[2]
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
- source = evaluated.first.loc.expression.source_buffer.source
108
- source[evaluated.first.loc.expression.begin_pos...evaluated.last.loc.expression.end_pos]
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
- @node.rewritten_source(@code)
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
- :begin != @instance.current_node.body.type &&
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
@@ -1,4 +1,4 @@
1
- Synvert::Rewriter.new 'upgrade_rails_3_1_to_3_2', 'Upgrade rails from 3.0 to 3.1' do
1
+ Synvert::Rewriter.new 'upgrade_rails_3_0_to_3_1', 'Upgrade rails from 3.0 to 3.1' do
2
2
  gem_spec 'rails', '3.0.0'
3
3
 
4
4
  within_file 'config/application.rb' do
@@ -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
@@ -1,5 +1,5 @@
1
1
  # coding: utf-8
2
2
 
3
3
  module Synvert
4
- VERSION = "0.0.9"
4
+ VERSION = "0.0.10"
5
5
  end
@@ -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
- subject {
6
- source = "post = FactoryGirl.create_list :post, 2"
7
- send_node = Parser::CurrentRuby.parse(source).children[1]
8
- instance = double(:current_node => send_node)
9
- Rewriter::ReplaceWithAction.new(instance, 'create_list {{arguments}}')
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
- it 'gets begin_pos' do
13
- expect(subject.begin_pos).to eq "post = ".length
14
- end
13
+ it 'gets begin_pos' do
14
+ expect(subject.begin_pos).to eq "post = ".length
15
+ end
15
16
 
16
- it 'gets end_pos' do
17
- expect(subject.end_pos).to eq "post = FactoryGirl.create_list :post, 2".length
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
- it 'gets rewritten_code' do
21
- expect(subject.rewritten_code).to eq 'create_list :post, 2'
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.9
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-28 00:00:00.000000000 Z
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