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 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