transpec 1.10.4 → 1.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +3 -3
  3. data/CHANGELOG.md +9 -0
  4. data/README.md +96 -18
  5. data/README.md.erb +117 -51
  6. data/lib/transpec/base_rewriter.rb +25 -28
  7. data/lib/transpec/cli.rb +27 -14
  8. data/lib/transpec/configuration.rb +2 -1
  9. data/lib/transpec/converter.rb +54 -32
  10. data/lib/transpec/dynamic_analyzer/helper.rb.erb +44 -0
  11. data/lib/transpec/dynamic_analyzer/node_util.rb +17 -0
  12. data/lib/transpec/dynamic_analyzer/rewriter.rb +12 -4
  13. data/lib/transpec/dynamic_analyzer/runtime_data.rb +3 -4
  14. data/lib/transpec/dynamic_analyzer.rb +14 -52
  15. data/lib/transpec/option_parser.rb +89 -81
  16. data/lib/transpec/processed_source.rb +48 -0
  17. data/lib/transpec/record.rb +2 -2
  18. data/lib/transpec/report.rb +5 -1
  19. data/lib/transpec/rspec_dsl.rb +12 -2
  20. data/lib/transpec/rspec_version.rb +8 -7
  21. data/lib/transpec/spec_suite.rb +114 -0
  22. data/lib/transpec/syntax/example.rb +4 -20
  23. data/lib/transpec/syntax/example_group.rb +38 -0
  24. data/lib/transpec/syntax/have.rb +6 -9
  25. data/lib/transpec/syntax/its.rb +5 -7
  26. data/lib/transpec/syntax/method_stub.rb +12 -13
  27. data/lib/transpec/syntax/mixin/any_instance_block.rb +14 -6
  28. data/lib/transpec/syntax/mixin/context_sensitive.rb +41 -0
  29. data/lib/transpec/syntax/mixin/matcher_owner.rb +16 -26
  30. data/lib/transpec/syntax/mixin/monkey_patch_any_instance.rb +1 -1
  31. data/lib/transpec/syntax/mixin/no_message_allowance.rb +2 -2
  32. data/lib/transpec/syntax/mixin/useless_and_return.rb +2 -2
  33. data/lib/transpec/syntax/oneliner_should.rb +9 -13
  34. data/lib/transpec/syntax/operator.rb +3 -7
  35. data/lib/transpec/syntax/pending.rb +4 -20
  36. data/lib/transpec/syntax/rspec_configure/configuration_modification.rb +86 -0
  37. data/lib/transpec/syntax/rspec_configure/framework.rb +45 -86
  38. data/lib/transpec/syntax/rspec_configure.rb +18 -6
  39. data/lib/transpec/syntax/should.rb +3 -5
  40. data/lib/transpec/syntax/should_receive.rb +1 -1
  41. data/lib/transpec/syntax.rb +8 -0
  42. data/lib/transpec/util.rb +0 -8
  43. data/lib/transpec/version.rb +2 -2
  44. data/spec/acceptance/configuration_modification_spec.rb +132 -0
  45. data/spec/acceptance/conversion_spec.rb +114 -0
  46. data/spec/support/shared_context.rb +6 -12
  47. data/spec/transpec/cli_spec.rb +21 -23
  48. data/spec/transpec/configuration_spec.rb +2 -1
  49. data/spec/transpec/converter_spec.rb +292 -213
  50. data/spec/transpec/dynamic_analyzer/rewriter_spec.rb +3 -3
  51. data/spec/transpec/dynamic_analyzer_spec.rb +8 -2
  52. data/spec/transpec/option_parser_spec.rb +42 -4
  53. data/spec/transpec/processed_source_spec.rb +67 -0
  54. data/spec/transpec/rspec_version_spec.rb +8 -2
  55. data/spec/transpec/spec_suite_spec.rb +107 -0
  56. data/spec/transpec/syntax/allow_spec.rb +9 -27
  57. data/spec/transpec/syntax/example_group_spec.rb +172 -0
  58. data/spec/transpec/syntax/expect_spec.rb +18 -54
  59. data/spec/transpec/syntax/have_spec.rb +35 -14
  60. data/spec/transpec/syntax/its_spec.rb +27 -7
  61. data/spec/transpec/syntax/method_stub_spec.rb +31 -8
  62. data/spec/transpec/syntax/oneliner_should_spec.rb +22 -131
  63. data/spec/transpec/syntax/rspec_configure_spec.rb +118 -15
  64. data/spec/transpec/syntax/should_spec.rb +51 -82
  65. data/tasks/fixtures/guard/COMMIT_EDITMSG +80 -0
  66. data/tasks/fixtures/mail/COMMIT_EDITMSG +84 -0
  67. data/tasks/fixtures/twitter/COMMIT_EDITMSG +36 -0
  68. data/tasks/lib/transpec_test.rb +23 -2
  69. data/tasks/readme.rake +35 -0
  70. metadata +22 -4
  71. data/lib/transpec/parser.rb +0 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 10bda7931ceab8672bcf49f68c925b59448543b4
4
- data.tar.gz: acf1950a6c9b917d2af8fc16ea292c7ec91aa2b8
3
+ metadata.gz: 2a58d3e3885da1a031fbcaded738c876e1a69ae7
4
+ data.tar.gz: 408e608704f0245c39dbb42ea308c909174b13f9
5
5
  SHA512:
6
- metadata.gz: 02b7167fc857ccb4956f439dd793eeae452d2e71e0666be7c6419f571e6b4facb026cd5a649f41fb07b1bf87ac493177deed91e1ee51945442f191d097689c93
7
- data.tar.gz: 1ce039438135ccbccdeecc92b73812650d86a811671a9d7e2ec67f1907912c04b59efe753f2394aa434911e25d6f9bde82c9614aa40d5da3376b5f5cab45087f
6
+ metadata.gz: 8950975c78264dfc28fccb498c9e669c3a69216f32f3d669148646d2d69858c0fd41919985a240c2660aba96f0686cdf05adf07bcfa469994117cf2329d674a5
7
+ data.tar.gz: a33005b1b484f2e8dab7b9c18d07da52838c3db3876d2f8b2100974a553dd287dff8f36355392e7242da5ba5fa0ddc6471fe6dd9bb48cf2c17e42ab5dc75cfee
data/.rubocop.yml CHANGED
@@ -1,8 +1,8 @@
1
1
 
2
2
  AllCops:
3
- Includes:
3
+ Include:
4
4
  - tasks/*.rake
5
- Excludes:
5
+ Exclude:
6
6
  - tmp/*
7
7
  - vendor/*
8
8
 
@@ -54,4 +54,4 @@ BracesAroundHashParameters:
54
54
 
55
55
  # TODO: Shorten to 100.
56
56
  ClassLength:
57
- Max: 140
57
+ Max: 137
data/CHANGELOG.md CHANGED
@@ -2,6 +2,15 @@
2
2
 
3
3
  ## Development
4
4
 
5
+ ## v1.11.0
6
+
7
+ * Support conversion to non-monkey-patch example groups ([#22](https://github.com/yujinakayama/transpec/issues/22))
8
+ * Support conversion of `unstub` ([#49](https://github.com/yujinakayama/transpec/issues/49))
9
+ * Modify `yield_receiver_to_any_instance_implementation_blocks` configuration in `RSpec.configure` only when necessary ([#56](https://github.com/yujinakayama/transpec/issues/56))
10
+ * Modify only the main `RSpec.configure` when there are multiple ones ([#56](https://github.com/yujinakayama/transpec/issues/56))
11
+ * Add `-v/--convert` option that allows to enable conversions that are disabled by default
12
+ * Deprecate `-t/--convert-stub-with-hash` option
13
+
5
14
  ## v1.10.4
6
15
 
7
16
  * Avoid confusing methods defined with `#let` or `#subject` by user with RSpec built-in methods ([#55](https://github.com/yujinakayama/transpec/issues/55))
data/README.md CHANGED
@@ -159,7 +159,9 @@ And you are done!
159
159
 
160
160
  ## Advanced Usage
161
161
 
162
- You can pass `transpec` arbitrary paths to be converted:
162
+ ### Convert only specific specs
163
+
164
+ You can pass `transpec` arbitrary paths to convert:
163
165
 
164
166
  ```bash
165
167
  # You always need to be in the project root directory
@@ -178,9 +180,21 @@ $ transpec spec/baz_spec.rb
178
180
  Note that the current working directory always needs to be the project root directory,
179
181
  so that Transpec can copy the project in dynamic analysis.
180
182
 
183
+ ### Enable/disable specific conversions
184
+
185
+ You can disable specific conversions that are enabled by default with `-k/--keep` option,
186
+ and enable conversions that are disabled by default with the `-v/--convert` option.
187
+
188
+ ```bash
189
+ $ transpec --keep its --convert example_group
190
+ ```
191
+
192
+ See [`-k/--keep`](#-k--keep) and [`-v/--convert`](#-v--convert) for more details.
193
+
181
194
  ## Upgrade Process to RSpec 3 beta
182
195
 
183
- 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):
196
+ If you are going to use Transpec in the upgrade process to RSpec 3 beta,
197
+ read this article by [Myron Marston](https://github.com/myronmarston), who is the lead maintainer of RSpec:
184
198
 
185
199
  * [Myron Marston » RSpec 2.99 and 3.0 betas have been released!](http://myronmars.to/n/dev-blog/2013/11/rspec-2-99-and-3-0-betas-have-been-released)
186
200
 
@@ -200,10 +214,6 @@ Copying project for dynamic analysis...
200
214
  Running dynamic analysis with command "bundle exec rspec"...
201
215
  ```
202
216
 
203
- ### `-s/--skip-dynamic-analysis`
204
-
205
- Skip dynamic analysis and convert with only static analysis. Note that specifying this option decreases the conversion accuracy especially in the conversion of [`have(n).items` matcher](#havenitems-matcher).
206
-
207
217
  ### `-c/--rspec-command`
208
218
 
209
219
  Specify a command to run your specs which is used for dynamic analysis.
@@ -230,7 +240,7 @@ Keep specific syntaxes by disabling conversions.
230
240
  $ transpec --keep should_receive,stub
231
241
  ```
232
242
 
233
- #### Available syntax types
243
+ #### Conversions enabled by default
234
244
 
235
245
  Note that some syntaxes are available only if your project's RSpec is specific version or later.
236
246
  If they are unavailable, conversions for such syntaxes will be disabled automatically.
@@ -248,6 +258,38 @@ Type | Target Syntax | Converted Syntax
248
258
 
249
259
  See [Supported Conversions](#supported-conversions) for more details.
250
260
 
261
+
262
+ ### `-v/--convert`
263
+
264
+ Enable specific conversions that are disabled by default.
265
+
266
+ ```bash
267
+ $ transpec --convert example_group
268
+ ```
269
+
270
+ #### Conversions disabled by default
271
+
272
+ Most of these target syntaxes are _not_ deprecated in both RSpec 2 and 3,
273
+ but the new syntaxes provide more modern and clear ways.
274
+
275
+ Type | Target Syntax | Converted Syntax
276
+ -----------------|--------------------------------|----------------------------------------------------
277
+ `example_group` | `describe 'something' { }` | `RSpec.describe 'something' { }`
278
+ `stub_with_hash` | `obj.stub(:message => value)` | `allow(obj).to receive(:message).and_return(value)`
279
+
280
+ Note: Specifying `stub_with_hash` enables conversion of `obj.stub(:message => value)`
281
+ to `allow(obj).to receive(:message).and_return(value)`
282
+ when `allow(obj).to receive_messages(:message => value)` is unavailable (prior to RSpec 3.0),
283
+ and it will be converted to multiple statements if the hash includes multiple pairs.
284
+ If your project's RSpec is 3.0 or later, it will be converted to `receive_messages(:message => value)`
285
+ regardless of this option.
286
+
287
+ See [Supported Conversions - Method stubs with a hash argument](#method-stubs-with-a-hash-argument) for more details.
288
+
289
+ ### `-s/--skip-dynamic-analysis`
290
+
291
+ Skip dynamic analysis and convert with only static analysis. Note that specifying this option decreases the conversion accuracy especially in the conversion of [`have(n).items` matcher](#havenitems-matcher).
292
+
251
293
  ### `-n/--negative-form`
252
294
 
253
295
  Specify a negative form of `to` which is used in the `expect` syntax.
@@ -281,14 +323,6 @@ Note that this is not same as `--keep deprecated` since this configures `yield_r
281
323
 
282
324
  See [Supported Conversions - `any_instance` implementation blocks](#any_instance-implementation-blocks) for more details.
283
325
 
284
- ### `-t/--convert-stub-with-hash`
285
-
286
- Enable conversion of `obj.stub(:message => value)` to `allow(obj).to receive(:message).and_return(value)` when `receive_messages(:message => value)` is unavailable (prior to RSpec 3.0).
287
- It will be converted to multiple statements if the hash includes multiple pairs.
288
- This conversion is disabled by default.
289
-
290
- See [Supported Conversions - Method stubs with a hash argument](#method-stubs-with-a-hash-argument) for more details.
291
-
292
326
  ### `-p/--no-parentheses-matcher-arg`
293
327
 
294
328
  Suppress parenthesizing arguments of matchers when converting
@@ -442,6 +476,7 @@ The one-liner (implicit receiver) `should`:
442
476
  * [Pending examples](#pending-examples)
443
477
  * [Current example object](#current-example-object)
444
478
  * [Custom matcher DSL](#custom-matcher-dsl)
479
+ * [Example Groups](#example-groups)
445
480
 
446
481
  ### Standard expectations
447
482
 
@@ -809,6 +844,9 @@ obj.stub!(:message)
809
844
  obj.stub_chain(:foo, :bar, :baz)
810
845
 
811
846
  Klass.any_instance.stub(:message)
847
+
848
+ obj.unstub(:message)
849
+ obj.unstub!(:message)
812
850
  ```
813
851
 
814
852
  Will be converted to:
@@ -821,9 +859,9 @@ allow(obj).to receive(:message)
821
859
  allow(obj).to receive_message_chain(:foo, :bar, :baz)
822
860
 
823
861
  allow_any_instance_of(Klass).to receive(:message)
824
- ```
825
862
 
826
- There's no replacement for `unstub` in the `expect` syntax. See [this discussion](https://github.com/rspec/rspec-mocks/issues/153#issuecomment-12208638) for more details.
863
+ allow(obj).to receive(:message).and_call_original
864
+ ```
827
865
 
828
866
  * This conversion can be disabled by: `--keep stub`
829
867
  * Deprecation: deprecated since RSpec 3.0
@@ -882,7 +920,7 @@ Will be converted to:
882
920
 
883
921
  ```ruby
884
922
  obj.stub(:message) # with `--keep stub`
885
- obj.unstub(:message)
923
+ obj.unstub(:message) # with `--keep stub`
886
924
  ```
887
925
 
888
926
  * This conversion can be disabled by: `--keep deprecated`
@@ -1191,6 +1229,46 @@ end
1191
1229
  * Deprecation: deprecated since RSpec 3.0
1192
1230
  * See also: [Expectations: Matcher protocol and custom matcher API changes - The Plan for RSpec 3](http://myronmars.to/n/dev-blog/2013/07/the-plan-for-rspec-3#expectations_matcher_protocol_and_custom_matcher_api_changes)
1193
1231
 
1232
+ ### Example Groups
1233
+
1234
+ **This conversion is disabled by default and available only if your project's RSpec is `3.0.0.beta2` or later.**
1235
+
1236
+ Targets:
1237
+
1238
+ ```ruby
1239
+ RSpec.configure do |rspec|
1240
+ end
1241
+
1242
+ describe 'top-level example group' do
1243
+ describe 'nested example group' do
1244
+ end
1245
+ end
1246
+
1247
+ shared_examples 'shared examples' do
1248
+ end
1249
+ ```
1250
+
1251
+ Will be converted to:
1252
+
1253
+ ```ruby
1254
+ RSpec.configure do |rspec|
1255
+ rspec.expose_dsl_globally = false
1256
+ end
1257
+
1258
+ RSpec.describe 'top-level example group' do
1259
+ describe 'nested example group' do
1260
+ end
1261
+ end
1262
+
1263
+ RSpec.shared_examples 'shared examples' do
1264
+ end
1265
+ ```
1266
+
1267
+ * This conversion can be enabled by: `--convert example_group`
1268
+ * Deprecation: Not deprecated
1269
+ * See also: [Zero Monkey Patching Mode! - The Plan for RSpec 3](http://myronmars.to/n/dev-blog/2013/07/the-plan-for-rspec-3#zero_monkey_patching_mode)
1270
+
1271
+
1194
1272
  ## Compatibility
1195
1273
 
1196
1274
  Tested on MRI 1.9, 2.0, 2.1 and JRuby in 1.9 mode.
data/README.md.erb CHANGED
@@ -65,7 +65,7 @@ END
65
65
  Transpec would convert it to the following form:
66
66
 
67
67
  ```ruby
68
- <%= Transpec::Converter.new.convert(example) -%>
68
+ <%= convert(example) -%>
69
69
  ```
70
70
 
71
71
  ### Actual examples
@@ -133,7 +133,9 @@ And you are done!
133
133
 
134
134
  ## Advanced Usage
135
135
 
136
- You can pass `transpec` arbitrary paths to be converted:
136
+ ### Convert only specific specs
137
+
138
+ You can pass `transpec` arbitrary paths to convert:
137
139
 
138
140
  ```bash
139
141
  # You always need to be in the project root directory
@@ -152,9 +154,21 @@ $ transpec spec/baz_spec.rb
152
154
  Note that the current working directory always needs to be the project root directory,
153
155
  so that Transpec can copy the project in dynamic analysis.
154
156
 
157
+ ### Enable/disable specific conversions
158
+
159
+ You can disable specific conversions that are enabled by default with `-k/--keep` option,
160
+ and enable conversions that are disabled by default with the `-v/--convert` option.
161
+
162
+ ```bash
163
+ $ transpec --keep its --convert example_group
164
+ ```
165
+
166
+ See [`-k/--keep`](#-k--keep) and [`-v/--convert`](#-v--convert) for more details.
167
+
155
168
  ## Upgrade Process to RSpec 3 beta
156
169
 
157
- 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):
170
+ If you are going to use Transpec in the upgrade process to RSpec 3 beta,
171
+ read this article by [Myron Marston](https://github.com/myronmarston), who is the lead maintainer of RSpec:
158
172
 
159
173
  * [Myron Marston » RSpec 2.99 and 3.0 betas have been released!](http://myronmars.to/n/dev-blog/2013/11/rspec-2-99-and-3-0-betas-have-been-released)
160
174
 
@@ -174,10 +188,6 @@ Copying project for dynamic analysis...
174
188
  Running dynamic analysis with command "bundle exec rspec"...
175
189
  ```
176
190
 
177
- ### `-s/--skip-dynamic-analysis`
178
-
179
- Skip dynamic analysis and convert with only static analysis. Note that specifying this option decreases the conversion accuracy especially in the conversion of [`have(n).items` matcher](#havenitems-matcher).
180
-
181
191
  ### `-c/--rspec-command`
182
192
 
183
193
  Specify a command to run your specs which is used for dynamic analysis.
@@ -204,7 +214,7 @@ Keep specific syntaxes by disabling conversions.
204
214
  $ transpec --keep should_receive,stub
205
215
  ```
206
216
 
207
- #### Available syntax types
217
+ #### Conversions enabled by default
208
218
 
209
219
  Note that some syntaxes are available only if your project's RSpec is specific version or later.
210
220
  If they are unavailable, conversions for such syntaxes will be disabled automatically.
@@ -223,22 +233,50 @@ conversion_type_table = <<END
223
233
  `deprecated` | All other deprecated syntaxes | Latest syntaxes
224
234
  END
225
235
 
226
- types_in_readme = conversion_type_table.lines.map do |line|
227
- first_column = line.split('|').first
228
- first_column.gsub(/[^\w]/, '').to_sym
229
- end.sort
236
+ validate_syntax_type_table(conversion_type_table, Transpec::OptionParser::CONFIG_ATTRS_FOR_KEEP_TYPES.keys)
237
+ conversion_type_table
238
+ -%>
230
239
 
231
- types_in_code = Transpec::OptionParser.available_conversion_types.sort
240
+ See [Supported Conversions](#supported-conversions) for more details.
232
241
 
233
- unless types_in_readme == types_in_code
234
- types_missing_description = types_in_code - types_in_readme
235
- fail "No descriptions for syntax types #{types_missing_description}"
236
- end
237
242
 
243
+ ### `-v/--convert`
244
+
245
+ Enable specific conversions that are disabled by default.
246
+
247
+ ```bash
248
+ $ transpec --convert example_group
249
+ ```
250
+
251
+ #### Conversions disabled by default
252
+
253
+ Most of these target syntaxes are _not_ deprecated in both RSpec 2 and 3,
254
+ but the new syntaxes provide more modern and clear ways.
255
+
256
+ Type | Target Syntax | Converted Syntax
257
+ -----------------|--------------------------------|----------------------------------------------------
258
+ <%=
259
+ conversion_type_table = <<END
260
+ `example_group` | `describe 'something' { }` | `RSpec.describe 'something' { }`
261
+ `stub_with_hash` | `obj.stub(:message => value)` | `allow(obj).to receive(:message).and_return(value)`
262
+ END
263
+
264
+ validate_syntax_type_table(conversion_type_table, Transpec::OptionParser::CONFIG_ATTRS_FOR_CONVERT_TYPES.keys)
238
265
  conversion_type_table
239
266
  -%>
240
267
 
241
- See [Supported Conversions](#supported-conversions) for more details.
268
+ Note: Specifying `stub_with_hash` enables conversion of `obj.stub(:message => value)`
269
+ to `allow(obj).to receive(:message).and_return(value)`
270
+ when `allow(obj).to receive_messages(:message => value)` is unavailable (prior to RSpec 3.0),
271
+ and it will be converted to multiple statements if the hash includes multiple pairs.
272
+ If your project's RSpec is 3.0 or later, it will be converted to `receive_messages(:message => value)`
273
+ regardless of this option.
274
+
275
+ See [Supported Conversions - Method stubs with a hash argument](#method-stubs-with-a-hash-argument) for more details.
276
+
277
+ ### `-s/--skip-dynamic-analysis`
278
+
279
+ Skip dynamic analysis and convert with only static analysis. Note that specifying this option decreases the conversion accuracy especially in the conversion of [`have(n).items` matcher](#havenitems-matcher).
242
280
 
243
281
  ### `-n/--negative-form`
244
282
 
@@ -273,14 +311,6 @@ Note that this is not same as `--keep deprecated` since this configures `yield_r
273
311
 
274
312
  See [Supported Conversions - `any_instance` implementation blocks](#any_instance-implementation-blocks) for more details.
275
313
 
276
- ### `-t/--convert-stub-with-hash`
277
-
278
- Enable conversion of `obj.stub(:message => value)` to `allow(obj).to receive(:message).and_return(value)` when `receive_messages(:message => value)` is unavailable (prior to RSpec 3.0).
279
- It will be converted to multiple statements if the hash includes multiple pairs.
280
- This conversion is disabled by default.
281
-
282
- See [Supported Conversions - Method stubs with a hash argument](#method-stubs-with-a-hash-argument) for more details.
283
-
284
314
  ### `-p/--no-parentheses-matcher-arg`
285
315
 
286
316
  Suppress parenthesizing arguments of matchers when converting
@@ -291,7 +321,7 @@ when parentheses are necessary to keep the meaning of the expression.
291
321
 
292
322
  ```ruby
293
323
  <%=
294
- parenthesizing_example = <<END
324
+ example = <<END
295
325
  describe 'original spec' do
296
326
  it 'is an example' do
297
327
  1.should == 1
@@ -304,18 +334,12 @@ end
304
334
  END
305
335
  -%>
306
336
 
307
- <%=
308
- Transpec::Converter.new.convert(parenthesizing_example).gsub(
309
- 'original spec',
310
- 'converted spec'
311
- )
312
- -%>
337
+ <%= convert(example).gsub('original spec', 'converted spec') -%>
313
338
 
314
339
  <%=
315
340
  configuration = Transpec::Configuration.new
316
341
  configuration.parenthesize_matcher_arg = false
317
- converter = Transpec::Converter.new(configuration)
318
- converter.convert(parenthesizing_example)
342
+ convert(example, configuration)
319
343
  .gsub(
320
344
  'original spec',
321
345
  'converted spec with -p/--no-parentheses-matcher-arg option'
@@ -664,7 +688,7 @@ Targets:
664
688
 
665
689
  ```ruby
666
690
  <%=
667
- its_target = <<END
691
+ example = <<END
668
692
  describe 'example' do
669
693
  subject { { foo: 1, bar: 2 } }
670
694
  its(:size) { should == 2 }
@@ -678,7 +702,7 @@ END
678
702
  Will be converted to:
679
703
 
680
704
  ```ruby
681
- <%= Transpec::Converter.new.convert(its_target) -%>
705
+ <%= convert(example) -%>
682
706
  ```
683
707
 
684
708
  There's an option to continue using `its` with [rspec-its](https://github.com/rspec/rspec-its) which is a gem extracted from `rspec-core`.
@@ -772,6 +796,9 @@ obj.stub!(:message)
772
796
  obj.stub_chain(:foo, :bar, :baz)
773
797
 
774
798
  Klass.any_instance.stub(:message)
799
+
800
+ obj.unstub(:message)
801
+ obj.unstub!(:message)
775
802
  ```
776
803
 
777
804
  Will be converted to:
@@ -784,9 +811,9 @@ allow(obj).to receive(:message)
784
811
  allow(obj).to receive_message_chain(:foo, :bar, :baz)
785
812
 
786
813
  allow_any_instance_of(Klass).to receive(:message)
787
- ```
788
814
 
789
- There's no replacement for `unstub` in the `expect` syntax. See [this discussion](https://github.com/rspec/rspec-mocks/issues/153#issuecomment-12208638) for more details.
815
+ allow(obj).to receive(:message).and_call_original
816
+ ```
790
817
 
791
818
  * This conversion can be disabled by: `--keep stub`
792
819
  * Deprecation: deprecated since RSpec 3.0
@@ -845,7 +872,7 @@ Will be converted to:
845
872
 
846
873
  ```ruby
847
874
  obj.stub(:message) # with `--keep stub`
848
- obj.unstub(:message)
875
+ obj.unstub(:message) # with `--keep stub`
849
876
  ```
850
877
 
851
878
  * This conversion can be disabled by: `--keep deprecated`
@@ -878,7 +905,7 @@ Targets:
878
905
 
879
906
  ```ruby
880
907
  <%=
881
- useless_and_return_target = <<END
908
+ example = <<END
882
909
  expect(obj).to receive(:message).and_return { 1 }
883
910
  allow(obj).to receive(:message).and_return { 1 }
884
911
 
@@ -891,7 +918,7 @@ END
891
918
  Will be converted to:
892
919
 
893
920
  ```ruby
894
- <%= Transpec::Converter.new.convert(useless_and_return_target) -%>
921
+ <%= convert(example) -%>
895
922
  ```
896
923
 
897
924
  * This conversion can be disabled by: `--keep deprecated`
@@ -906,7 +933,7 @@ Targets:
906
933
 
907
934
  ```ruby
908
935
  <%=
909
- any_instance_block_target = <<END
936
+ example = <<END
910
937
  RSpec.configure do |rspec|
911
938
  end
912
939
 
@@ -927,7 +954,7 @@ Will be converted to:
927
954
  ```ruby
928
955
  <%=
929
956
  rspec_version = Transpec::RSpecVersion.yielding_receiver_to_any_instance_implementation_block_available_version
930
- Transpec::Converter.new(nil, rspec_version).convert(any_instance_block_target)
957
+ convert(example, nil, rspec_version)
931
958
  -%>
932
959
 
933
960
  # With `--no-yield-any-instance`
@@ -935,7 +962,7 @@ Transpec::Converter.new(nil, rspec_version).convert(any_instance_block_target)
935
962
  configuration = Transpec::Configuration.new
936
963
  configuration.add_receiver_arg_to_any_instance_implementation_block = false
937
964
  rspec_version = Transpec::RSpecVersion.yielding_receiver_to_any_instance_implementation_block_available_version
938
- Transpec::Converter.new(configuration, rspec_version).convert(any_instance_block_target)
965
+ convert(example, configuration, rspec_version)
939
966
  -%>
940
967
  ```
941
968
 
@@ -989,7 +1016,7 @@ Targets:
989
1016
 
990
1017
  ```ruby
991
1018
  <%=
992
- pending_example_target = <<END
1019
+ example = <<END
993
1020
  describe 'example' do
994
1021
  it 'is skipped', :pending => true do
995
1022
  do_something_possibly_fail # This won't be run
@@ -1019,7 +1046,7 @@ Will be converted to:
1019
1046
  ```ruby
1020
1047
  <%=
1021
1048
  rspec_version = Transpec::RSpecVersion.skip_available_version
1022
- Transpec::Converter.new(nil, rspec_version).convert(pending_example_target)
1049
+ convert(example, nil, rspec_version)
1023
1050
  .gsub('pending', 'pending # #pending with block is no longer supported')
1024
1051
  -%>
1025
1052
  ```
@@ -1048,7 +1075,7 @@ Targets:
1048
1075
 
1049
1076
  ```ruby
1050
1077
  <%=
1051
- example_target = <<END
1078
+ example = <<END
1052
1079
  module ScreenshotHelper
1053
1080
  def save_failure_screenshot
1054
1081
  return unless example.exception
@@ -1071,7 +1098,7 @@ Will be converted to:
1071
1098
  ```ruby
1072
1099
  <%=
1073
1100
  rspec_version = Transpec::RSpecVersion.yielded_example_available_version
1074
- Transpec::Converter.new(nil, rspec_version).convert(example_target)
1101
+ convert(example, nil, rspec_version)
1075
1102
  -%>
1076
1103
  ```
1077
1104
 
@@ -1103,7 +1130,7 @@ Targets:
1103
1130
 
1104
1131
  ```ruby
1105
1132
  <%=
1106
- custom_matcher_dsl_target = <<END
1133
+ example = <<END
1107
1134
  RSpec::Matchers.define :be_awesome do
1108
1135
  match_for_should { }
1109
1136
  match_for_should_not { }
@@ -1119,7 +1146,7 @@ Will be converted to:
1119
1146
  ```ruby
1120
1147
  <%=
1121
1148
  rspec_version = Transpec::RSpecVersion.non_should_matcher_protocol_available_version
1122
- Transpec::Converter.new(nil, rspec_version).convert(custom_matcher_dsl_target)
1149
+ convert(example, nil, rspec_version)
1123
1150
  -%>
1124
1151
  ```
1125
1152
 
@@ -1127,6 +1154,45 @@ Transpec::Converter.new(nil, rspec_version).convert(custom_matcher_dsl_target)
1127
1154
  * Deprecation: deprecated since RSpec 3.0
1128
1155
  * See also: [Expectations: Matcher protocol and custom matcher API changes - The Plan for RSpec 3](http://myronmars.to/n/dev-blog/2013/07/the-plan-for-rspec-3#expectations_matcher_protocol_and_custom_matcher_api_changes)
1129
1156
 
1157
+ ### Example Groups
1158
+
1159
+ **This conversion is disabled by default and available only if your project's RSpec is `<%= Transpec::RSpecVersion.non_monkey_patch_example_group_available_version %>` or later.**
1160
+
1161
+ Targets:
1162
+
1163
+ ```ruby
1164
+ <%=
1165
+ example = <<END
1166
+ RSpec.configure do |rspec|
1167
+ end
1168
+
1169
+ describe 'top-level example group' do
1170
+ describe 'nested example group' do
1171
+ end
1172
+ end
1173
+
1174
+ shared_examples 'shared examples' do
1175
+ end
1176
+ END
1177
+ -%>
1178
+ ```
1179
+
1180
+ Will be converted to:
1181
+
1182
+ ```ruby
1183
+ <%=
1184
+ configuration = Transpec::Configuration.new
1185
+ configuration.convert_example_group = true
1186
+ rspec_version = Transpec::RSpecVersion.non_monkey_patch_example_group_available_version
1187
+ convert(example, configuration, rspec_version)
1188
+ -%>
1189
+ ```
1190
+
1191
+ * This conversion can be enabled by: `--convert example_group`
1192
+ * Deprecation: Not deprecated
1193
+ * See also: [Zero Monkey Patching Mode! - The Plan for RSpec 3](http://myronmars.to/n/dev-blog/2013/07/the-plan-for-rspec-3#zero_monkey_patching_mode)
1194
+
1195
+
1130
1196
  ## Compatibility
1131
1197
 
1132
1198
  Tested on MRI 1.9, 2.0, 2.1 and JRuby in 1.9 mode.
@@ -1,32 +1,42 @@
1
1
  # coding: utf-8
2
2
 
3
- require 'transpec/ast/builder'
4
- require 'transpec/parser'
3
+ require 'transpec/processed_source'
5
4
 
6
5
  module Transpec
7
6
  class BaseRewriter
8
- def rewrite_file!(file_path)
9
- source = File.read(file_path)
10
- rewritten_source = rewrite(source, file_path)
11
- return if source == rewritten_source
12
- File.write(file_path, rewritten_source)
7
+ def rewrite_file!(arg)
8
+ processed_source = case arg
9
+ when String then ProcessedSource.parse_file(arg)
10
+ when ProcessedSource then arg
11
+ else fail "Invalid argument: #{arg}"
12
+ end
13
+
14
+ fail 'ProcessedSource must be derived from a file' unless processed_source.path
15
+
16
+ rewritten_source = rewrite(processed_source)
17
+ return if processed_source.to_s == rewritten_source
18
+ File.write(processed_source.path, rewritten_source)
13
19
  end
14
20
 
15
- def rewrite(source, name = '(string)')
16
- source_buffer = create_source_buffer(source, name)
17
- ast = parse(source_buffer)
21
+ def rewrite_source(source, path = nil)
22
+ processed_source = ProcessedSource.parse(source, path)
23
+ rewrite(processed_source)
24
+ end
25
+
26
+ def rewrite(processed_source)
27
+ fail processed_source.syntax_error if processed_source.syntax_error
18
28
 
19
- source_rewriter = Parser::Source::Rewriter.new(source_buffer)
20
- failed_overlapping_rewrite = false
29
+ source_rewriter = Parser::Source::Rewriter.new(processed_source.buffer)
30
+ incomplete = false
21
31
  source_rewriter.diagnostics.consumer = proc do
22
- failed_overlapping_rewrite = true
32
+ incomplete = true
23
33
  fail OverlappedRewriteError
24
34
  end
25
35
 
26
- process(ast, source_rewriter)
36
+ process(processed_source.ast, source_rewriter)
27
37
 
28
38
  rewritten_source = source_rewriter.process
29
- rewritten_source = rewrite(rewritten_source, name) if failed_overlapping_rewrite
39
+ rewritten_source = rewrite_source(rewritten_source, processed_source.path) if incomplete
30
40
 
31
41
  rewritten_source
32
42
  end
@@ -37,19 +47,6 @@ module Transpec
37
47
  fail NotImplementedError
38
48
  end
39
49
 
40
- def create_source_buffer(source, name)
41
- source_buffer = Parser::Source::Buffer.new(name)
42
- source_buffer.source = source
43
- source_buffer
44
- end
45
-
46
- def parse(source_buffer)
47
- builder = AST::Builder.new
48
- parser = Parser::CurrentRuby.new(builder)
49
- ast = parser.parse(source_buffer)
50
- ast
51
- end
52
-
53
50
  class OverlappedRewriteError < StandardError; end
54
51
  end
55
52
  end