transpec 1.10.4 → 1.11.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 (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
@@ -72,12 +72,23 @@ module Transpec
72
72
  end
73
73
  end
74
74
 
75
- describe '#convert_to_standard_expectation!' do
76
- let(:record) { have_object.report.records.last }
75
+ describe '#conversion_target?' do
76
+ let(:should_node) do
77
+ ast.each_descendent_node do |node|
78
+ next unless node.send_type?
79
+ method_name = node.children[1]
80
+ return node if method_name == :should
81
+ end
82
+ fail 'No #should node is found!'
83
+ end
77
84
 
78
- context 'when rspec-rails is loaded in the spec' do
79
- include_context 'dynamic analysis objects'
85
+ let(:should_object) do
86
+ Should.new(should_node, source_rewriter, runtime_data)
87
+ end
88
+
89
+ subject { should_object.have_matcher.conversion_target? }
80
90
 
91
+ context 'when rspec-rails is loaded in the spec' do
81
92
  let(:source) do
82
93
  <<-END
83
94
  module RSpec
@@ -93,17 +104,17 @@ module Transpec
93
104
  END
94
105
  end
95
106
 
96
- let(:have_object) { should_object.have_matcher }
107
+ context 'without runtime information' do
108
+ it { should be_true }
109
+ end
97
110
 
98
- it 'does nothing' do
99
- have_object.convert_to_standard_expectation!
100
- rewritten_source.should == source
111
+ context 'with runtime information' do
112
+ include_context 'dynamic analysis objects'
113
+ it { should be_false }
101
114
  end
102
115
  end
103
116
 
104
117
  context 'when rspec-collection_matchers is loaded in the spec' do
105
- include_context 'dynamic analysis objects'
106
-
107
118
  let(:source) do
108
119
  <<-END
109
120
  module RSpec
@@ -119,13 +130,23 @@ module Transpec
119
130
  END
120
131
  end
121
132
 
122
- let(:have_object) { should_object.have_matcher }
133
+ context 'without runtime information' do
134
+ it { should be_true }
135
+ end
123
136
 
124
- it 'does nothing' do
125
- have_object.convert_to_standard_expectation!
126
- rewritten_source.should == source
137
+ context 'with runtime information' do
138
+ include_context 'dynamic analysis objects'
139
+ it { should be_false }
127
140
  end
128
141
  end
142
+ end
143
+
144
+ describe '#convert_to_standard_expectation!' do
145
+ let(:record) { have_object.report.records.last }
146
+
147
+ before do
148
+ fail 'The #have_matcher is not a conversion target!' unless have_object.conversion_target?
149
+ end
129
150
 
130
151
  context 'with expression `collection.should have(2).items`' do
131
152
  let(:source) do
@@ -11,14 +11,23 @@ module Transpec
11
11
 
12
12
  let(:record) { its_object.report.records.last }
13
13
 
14
- describe '#convert_to_describe_subject_it!' do
15
- before do
16
- its_object.convert_to_describe_subject_it!
14
+ describe '#conversion_target?' do
15
+ let(:its_node) do
16
+ ast.each_descendent_node do |node|
17
+ next unless node.send_type?
18
+ method_name = node.children[1]
19
+ return node if method_name == :its
20
+ end
21
+ fail 'No #its node is found!'
17
22
  end
18
23
 
19
- context 'when rspec-its is loaded in the spec' do
20
- include_context 'dynamic analysis objects'
24
+ let(:its_object) do
25
+ Its.new(its_node, source_rewriter, runtime_data)
26
+ end
27
+
28
+ subject { its_object.conversion_target? }
21
29
 
30
+ context 'when rspec-its is loaded in the spec' do
22
31
  let(:source) do
23
32
  <<-END
24
33
  module RSpec
@@ -34,9 +43,20 @@ module Transpec
34
43
  END
35
44
  end
36
45
 
37
- it 'does nothing' do
38
- rewritten_source.should == source
46
+ context 'without runtime information' do
47
+ it { should be_true }
39
48
  end
49
+
50
+ context 'with runtime information' do
51
+ include_context 'dynamic analysis objects'
52
+ it { should be_false }
53
+ end
54
+ end
55
+ end
56
+
57
+ describe '#convert_to_describe_subject_it!' do
58
+ before do
59
+ its_object.convert_to_describe_subject_it!
40
60
  end
41
61
 
42
62
  context 'with expression `its(:size) { ... }`' do
@@ -684,12 +684,23 @@ module Transpec
684
684
  END
685
685
  end
686
686
 
687
- it 'does nothing' do
688
- rewritten_source.should == source
687
+ let(:expected_source) do
688
+ <<-END
689
+ describe 'example' do
690
+ it 'does not respond to #foo' do
691
+ allow(subject).to receive(:foo).and_call_original
692
+ end
693
+ end
694
+ END
689
695
  end
690
696
 
691
- it 'reports nothing' do
692
- method_stub_object.report.records.should be_empty
697
+ it 'converts to `allow(subject).to receive(:method).and_call_original`' do
698
+ rewritten_source.should == expected_source
699
+ end
700
+
701
+ it "adds record `obj.#{method}(:message)` -> `allow(obj).to receive(:message).and_call_original`" do
702
+ record.original_syntax.should == "obj.#{method}(:message)"
703
+ record.converted_syntax.should == 'allow(obj).to receive(:message).and_call_original'
693
704
  end
694
705
  end
695
706
  end
@@ -848,12 +859,24 @@ module Transpec
848
859
  END
849
860
  end
850
861
 
851
- it 'does nothing' do
852
- rewritten_source.should == source
862
+ let(:expected_source) do
863
+ <<-END
864
+ describe 'example' do
865
+ it 'does not respond to #foo' do
866
+ allow_any_instance_of(Klass).to receive(:foo).and_call_original
867
+ end
868
+ end
869
+ END
853
870
  end
854
871
 
855
- it 'reports nothing' do
856
- method_stub_object.report.records.should be_empty
872
+ it 'converts to `allow(subject).to receive(:method).and_call_original`' do
873
+ rewritten_source.should == expected_source
874
+ end
875
+
876
+ it "adds record `Klass.any_instance.#{method}(:message)` " \
877
+ '-> `allow_any_instance_of(Klass).to receive(:message).and_call_original`' do
878
+ record.original_syntax.should == "Klass.any_instance.#{method}(:message)"
879
+ record.converted_syntax.should == 'allow_any_instance_of(Klass).to receive(:message).and_call_original'
857
880
  end
858
881
  end
859
882
  end
@@ -112,97 +112,36 @@ module Transpec
112
112
  describe '#operator_matcher' do
113
113
  subject { should_object.operator_matcher }
114
114
 
115
- context 'when it is taking operator matcher' do
116
- let(:source) do
117
- <<-END
118
- describe 'example' do
119
- it { should == 1 }
120
- end
121
- END
122
- end
123
-
124
- it 'returns an instance of Operator' do
125
- should be_an(Operator)
126
- end
115
+ let(:source) do
116
+ <<-END
117
+ describe 'example' do
118
+ it { should == 1 }
119
+ end
120
+ END
127
121
  end
128
122
 
129
- context 'when it is taking non-operator matcher' do
130
- let(:source) do
131
- <<-END
132
- describe 'example' do
133
- it { should be_empty }
134
- end
135
- END
136
- end
137
-
138
- it 'returns nil' do
139
- should be_nil
140
- end
123
+ it 'returns an instance of Operator' do
124
+ should be_an(Operator)
141
125
  end
142
126
  end
143
127
 
144
128
  describe '#have_matcher' do
145
129
  subject { should_object.have_matcher }
146
130
 
147
- context 'when it is taking #have matcher' do
148
- let(:source) do
149
- <<-END
150
- describe 'example' do
151
- it { should have(2).items }
152
- end
153
- END
154
- end
155
-
156
- it 'returns an instance of Have' do
157
- should be_an(Have)
158
- end
131
+ let(:source) do
132
+ <<-END
133
+ describe 'example' do
134
+ it { should have(2).items }
135
+ end
136
+ END
159
137
  end
160
138
 
161
- context 'when it is taking operator matcher' do
162
- let(:source) do
163
- <<-END
164
- describe 'example' do
165
- it { should == 1 }
166
- end
167
- END
168
- end
169
-
170
- it 'returns nil' do
171
- should be_nil
172
- end
173
- end
174
-
175
- context 'when it is taking any other non-operator matcher' do
176
- let(:source) do
177
- <<-END
178
- describe 'example' do
179
- it { should be_empty }
180
- end
181
- END
182
- end
183
-
184
- it 'returns nil' do
185
- should be_nil
186
- end
139
+ it 'returns an instance of Have' do
140
+ should be_an(Have)
187
141
  end
188
142
  end
189
143
 
190
144
  describe '#expectize!' do
191
- context 'when it has an operator matcher' do
192
- let(:source) do
193
- <<-END
194
- describe 'example' do
195
- it { should == 1 }
196
- end
197
- END
198
- end
199
-
200
- it 'invokes Operator#convert_operator!' do
201
- should_object.operator_matcher.should_receive(:convert_operator!)
202
- should_object.expectize!
203
- end
204
- end
205
-
206
145
  context 'with expression `it { should be true }`' do
207
146
  let(:source) do
208
147
  <<-END
@@ -244,71 +183,24 @@ module Transpec
244
183
  let(:expected_source) do
245
184
  <<-END
246
185
  describe 'example' do
247
- it { is_expected.to eq(1) }
186
+ it { is_expected.to == 1 }
248
187
  end
249
188
  END
250
189
  end
251
190
 
252
- it 'converts to `it { is_expected.to eq(1) }` form' do
191
+ it 'converts to `it { is_expected.to == 1 }` form' do
253
192
  should_object.expectize!
254
193
  rewritten_source.should == expected_source
255
194
  end
256
195
  end
257
196
  end
258
197
 
259
- shared_examples 'does not convert if project requires have(n).items matcher' do
260
- context 'when rspec-rails is loaded in the spec' do
261
- include_context 'dynamic analysis objects'
262
-
263
- let(:source) do
264
- <<-END
265
- module RSpec
266
- module Rails
267
- end
268
- end
269
-
270
- describe [:foo, :bar] do
271
- it { should have(2).items }
272
- end
273
- END
274
- end
275
-
276
- it 'does nothing' do
277
- rewritten_source.should == source
278
- end
279
- end
280
-
281
- context 'when rspec-collection_matchers is loaded in the spec' do
282
- include_context 'dynamic analysis objects'
283
-
284
- let(:source) do
285
- <<-END
286
- module RSpec
287
- module CollectionMatchers
288
- end
289
- end
290
-
291
- describe [:foo, :bar] do
292
- it { should have(2).items }
293
- end
294
- END
295
- end
296
-
297
- let(:have_object) { should_object.have_matcher }
298
-
299
- it 'does nothing' do
300
- rewritten_source.should == source
301
- end
302
- end
303
- end
304
-
305
- describe '#convert_have_items_to_standard_should!' do
198
+ describe '#convert_have_items_to_standard_should! and Have#convert_to_standard_expectation!' do
306
199
  before do
307
200
  should_object.convert_have_items_to_standard_should!
201
+ should_object.have_matcher.convert_to_standard_expectation!
308
202
  end
309
203
 
310
- include_examples 'does not convert if project requires have(n).items matcher'
311
-
312
204
  context 'with expression `it { should have(2).items }`' do
313
205
  let(:source) do
314
206
  <<-END
@@ -632,13 +524,12 @@ module Transpec
632
524
  end
633
525
  end
634
526
 
635
- describe '#convert_have_items_to_standard_expect!' do
527
+ describe '#convert_have_items_to_standard_expect! and Have#convert_to_standard_expectation!' do
636
528
  before do
637
529
  should_object.convert_have_items_to_standard_expect!
530
+ should_object.have_matcher.convert_to_standard_expectation!
638
531
  end
639
532
 
640
- include_examples 'does not convert if project requires have(n).items matcher'
641
-
642
533
  context 'with expression `it { should have(2).items }`' do
643
534
  let(:source) do
644
535
  <<-END
@@ -9,6 +9,79 @@ module Transpec
9
9
  include_context 'parsed objects'
10
10
  include_context 'syntax object', RSpecConfigure, :rspec_configure
11
11
 
12
+ describe '#expose_dsl_globally=' do
13
+ before do
14
+ rspec_configure.expose_dsl_globally = value
15
+ end
16
+
17
+ let(:value) { true }
18
+
19
+ let(:source) do
20
+ <<-END
21
+ RSpec.configure do |config|
22
+ config.expose_dsl_globally = false
23
+ end
24
+ END
25
+ end
26
+
27
+ let(:expected_source) do
28
+ <<-END
29
+ RSpec.configure do |config|
30
+ config.expose_dsl_globally = true
31
+ end
32
+ END
33
+ end
34
+
35
+ it 'rewrites the `expose_dsl_globally` configuration' do
36
+ rewritten_source.should == expected_source
37
+ end
38
+
39
+ context 'when #expose_dsl_globally= does not exist' do
40
+ let(:source) do
41
+ <<-END
42
+ RSpec.configure do |config|
43
+ end
44
+ END
45
+ end
46
+
47
+ let(:expected_source) do
48
+ <<-END
49
+ RSpec.configure do |config|
50
+ config.expose_dsl_globally = true
51
+ end
52
+ END
53
+ end
54
+
55
+ it 'adds #expose_dsl_globally= statement' do
56
+ rewritten_source.should == expected_source
57
+ end
58
+ end
59
+
60
+ context 'when there are already some configurations' do
61
+ let(:source) do
62
+ <<-END
63
+ RSpec.configure do |config|
64
+ config.foo = 1
65
+ end
66
+ END
67
+ end
68
+
69
+ let(:expected_source) do
70
+ <<-END
71
+ RSpec.configure do |config|
72
+ config.foo = 1
73
+
74
+ config.expose_dsl_globally = true
75
+ end
76
+ END
77
+ end
78
+
79
+ it 'adds the block after a blank line' do
80
+ rewritten_source.should == expected_source
81
+ end
82
+ end
83
+ end
84
+
12
85
  shared_examples '#syntaxes' do |framework_block_method|
13
86
  describe '#syntaxes' do
14
87
  subject { super().syntaxes }
@@ -91,7 +164,7 @@ module Transpec
91
164
  end
92
165
  end
93
166
 
94
- shared_examples '#syntaxes=' do |framework_block_method|
167
+ shared_examples '#syntaxes=' do |framework_block_method, block_arg_name|
95
168
  describe '#syntaxes=' do
96
169
  before do
97
170
  subject.syntaxes = syntaxes
@@ -183,8 +256,8 @@ module Transpec
183
256
  let(:expected_source) do
184
257
  <<-END
185
258
  RSpec.configure do |config|
186
- config.#{framework_block_method} :rspec do |c|
187
- c.syntax = :expect
259
+ config.#{framework_block_method} :rspec do |#{block_arg_name}|
260
+ #{block_arg_name}.syntax = :expect
188
261
  end
189
262
  end
190
263
  END
@@ -211,8 +284,8 @@ module Transpec
211
284
  RSpec.configure do |config|
212
285
  config.foo = 1
213
286
 
214
- config.#{framework_block_method} :rspec do |c|
215
- c.syntax = :expect
287
+ config.#{framework_block_method} :rspec do |#{block_arg_name}|
288
+ #{block_arg_name}.syntax = :expect
216
289
  end
217
290
  end
218
291
  END
@@ -230,14 +303,14 @@ module Transpec
230
303
  subject { rspec_configure.expectations }
231
304
 
232
305
  include_examples '#syntaxes', :expect_with
233
- include_examples '#syntaxes=', :expect_with
306
+ include_examples '#syntaxes=', :expect_with, :expectations
234
307
  end
235
308
 
236
309
  describe '#mocks' do
237
310
  subject(:mocks) { rspec_configure.mocks }
238
311
 
239
312
  include_examples '#syntaxes', :mock_with
240
- include_examples '#syntaxes=', :mock_with
313
+ include_examples '#syntaxes=', :mock_with, :mocks
241
314
 
242
315
  describe '#yield_receiver_to_any_instance_implementation_blocks=' do
243
316
  before do
@@ -332,8 +405,8 @@ module Transpec
332
405
  let(:expected_source) do
333
406
  <<-END
334
407
  RSpec.configure do |config|
335
- config.mock_with :rspec do |c|
336
- c.yield_receiver_to_any_instance_implementation_blocks = true
408
+ config.mock_with :rspec do |mocks|
409
+ mocks.yield_receiver_to_any_instance_implementation_blocks = true
337
410
  end
338
411
  end
339
412
  END
@@ -344,31 +417,61 @@ module Transpec
344
417
  rewritten_source.should == expected_source
345
418
  end
346
419
 
347
- context "when RSpec.configure's argument variable name is `rspec`" do
420
+ context "when RSpec.configure's block argument name is `mocks`" do
348
421
  let(:source) do
349
422
  <<-END
350
- RSpec.configure do |rspec|
423
+ RSpec.configure do |mocks|
351
424
  end
352
425
  END
353
426
  end
354
427
 
355
428
  let(:expected_source) do
356
429
  <<-END
357
- RSpec.configure do |rspec|
358
- rspec.mock_with :rspec do |mocks|
359
- mocks.yield_receiver_to_any_instance_implementation_blocks = true
430
+ RSpec.configure do |mocks|
431
+ mocks.mock_with :rspec do |config|
432
+ config.yield_receiver_to_any_instance_implementation_blocks = true
360
433
  end
361
434
  end
362
435
  END
363
436
  end
364
437
 
365
- it 'defines #mock_with block argument name as `mocks`' do
438
+ it 'defines #mock_with block argument name as `config`' do
366
439
  rewritten_source.should == expected_source
367
440
  end
368
441
  end
369
442
  end
370
443
  end
371
444
  end
445
+
446
+ context 'when multiple configurations are added' do
447
+ before do
448
+ rspec_configure.expose_dsl_globally = true
449
+ rspec_configure.mocks.yield_receiver_to_any_instance_implementation_blocks = false
450
+ end
451
+
452
+ let(:source) do
453
+ <<-END
454
+ RSpec.configure do |config|
455
+ end
456
+ END
457
+ end
458
+
459
+ let(:expected_source) do
460
+ <<-END
461
+ RSpec.configure do |config|
462
+ config.expose_dsl_globally = true
463
+
464
+ config.mock_with :rspec do |mocks|
465
+ mocks.yield_receiver_to_any_instance_implementation_blocks = false
466
+ end
467
+ end
468
+ END
469
+ end
470
+
471
+ it 'adds them properly' do
472
+ rewritten_source.should == expected_source
473
+ end
474
+ end
372
475
  end
373
476
  end
374
477
  end