transpec 1.11.1 → 1.12.0

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: be81d8c6008e09a8dd02f276b7dd3b01155b28be
4
- data.tar.gz: 06c16bc90a1ba3851bc4004f29aadb1daf736dd4
3
+ metadata.gz: 9028442bbb2a56a7ad1ef1a0205980d1f460ca95
4
+ data.tar.gz: 136e4e0450ee5747ac17922275b1b1dad1b1991a
5
5
  SHA512:
6
- metadata.gz: f7cd465d319c14f360688e20e34c3cf8ce66b7f209d7cbd2f9b84397761d9ec44f39f0f78c19fa474af8509f0d894c54154f982dbc677d7ab6be1be5ec6c4478
7
- data.tar.gz: 212dcc0282e32fc1a64a1887d3159635434cdfb48567a34a077c9c6712f578f277a4ab229e6c0a9e5ac569dbf51f7d308603d96ec31123d607bb18e0bc38ba71
6
+ metadata.gz: 401af30bd4fdfb1144dd5d1d9577b12e2d043c9800b0b0a23edc973c7be6af3da89b426e900b4d31f5ea827e594a4203243c9437b9194715453386b9a49b9688
7
+ data.tar.gz: 3722e2241be35ef86e5b2df35e777322c63759a994c84fb4066813650521c7d05cf27526005d2320ba341d9447798a183215cbd112c863e42ce952f7349faa3e
data/.gitignore CHANGED
@@ -16,3 +16,4 @@ test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
18
  /vendor
19
+ .cache
data/CHANGELOG.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  ## Development
4
4
 
5
+ ## v1.12.0
6
+
7
+ * Support conversion of hook scope names ([#53](https://github.com/yujinakayama/transpec/issues/53))
8
+
5
9
  ## v1.11.1
6
10
 
7
11
  * Add missing description of `example_group` for `-v/--convert` option in the `-h/--help` text
data/lib/transpec/cli.rb CHANGED
@@ -134,7 +134,7 @@ module Transpec
134
134
  puts 'A commit message that describes the conversion summary was generated to'.color(:cyan)
135
135
  puts '.git/COMMIT_EDITMSG. To use the message, type the following command for'.color(:cyan)
136
136
  puts 'the next commit:'.color(:cyan)
137
- puts ' git commit -eF .git/COMMIT_EDITMSG'
137
+ puts ' git commit -aeF .git/COMMIT_EDITMSG'
138
138
  end
139
139
 
140
140
  def display_final_guide
@@ -19,6 +19,7 @@ module Transpec
19
19
  [:add_receiver_arg_to_any_instance_implementation_block, true],
20
20
  [:convert_stub_with_hash_to_allow_to_receive_and_return, false],
21
21
  [:convert_example_group, false],
22
+ [:convert_hook_scope, false],
22
23
  [:forced, false],
23
24
  [:skip_dynamic_analysis, false]
24
25
  ].freeze
@@ -214,6 +214,11 @@ module Transpec
214
214
  have.convert_to_standard_expectation!(configuration.parenthesize_matcher_arg)
215
215
  end
216
216
 
217
+ def process_hook(hook)
218
+ return if !configuration.convert_hook_scope? || !rspec_version.hook_scope_alias_available?
219
+ hook.convert_scope_name!
220
+ end
221
+
217
222
  def process_messaging_host(messaging_host)
218
223
  process_useless_and_return(messaging_host)
219
224
  process_any_instance_block(messaging_host)
@@ -21,8 +21,9 @@ module Transpec
21
21
  }
22
22
 
23
23
  CONFIG_ATTRS_FOR_CONVERT_TYPES = {
24
- stub_with_hash: :convert_stub_with_hash_to_allow_to_receive_and_return=,
25
- example_group: :convert_example_group=
24
+ example_group: :convert_example_group=,
25
+ hook_scope: :convert_hook_scope=,
26
+ stub_with_hash: :convert_stub_with_hash_to_allow_to_receive_and_return=
26
27
  }
27
28
 
28
29
  VALID_BOOLEAN_MATCHER_TYPES = %w(truthy,falsey truthy,falsy true,false)
@@ -149,6 +150,7 @@ module Transpec
149
150
  'Enable specific conversions that are disabled by default.',
150
151
  'Conversion Types:',
151
152
  ' *example_group* (`describe` to `RSpec.describe`)',
153
+ ' *hook_scope* (`before(:all)` to `before(:context)`)',
152
154
  ' *stub_with_hash* (`obj.stub(:msg => val)` to',
153
155
  ' `allow(obj).to receive(:msg).and_return(val)`)',
154
156
  'These conversions are disabled by default.'
@@ -50,6 +50,7 @@ module Transpec
50
50
  define_feature :receive_message_chain, '3.0.0.beta2'
51
51
  define_feature :non_should_matcher_protocol, '3.0.0.beta2'
52
52
  define_feature :non_monkey_patch_example_group, '3.0.0.beta2'
53
+ define_feature :hook_scope_alias, '3.0.0.beta2'
53
54
 
54
55
  RSPEC_2_99 = new('2.99.0.beta1')
55
56
  RSPEC_3_0 = new('3.0.0.beta1')
@@ -129,7 +129,7 @@ module Transpec
129
129
 
130
130
  if arg_node && [:sym, :str].include?(arg_node.type)
131
131
  hook_arg = arg_node.children.first.to_sym
132
- return :all_before_after if hook_arg == :all
132
+ return :all_before_after if [:all, :context].include?(hook_arg)
133
133
  end
134
134
 
135
135
  :each_before_after
@@ -0,0 +1,45 @@
1
+ # coding: utf-8
2
+
3
+ require 'transpec/syntax'
4
+ require 'transpec/syntax/mixin/send'
5
+ require 'transpec/rspec_dsl'
6
+
7
+ module Transpec
8
+ class Syntax
9
+ class Hook < Syntax
10
+ include Mixin::Send, RSpecDSL
11
+
12
+ SCOPE_ALIASES = {
13
+ each: :example,
14
+ all: :context
15
+ }
16
+
17
+ def dynamic_analysis_target?
18
+ super && HOOK_METHODS.include?(method_name)
19
+ end
20
+
21
+ def convert_scope_name!
22
+ return if !scope_name || !replacement_scope_name
23
+ replace(arg_range, replacement_scope_name.inspect)
24
+ register_record
25
+ end
26
+
27
+ private
28
+
29
+ def scope_name
30
+ return nil unless arg_node
31
+ arg_node.children.first
32
+ end
33
+
34
+ def replacement_scope_name
35
+ SCOPE_ALIASES[scope_name]
36
+ end
37
+
38
+ def register_record
39
+ original_syntax = "#{method_name}(#{scope_name.inspect}) { }"
40
+ converted_syntax = "#{method_name}(#{replacement_scope_name.inspect}) { }"
41
+ report.records << Record.new(original_syntax, converted_syntax)
42
+ end
43
+ end
44
+ end
45
+ end
@@ -4,8 +4,8 @@ module Transpec
4
4
  # http://semver.org/
5
5
  module Version
6
6
  MAJOR = 1
7
- MINOR = 11
8
- PATCH = 1
7
+ MINOR = 12
8
+ PATCH = 0
9
9
 
10
10
  def self.to_s
11
11
  [MAJOR, MINOR, PATCH].join('.')
@@ -48,8 +48,8 @@ module CacheHelper
48
48
  def cache_dir
49
49
  @cache_dir ||= begin
50
50
  project_root = File.expand_path(File.join(File.dirname(__FILE__), '..', '..'))
51
- ruby_version = "#{RUBY_ENGINE}#{RUBY_VERSION}"
52
- cache_dir = File.join(project_root, 'tmp', 'spec_cache', ruby_version)
51
+ ruby_version = [RUBY_ENGINE, RUBY_VERSION].join('-')
52
+ cache_dir = File.join(project_root, '.cache', 'spec', ruby_version)
53
53
 
54
54
  unless Dir.exist?(cache_dir)
55
55
  require 'fileutils'
@@ -21,6 +21,7 @@ module Transpec
21
21
  [:add_receiver_arg_to_any_instance_implementation_block?, true],
22
22
  [:convert_stub_with_hash_to_allow_to_receive_and_return?, false],
23
23
  [:convert_example_group?, false],
24
+ [:convert_hook_scope?, false],
24
25
  [:forced?, false],
25
26
  [:skip_dynamic_analysis?, false],
26
27
  [:negative_form_of_to, 'not_to'],
@@ -830,6 +830,45 @@ module Transpec
830
830
  end
831
831
  end
832
832
 
833
+ describe '#process_hook' do
834
+ let(:hook_object) { double('hook_object').as_null_object }
835
+
836
+ context 'when Configuration#convert_hook_scope? is true' do
837
+ before { configuration.convert_hook_scope = true }
838
+
839
+ context 'when RSpecVersion#hook_scope_alias_available? returns true' do
840
+ before { rspec_version.stub(:hook_scope_alias_available?).and_return(true) }
841
+
842
+ it 'invokes Hook#convert_scope_name!' do
843
+ hook_object.should_receive(:convert_scope_name!)
844
+ converter.process_hook(hook_object)
845
+ end
846
+ end
847
+
848
+ context 'when RSpecVersion#hook_scope_alias_available? returns false' do
849
+ before { rspec_version.stub(:hook_scope_alias_available?).and_return(false) }
850
+
851
+ it 'does nothing' do
852
+ hook_object.should_not_receive(:convert_scope_name!)
853
+ converter.process_hook(hook_object)
854
+ end
855
+ end
856
+ end
857
+
858
+ context 'when Configuration#convert_hook_scope? is false' do
859
+ before { configuration.convert_hook_scope = false }
860
+
861
+ context 'when RSpecVersion#hook_scope_alias_available? returns true' do
862
+ before { rspec_version.stub(:hook_scope_alias_available?).and_return(true) }
863
+
864
+ it 'does nothing' do
865
+ hook_object.should_not_receive(:convert_scope_name!)
866
+ converter.process_hook(hook_object)
867
+ end
868
+ end
869
+ end
870
+ end
871
+
833
872
  describe '#process_raise_error' do
834
873
  let(:raise_error_object) { double('raise_error_object').as_null_object }
835
874
 
@@ -103,8 +103,9 @@ module Transpec
103
103
 
104
104
  describe '-v/--convert option' do
105
105
  [
106
- ['stub_with_hash', :convert_stub_with_hash_to_allow_to_receive_and_return?],
107
- ['example_group', :convert_example_group?]
106
+ ['example_group', :convert_example_group?],
107
+ ['hook_scope', :convert_hook_scope?],
108
+ ['stub_with_hash', :convert_stub_with_hash_to_allow_to_receive_and_return?]
108
109
  ].each do |cli_type, config_attr|
109
110
  context "when #{cli_type.inspect} is specified" do
110
111
  let(:args) { ['--convert', cli_type] }
@@ -256,20 +257,29 @@ module Transpec
256
257
  end
257
258
  end
258
259
 
259
- it 'describes all conversion types for -k/--keep option' do
260
- option_sections = help_text.lines.slice_before(/^\s*-/)
260
+ def description_for_option(option)
261
+ description_lines = parser.send(:descriptions)[option]
262
+ description_lines.map { |line| parser.send(:highlight_text, line) }
263
+ end
261
264
 
262
- keep_section = option_sections.find do |lines|
263
- lines.first =~ /^\s*-k/
264
- end
265
+ def conversion_types_for_option(option)
266
+ section = description_for_option(option)
265
267
 
266
- conversion_types = keep_section.reduce([]) do |types, line|
267
- match = line.match(/^[ ]{37}([a-z_]+)/)
268
- next types unless match
268
+ section.each_with_object([]) do |line, types|
269
+ match = line.match(/^[ ]{2}([a-z_]+)/)
270
+ next unless match
269
271
  types << match.captures.first
270
272
  end
273
+ end
274
+
275
+ it 'describes all conversion types for -k/--keep option' do
276
+ conversion_types = conversion_types_for_option('-k')
277
+ conversion_types.should =~ OptionParser::CONFIG_ATTRS_FOR_KEEP_TYPES.keys.map(&:to_s)
278
+ end
271
279
 
272
- conversion_types.should =~ OptionParser.available_conversion_types.map(&:to_s)
280
+ it 'describes all conversion types for -v/--convert option' do
281
+ conversion_types = conversion_types_for_option('-v')
282
+ conversion_types.should =~ OptionParser::CONFIG_ATTRS_FOR_CONVERT_TYPES.keys.map(&:to_s)
273
283
  end
274
284
  end
275
285
  end
@@ -71,7 +71,8 @@ module Transpec
71
71
  [
72
72
  :receive_message_chain_available?,
73
73
  :non_should_matcher_protocol_available?,
74
- :non_monkey_patch_example_group_available?
74
+ :non_monkey_patch_example_group_available?,
75
+ :hook_scope_alias_available?
75
76
  ].each do |method|
76
77
  include_examples 'version comparisons', method, [
77
78
  ['2.14.0', false],
@@ -0,0 +1,215 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+ require 'transpec/syntax/hook'
5
+
6
+ module Transpec
7
+ class Syntax
8
+ describe Hook do
9
+ include_context 'parsed objects'
10
+ include_context 'syntax object', Hook, :hook_object
11
+
12
+ let(:record) { hook_object.report.records.last }
13
+
14
+ describe '#convert_scope_name!' do
15
+ before do
16
+ hook_object.convert_scope_name!
17
+ end
18
+
19
+ RSpecDSL::HOOK_METHODS.each do |hook_method|
20
+ context "with expression `#{hook_method}(:each) { }`" do
21
+ let(:source) do
22
+ <<-END
23
+ describe 'example' do
24
+ #{hook_method}(:each) do
25
+ do_something
26
+ end
27
+ end
28
+ END
29
+ end
30
+
31
+ let(:expected_source) do
32
+ <<-END
33
+ describe 'example' do
34
+ #{hook_method}(:example) do
35
+ do_something
36
+ end
37
+ end
38
+ END
39
+ end
40
+
41
+ it "converts to `#{hook_method}(:example) { }` form" do
42
+ rewritten_source.should == expected_source
43
+ end
44
+
45
+ it "adds record `#{hook_method}(:each) { }` -> `#{hook_method}(:example) { }`" do
46
+ record.original_syntax.should == "#{hook_method}(:each) { }"
47
+ record.converted_syntax.should == "#{hook_method}(:example) { }"
48
+ end
49
+ end
50
+ end
51
+
52
+ [:before, :after].each do |hook_method|
53
+ context "with expression `#{hook_method}(:all) { }`" do
54
+ let(:source) do
55
+ <<-END
56
+ describe 'example' do
57
+ #{hook_method}(:all) do
58
+ do_something
59
+ end
60
+ end
61
+ END
62
+ end
63
+
64
+ let(:expected_source) do
65
+ <<-END
66
+ describe 'example' do
67
+ #{hook_method}(:context) do
68
+ do_something
69
+ end
70
+ end
71
+ END
72
+ end
73
+
74
+ it "converts to `#{hook_method}(:context) { }` form" do
75
+ rewritten_source.should == expected_source
76
+ end
77
+
78
+ it "adds record `#{hook_method}(:all) { }` -> `#{hook_method}(:context) { }`" do
79
+ record.original_syntax.should == "#{hook_method}(:all) { }"
80
+ record.converted_syntax.should == "#{hook_method}(:context) { }"
81
+ end
82
+ end
83
+
84
+ context "with expression `RSpec.configure { |c| c.#{hook_method}(:each) { } }`" do
85
+ let(:source) do
86
+ <<-END
87
+ RSpec.configure do |config|
88
+ config.#{hook_method}(:each) do
89
+ do_something
90
+ end
91
+ end
92
+ END
93
+ end
94
+
95
+ let(:expected_source) do
96
+ <<-END
97
+ RSpec.configure do |config|
98
+ config.#{hook_method}(:example) do
99
+ do_something
100
+ end
101
+ end
102
+ END
103
+ end
104
+
105
+ it "converts to `RSpec.configure { |c| c.#{hook_method}(:example) { } }` form" do
106
+ rewritten_source.should == expected_source
107
+ end
108
+
109
+ it "adds record `#{hook_method}(:each) { }` -> `#{hook_method}(:example) { }`" do
110
+ record.original_syntax.should == "#{hook_method}(:each) { }"
111
+ record.converted_syntax.should == "#{hook_method}(:example) { }"
112
+ end
113
+ end
114
+
115
+ context "with expression `RSpec.configure { |c| c.#{hook_method}(:suite) { } }`" do
116
+ let(:source) do
117
+ <<-END
118
+ RSpec.configure do |config|
119
+ config.#{hook_method}(:suite) do
120
+ do_something
121
+ end
122
+ end
123
+ END
124
+ end
125
+
126
+ it 'does nothing' do
127
+ rewritten_source.should == source
128
+ end
129
+
130
+ it 'does not add record' do
131
+ record.should be_nil
132
+ end
133
+ end
134
+ end
135
+
136
+ context 'with expression `before { }`' do
137
+ let(:source) do
138
+ <<-END
139
+ describe 'example' do
140
+ before do
141
+ do_something
142
+ end
143
+ end
144
+ END
145
+ end
146
+
147
+ it 'does nothing' do
148
+ rewritten_source.should == source
149
+ end
150
+
151
+ it 'does not add record' do
152
+ record.should be_nil
153
+ end
154
+ end
155
+
156
+ context 'with expression `before(variable) { }`' do
157
+ let(:source) do
158
+ <<-END
159
+ scope = :each
160
+
161
+ describe 'example' do
162
+ before(scope) do
163
+ do_something
164
+ end
165
+ end
166
+ END
167
+ end
168
+
169
+ it 'does nothing' do
170
+ rewritten_source.should == source
171
+ end
172
+
173
+ it 'does not add record' do
174
+ record.should be_nil
175
+ end
176
+ end
177
+
178
+ context 'with expression `before(:each, :type => :model) { }`' do
179
+ let(:source) do
180
+ <<-END
181
+ scope = :each
182
+
183
+ describe 'example' do
184
+ before(:each, :type => :model) do
185
+ do_something
186
+ end
187
+ end
188
+ END
189
+ end
190
+
191
+ let(:expected_source) do
192
+ <<-END
193
+ scope = :each
194
+
195
+ describe 'example' do
196
+ before(:example, :type => :model) do
197
+ do_something
198
+ end
199
+ end
200
+ END
201
+ end
202
+
203
+ it 'converts to `before(:example, :type => :model) { }` form' do
204
+ rewritten_source.should == expected_source
205
+ end
206
+
207
+ it 'adds record `before(:each) { }` -> `before(:example) { }`' do
208
+ record.original_syntax.should == 'before(:each) { }'
209
+ record.converted_syntax.should == 'before(:example) { }'
210
+ end
211
+ end
212
+ end
213
+ end
214
+ end
215
+ end
data/tasks/demo.rake CHANGED
@@ -1,13 +1,13 @@
1
1
  # coding: utf-8
2
2
 
3
- require_relative 'lib/transpec_demo'
3
+ require_relative 'lib/demo'
4
4
 
5
5
  namespace :demo do
6
6
  # rubocop:disable LineLength
7
7
  demos = [
8
- TranspecDemo.new('git@github.com:yujinakayama/twitter.git', 'transpec-test-rspec-2-99'),
9
- TranspecDemo.new('git@github.com:yujinakayama/guard.git', 'transpec-test-rspec-2-99', %w(--without development)),
10
- TranspecDemo.new('git@github.com:yujinakayama/mail.git', 'transpec-test-rspec-2-99')
8
+ Demo.new('git@github.com:yujinakayama/twitter.git', 'transpec-test-rspec-2-99'),
9
+ Demo.new('git@github.com:yujinakayama/guard.git', 'transpec-test-rspec-2-99', %w(--without development)),
10
+ Demo.new('git@github.com:yujinakayama/mail.git', 'transpec-test-rspec-2-99')
11
11
  ]
12
12
  # rubocop:enable LineLength
13
13
 
@@ -1,6 +1,6 @@
1
1
  Convert specs to RSpec 2.99.0.beta2 syntax with Transpec
2
2
 
3
- This conversion is done by Transpec 1.10.4 with the following command:
3
+ This conversion is done by Transpec 1.11.1 with the following command:
4
4
  transpec --force
5
5
 
6
6
  * 396 conversions
@@ -0,0 +1,32 @@
1
+ Convert specs to RSpec 3.0.0.beta2 syntax with Transpec
2
+
3
+ This conversion is done by Transpec 1.11.1 with the following command:
4
+ transpec --force --convert example_group,hook_scope
5
+
6
+ * 31 conversions
7
+ from: describe 'something' { }
8
+ to: RSpec.describe 'something' { }
9
+
10
+ * 16 conversions
11
+ from: obj.stub(:message => value)
12
+ to: allow(obj).to receive_messages(:message => value)
13
+
14
+ * 13 conversions
15
+ from: before(:all) { }
16
+ to: before(:context) { }
17
+
18
+ * 10 conversions
19
+ from: before(:each) { }
20
+ to: before(:example) { }
21
+
22
+ * 8 conversions
23
+ from: after(:all) { }
24
+ to: after(:context) { }
25
+
26
+ * 4 conversions
27
+ from: shared_examples_for 'something' { }
28
+ to: RSpec.shared_examples_for 'something' { }
29
+
30
+ * 1 conversion
31
+ from: after(:each) { }
32
+ to: after(:example) { }
@@ -1,6 +1,6 @@
1
1
  Convert specs to RSpec 2.99.0.beta2 syntax with Transpec
2
2
 
3
- This conversion is done by Transpec 1.10.4 with the following command:
3
+ This conversion is done by Transpec 1.11.1 with the following command:
4
4
  transpec --force
5
5
 
6
6
  * 2161 conversions
@@ -0,0 +1,28 @@
1
+ Convert specs to RSpec 3.0.0.beta2 syntax with Transpec
2
+
3
+ This conversion is done by Transpec 1.11.1 with the following command:
4
+ transpec --force --convert example_group,hook_scope
5
+
6
+ * 82 conversions
7
+ from: describe 'something' { }
8
+ to: RSpec.describe 'something' { }
9
+
10
+ * 39 conversions
11
+ from: before(:each) { }
12
+ to: before(:example) { }
13
+
14
+ * 4 conversions
15
+ from: after(:each) { }
16
+ to: after(:example) { }
17
+
18
+ * 1 conversion
19
+ from: after(:all) { }
20
+ to: after(:context) { }
21
+
22
+ * 1 conversion
23
+ from: before(:all) { }
24
+ to: before(:context) { }
25
+
26
+ * 1 conversion
27
+ from: obj.stub(:message => value)
28
+ to: allow(obj).to receive_messages(:message => value)
@@ -1,6 +1,6 @@
1
1
  Convert specs to RSpec 2.99.0.beta2 syntax with Transpec
2
2
 
3
- This conversion is done by Transpec 1.10.4 with the following command:
3
+ This conversion is done by Transpec 1.11.1 with the following command:
4
4
  transpec --force
5
5
 
6
6
  * 899 conversions
@@ -0,0 +1,16 @@
1
+ Convert specs to RSpec 3.0.0.beta2 syntax with Transpec
2
+
3
+ This conversion is done by Transpec 1.11.1 with the following command:
4
+ transpec --force --convert example_group,hook_scope
5
+
6
+ * 54 conversions
7
+ from: describe 'something' { }
8
+ to: RSpec.describe 'something' { }
9
+
10
+ * 1 conversion
11
+ from: after(:all) { }
12
+ to: after(:context) { }
13
+
14
+ * 1 conversion
15
+ from: before(:all) { }
16
+ to: before(:context) { }
data/tasks/lib/demo.rb ADDED
@@ -0,0 +1,46 @@
1
+ # coding: utf-8
2
+
3
+ require_relative 'project'
4
+
5
+ class Demo < Project
6
+ DEMO_BRANCH = 'transpec-demo'
7
+
8
+ def self.base_dir_path
9
+ File.join('tmp', 'demo')
10
+ end
11
+
12
+ def run
13
+ puts " Publishing conversion example of #{name} project ".center(80, '=')
14
+
15
+ setup
16
+
17
+ in_project_dir do
18
+ transpec '--force', '--convert', 'stub_with_hash'
19
+ sh 'bundle exec rspec'
20
+ sh "git checkout --quiet -b #{DEMO_BRANCH}"
21
+ sh 'git commit -aF .git/COMMIT_EDITMSG'
22
+ sh "git push --force origin #{DEMO_BRANCH}"
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ def transpec(*args)
29
+ sh File.join(Transpec.root, 'bin', 'transpec'), *args
30
+ end
31
+
32
+ def setup_from_remote
33
+ FileUtils.rm_rf(project_dir) if Dir.exist?(project_dir)
34
+ super
35
+ end
36
+
37
+ def shallow_clone?
38
+ false
39
+ end
40
+
41
+ def git_local_branch_exist?(branch)
42
+ in_project_dir do
43
+ system('git', 'show-ref', '--verify', '--quiet', "refs/heads/#{branch}")
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,129 @@
1
+ # coding: utf-8
2
+
3
+ require 'transpec'
4
+ require 'fileutils'
5
+
6
+ class Project
7
+ include FileUtils # This is Rake's one.
8
+
9
+ BUNDLER_RETRY_COUNT = 3
10
+
11
+ attr_reader :url, :ref, :bundler_args
12
+
13
+ def self.base_dir
14
+ @base_dir ||= begin
15
+ path = base_dir_path
16
+ FileUtils.mkdir_p(path) unless Dir.exist?(path)
17
+ path
18
+ end
19
+ end
20
+
21
+ def self.base_dir_path
22
+ File.join(Transpec.root, 'tmp', 'test')
23
+ end
24
+
25
+ def initialize(url, ref = nil, bundler_args = [])
26
+ @url = url
27
+ @ref = ref
28
+ @bundler_args = bundler_args
29
+ end
30
+
31
+ def name
32
+ @name ||= File.basename(url, '.git')
33
+ end
34
+
35
+ def project_dir
36
+ @project_dir ||= File.join(self.class.base_dir, name)
37
+ end
38
+
39
+ def in_project_dir
40
+ Dir.chdir(project_dir) do
41
+ with_clean_bundler_env do
42
+ yield
43
+ end
44
+ end
45
+ end
46
+
47
+ def git(*args)
48
+ in_project_dir do
49
+ sh 'git', *args
50
+ end
51
+ end
52
+
53
+ private
54
+
55
+ def setup
56
+ if url.start_with?('/')
57
+ setup_from_local
58
+ else
59
+ setup_from_remote
60
+ end
61
+ end
62
+
63
+ def setup_from_local
64
+ FileUtils.rm_rf(project_dir) if Dir.exist?(project_dir)
65
+ Dir.mkdir(project_dir)
66
+
67
+ Dir.chdir(url) do
68
+ Dir.new('.').each do |entry|
69
+ next if ['.', '..', 'tmp'].include?(entry)
70
+ FileUtils.cp_r(entry, project_dir)
71
+ end
72
+ end
73
+
74
+ bundle_install
75
+ end
76
+
77
+ def setup_from_remote
78
+ if Dir.exist?(project_dir)
79
+ git 'checkout', '.'
80
+ git 'checkout', ref
81
+ else
82
+ git_clone
83
+ bundle_install
84
+ end
85
+ end
86
+
87
+ def git_clone
88
+ Dir.chdir(self.class.base_dir) do
89
+ # Disabling checkout here to suppress "detached HEAD" warning.
90
+ command = %w(git clone --no-checkout)
91
+ command.concat(%w(--depth 1)) if shallow_clone?
92
+ command.concat(['--branch', ref, url])
93
+ sh command.join(' ')
94
+ end
95
+
96
+ git 'checkout', '--quiet', ref
97
+ end
98
+
99
+ def shallow_clone?
100
+ true
101
+ end
102
+
103
+ def bundle_install
104
+ in_project_dir do
105
+ sh 'bundle', 'install', '--retry', BUNDLER_RETRY_COUNT.to_s, *bundler_args
106
+ end
107
+ end
108
+
109
+ def with_clean_bundler_env
110
+ if defined?(Bundler)
111
+ Bundler.with_clean_env do
112
+ # Bundler.with_clean_env cleans environment variables
113
+ # which are set after bundler is loaded.
114
+ prepare_env
115
+ yield
116
+ end
117
+ else
118
+ prepare_env
119
+ yield
120
+ end
121
+ end
122
+
123
+ def prepare_env
124
+ # Disable Coveralls.
125
+ ENV['CI'] = ENV['JENKINS_URL'] = ENV['COVERALLS_RUN_LOCALLY'] = nil
126
+
127
+ ENV['TRANSPEC_TEST'] = 'true'
128
+ end
129
+ end
data/tasks/lib/test.rb ADDED
@@ -0,0 +1,84 @@
1
+ # coding: utf-8
2
+
3
+ require 'rspec/expectations'
4
+ require_relative 'project'
5
+
6
+ class Test < Project
7
+ include RSpec::Matchers
8
+
9
+ attr_reader :simple
10
+ alias_method :simple?, :simple
11
+
12
+ def initialize(url, ref = nil, bundler_args = [], simple = false)
13
+ super(url, ref, bundler_args)
14
+ @simple = simple
15
+ end
16
+
17
+ def run
18
+ puts " Testing transpec on #{name} project ".center(80, '=')
19
+
20
+ setup
21
+
22
+ in_project_dir do
23
+ transpec '--force'
24
+ sh 'bundle exec rspec'
25
+ return if simple?
26
+ compare_summary!('2.99.0')
27
+
28
+ add_rspec_3_to_gemfile
29
+ sh 'bundle update'
30
+
31
+ transpec '--force', '--convert', 'example_group,hook_scope'
32
+ sh 'bundle exec rspec'
33
+ compare_summary!('3.0.0')
34
+ end
35
+ end
36
+
37
+ private
38
+
39
+ def transpec(*args)
40
+ sh File.join(Transpec.root, 'bin', 'transpec'), *args
41
+ end
42
+
43
+ def add_rspec_3_to_gemfile
44
+ gemfile = File.read('Gemfile')
45
+
46
+ pattern = /\bgem\s+['"]rspec.+/
47
+ rspec_3_specification = "gem 'rspec', '~> 3.0.0.beta1'"
48
+
49
+ if gemfile.match(pattern)
50
+ gemfile.sub!(pattern, rspec_3_specification)
51
+ else
52
+ gemfile << rspec_3_specification
53
+ end
54
+
55
+ File.write('Gemfile', gemfile)
56
+ end
57
+
58
+ def compare_summary!(key)
59
+ fixture_path = commit_message_fixture_path(key)
60
+
61
+ if File.exist?(fixture_path)
62
+ summary = summary_in_commit_message(File.read(commit_message_path))
63
+ expected_summary = summary_in_commit_message(File.read(fixture_path))
64
+ expect(summary).to eq(expected_summary)
65
+ else
66
+ warn "#{fixture_path} does not exist. Copying from #{commit_message_path}."
67
+ FileUtils.mkdir_p(File.dirname(fixture_path))
68
+ FileUtils.cp(commit_message_path, fixture_path)
69
+ end
70
+ end
71
+
72
+ def summary_in_commit_message(message)
73
+ message.lines.to_a[5..-1].join("\n")
74
+ end
75
+
76
+ def commit_message_path
77
+ File.join(project_dir, '.git', 'COMMIT_EDITMSG')
78
+ end
79
+
80
+ def commit_message_fixture_path(key)
81
+ path = File.join(Transpec.root, 'tasks', 'fixtures', name, key, 'COMMIT_EDITMSG')
82
+ File.expand_path(path)
83
+ end
84
+ end
data/tasks/test.rake CHANGED
@@ -1,6 +1,6 @@
1
1
  # coding: utf-8
2
2
 
3
- require_relative 'lib/transpec_test'
3
+ require_relative 'lib/test'
4
4
 
5
5
  namespace :test do
6
6
  # On Travis CI, reuse system gems to speed up build.
@@ -12,14 +12,14 @@ namespace :test do
12
12
 
13
13
  # rubocop:disable LineLength
14
14
  tests = [
15
- TranspecTest.new(File.expand_path('.'), nil, ['--quiet']),
16
- TranspecTest.new('https://github.com/yujinakayama/twitter.git', 'transpec-test-rspec-2-99', bundler_args),
17
- TranspecTest.new('https://github.com/yujinakayama/mail.git', 'transpec-test-rspec-2-99', bundler_args)
15
+ Test.new(Transpec.root, nil, ['--quiet'], true),
16
+ Test.new('https://github.com/yujinakayama/twitter.git', 'transpec-test-rspec-2-99', bundler_args),
17
+ Test.new('https://github.com/yujinakayama/mail.git', 'transpec-test-rspec-2-99', bundler_args)
18
18
  ]
19
19
 
20
20
  # Sometimes Guard fails with JRuby randomly.
21
21
  unless RUBY_ENGINE == 'jruby'
22
- tests << TranspecTest.new('https://github.com/yujinakayama/guard.git', 'transpec-test-rspec-2-99', bundler_args + %w(--without development))
22
+ tests << Test.new('https://github.com/yujinakayama/guard.git', 'transpec-test-rspec-2-99', bundler_args + %w(--without development))
23
23
  end
24
24
  # rubocop:enable LineLength
25
25
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: transpec
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.11.1
4
+ version: 1.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yuji Nakayama
@@ -284,6 +284,7 @@ files:
284
284
  - lib/transpec/syntax/have/dynamic_analysis.rb
285
285
  - lib/transpec/syntax/have/have_record.rb
286
286
  - lib/transpec/syntax/have/source_builder.rb
287
+ - lib/transpec/syntax/hook.rb
287
288
  - lib/transpec/syntax/its.rb
288
289
  - lib/transpec/syntax/matcher_definition.rb
289
290
  - lib/transpec/syntax/method_stub.rb
@@ -347,6 +348,7 @@ files:
347
348
  - spec/transpec/syntax/example_spec.rb
348
349
  - spec/transpec/syntax/expect_spec.rb
349
350
  - spec/transpec/syntax/have_spec.rb
351
+ - spec/transpec/syntax/hook_spec.rb
350
352
  - spec/transpec/syntax/its_spec.rb
351
353
  - spec/transpec/syntax/matcher_definition_spec.rb
352
354
  - spec/transpec/syntax/method_stub_spec.rb
@@ -362,11 +364,15 @@ files:
362
364
  - spec/transpec_spec.rb
363
365
  - tasks/ci/spec.rake
364
366
  - tasks/demo.rake
365
- - tasks/fixtures/guard/COMMIT_EDITMSG
366
- - tasks/fixtures/mail/COMMIT_EDITMSG
367
- - tasks/fixtures/twitter/COMMIT_EDITMSG
368
- - tasks/lib/transpec_demo.rb
369
- - tasks/lib/transpec_test.rb
367
+ - tasks/fixtures/guard/2.99.0/COMMIT_EDITMSG
368
+ - tasks/fixtures/guard/3.0.0/COMMIT_EDITMSG
369
+ - tasks/fixtures/mail/2.99.0/COMMIT_EDITMSG
370
+ - tasks/fixtures/mail/3.0.0/COMMIT_EDITMSG
371
+ - tasks/fixtures/twitter/2.99.0/COMMIT_EDITMSG
372
+ - tasks/fixtures/twitter/3.0.0/COMMIT_EDITMSG
373
+ - tasks/lib/demo.rb
374
+ - tasks/lib/project.rb
375
+ - tasks/lib/test.rb
370
376
  - tasks/readme.rake
371
377
  - tasks/test.rake
372
378
  - transpec.gemspec
@@ -428,6 +434,7 @@ test_files:
428
434
  - spec/transpec/syntax/example_spec.rb
429
435
  - spec/transpec/syntax/expect_spec.rb
430
436
  - spec/transpec/syntax/have_spec.rb
437
+ - spec/transpec/syntax/hook_spec.rb
431
438
  - spec/transpec/syntax/its_spec.rb
432
439
  - spec/transpec/syntax/matcher_definition_spec.rb
433
440
  - spec/transpec/syntax/method_stub_spec.rb
@@ -1,55 +0,0 @@
1
- # coding: utf-8
2
-
3
- require_relative 'transpec_test'
4
-
5
- class TranspecDemo < TranspecTest
6
- DEMO_BRANCH = 'transpec-demo'
7
-
8
- def self.base_dir_path
9
- @base_dir_path = File.join('tmp', 'demos')
10
- end
11
-
12
- def run
13
- require 'transpec'
14
-
15
- puts " Publishing conversion example of #{name} project ".center(80, '=')
16
-
17
- prepare_project
18
- run_demo
19
- end
20
-
21
- private
22
-
23
- def prepare_with_git_repo
24
- super
25
- git_branch_delete(DEMO_BRANCH) if git_local_branch_exist?(DEMO_BRANCH)
26
- end
27
-
28
- def shallow_clone?
29
- false
30
- end
31
-
32
- def run_demo(transpec_args = [])
33
- in_project_dir do
34
- with_clean_bundler_env do
35
- sh File.join(Transpec.root, 'bin', 'transpec'), '--force', '--convert', 'stub_with_hash'
36
- sh 'bundle exec rspec'
37
- sh "git checkout --quiet -b #{DEMO_BRANCH}"
38
- sh 'git commit --all --file .git/COMMIT_EDITMSG'
39
- sh "git push --force origin #{DEMO_BRANCH}"
40
- end
41
- end
42
- end
43
-
44
- def git_local_branch_exist?(branch_name)
45
- in_project_dir do
46
- system('git', 'show-ref', '--verify', '--quiet', "refs/heads/#{branch_name}")
47
- end
48
- end
49
-
50
- def git_branch_delete(branch_name)
51
- in_project_dir do
52
- sh "git branch -D #{branch_name}"
53
- end
54
- end
55
- end
@@ -1,181 +0,0 @@
1
- # coding: utf-8
2
-
3
- class TranspecTest # rubocop:disable ClassLength
4
- include FileUtils # This is Rake's one.
5
-
6
- BUNDLER_RETRY_COUNT = 3
7
-
8
- attr_reader :url, :ref, :bundler_args
9
-
10
- def self.base_dir
11
- @base_dir ||= begin
12
- unless Dir.exist?(base_dir_path)
13
- require 'fileutils'
14
- FileUtils.mkdir_p(base_dir_path)
15
- end
16
-
17
- base_dir_path
18
- end
19
- end
20
-
21
- def self.base_dir_path
22
- @base_dir_path = File.join('tmp', 'tests')
23
- end
24
-
25
- def initialize(url, ref = nil, bundler_args = [])
26
- @url = url
27
- @ref = ref
28
- @bundler_args = bundler_args
29
- end
30
-
31
- def name
32
- @name ||= File.basename(url, '.git')
33
- end
34
-
35
- def project_dir
36
- @project_dir ||= File.join(self.class.base_dir, name)
37
- end
38
-
39
- def run
40
- require 'transpec'
41
- puts " Testing transpec on #{name} project ".center(80, '=')
42
- prepare_project
43
- run_test(%w(--force))
44
- end
45
-
46
- private
47
-
48
- def prepare_project
49
- if url.start_with?('/')
50
- prepare_with_local_dir
51
- else
52
- prepare_with_git_repo
53
- end
54
- end
55
-
56
- def prepare_with_local_dir
57
- if Dir.exist?(project_dir)
58
- require 'fileutils'
59
- FileUtils.rm_rf(project_dir)
60
- end
61
-
62
- Dir.mkdir(project_dir)
63
-
64
- Dir.chdir(url) do
65
- Dir.new('.').each do |entry|
66
- next if ['.', '..', 'tmp'].include?(entry)
67
- FileUtils.cp_r(entry, project_dir)
68
- end
69
-
70
- spec_cache_dir = File.join('tmp', 'spec_cache')
71
-
72
- if Dir.exist?(spec_cache_dir)
73
- Dir.mkdir(File.join(project_dir, 'tmp'))
74
- FileUtils.cp_r(spec_cache_dir, File.join(project_dir, spec_cache_dir))
75
- end
76
- end
77
-
78
- bundle_install
79
- end
80
-
81
- def prepare_with_git_repo
82
- if Dir.exist?(project_dir)
83
- git_checkout(ref) unless current_ref == ref
84
- git_checkout('.')
85
- else
86
- git_clone
87
- bundle_install
88
- end
89
- end
90
-
91
- def run_test(transpec_args = [])
92
- in_project_dir do
93
- with_clean_bundler_env do
94
- sh File.join(Transpec.root, 'bin', 'transpec'), *transpec_args
95
- sh 'bundle exec rspec'
96
- compare_summary!
97
- end
98
- end
99
- end
100
-
101
- def compare_summary!
102
- unless File.exist?(commit_message_fixture_path)
103
- warn "#{commit_message_fixture_path} does not exist. Skipping summary comparison."
104
- return
105
- end
106
-
107
- require 'rspec/expectations'
108
- extend RSpec::Matchers
109
- summary = File.read(File.join('.git', 'COMMIT_EDITMSG')).lines.to_a[5..-1]
110
- expected_summary = File.read(commit_message_fixture_path).lines.to_a[5..-1]
111
- expect(summary).to eq(expected_summary)
112
- end
113
-
114
- def commit_message_fixture_path
115
- path = File.join(File.dirname(__FILE__), '..', 'fixtures', name, 'COMMIT_EDITMSG')
116
- File.expand_path(path)
117
- end
118
-
119
- def in_project_dir(&block)
120
- Dir.chdir(project_dir, &block)
121
- end
122
-
123
- def current_ref
124
- in_project_dir do
125
- `git describe --all`.chomp.sub(/\Aheads\//, '')
126
- end
127
- end
128
-
129
- def git_checkout(*args)
130
- in_project_dir do
131
- sh 'git', 'checkout', *args
132
- end
133
- end
134
-
135
- def git_clone
136
- Dir.chdir(self.class.base_dir) do
137
- # Disabling checkout here to suppress "detached HEAD" warning.
138
- command = %w(git clone --no-checkout)
139
- command.concat(%w(--depth 1)) if shallow_clone?
140
- command.concat(['--branch', ref, url])
141
- sh command.join(' ')
142
- end
143
-
144
- in_project_dir do
145
- sh "git checkout --quiet #{ref}"
146
- end
147
- end
148
-
149
- def shallow_clone?
150
- true
151
- end
152
-
153
- def bundle_install
154
- in_project_dir do
155
- with_clean_bundler_env do
156
- sh 'bundle', 'install', '--retry', BUNDLER_RETRY_COUNT.to_s, *bundler_args
157
- end
158
- end
159
- end
160
-
161
- def with_clean_bundler_env
162
- if defined?(Bundler)
163
- Bundler.with_clean_env do
164
- # Bundler.with_clean_env cleans environment variables
165
- # which are set after bundler is loaded.
166
- prepare_env
167
- yield
168
- end
169
- else
170
- prepare_env
171
- yield
172
- end
173
- end
174
-
175
- def prepare_env
176
- # Disable Coveralls.
177
- ENV['CI'] = ENV['JENKINS_URL'] = ENV['COVERALLS_RUN_LOCALLY'] = nil
178
-
179
- ENV['TRANSPEC_TEST'] = 'true'
180
- end
181
- end