transpec 1.6.1 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
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
  >