transpec 1.6.1 → 1.7.0

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.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +0 -4
  3. data/.travis.yml +2 -1
  4. data/CHANGELOG.md +4 -0
  5. data/Guardfile +1 -1
  6. data/README.md +168 -18
  7. data/README.md.erb +154 -18
  8. data/lib/transpec/ast/node.rb +47 -0
  9. data/lib/transpec/cli.rb +1 -1
  10. data/lib/transpec/commit_message.rb +11 -1
  11. data/lib/transpec/configuration.rb +11 -10
  12. data/lib/transpec/converter.rb +36 -14
  13. data/lib/transpec/dynamic_analyzer/rewriter.rb +2 -2
  14. data/lib/transpec/option_parser.rb +11 -0
  15. data/lib/transpec/report.rb +16 -9
  16. data/lib/transpec/rspec_version.rb +9 -0
  17. data/lib/transpec/static_context_inspector.rb +4 -4
  18. data/lib/transpec/syntax/allow.rb +20 -0
  19. data/lib/transpec/syntax/example.rb +1 -1
  20. data/lib/transpec/syntax/expect.rb +5 -20
  21. data/lib/transpec/syntax/its.rb +2 -8
  22. data/lib/transpec/syntax/method_stub.rb +72 -37
  23. data/lib/transpec/syntax/mixin/allow_no_message.rb +8 -17
  24. data/lib/transpec/syntax/mixin/any_instance_block.rb +34 -0
  25. data/lib/transpec/syntax/mixin/expect_base.rb +70 -0
  26. data/lib/transpec/syntax/mixin/expectizable.rb +3 -0
  27. data/lib/transpec/syntax/mixin/have_matcher_owner.rb +5 -2
  28. data/lib/transpec/syntax/mixin/monkey_patch.rb +6 -0
  29. data/lib/transpec/syntax/mixin/{any_instance.rb → monkey_patch_any_instance.rb} +12 -8
  30. data/lib/transpec/syntax/mixin/send.rb +16 -3
  31. data/lib/transpec/syntax/mixin/should_base.rb +8 -2
  32. data/lib/transpec/syntax/oneliner_should.rb +2 -4
  33. data/lib/transpec/syntax/operator_matcher.rb +2 -2
  34. data/lib/transpec/syntax/raise_error.rb +2 -2
  35. data/lib/transpec/syntax/receive.rb +49 -0
  36. data/lib/transpec/syntax/rspec_configure.rb +8 -96
  37. data/lib/transpec/syntax/rspec_configure/expectations.rb +15 -0
  38. data/lib/transpec/syntax/rspec_configure/framework.rb +166 -0
  39. data/lib/transpec/syntax/rspec_configure/mocks.rb +19 -0
  40. data/lib/transpec/syntax/should.rb +1 -4
  41. data/lib/transpec/syntax/should_receive.rb +89 -43
  42. data/lib/transpec/util.rb +21 -7
  43. data/lib/transpec/version.rb +2 -2
  44. data/spec/transpec/ast/node_spec.rb +52 -0
  45. data/spec/transpec/commit_message_spec.rb +2 -2
  46. data/spec/transpec/configuration_spec.rb +14 -13
  47. data/spec/transpec/converter_spec.rb +151 -20
  48. data/spec/transpec/option_parser_spec.rb +10 -0
  49. data/spec/transpec/rspec_version_spec.rb +20 -6
  50. data/spec/transpec/static_context_inspector_spec.rb +2 -2
  51. data/spec/transpec/syntax/allow_spec.rb +140 -0
  52. data/spec/transpec/syntax/double_spec.rb +1 -1
  53. data/spec/transpec/syntax/expect_spec.rb +103 -10
  54. data/spec/transpec/syntax/have_spec.rb +4 -4
  55. data/spec/transpec/syntax/method_stub_spec.rb +41 -1
  56. data/spec/transpec/syntax/operator_matcher_spec.rb +6 -6
  57. data/spec/transpec/syntax/receive_spec.rb +270 -0
  58. data/spec/transpec/syntax/rspec_configure_spec.rb +241 -30
  59. data/spec/transpec/syntax/should_receive_spec.rb +93 -2
  60. data/spec/transpec/syntax/should_spec.rb +2 -2
  61. data/spec/transpec/util_spec.rb +2 -6
  62. data/transpec.gemspec +5 -3
  63. metadata +37 -14
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5c6f45e13cea25a0a7b868b61b75167e862c7fb2
4
- data.tar.gz: d34f0aab8e600dd52627e25d1e636c6c130ef419
3
+ metadata.gz: c46495e8ece5679b985320ebfd8f026bd089fa0f
4
+ data.tar.gz: 3096577bb24dfc010639d541e8f3471a5568cba1
5
5
  SHA512:
6
- metadata.gz: bf29aecabd3c9ee734eaae5f751d60fb032cc1dd4ccd2909ac27cbe76fe1e61e0dcae77e27794232bc9c99ce4c501490684aded1f6ee8c920624116deda96998
7
- data.tar.gz: ae26aaec177b656156b01db64afb3a5c644b08448795f3d82ccd51d17bedacb62bf6cb13d80de2992b5286bfd7e24ae69da4909cc31e059022db5a8a576ff6e9
6
+ metadata.gz: 81b9a2e1fe74cb4125f8ea25790198f528200973073a253c3d8facb5e036f883cc5dd9d7b519ac59705580f395a79baaac854f2055f96c31032087bd233b0237
7
+ data.tar.gz: 7c34385af11c5d9eee744d334141820f47436c907d26e8d1f66a7bb8391e3835698f24bdddc2a60e22635933c242fa3dbeb0b6855170b8324a6ed6735ec7f4d5
data/.rubocop.yml CHANGED
@@ -48,10 +48,6 @@ AlignHash:
48
48
  Documentation:
49
49
  Enabled: false
50
50
 
51
- # Currently IndentationWidth reports false positive offence around here document.
52
- IndentationWidth:
53
- Enabled: false
54
-
55
51
  # TODO: This should not register offences for non keyword hashes.
56
52
  BracesAroundHashParameters:
57
53
  Enabled: false
data/.travis.yml CHANGED
@@ -2,6 +2,7 @@ language: ruby
2
2
  rvm:
3
3
  - 1.9.3
4
4
  - 2.0.0
5
- - 2.1.0-rc1
5
+ - 2.1.0
6
6
  - jruby-19mode
7
+ before_install: gem update --remote bundler
7
8
  script: bundle exec rake travis
data/CHANGELOG.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  ## Development
4
4
 
5
+ ## v1.7.0
6
+
7
+ * Support conversion of `any_instance` block
8
+
5
9
  ## v1.6.1
6
10
 
7
11
  * Handle deprecation messages from `rainbow` gem
data/Guardfile CHANGED
@@ -4,7 +4,7 @@
4
4
  # This group allows to skip running RuboCop if RSpec failed,
5
5
  # like Red > Green (RSpec) > Refactor (RuboCop).
6
6
  group :red_green_refactor, halt_on_fail: true do
7
- guard :rspec, all_after_pass: true, all_on_start: true, cmd: 'bundle exec rspec' do
7
+ guard :rspec, all_on_start: true, failed_mode: :keep, cmd: 'bundle exec rspec' do
8
8
  watch(%r{^spec/.+_spec\.rb$})
9
9
  watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
10
10
  watch('spec/spec_helper.rb') { "spec" }
data/README.md CHANGED
@@ -145,7 +145,7 @@ After the conversion, run `rspec` again and check whether everything is green:
145
145
  $ bundle exec rspec
146
146
  ```
147
147
 
148
- If it's green, commit the changes with an auto-generated message that describes the conversion summary:
148
+ If it's green, commit the changes with an auto-generated message which describes the conversion summary:
149
149
 
150
150
  ```bash
151
151
  $ git commit -aeF .git/COMMIT_EDITMSG
@@ -153,6 +153,27 @@ $ git commit -aeF .git/COMMIT_EDITMSG
153
153
 
154
154
  And you are done!
155
155
 
156
+ ## Advanced Usage
157
+
158
+ You can pass `transpec` arbitrary paths to be converted:
159
+
160
+ ```bash
161
+ # You always need to be in the project root directory
162
+ $ cd some-project
163
+
164
+ # Convert only files in `features` directory
165
+ $ transpec features
166
+
167
+ # Convert only files in `spec/foo` and `spec/bar` directory
168
+ $ transpec spec/foo spec/bar
169
+
170
+ # Convert only `spec/baz_spec.rb`
171
+ $ transpec spec/baz_spec.rb
172
+ ```
173
+
174
+ Note that the current working directory always needs to be the project root directory,
175
+ so that Transpec can copy the project in dynamic analysis.
176
+
156
177
  ## Upgrade Process to RSpec 3 beta
157
178
 
158
179
  If you are going to use Transpec in the upgrade process to RSpec 3 beta, read the article by [Myron Marston](https://github.com/myronmarston):
@@ -181,7 +202,7 @@ Skip dynamic analysis and convert with only static analysis. Note that specifyin
181
202
 
182
203
  ### `-c/--rspec-command`
183
204
 
184
- Specify a command to run your specs that is used for dynamic analysis.
205
+ Specify a command to run your specs which is used for dynamic analysis.
185
206
 
186
207
  Transpec needs to run your specs in a copied project directory for dynamic analysis.
187
208
  If your project requires some special setup or commands to run specs, use this option.
@@ -201,21 +222,24 @@ $ transpec --keep should_receive,stub
201
222
 
202
223
  #### Available syntax types
203
224
 
204
- Type | Target Syntax | Converted Syntax
205
- -----------------|----------------------------------|-----------------------------------
206
- `should` | `obj.should matcher` | `expect(obj).to matcher`
207
- `oneliner` | `it { should ... }` | `it { is_expected.to ... }`
208
- `should_receive` | `obj.should_receive` | `expect(obj).to receive`
209
- `stub` | `obj.stub` | `allow(obj).to receive`
210
- `have_items` | `expect(obj).to have(n).items` | `expect(obj.size).to eq(n)`
211
- `its` | `its(:attr) { }` | `describe { subject { }; it { } }`
212
- `deprecated` | `obj.stub!`, `mock('foo')`, etc. | `obj.stub`, `double('foo')`
225
+ Note that some syntaxes are available only if your project's RSpec is specific version or later.
226
+ If they are unavailable, conversions for such syntaxes will be disabled automatically.
227
+
228
+ Type | Target Syntax | Converted Syntax
229
+ -----------------|--------------------------------|-------------------------------------------
230
+ `should` | `obj.should matcher` | `expect(obj).to matcher`
231
+ `oneliner` | `it { should ... }` | `it { is_expected.to ... }`
232
+ `should_receive` | `obj.should_receive(:message)` | `expect(obj).to receive(:message)`
233
+ `stub` | `obj.stub(:message)` | `allow(obj).to receive(:message)`
234
+ `have_items` | `expect(obj).to have(n).items` | `expect(obj.size).to eq(n)`
235
+ `its` | `its(:attr) { }` | `describe '#attr' { subject { }; it { } }`
236
+ `deprecated` | All other deprecated syntaxes | Latest syntaxes
213
237
 
214
238
  See [Supported Conversions](#supported-conversions) for more details.
215
239
 
216
240
  ### `-n/--negative-form`
217
241
 
218
- Specify a negative form of `to` that is used in the `expect` syntax.
242
+ Specify a negative form of `to` which is used in the `expect` syntax.
219
243
  Either `not_to` or `to_not`.
220
244
  `not_to` is used by default.
221
245
 
@@ -225,7 +249,7 @@ $ transpec --negative-form to_not
225
249
 
226
250
  ### `-b/--boolean-matcher`
227
251
 
228
- Specify a matcher type that `be_true` and `be_false` will be converted to.
252
+ Specify a boolean matcher type which `be_true` and `be_false` will be converted to.
229
253
  Any of `truthy,falsey`, `truthy,falsy` or `true,false` can be specified.
230
254
  `truthy,falsey` is used by default.
231
255
 
@@ -235,6 +259,17 @@ $ transpec --boolean-matcher true,false
235
259
 
236
260
  See [Supported Conversions - Boolean matchers](#boolean-matchers) for more details.
237
261
 
262
+ ### `-a/--no-yield-any-instance`
263
+
264
+ Suppress yielding receiver instances to `any_instance` implementation blocks as the first block argument.
265
+
266
+ By default in RSpec 3, `any_instance` implementation blocks will be yielded the receiving
267
+ instance as the first block argument, and by default Transpec converts specs by adding instance arguments to the blocks so that they conform to the behavior of RSpec 3.
268
+ Specifying this option suppresses the conversion and keeps them compatible with RSpec 2.
269
+ Note that this is not same as `--keep deprecated` since this configures `yield_receiver_to_any_instance_implementation_blocks` with `RSpec.configure`.
270
+
271
+ See [Supported Conversions - `any_instance` implementation blocks](#any_instance-implementation-blocks) for more details.
272
+
238
273
  ### `-p/--no-parentheses-matcher-arg`
239
274
 
240
275
  Suppress parenthesizing arguments of matchers when converting
@@ -306,7 +341,7 @@ end
306
341
  ### Reason
307
342
 
308
343
  * `should` is defined on `BasicObject` class, so you can use `should` everywhere.
309
- * `expect` is defined on `RSpec::Matchers` module that is included by `RSpec::Core::ExampleGroup` class, so you can use `expect` only where `self` is an instance of `RSpec::Core::ExampleGroup` (i.e. in `it` blocks, `:each` hook blocks or included module methods) or other classes that explicitly include `RSpec::Matchers`.
344
+ * `expect` is defined on `RSpec::Matchers` module which is included by `RSpec::Core::ExampleGroup` class, so you can use `expect` only where `self` is an instance of `RSpec::Core::ExampleGroup` (i.e. in `it` blocks, `:each` hook blocks or included module methods) or other classes that explicitly include `RSpec::Matchers`.
310
345
 
311
346
  With the above example, in the context of `1.should == 1`, the `self` is an instance of `MyAwesomeTestRunner`.
312
347
  Transpec tracks contexts and skips conversion if the target syntax cannot be converted in a case like this.
@@ -327,6 +362,43 @@ Include or extend `RSpec::Matchers` module to make `expect` available in the con
327
362
 
328
363
  Then run `transpec` again.
329
364
 
365
+ ## Two Types of `should`
366
+
367
+ There are two types of `should`:
368
+
369
+ ```ruby
370
+ describe 'the monkey-patched should' do
371
+ subject { [] }
372
+
373
+ it 'is empty' do
374
+ subject.should be_empty
375
+ # ^^^^^^ BasicObject#should in RSpec 2.11 or later,
376
+ # or Kernel#should prior to RSpec 2.11.
377
+ end
378
+ end
379
+
380
+ describe 'the one-liner should' do
381
+ subject { [] }
382
+
383
+ it { should be_empty }
384
+ # ^^^^^^ RSpec::Core::ExampleGroup#should
385
+ end
386
+ ```
387
+
388
+ The monkey-patched `obj.should`:
389
+
390
+ * Is provided by `rspec-expectations` gem.
391
+ * Is deprecated in RSpec 3.
392
+ * Has [the issue](http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax#delegation_issues) with delegate/proxy objects.
393
+ * There's the alternative syntax [`expect(obj).to`](#standard-expectations) since RSpec 2.11.
394
+
395
+ The one-liner (implicit receiver) `should`:
396
+
397
+ * Is provided by `rspec-core` gem.
398
+ * Is _not_ deprecated in RSpec 3.
399
+ * Does _not_ have the issue with delegate/proxy objects.
400
+ * There's the alternative syntax [`is_expected.to`](#one-liner-expectations) since RSpec 2.99.beta2 (not yet released).
401
+
330
402
  ## Supported Conversions
331
403
 
332
404
  ### Standard expectations
@@ -509,7 +581,7 @@ Note: `rspec-rails` 3.0 [still uses `have(n).items` matcher with `rspec-collecti
509
581
 
510
582
  * This conversion can be disabled by: `--keep have_items`
511
583
  * Deprecation: deprecated since RSpec 2.99, removed in RSpec 3.0
512
- * See also: [Expectations: have(x).items matchers will be moved into an external gem - The Plan for RSpec 3](http://myronmars.to/n/dev-blog/2013/07/the-plan-for-rspec-3#expectations__matchers_will_be_moved_into_an_external_gem)
584
+ * See also: [Expectations: `have(x).items` matchers will be moved into an external gem - The Plan for RSpec 3](http://myronmars.to/n/dev-blog/2013/07/the-plan-for-rspec-3#expectations__matchers_will_be_moved_into_an_external_gem)
513
585
 
514
586
  ### One-liner expectations with `have(n).items` matcher
515
587
 
@@ -669,7 +741,7 @@ There's no replacement for `unstub` in the `expect` syntax. See [this discussion
669
741
 
670
742
  #### Steps to upgrade `obj.stub(:foo => 1, :bar => 2)`
671
743
 
672
- `allow(obj).to receive_messages(:foo => 1, :bar => 2)` that is designed to be the replacement for `obj.stub(:foo => 1, :bar => 2)` is available from RSpec 3.0 (though [it's now being considered to be backported to RSpec 2.99](https://github.com/rspec/rspec-mocks/issues/454)). So, in [the upgrade path to RSpec 3](http://myronmars.to/n/dev-blog/2013/07/the-plan-for-rspec-3#the_upgrade_path), if you want to convert them with keeping the syntax correspondence, you need to follow these steps:
744
+ `allow(obj).to receive_messages(:foo => 1, :bar => 2)` which is designed to be the replacement for `obj.stub(:foo => 1, :bar => 2)` is available from RSpec 3.0 (though [it's now being considered to be backported to RSpec 2.99](https://github.com/rspec/rspec-mocks/issues/454)). So, in [the upgrade path to RSpec 3](http://myronmars.to/n/dev-blog/2013/07/the-plan-for-rspec-3#the_upgrade_path), if you want to convert them with keeping the syntax correspondence, you need to follow these steps:
673
745
 
674
746
  1. Upgrade to RSpec 2.99
675
747
  2. Run `transpec --keep stub`
@@ -727,6 +799,84 @@ obj.stub(:foo) # with `--keep stub`
727
799
  * Deprecation: deprecated since RSpec 2.14, removed in RSpec 3.0
728
800
  * See also: [Don't allow at_least(0) · rspec/rspec-mocks](https://github.com/rspec/rspec-mocks/issues/133)
729
801
 
802
+ ### `any_instance` implementation blocks
803
+
804
+ **This conversion is available only if your project's RSpec is `>= 2.99.0.beta1` and `< 3.0.0.beta1`.**
805
+
806
+ Targets:
807
+
808
+ ```ruby
809
+ RSpec.configure do |rspec|
810
+ end
811
+
812
+ describe 'example' do
813
+ it 'is any_instance implementation block' do
814
+ Klass.any_instance.should_receive(:message) { |arg| puts arg }
815
+ Klass.any_instance.stub(:message) { |arg| puts arg }
816
+ expect_any_instance_of(Klass).to receive(:message) { |arg| puts arg }
817
+ allow_any_instance_of(Klass).to receive(:message) { |arg| puts arg }
818
+ end
819
+ end
820
+ ```
821
+
822
+ Will be converted to:
823
+
824
+ ```ruby
825
+ RSpec.configure do |rspec|
826
+ rspec.mock_with :rspec do |mocks|
827
+ mocks.yield_receiver_to_any_instance_implementation_blocks = true
828
+ end
829
+ end
830
+
831
+ describe 'example' do
832
+ it 'is any_instance implementation block' do
833
+ expect_any_instance_of(Klass).to receive(:message) { |instance, arg| puts arg }
834
+ allow_any_instance_of(Klass).to receive(:message) { |instance, arg| puts arg }
835
+ expect_any_instance_of(Klass).to receive(:message) { |instance, arg| puts arg }
836
+ allow_any_instance_of(Klass).to receive(:message) { |instance, arg| puts arg }
837
+ end
838
+ end
839
+
840
+ # With `--no-yield-any-instance`
841
+ RSpec.configure do |rspec|
842
+ rspec.mock_with :rspec do |mocks|
843
+ mocks.yield_receiver_to_any_instance_implementation_blocks = false
844
+ end
845
+ end
846
+
847
+ describe 'example' do
848
+ it 'is any_instance implementation block' do
849
+ expect_any_instance_of(Klass).to receive(:message) { |arg| puts arg }
850
+ allow_any_instance_of(Klass).to receive(:message) { |arg| puts arg }
851
+ expect_any_instance_of(Klass).to receive(:message) { |arg| puts arg }
852
+ allow_any_instance_of(Klass).to receive(:message) { |arg| puts arg }
853
+ end
854
+ end
855
+ ```
856
+
857
+ Here's an excerpt from [the warning](https://github.com/rspec/rspec-mocks/blob/aab8dc9/lib/rspec/mocks/message_expectation.rb#L478-L491) for `any_instance` implementation blocks in RSpec 2.99:
858
+
859
+ > In RSpec 3, `any_instance` implementation blocks will be yielded the receiving
860
+ > instance as the first block argument to allow the implementation block to use
861
+ > the state of the receiver. To maintain compatibility with RSpec 3 you need to
862
+ > either set rspec-mocks' `yield_receiver_to_any_instance_implementation_blocks`
863
+ > config option to `false` OR set it to `true` and update your `any_instance`
864
+ > implementation blocks to account for the first block argument being the receiving instance.
865
+ >
866
+ > To set the config option, use a snippet like:
867
+ >
868
+ > ```ruby
869
+ > RSpec.configure do |rspec|
870
+ > rspec.mock_with :rspec do |mocks|
871
+ > mocks.yield_receiver_to_any_instance_implementation_blocks = false
872
+ > end
873
+ > end
874
+ > ```
875
+
876
+ * This conversion can be disabled by: `--keep deprecated`
877
+ * Deprecation: deprecated since RSpec 2.99
878
+ * See also: [Mocks: `any_instance` block implementations will yield the receiver](http://myronmars.to/n/dev-blog/2013/07/the-plan-for-rspec-3#mocks__block_implementations_will_yield_the_receiver)
879
+
730
880
  ### Deprecated test double aliases
731
881
 
732
882
  Targets:
@@ -797,7 +947,7 @@ If you choose to do so, disable this conversion by either:
797
947
 
798
948
  * This conversion can be disabled by: `--keep its`
799
949
  * Deprecation: deprecated since RSpec 2.99, removed in RSpec 3.0
800
- * See also: [Core: its will be moved into an external gem - The Plan for RSpec 3](http://myronmars.to/n/dev-blog/2013/07/the-plan-for-rspec-3#core__will_be_moved_into_an_external_gem)
950
+ * See also: [Core: `its` will be moved into an external gem - The Plan for RSpec 3](http://myronmars.to/n/dev-blog/2013/07/the-plan-for-rspec-3#core__will_be_moved_into_an_external_gem)
801
951
 
802
952
  ### Current example object
803
953
 
@@ -839,7 +989,7 @@ describe 'example page' do
839
989
  end
840
990
  ```
841
991
 
842
- Here's an excerpt from [the warning for `RSpec::Core::ExampleGroup#example` and `#running_example` in RSpec 2.99](https://github.com/rspec/rspec-core/blob/7d6d2ca/lib/rspec/core/example_group.rb#L513-L527):
992
+ Here's an excerpt from [the warning](https://github.com/rspec/rspec-core/blob/7d6d2ca/lib/rspec/core/example_group.rb#L513-L527) for `RSpec::Core::ExampleGroup#example` and `#running_example` in RSpec 2.99:
843
993
 
844
994
  > `RSpec::Core::ExampleGroup#example` is deprecated and will be removed in RSpec 3. There are a few options for what you can use instead:
845
995
  >
data/README.md.erb CHANGED
@@ -118,7 +118,7 @@ After the conversion, run `rspec` again and check whether everything is green:
118
118
  $ bundle exec rspec
119
119
  ```
120
120
 
121
- If it's green, commit the changes with an auto-generated message that describes the conversion summary:
121
+ If it's green, commit the changes with an auto-generated message which describes the conversion summary:
122
122
 
123
123
  ```bash
124
124
  $ git commit -aeF .git/COMMIT_EDITMSG
@@ -126,6 +126,27 @@ $ git commit -aeF .git/COMMIT_EDITMSG
126
126
 
127
127
  And you are done!
128
128
 
129
+ ## Advanced Usage
130
+
131
+ You can pass `transpec` arbitrary paths to be converted:
132
+
133
+ ```bash
134
+ # You always need to be in the project root directory
135
+ $ cd some-project
136
+
137
+ # Convert only files in `features` directory
138
+ $ transpec features
139
+
140
+ # Convert only files in `spec/foo` and `spec/bar` directory
141
+ $ transpec spec/foo spec/bar
142
+
143
+ # Convert only `spec/baz_spec.rb`
144
+ $ transpec spec/baz_spec.rb
145
+ ```
146
+
147
+ Note that the current working directory always needs to be the project root directory,
148
+ so that Transpec can copy the project in dynamic analysis.
149
+
129
150
  ## Upgrade Process to RSpec 3 beta
130
151
 
131
152
  If you are going to use Transpec in the upgrade process to RSpec 3 beta, read the article by [Myron Marston](https://github.com/myronmarston):
@@ -154,7 +175,7 @@ Skip dynamic analysis and convert with only static analysis. Note that specifyin
154
175
 
155
176
  ### `-c/--rspec-command`
156
177
 
157
- Specify a command to run your specs that is used for dynamic analysis.
178
+ Specify a command to run your specs which is used for dynamic analysis.
158
179
 
159
180
  Transpec needs to run your specs in a copied project directory for dynamic analysis.
160
181
  If your project requires some special setup or commands to run specs, use this option.
@@ -174,17 +195,20 @@ $ transpec --keep should_receive,stub
174
195
 
175
196
  #### Available syntax types
176
197
 
177
- Type | Target Syntax | Converted Syntax
178
- -----------------|----------------------------------|-----------------------------------
198
+ Note that some syntaxes are available only if your project's RSpec is specific version or later.
199
+ If they are unavailable, conversions for such syntaxes will be disabled automatically.
200
+
201
+ Type | Target Syntax | Converted Syntax
202
+ -----------------|--------------------------------|-------------------------------------------
179
203
  <%=
180
204
  conversion_type_table = <<END
181
- `should` | `obj.should matcher` | `expect(obj).to matcher`
182
- `oneliner` | `it { should ... }` | `it { is_expected.to ... }`
183
- `should_receive` | `obj.should_receive` | `expect(obj).to receive`
184
- `stub` | `obj.stub` | `allow(obj).to receive`
185
- `have_items` | `expect(obj).to have(n).items` | `expect(obj.size).to eq(n)`
186
- `its` | `its(:attr) { }` | `describe { subject { }; it { } }`
187
- `deprecated` | `obj.stub!`, `mock('foo')`, etc. | `obj.stub`, `double('foo')`
205
+ `should` | `obj.should matcher` | `expect(obj).to matcher`
206
+ `oneliner` | `it { should ... }` | `it { is_expected.to ... }`
207
+ `should_receive` | `obj.should_receive(:message)` | `expect(obj).to receive(:message)`
208
+ `stub` | `obj.stub(:message)` | `allow(obj).to receive(:message)`
209
+ `have_items` | `expect(obj).to have(n).items` | `expect(obj.size).to eq(n)`
210
+ `its` | `its(:attr) { }` | `describe '#attr' { subject { }; it { } }`
211
+ `deprecated` | All other deprecated syntaxes | Latest syntaxes
188
212
  END
189
213
 
190
214
  types_in_readme = conversion_type_table.lines.map do |line|
@@ -206,7 +230,7 @@ See [Supported Conversions](#supported-conversions) for more details.
206
230
 
207
231
  ### `-n/--negative-form`
208
232
 
209
- Specify a negative form of `to` that is used in the `expect` syntax.
233
+ Specify a negative form of `to` which is used in the `expect` syntax.
210
234
  Either `not_to` or `to_not`.
211
235
  `not_to` is used by default.
212
236
 
@@ -216,7 +240,7 @@ $ transpec --negative-form to_not
216
240
 
217
241
  ### `-b/--boolean-matcher`
218
242
 
219
- Specify a matcher type that `be_true` and `be_false` will be converted to.
243
+ Specify a boolean matcher type which `be_true` and `be_false` will be converted to.
220
244
  Any of `truthy,falsey`, `truthy,falsy` or `true,false` can be specified.
221
245
  `truthy,falsey` is used by default.
222
246
 
@@ -226,6 +250,17 @@ $ transpec --boolean-matcher true,false
226
250
 
227
251
  See [Supported Conversions - Boolean matchers](#boolean-matchers) for more details.
228
252
 
253
+ ### `-a/--no-yield-any-instance`
254
+
255
+ Suppress yielding receiver instances to `any_instance` implementation blocks as the first block argument.
256
+
257
+ By default in RSpec 3, `any_instance` implementation blocks will be yielded the receiving
258
+ instance as the first block argument, and by default Transpec converts specs by adding instance arguments to the blocks so that they conform to the behavior of RSpec 3.
259
+ Specifying this option suppresses the conversion and keeps them compatible with RSpec 2.
260
+ Note that this is not same as `--keep deprecated` since this configures `yield_receiver_to_any_instance_implementation_blocks` with `RSpec.configure`.
261
+
262
+ See [Supported Conversions - `any_instance` implementation blocks](#any_instance-implementation-blocks) for more details.
263
+
229
264
  ### `-p/--no-parentheses-matcher-arg`
230
265
 
231
266
  Suppress parenthesizing arguments of matchers when converting
@@ -302,7 +337,7 @@ end
302
337
  ### Reason
303
338
 
304
339
  * `should` is defined on `BasicObject` class, so you can use `should` everywhere.
305
- * `expect` is defined on `RSpec::Matchers` module that is included by `RSpec::Core::ExampleGroup` class, so you can use `expect` only where `self` is an instance of `RSpec::Core::ExampleGroup` (i.e. in `it` blocks, `:each` hook blocks or included module methods) or other classes that explicitly include `RSpec::Matchers`.
340
+ * `expect` is defined on `RSpec::Matchers` module which is included by `RSpec::Core::ExampleGroup` class, so you can use `expect` only where `self` is an instance of `RSpec::Core::ExampleGroup` (i.e. in `it` blocks, `:each` hook blocks or included module methods) or other classes that explicitly include `RSpec::Matchers`.
306
341
 
307
342
  With the above example, in the context of `1.should == 1`, the `self` is an instance of `MyAwesomeTestRunner`.
308
343
  Transpec tracks contexts and skips conversion if the target syntax cannot be converted in a case like this.
@@ -323,6 +358,43 @@ Include or extend `RSpec::Matchers` module to make `expect` available in the con
323
358
 
324
359
  Then run `transpec` again.
325
360
 
361
+ ## Two Types of `should`
362
+
363
+ There are two types of `should`:
364
+
365
+ ```ruby
366
+ describe 'the monkey-patched should' do
367
+ subject { [] }
368
+
369
+ it 'is empty' do
370
+ subject.should be_empty
371
+ # ^^^^^^ BasicObject#should in RSpec 2.11 or later,
372
+ # or Kernel#should prior to RSpec 2.11.
373
+ end
374
+ end
375
+
376
+ describe 'the one-liner should' do
377
+ subject { [] }
378
+
379
+ it { should be_empty }
380
+ # ^^^^^^ RSpec::Core::ExampleGroup#should
381
+ end
382
+ ```
383
+
384
+ The monkey-patched `obj.should`:
385
+
386
+ * Is provided by `rspec-expectations` gem.
387
+ * Is deprecated in RSpec 3.
388
+ * Has [the issue](http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax#delegation_issues) with delegate/proxy objects.
389
+ * There's the alternative syntax [`expect(obj).to`](#standard-expectations) since RSpec 2.11.
390
+
391
+ The one-liner (implicit receiver) `should`:
392
+
393
+ * Is provided by `rspec-core` gem.
394
+ * Is _not_ deprecated in RSpec 3.
395
+ * Does _not_ have the issue with delegate/proxy objects.
396
+ * There's the alternative syntax [`is_expected.to`](#one-liner-expectations) since RSpec 2.99.beta2 (not yet released).
397
+
326
398
  ## Supported Conversions
327
399
 
328
400
  ### Standard expectations
@@ -505,7 +577,7 @@ Note: `rspec-rails` 3.0 [still uses `have(n).items` matcher with `rspec-collecti
505
577
 
506
578
  * This conversion can be disabled by: `--keep have_items`
507
579
  * Deprecation: deprecated since RSpec 2.99, removed in RSpec 3.0
508
- * See also: [Expectations: have(x).items matchers will be moved into an external gem - The Plan for RSpec 3](http://myronmars.to/n/dev-blog/2013/07/the-plan-for-rspec-3#expectations__matchers_will_be_moved_into_an_external_gem)
580
+ * See also: [Expectations: `have(x).items` matchers will be moved into an external gem - The Plan for RSpec 3](http://myronmars.to/n/dev-blog/2013/07/the-plan-for-rspec-3#expectations__matchers_will_be_moved_into_an_external_gem)
509
581
 
510
582
  ### One-liner expectations with `have(n).items` matcher
511
583
 
@@ -665,7 +737,7 @@ There's no replacement for `unstub` in the `expect` syntax. See [this discussion
665
737
 
666
738
  #### Steps to upgrade `obj.stub(:foo => 1, :bar => 2)`
667
739
 
668
- `allow(obj).to receive_messages(:foo => 1, :bar => 2)` that is designed to be the replacement for `obj.stub(:foo => 1, :bar => 2)` is available from RSpec 3.0 (though [it's now being considered to be backported to RSpec 2.99](https://github.com/rspec/rspec-mocks/issues/454)). So, in [the upgrade path to RSpec 3](http://myronmars.to/n/dev-blog/2013/07/the-plan-for-rspec-3#the_upgrade_path), if you want to convert them with keeping the syntax correspondence, you need to follow these steps:
740
+ `allow(obj).to receive_messages(:foo => 1, :bar => 2)` which is designed to be the replacement for `obj.stub(:foo => 1, :bar => 2)` is available from RSpec 3.0 (though [it's now being considered to be backported to RSpec 2.99](https://github.com/rspec/rspec-mocks/issues/454)). So, in [the upgrade path to RSpec 3](http://myronmars.to/n/dev-blog/2013/07/the-plan-for-rspec-3#the_upgrade_path), if you want to convert them with keeping the syntax correspondence, you need to follow these steps:
669
741
 
670
742
  1. Upgrade to RSpec 2.99
671
743
  2. Run `transpec --keep stub`
@@ -723,6 +795,70 @@ obj.stub(:foo) # with `--keep stub`
723
795
  * Deprecation: deprecated since RSpec 2.14, removed in RSpec 3.0
724
796
  * See also: [Don't allow at_least(0) · rspec/rspec-mocks](https://github.com/rspec/rspec-mocks/issues/133)
725
797
 
798
+ ### `any_instance` implementation blocks
799
+
800
+ **This conversion is available only if your project's RSpec is `>= <%= Transpec::RSpecVersion::ANY_INSTANCE_IMPLEMENTATION_BLOCK_MIGRATION_BEGIN %>` and `< <%= Transpec::RSpecVersion::ANY_INSTANCE_IMPLEMENTATION_BLOCK_MIGRATION_EXCLUSIVE_END %>`.**
801
+
802
+ Targets:
803
+
804
+ ```ruby
805
+ <%=
806
+ any_instance_block_target = <<END
807
+ RSpec.configure do |rspec|
808
+ end
809
+
810
+ describe 'example' do
811
+ it 'is any_instance implementation block' do
812
+ Klass.any_instance.should_receive(:message) { |arg| puts arg }
813
+ Klass.any_instance.stub(:message) { |arg| puts arg }
814
+ expect_any_instance_of(Klass).to receive(:message) { |arg| puts arg }
815
+ allow_any_instance_of(Klass).to receive(:message) { |arg| puts arg }
816
+ end
817
+ end
818
+ END
819
+ -%>
820
+ ```
821
+
822
+ Will be converted to:
823
+
824
+ ```ruby
825
+ <%=
826
+ rspec_version = Transpec::RSpecVersion.yielding_receiver_to_any_instance_implementation_block_available_version
827
+ Transpec::Converter.new(nil, rspec_version).convert(any_instance_block_target)
828
+ -%>
829
+
830
+ # With `--no-yield-any-instance`
831
+ <%=
832
+ configuration = Transpec::Configuration.new
833
+ configuration.add_receiver_arg_to_any_instance_implementation_block = false
834
+ rspec_version = Transpec::RSpecVersion.yielding_receiver_to_any_instance_implementation_block_available_version
835
+ Transpec::Converter.new(configuration, rspec_version).convert(any_instance_block_target)
836
+ -%>
837
+ ```
838
+
839
+ Here's an excerpt from [the warning](https://github.com/rspec/rspec-mocks/blob/aab8dc9/lib/rspec/mocks/message_expectation.rb#L478-L491) for `any_instance` implementation blocks in RSpec 2.99:
840
+
841
+ > In RSpec 3, `any_instance` implementation blocks will be yielded the receiving
842
+ > instance as the first block argument to allow the implementation block to use
843
+ > the state of the receiver. To maintain compatibility with RSpec 3 you need to
844
+ > either set rspec-mocks' `yield_receiver_to_any_instance_implementation_blocks`
845
+ > config option to `false` OR set it to `true` and update your `any_instance`
846
+ > implementation blocks to account for the first block argument being the receiving instance.
847
+ >
848
+ > To set the config option, use a snippet like:
849
+ >
850
+ > ```ruby
851
+ > RSpec.configure do |rspec|
852
+ > rspec.mock_with :rspec do |mocks|
853
+ > mocks.yield_receiver_to_any_instance_implementation_blocks = false
854
+ > end
855
+ > end
856
+ > ```
857
+
858
+ * This conversion can be disabled by: `--keep deprecated`
859
+ * Deprecation: deprecated since RSpec 2.99
860
+ * See also: [Mocks: `any_instance` block implementations will yield the receiver](http://myronmars.to/n/dev-blog/2013/07/the-plan-for-rspec-3#mocks__block_implementations_will_yield_the_receiver)
861
+
726
862
  ### Deprecated test double aliases
727
863
 
728
864
  Targets:
@@ -777,7 +913,7 @@ If you choose to do so, disable this conversion by either:
777
913
 
778
914
  * This conversion can be disabled by: `--keep its`
779
915
  * Deprecation: deprecated since RSpec 2.99, removed in RSpec 3.0
780
- * See also: [Core: its will be moved into an external gem - The Plan for RSpec 3](http://myronmars.to/n/dev-blog/2013/07/the-plan-for-rspec-3#core__will_be_moved_into_an_external_gem)
916
+ * See also: [Core: `its` will be moved into an external gem - The Plan for RSpec 3](http://myronmars.to/n/dev-blog/2013/07/the-plan-for-rspec-3#core__will_be_moved_into_an_external_gem)
781
917
 
782
918
  ### Current example object
783
919
 
@@ -814,7 +950,7 @@ Transpec::Converter.new(nil, rspec_version).convert(example_target)
814
950
  -%>
815
951
  ```
816
952
 
817
- Here's an excerpt from [the warning for `RSpec::Core::ExampleGroup#example` and `#running_example` in RSpec 2.99](https://github.com/rspec/rspec-core/blob/7d6d2ca/lib/rspec/core/example_group.rb#L513-L527):
953
+ Here's an excerpt from [the warning](https://github.com/rspec/rspec-core/blob/7d6d2ca/lib/rspec/core/example_group.rb#L513-L527) for `RSpec::Core::ExampleGroup#example` and `#running_example` in RSpec 2.99:
818
954
 
819
955
  > `RSpec::Core::ExampleGroup#example` is deprecated and will be removed in RSpec 3. There are a few options for what you can use instead:
820
956
  >