transpec 0.2.6 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +1 -1
  4. data/CHANGELOG.md +10 -0
  5. data/README.md +111 -56
  6. data/README.md.erb +117 -62
  7. data/lib/transpec/ast/node.rb +41 -0
  8. data/lib/transpec/base_rewriter.rb +55 -0
  9. data/lib/transpec/cli.rb +43 -153
  10. data/lib/transpec/configuration.rb +13 -9
  11. data/lib/transpec/{rewriter.rb → converter.rb} +44 -71
  12. data/lib/transpec/dynamic_analyzer/rewriter.rb +94 -0
  13. data/lib/transpec/dynamic_analyzer/runtime_data.rb +27 -0
  14. data/lib/transpec/dynamic_analyzer.rb +166 -0
  15. data/lib/transpec/file_finder.rb +53 -0
  16. data/lib/transpec/option_parser.rb +166 -0
  17. data/lib/transpec/{context.rb → static_context_inspector.rb} +2 -2
  18. data/lib/transpec/syntax/be_close.rb +7 -9
  19. data/lib/transpec/syntax/double.rb +6 -10
  20. data/lib/transpec/syntax/expect.rb +35 -0
  21. data/lib/transpec/syntax/have.rb +195 -0
  22. data/lib/transpec/syntax/method_stub.rb +22 -27
  23. data/lib/transpec/syntax/mixin/allow_no_message.rb +73 -0
  24. data/lib/transpec/syntax/mixin/any_instance.rb +22 -0
  25. data/lib/transpec/syntax/mixin/expectizable.rb +26 -0
  26. data/lib/transpec/syntax/mixin/have_matcher.rb +23 -0
  27. data/lib/transpec/syntax/mixin/monkey_patch.rb +37 -0
  28. data/lib/transpec/syntax/mixin/send.rb +109 -0
  29. data/lib/transpec/syntax/{matcher.rb → operator_matcher.rb} +27 -14
  30. data/lib/transpec/syntax/raise_error.rb +6 -10
  31. data/lib/transpec/syntax/rspec_configure.rb +29 -28
  32. data/lib/transpec/syntax/should.rb +45 -15
  33. data/lib/transpec/syntax/should_receive.rb +44 -16
  34. data/lib/transpec/syntax.rb +29 -21
  35. data/lib/transpec/util.rb +12 -2
  36. data/lib/transpec/version.rb +3 -3
  37. data/spec/spec_helper.rb +8 -6
  38. data/spec/support/cache_helper.rb +50 -0
  39. data/spec/support/shared_context.rb +49 -1
  40. data/spec/transpec/ast/node_spec.rb +65 -0
  41. data/spec/transpec/cli_spec.rb +33 -242
  42. data/spec/transpec/commit_message_spec.rb +2 -2
  43. data/spec/transpec/configuration_spec.rb +12 -8
  44. data/spec/transpec/{rewriter_spec.rb → converter_spec.rb} +198 -148
  45. data/spec/transpec/dynamic_analyzer/rewriter_spec.rb +183 -0
  46. data/spec/transpec/dynamic_analyzer_spec.rb +164 -0
  47. data/spec/transpec/file_finder_spec.rb +118 -0
  48. data/spec/transpec/option_parser_spec.rb +185 -0
  49. data/spec/transpec/{context_spec.rb → static_context_inspector_spec.rb} +27 -12
  50. data/spec/transpec/syntax/be_close_spec.rb +8 -4
  51. data/spec/transpec/syntax/double_spec.rb +105 -12
  52. data/spec/transpec/syntax/expect_spec.rb +83 -0
  53. data/spec/transpec/syntax/have_spec.rb +599 -0
  54. data/spec/transpec/syntax/method_stub_spec.rb +276 -115
  55. data/spec/transpec/syntax/{matcher_spec.rb → operator_matcher_spec.rb} +277 -98
  56. data/spec/transpec/syntax/raise_error_spec.rb +92 -46
  57. data/spec/transpec/syntax/should_receive_spec.rb +298 -92
  58. data/spec/transpec/syntax/should_spec.rb +230 -44
  59. data/spec/transpec/util_spec.rb +2 -9
  60. data/tasks/lib/transpec_demo.rb +1 -1
  61. data/tasks/lib/transpec_test.rb +5 -7
  62. data/tasks/test.rake +5 -1
  63. data/transpec.gemspec +1 -1
  64. metadata +46 -22
  65. data/lib/transpec/syntax/able_to_allow_no_message.rb +0 -73
  66. data/lib/transpec/syntax/able_to_target_any_instance.rb +0 -24
  67. data/lib/transpec/syntax/expectizable.rb +0 -27
  68. data/lib/transpec/syntax/send_node_syntax.rb +0 -57
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2d1e226cde065f5be1ba8ed1a21d0cf0a8721791
4
- data.tar.gz: 6e53c222eb7070fe7a958a24615c6fb10071709c
3
+ metadata.gz: e89b721e834bdcbbc84616c93aeb74dcdcd69d29
4
+ data.tar.gz: 5678c00ce5a1bcc36e55cdcc41233fc0bd24d075
5
5
  SHA512:
6
- metadata.gz: 65dad2b78acf24ce17d78d677b99daddc806ef5bc72f5a6ea7f0f9418b40828d0b709bbe313c711a6ce85b0769ff2577097582ae04207e2426c1c7cef4aea99c
7
- data.tar.gz: f02830fbb953af904c67c6a5bdec5cddc20fb57fcc8d536cdde5cdf8da16842e4b6fbf125ae0d489349b49cf2f70eb0723713a8ae36a628f82c6f576fb63b34f
6
+ metadata.gz: b71de56cdff03743ced725d67478c80be77a2772421dd73c1bdc8d8d4a67fc17f6b1907f819b421feb40de91960afa64cf71ab5a9e5dbe3193924fd49ba8289c
7
+ data.tar.gz: 39ca211fe213c2d6858ac2fbd669953d363de542443ceb85c4c0f7d8dc578cde12be976e94eb0a578d718e29cfeb65e29bba1516060f1f1c57279c2563e3f95f
data/.gitignore CHANGED
@@ -12,6 +12,7 @@ lib/bundler/man
12
12
  pkg
13
13
  rdoc
14
14
  spec/reports
15
+ spec/cache
15
16
  test/tmp
16
17
  test/version_tmp
17
18
  tmp
data/.rubocop.yml CHANGED
@@ -50,4 +50,4 @@ IndentationWidth:
50
50
 
51
51
  # TODO: Shorten to 100.
52
52
  ClassLength:
53
- Max: 186
53
+ Max: 194
data/CHANGELOG.md CHANGED
@@ -2,6 +2,16 @@
2
2
 
3
3
  ## Master
4
4
 
5
+ * Now Transpec does dynamic code analysis!
6
+ * Support conversion of `have(n).items` matcher ([#5](https://github.com/yujinakayama/transpec/issues/5))
7
+ * Add `-s/--skip-dynamic-analysis` option that allows to skip dynamic analysis and convert with only static analysis
8
+ * Add `-c/--rspec-command` option that allows to specify command to run RSpec that is used for dynamic analysis
9
+ * Check contexts correctly with runtime information
10
+ * Detect same name but non-RSpec methods with runtime information ([#4](https://github.com/yujinakayama/transpec/issues/4))
11
+ * Consider runtime type information when converting `=~` to `match_array`
12
+ * Rename `-d/--disable` option to `-k/--keep` and change its syntax types
13
+ * Rename `--commit-message` option to `--generate-commit-message`
14
+
5
15
  ## v0.2.6
6
16
 
7
17
  * Fix a bug where `Node#each_descendent_node` enumerates only within depth 2
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  # Transpec
4
4
 
5
- **Transpec** automatically converts your specs into latest [RSpec](http://rspec.info/) syntax with static analysis.
5
+ **Transpec** automatically converts your specs into latest [RSpec](http://rspec.info/) syntax with static and dynamic code analysis.
6
6
 
7
7
  This aims to facilitate smooth transition to RSpec 3.
8
8
 
@@ -91,9 +91,9 @@ describe Account do
91
91
  end
92
92
  ```
93
93
 
94
- ### Real Examples
94
+ ### Actual Examples
95
95
 
96
- You can see real conversion examples below:
96
+ You can see actual conversion examples below:
97
97
 
98
98
  * https://github.com/yujinakayama/guard/commit/transpec-demo
99
99
  * https://github.com/yujinakayama/mail/commit/transpec-demo
@@ -113,27 +113,32 @@ Before converting your specs:
113
113
  * Run `rspec` and check if all the specs pass.
114
114
  * Ensure the Git repository is clean. (You don't want to mix up your changes and Transpec's changes, right?)
115
115
 
116
- Then, run `transpec` (using `--commit-message` is recommended) in the project root directory:
116
+ Then, run `transpec` (using `--generate-commit-message` is recommended) in the project root directory:
117
117
 
118
118
  ```bash
119
119
  $ cd some-project
120
- $ transpec --commit-message
121
- Processing spec/spec_helper.rb
122
- Processing spec/spec_spec.rb
123
- Processing spec/support/file_helper.rb
124
- Processing spec/support/shared_context.rb
125
- Processing spec/transpec/ast/scanner_spec.rb
126
- Processing spec/transpec/ast/scope_stack_spec.rb
120
+ $ transpec --generate-commit-message
121
+ Copying project for dynamic analysis...
122
+ Running dynamic analysis with command "bundle exec rspec"...
123
+ ...............................................................................
124
+ ...................
125
+
126
+ Finished in 13.07 seconds
127
+ 100 examples, 0 failures
128
+
129
+ Converting spec/spec_helper.rb
130
+ Converting spec/support/cache_helper.rb
131
+ Converting spec/support/file_helper.rb
132
+ Converting spec/support/shared_context.rb
133
+ Converting spec/transpec/ast/node_spec.rb
127
134
  ```
128
135
 
129
- This will convert and overwrite all spec files in the `spec` directory.
136
+ This will run your specs, convert them, and overwrite all spec files in the `spec` directory.
130
137
 
131
138
  After the conversion, run `rspec` again and check whether all pass:
132
139
 
133
140
  ```bash
134
141
  $ bundle exec rspec
135
- # ...
136
- 843 examples, 0 failures
137
142
  ```
138
143
 
139
144
  If all pass, commit the changes with auto-generated message:
@@ -162,7 +167,23 @@ Processing spec/spec_spec.rb
162
167
  Processing spec/support/file_helper.rb
163
168
  ```
164
169
 
165
- ### `-m/--commit-message`
170
+ ### `-s/--skip-dynamic-analysis`
171
+
172
+ Skip dynamic analysis and convert with only static analysis. Note that specifying this option decreases the conversion accuracy.
173
+
174
+ ### `-c/--rspec-command`
175
+
176
+ Specify command to run RSpec that is used for dynamic analysis.
177
+
178
+ Transpec needs to run your specs in copied project directory for dynamic analysis.
179
+ If your project requires some special setup or commands to run specs, use this option.
180
+ `bundle exec rspec` is used by default.
181
+
182
+ ```bash
183
+ $ transpec --rspec-command "./some_special_setup.sh && bundle exec rspec"
184
+ ```
185
+
186
+ ### `-m/--generate-commit-message`
166
187
 
167
188
  Generate commit message that describes conversion summary.
168
189
  Currently only Git is supported.
@@ -173,22 +194,23 @@ When you commit, you need to run the following command to use the generated mess
173
194
  $ git commit -eF .git/COMMIT_EDITMSG
174
195
  ```
175
196
 
176
- ### `-d/--disable`
197
+ ### `-k/--keep`
177
198
 
178
- Disable specific conversions.
199
+ Keep specific syntaxes by disabling conversions.
179
200
 
180
201
  ```bash
181
- $ transpec --disable expect_to_receive,allow_to_receive
202
+ $ transpec --keep should_receive,stub
182
203
  ```
183
204
 
184
- #### Available conversion types
205
+ #### Available syntax types
185
206
 
186
- Conversion Type | Target Syntax | Converted Syntax
187
- --------------------|----------------------------------|----------------------------
188
- `expect_to_matcher` | `obj.should matcher` | `expect(obj).to matcher`
189
- `expect_to_receive` | `obj.should_receive` | `expect(obj).to receive`
190
- `allow_to_receive` | `obj.stub` | `allow(obj).to receive`
191
- `deprecated` | `obj.stub!`, `mock('foo')`, etc. | `obj.stub`, `double('foo')`
207
+ Type | Target Syntax | Converted Syntax
208
+ -----------------|----------------------------------|----------------------------
209
+ `should` | `obj.should matcher` | `expect(obj).to matcher`
210
+ `should_receive` | `obj.should_receive` | `expect(obj).to receive`
211
+ `stub` | `obj.stub` | `allow(obj).to receive`
212
+ `have_items` | `expect(obj).to have(x).items` | `expect(obj.size).to eq(x)`
213
+ `deprecated` | `obj.stub!`, `mock('foo')`, etc. | `obj.stub`, `double('foo')`
192
214
 
193
215
  ### `-n/--negative-form`
194
216
 
@@ -242,7 +264,7 @@ describe 'converted spec with -p/--no-parentheses-matcher-arg option' do
242
264
  end
243
265
  ```
244
266
 
245
- ## Troubleshooting
267
+ ## Inconvertible Specs
246
268
 
247
269
  You might see the following warning while conversion:
248
270
 
@@ -270,11 +292,11 @@ end
270
292
 
271
293
  ### Reason
272
294
 
273
- * `should` is defined on `Kernel` (included by `Object`), so you can use `should` almost everywhere.
274
- * `expect` is defined on `RSpec::Matchers` (included by `RSpec::Core::ExampleGroup`), so you can use `expect` only where `self` is an instance of `RSpec::Core::ExampleGroup`.
295
+ * `should` is defined on `Kernel` module that is included by `Object` class, so you can use `should` almost everywhere.
296
+ * `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 methods).
275
297
 
276
298
  With the above example, in the context of `1.should == 1`, the `self` is an instance of `MyAwesomeTestRunner`.
277
- So Transpec tracks contexts and skips conversion if the target syntax cannot be converted in a case like this.
299
+ Transpec tracks contexts and skips conversion if the target syntax cannot be converted in a case like this.
278
300
 
279
301
  ### Solution
280
302
 
@@ -295,8 +317,8 @@ expect(obj).not_to matcher
295
317
  expect(obj).to_not matcher # with `--negative-form to_not`
296
318
  ```
297
319
 
298
- * Disabled by: `--disable expect_to_matcher`
299
- * Related Information: [Myron Marston » RSpec's New Expectation Syntax](http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax)
320
+ * Disabled by: `--keep should`
321
+ * See also: [Myron Marston » RSpec's New Expectation Syntax](http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax)
300
322
 
301
323
  ### Operator matchers
302
324
 
@@ -316,7 +338,7 @@ expect('string').to match(/^str/)
316
338
  expect([1, 2, 3]).to match_array([2, 1, 3])
317
339
  ```
318
340
 
319
- * Related Information: [Myron Marston » RSpec's New Expectation Syntax](http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax#almost_all_matchers_are_supported)
341
+ * See also: [(Almost) All Matchers Are Supported - RSpec's New Expectation Syntax](http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax#almost_all_matchers_are_supported)
320
342
 
321
343
  ### `be_close` matcher
322
344
 
@@ -328,10 +350,43 @@ expect([1, 2, 3]).to match_array([2, 1, 3])
328
350
  (1.0 / 3.0).should be_within(0.001).of(0.333)
329
351
  ```
330
352
 
331
- * Disabled by: `--disable deprecated`
332
- * Related Information: [New be within matcher and RSpec.deprecate fix · rspec/rspec-expectations](https://github.com/rspec/rspec-expectations/pull/32)
353
+ * Disabled by: `--keep deprecated`
354
+ * See also: [New be within matcher and RSpec.deprecate fix · rspec/rspec-expectations](https://github.com/rspec/rspec-expectations/pull/32)
355
+
356
+ ### `have(n).items` matcher
357
+
358
+ ```ruby
359
+ # Targets
360
+ expect(collection).to have(3).items
361
+ expect(collection).to have_exactly(3).items
362
+ expect(collection).to have_at_least(3).items
363
+ expect(collection).to have_at_most(3).items
364
+ collection.should have(3).items
365
+
366
+ expect(team).to have(3).players
367
+
368
+ # Assume #players is a private method.
369
+ expect(team).to have(3).players
370
+
371
+ # Converted
372
+ expect(collection.size).to eq(3)
373
+ expect(collection.size).to be >= 3
374
+ expect(collection.size).to be <= 3
375
+ collection.size.should == 3 # with `--keep should`
376
+
377
+ expect(team.players.size).to eq(3)
378
+
379
+ # have(n).items matcher invokes #players even if it's a private method.
380
+ expect(team.send(:players).size).to eq(3)
381
+ ```
382
+
383
+ You have the option to continue using `have(n).items` matcher with [rspec-collection_matchers](https://github.com/rspec/rspec-collection_matchers) that is an external gem extracted from `rspec-expectations`.
384
+ If you choose so, disable this conversion with `--keep have_items`.
385
+
386
+ * Disabled by: `--keep have_items`
387
+ * 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)
333
388
 
334
- ### Expectations on Proc
389
+ ### Expectations on Block
335
390
 
336
391
  ```ruby
337
392
  # Targets
@@ -343,8 +398,8 @@ proc { do_something }.should raise_error
343
398
  expect { do_something }.to raise_error
344
399
  ```
345
400
 
346
- * Disabled by: `--disable expect_to_matcher`
347
- * Related Information: [Myron Marston » RSpec's New Expectation Syntax](http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax#unification_of_block_vs_value_syntaxes)
401
+ * Disabled by: `--keep should`
402
+ * See also: [Unification of Block vs. Value Syntaxes - RSpec's New Expectation Syntax](http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax#unification_of_block_vs_value_syntaxes)
348
403
 
349
404
  ### Negative error expectations with specific error
350
405
 
@@ -357,11 +412,11 @@ lambda { do_something }.should_not raise_error(SomeErrorClass)
357
412
 
358
413
  # Converted
359
414
  expect { do_something }.not_to raise_error
360
- lambda { do_something }.should_not raise_error # with `--disable expect_to_matcher`
415
+ lambda { do_something }.should_not raise_error # with `--keep should`
361
416
  ```
362
417
 
363
- * Disabled by: `--disable deprecated`
364
- * Related Information: [Consider deprecating `expect { }.not_to raise_error(SpecificErrorClass)` · rspec/rspec-expectations](https://github.com/rspec/rspec-expectations/issues/231)
418
+ * Disabled by: `--keep deprecated`
419
+ * See also: [Consider deprecating `expect { }.not_to raise_error(SpecificErrorClass)` · rspec/rspec-expectations](https://github.com/rspec/rspec-expectations/issues/231)
365
420
 
366
421
  ### Message expectations
367
422
 
@@ -375,8 +430,8 @@ expect(obj).to receive(:foo)
375
430
  expect_any_instance_of(SomeClass).to receive(:foo)
376
431
  ```
377
432
 
378
- * Disabled by: `--disable expect_to_receive`
379
- * Related Information: [RSpec's new message expectation syntax - Tea is awesome.](http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/)
433
+ * Disabled by: `--keep should_receive`
434
+ * See also: [RSpec's new message expectation syntax - Tea is awesome.](http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/)
380
435
 
381
436
  ### Message expectations that are actually method stubs
382
437
 
@@ -390,14 +445,14 @@ SomeClass.any_instance.should_receive(:foo).at_least(0)
390
445
 
391
446
  # Converted
392
447
  allow(obj).to receive(:foo)
393
- obj.stub(:foo) # with `--disable allow_to_receive`
448
+ obj.stub(:foo) # with `--keep stub`
394
449
 
395
450
  allow_any_instance_of(SomeClass).to receive(:foo)
396
- SomeClass.any_instance.stub(:foo) # with `--disable allow_to_receive`
451
+ SomeClass.any_instance.stub(:foo) # with `--keep stub`
397
452
  ```
398
453
 
399
- * Disabled by: `--disable deprecated`
400
- * Related Information: [Don't allow at_least(0) · rspec/rspec-mocks](https://github.com/rspec/rspec-mocks/issues/133)
454
+ * Disabled by: `--keep deprecated`
455
+ * See also: [Don't allow at_least(0) · rspec/rspec-mocks](https://github.com/rspec/rspec-mocks/issues/133)
401
456
 
402
457
  ### Method stubs
403
458
 
@@ -422,8 +477,8 @@ allow(obj).to receive(:bar).and_return(2)
422
477
  allow_any_instance_of(SomeClass).to receive(:foo)
423
478
  ```
424
479
 
425
- * Disabled by: `--disable allow_to_receive`
426
- * Related Information: [RSpec's new message expectation syntax - Tea is awesome.](http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/)
480
+ * Disabled by: `--keep stub`
481
+ * See also: [RSpec's new message expectation syntax - Tea is awesome.](http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/)
427
482
 
428
483
  ### Deprecated method stub aliases
429
484
 
@@ -433,12 +488,12 @@ obj.stub!(:foo)
433
488
  obj.unstub!(:foo)
434
489
 
435
490
  # Converted
436
- obj.stub(:foo) # with `--disable allow_to_receive`
491
+ obj.stub(:foo) # with `--keep stub`
437
492
  obj.unstub(:foo)
438
493
  ```
439
494
 
440
- * Disabled by: `--disable deprecated`
441
- * Related Information: [Consider deprecating and/or removing #stub! and #unstub! at some point · rspec/rspec-mocks](https://github.com/rspec/rspec-mocks/issues/122)
495
+ * Disabled by: `--keep deprecated`
496
+ * See also: [Consider deprecating and/or removing #stub! and #unstub! at some point · rspec/rspec-mocks](https://github.com/rspec/rspec-mocks/issues/122)
442
497
 
443
498
  ### Method stubs with deprecated specification of number of times
444
499
 
@@ -449,11 +504,11 @@ obj.stub(:foo).at_least(0)
449
504
 
450
505
  # Converted
451
506
  allow(obj).to receive(:foo)
452
- obj.stub(:foo) # with `--disable allow_to_receive`
507
+ obj.stub(:foo) # with `--keep stub`
453
508
  ```
454
509
 
455
- * Disabled by: `--disable deprecated`
456
- * Related Information: [Don't allow at_least(0) · rspec/rspec-mocks](https://github.com/rspec/rspec-mocks/issues/133)
510
+ * Disabled by: `--keep deprecated`
511
+ * See also: [Don't allow at_least(0) · rspec/rspec-mocks](https://github.com/rspec/rspec-mocks/issues/133)
457
512
 
458
513
  ### Deprecated test double aliases
459
514
 
@@ -466,8 +521,8 @@ mock('something')
466
521
  double('something')
467
522
  ```
468
523
 
469
- * Disabled by: `--disable deprecated`
470
- * Related Information: [Deprecate "stub" for doubles · rspec/rspec-mocks](https://github.com/rspec/rspec-mocks/issues/214)
524
+ * Disabled by: `--keep deprecated`
525
+ * See also: [Deprecate "stub" for doubles · rspec/rspec-mocks](https://github.com/rspec/rspec-mocks/issues/214)
471
526
 
472
527
  ## Compatibility
473
528