transpec 1.9.3 → 1.10.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 (68) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/.travis.yml +1 -1
  4. data/CHANGELOG.md +5 -0
  5. data/CONTRIBUTING.md +19 -0
  6. data/README.md +78 -9
  7. data/README.md.erb +68 -10
  8. data/lib/transpec/annotatable.rb +16 -0
  9. data/lib/transpec/cli.rb +35 -27
  10. data/lib/transpec/configuration.rb +1 -0
  11. data/lib/transpec/conversion_error.rb +23 -0
  12. data/lib/transpec/converter.rb +59 -50
  13. data/lib/transpec/dynamic_analyzer.rb +13 -29
  14. data/lib/transpec/dynamic_analyzer/rewriter.rb +3 -10
  15. data/lib/transpec/dynamic_analyzer/runtime_data.rb +16 -8
  16. data/lib/transpec/file_finder.rb +1 -1
  17. data/lib/transpec/git.rb +1 -1
  18. data/lib/transpec/option_parser.rb +12 -10
  19. data/lib/transpec/project.rb +3 -3
  20. data/lib/transpec/record.rb +19 -2
  21. data/lib/transpec/report.rb +29 -13
  22. data/lib/transpec/rspec_version.rb +7 -7
  23. data/lib/transpec/static_context_inspector.rb +1 -5
  24. data/lib/transpec/syntax.rb +11 -16
  25. data/lib/transpec/syntax/be_boolean.rb +1 -1
  26. data/lib/transpec/syntax/be_close.rb +1 -1
  27. data/lib/transpec/syntax/current_example.rb +88 -0
  28. data/lib/transpec/syntax/double.rb +1 -1
  29. data/lib/transpec/syntax/example.rb +60 -54
  30. data/lib/transpec/syntax/have.rb +27 -15
  31. data/lib/transpec/syntax/have/have_record.rb +12 -0
  32. data/lib/transpec/syntax/have/source_builder.rb +18 -16
  33. data/lib/transpec/syntax/its.rb +12 -11
  34. data/lib/transpec/syntax/matcher_definition.rb +1 -1
  35. data/lib/transpec/syntax/method_stub.rb +3 -7
  36. data/lib/transpec/syntax/mixin/matcher_owner.rb +2 -2
  37. data/lib/transpec/syntax/mixin/monkey_patch.rb +3 -5
  38. data/lib/transpec/syntax/mixin/monkey_patch_any_instance.rb +2 -4
  39. data/lib/transpec/syntax/mixin/owned_matcher.rb +1 -4
  40. data/lib/transpec/syntax/mixin/send.rb +7 -9
  41. data/lib/transpec/syntax/oneliner_should.rb +4 -4
  42. data/lib/transpec/syntax/operator.rb +27 -11
  43. data/lib/transpec/syntax/pending.rb +110 -0
  44. data/lib/transpec/syntax/raise_error.rb +1 -1
  45. data/lib/transpec/syntax/receive.rb +4 -4
  46. data/lib/transpec/syntax/rspec_configure/framework.rb +3 -3
  47. data/lib/transpec/syntax/should.rb +2 -2
  48. data/lib/transpec/syntax/should_receive.rb +3 -3
  49. data/lib/transpec/util.rb +38 -6
  50. data/lib/transpec/version.rb +2 -2
  51. data/spec/support/file_helper.rb +1 -1
  52. data/spec/support/shared_context.rb +3 -8
  53. data/spec/transpec/cli_spec.rb +63 -1
  54. data/spec/transpec/configuration_spec.rb +1 -0
  55. data/spec/transpec/converter_spec.rb +106 -15
  56. data/spec/transpec/dynamic_analyzer/rewriter_spec.rb +12 -52
  57. data/spec/transpec/dynamic_analyzer_spec.rb +2 -2
  58. data/spec/transpec/option_parser_spec.rb +3 -2
  59. data/spec/transpec/report_spec.rb +33 -4
  60. data/spec/transpec/rspec_version_spec.rb +5 -2
  61. data/spec/transpec/syntax/current_example_spec.rb +267 -0
  62. data/spec/transpec/syntax/example_spec.rb +156 -122
  63. data/spec/transpec/syntax/have_spec.rb +43 -32
  64. data/spec/transpec/syntax/method_stub_spec.rb +8 -0
  65. data/spec/transpec/syntax/operator_spec.rb +67 -2
  66. data/spec/transpec/syntax/pending_spec.rb +375 -0
  67. metadata +12 -4
  68. data/lib/transpec/context_error.rb +0 -23
@@ -319,39 +319,8 @@ module Transpec
319
319
  end
320
320
 
321
321
  context 'when it is `expect(collection).to have(2).items` form' do
322
- let(:source) do
323
- <<-END
324
- describe 'example' do
325
- it 'has 2 items' do
326
- expect(collection).to have(2).items
327
- end
328
- end
329
- END
330
- end
331
-
332
- let(:expected_source) do
333
- <<-END
334
- describe 'example' do
335
- it 'has 2 items' do
336
- expect(collection.size).to eq(2)
337
- end
338
- end
339
- END
340
- end
341
-
342
322
  let(:have_object) { expect_object.have_matcher }
343
323
 
344
- it 'converts into `expect(collection.size).to eq(2)` form' do
345
- have_object.convert_to_standard_expectation!
346
- rewritten_source.should == expected_source
347
- end
348
-
349
- it 'adds record `expect(collection).to have(n).items` -> `expect(collection.size).to eq(n)`' do
350
- have_object.convert_to_standard_expectation!
351
- record.original_syntax.should == 'expect(collection).to have(n).items'
352
- record.converted_syntax.should == 'expect(collection.size).to eq(n)'
353
- end
354
-
355
324
  context 'with runtime information' do
356
325
  include_context 'dynamic analysis objects'
357
326
 
@@ -393,13 +362,55 @@ module Transpec
393
362
  rewritten_source.should == expected_source
394
363
  end
395
364
 
396
- it 'adds record `expect(collection).to have(n).items` -> `expect(collection.size).to eq(n)`' do
365
+ it 'adds record `expect(collection).to have(n).items` -> `expect(collection.size).to eq(n)` ' \
366
+ 'without annotation' do
397
367
  have_object.convert_to_standard_expectation!
398
368
  record.original_syntax.should == 'expect(collection).to have(n).items'
399
369
  record.converted_syntax.should == 'expect(collection.size).to eq(n)'
370
+ record.annotation.should be_nil
400
371
  end
401
372
  end
402
373
  end
374
+
375
+ context 'without runtime information' do
376
+ let(:source) do
377
+ <<-END
378
+ describe 'example' do
379
+ it 'has 2 items' do
380
+ expect(collection).to have(2).items
381
+ end
382
+ end
383
+ END
384
+ end
385
+
386
+ let(:expected_source) do
387
+ <<-END
388
+ describe 'example' do
389
+ it 'has 2 items' do
390
+ expect(collection.size).to eq(2)
391
+ end
392
+ end
393
+ END
394
+ end
395
+
396
+ it 'converts into `expect(collection.size).to eq(2)` form' do
397
+ have_object.convert_to_standard_expectation!
398
+ rewritten_source.should == expected_source
399
+ end
400
+
401
+ it 'adds record `expect(collection).to have(n).items` -> `expect(collection.size).to eq(n)` ' \
402
+ 'with annotation' do
403
+ have_object.convert_to_standard_expectation!
404
+
405
+ record.original_syntax.should == 'expect(collection).to have(n).items'
406
+ record.converted_syntax.should == 'expect(collection.size).to eq(n)'
407
+
408
+ record.annotation.message.should ==
409
+ 'The `have(2).items` has been converted but it might possibly be incorrect ' \
410
+ "due to a lack of runtime information. It's recommended to review the change carefully."
411
+ record.annotation.source_range.source.should == 'have(2).items'
412
+ end
413
+ end
403
414
  end
404
415
 
405
416
  context 'when it is `expect(collection).not_to have(2).items` form' do
@@ -220,6 +220,14 @@ module Transpec
220
220
  record.converted_syntax.should == 'allow(obj).to receive(:message)'
221
221
  end
222
222
 
223
+ context 'with runtime information' do
224
+ include_context 'dynamic analysis objects'
225
+
226
+ it 'converts into `allow(subject).to receive(:method)` form' do
227
+ rewritten_source.should == expected_source
228
+ end
229
+ end
230
+
223
231
  context 'and #allow and #receive are not available in the context', :no_before_allowize! do
224
232
  context 'and the context is determinable statically' do
225
233
  let(:source) do
@@ -65,6 +65,7 @@ module Transpec
65
65
  it 'adds record `== expected` -> `eq(expected)`' do
66
66
  record.original_syntax.should == '== expected'
67
67
  record.converted_syntax.should == 'eq(expected)'
68
+ record.annotation.should be_nil
68
69
  end
69
70
 
70
71
  # Operator methods allow their argument to be in the next line,
@@ -185,6 +186,7 @@ module Transpec
185
186
  it 'adds record `== expected` -> `eq(expected)`' do
186
187
  record.original_syntax.should == '== expected'
187
188
  record.converted_syntax.should == 'eq(expected)'
189
+ record.annotation.should be_nil
188
190
  end
189
191
  end
190
192
 
@@ -335,6 +337,7 @@ module Transpec
335
337
  it "adds record `#{operator} expected` -> `be #{operator} expected`" do
336
338
  record.original_syntax.should == "#{operator} expected"
337
339
  record.converted_syntax.should == "be #{operator} expected"
340
+ record.annotation.should be_nil
338
341
  end
339
342
  end
340
343
 
@@ -384,9 +387,10 @@ module Transpec
384
387
  rewritten_source.should == expected_source
385
388
  end
386
389
 
387
- it 'adds record `=~ /pattern/` -> `match(/pattern/)`' do
390
+ it 'adds record `=~ /pattern/` -> `match(/pattern/)` without annotation' do
388
391
  record.original_syntax.should == '=~ /pattern/'
389
392
  record.converted_syntax.should == 'match(/pattern/)'
393
+ record.annotation.should be_nil
390
394
  end
391
395
  end
392
396
 
@@ -467,9 +471,10 @@ module Transpec
467
471
  rewritten_source.should == expected_source
468
472
  end
469
473
 
470
- it 'adds record `=~ [1, 2]` -> `match_array([1, 2])`' do
474
+ it 'adds record `=~ [1, 2]` -> `match_array([1, 2])` without annotation' do
471
475
  record.original_syntax.should == '=~ [1, 2]'
472
476
  record.converted_syntax.should == 'match_array([1, 2])'
477
+ record.annotation.should be_nil
473
478
  end
474
479
  end
475
480
 
@@ -554,6 +559,12 @@ module Transpec
554
559
  it 'converts into `match_array(variable)` form' do
555
560
  rewritten_source.should == expected_source
556
561
  end
562
+
563
+ it 'adds record `=~ [1, 2]` -> `match_array([1, 2])` without annotation' do
564
+ record.original_syntax.should == '=~ [1, 2]'
565
+ record.converted_syntax.should == 'match_array([1, 2])'
566
+ record.annotation.should be_nil
567
+ end
557
568
  end
558
569
 
559
570
  context 'and runtime type of the variable is regular expression' do
@@ -584,6 +595,12 @@ module Transpec
584
595
  it 'converts into `match(variable)` form' do
585
596
  rewritten_source.should == expected_source
586
597
  end
598
+
599
+ it 'adds record `=~ /pattern/` -> `match(/pattern/)` without annotation' do
600
+ record.original_syntax.should == '=~ /pattern/'
601
+ record.converted_syntax.should == 'match(/pattern/)'
602
+ record.annotation.should be_nil
603
+ end
587
604
  end
588
605
 
589
606
  context 'and no runtime type information is provided' do
@@ -610,6 +627,54 @@ module Transpec
610
627
  it 'converts into `match(variable)` form' do
611
628
  rewritten_source.should == expected_source
612
629
  end
630
+
631
+ it 'adds record `=~ /pattern/` -> `match(/pattern/)` with annotation' do
632
+ record.original_syntax.should == '=~ /pattern/'
633
+ record.converted_syntax.should == 'match(/pattern/)'
634
+
635
+ record.annotation.message.should ==
636
+ 'The `=~ variable` has been converted but it might possibly be incorrect ' \
637
+ "due to a lack of runtime information. It's recommended to review the change carefully."
638
+ record.annotation.source_range.source.should == '=~ variable'
639
+ end
640
+ end
641
+ end
642
+
643
+ context 'when it is `be =~ variable` form' do
644
+ context 'and no runtime type information is provided' do
645
+ let(:source) do
646
+ <<-END
647
+ describe 'example' do
648
+ it 'matches the pattern' do
649
+ subject.should be =~ variable
650
+ end
651
+ end
652
+ END
653
+ end
654
+
655
+ let(:expected_source) do
656
+ <<-END
657
+ describe 'example' do
658
+ it 'matches the pattern' do
659
+ subject.should match(variable)
660
+ end
661
+ end
662
+ END
663
+ end
664
+
665
+ it 'converts into `match(variable)` form' do
666
+ rewritten_source.should == expected_source
667
+ end
668
+
669
+ it 'adds record `=~ /pattern/` -> `match(/pattern/)` with annotation' do
670
+ record.original_syntax.should == '=~ /pattern/'
671
+ record.converted_syntax.should == 'match(/pattern/)'
672
+
673
+ record.annotation.message.should ==
674
+ 'The `be =~ variable` has been converted but it might possibly be incorrect ' \
675
+ "due to a lack of runtime information. It's recommended to review the change carefully."
676
+ record.annotation.source_range.source.should == 'be =~ variable'
677
+ end
613
678
  end
614
679
  end
615
680
  end
@@ -0,0 +1,375 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+ require 'transpec/syntax/pending'
5
+
6
+ module Transpec
7
+ class Syntax
8
+ describe Pending do
9
+ include_context 'parsed objects'
10
+ include_context 'syntax object', Pending, :pending_object
11
+
12
+ let(:record) { pending_object.report.records.last }
13
+
14
+ describe '.conversion_target_node?' do
15
+ subject { Pending.conversion_target_node?(pending_node, runtime_data) }
16
+
17
+ let(:pending_node) do
18
+ ast.each_descendent_node do |node|
19
+ next unless node.send_type?
20
+ method_name = node.children[1]
21
+ return node if method_name == :pending
22
+ end
23
+ fail 'No #pending node is found!'
24
+ end
25
+
26
+ context 'when #pending specification node inside of an example is passed' do
27
+ let(:source) do
28
+ <<-END
29
+ describe 'example' do
30
+ it 'will be skipped' do
31
+ pending
32
+ end
33
+ end
34
+ END
35
+ end
36
+
37
+ context 'without runtime information' do
38
+ it { should be_true }
39
+ end
40
+
41
+ context 'with runtime information' do
42
+ include_context 'dynamic analysis objects'
43
+ it { should be_true }
44
+ end
45
+ end
46
+
47
+ context 'when #pending example node is passed' do
48
+ let(:source) do
49
+ <<-END
50
+ describe 'example' do
51
+ pending 'will be skipped' do
52
+ end
53
+ end
54
+ END
55
+ end
56
+
57
+ context 'without runtime information' do
58
+ it { should be_false }
59
+ end
60
+
61
+ context 'with runtime information' do
62
+ include_context 'dynamic analysis objects'
63
+ it { should be_false }
64
+ end
65
+ end
66
+ end
67
+
68
+ describe '#convert_deprecated_syntax!' do
69
+ before do
70
+ pending_object.convert_deprecated_syntax!
71
+ end
72
+
73
+ context 'when it is `pending` form' do
74
+ let(:source) do
75
+ <<-END
76
+ describe 'example' do
77
+ it 'will be skipped' do
78
+ pending
79
+ end
80
+ end
81
+ END
82
+ end
83
+
84
+ let(:expected_source) do
85
+ <<-END
86
+ describe 'example' do
87
+ it 'will be skipped' do
88
+ skip
89
+ end
90
+ end
91
+ END
92
+ end
93
+
94
+ it 'converts into `skip` form' do
95
+ rewritten_source.should == expected_source
96
+ end
97
+
98
+ it 'adds record `pending` -> `skip`' do
99
+ record.original_syntax.should == 'pending'
100
+ record.converted_syntax.should == 'skip'
101
+ end
102
+ end
103
+
104
+ context "when it is `pending 'some reason'` form" do
105
+ let(:source) do
106
+ <<-END
107
+ describe 'example' do
108
+ it 'will be skipped' do
109
+ pending 'some reason'
110
+ end
111
+ end
112
+ END
113
+ end
114
+
115
+ let(:expected_source) do
116
+ <<-END
117
+ describe 'example' do
118
+ it 'will be skipped' do
119
+ skip 'some reason'
120
+ end
121
+ end
122
+ END
123
+ end
124
+
125
+ it "converts into `skip 'some reason` form" do
126
+ rewritten_source.should == expected_source
127
+ end
128
+
129
+ it 'adds record `pending` -> `skip`' do
130
+ record.original_syntax.should == 'pending'
131
+ record.converted_syntax.should == 'skip'
132
+ end
133
+ end
134
+
135
+ context 'when it is singleline `pending { do_something_fail }` form' do
136
+ let(:source) do
137
+ <<-END
138
+ describe 'example' do
139
+ it 'is expected to fail' do
140
+ pending { do_something_fail }
141
+ end
142
+ end
143
+ END
144
+ end
145
+
146
+ let(:expected_source) do
147
+ <<-END
148
+ describe 'example' do
149
+ it 'is expected to fail' do
150
+ pending
151
+ do_something_fail
152
+ end
153
+ end
154
+ END
155
+ end
156
+
157
+ it 'converts into `pending; do_something_fail` form' do
158
+ rewritten_source.should == expected_source
159
+ end
160
+ end
161
+
162
+ context "when it is singleline `pending('some reason') { do_something_fail }` form" do
163
+ let(:source) do
164
+ <<-END
165
+ describe 'example' do
166
+ it 'is expected to fail' do
167
+ pending('some reason') { do_something_fail }
168
+ end
169
+ end
170
+ END
171
+ end
172
+
173
+ let(:expected_source) do
174
+ <<-END
175
+ describe 'example' do
176
+ it 'is expected to fail' do
177
+ pending('some reason')
178
+ do_something_fail
179
+ end
180
+ end
181
+ END
182
+ end
183
+
184
+ it "converts into `pending('some reason'); do_something_fail` form" do
185
+ rewritten_source.should == expected_source
186
+ end
187
+ end
188
+
189
+ context 'when it is multiline `pending { do_something_fail }` form' do
190
+ let(:source) do
191
+ <<-END
192
+ describe 'example' do
193
+ it 'is expected to fail' do
194
+ pending do
195
+ do_something_first
196
+ do_something_fail
197
+ end
198
+ end
199
+ end
200
+ END
201
+ end
202
+
203
+ let(:expected_source) do
204
+ <<-END
205
+ describe 'example' do
206
+ it 'is expected to fail' do
207
+ pending
208
+ do_something_first
209
+ do_something_fail
210
+ end
211
+ end
212
+ END
213
+ end
214
+
215
+ it 'converts into `pending; do_something_fail` form' do
216
+ rewritten_source.should == expected_source
217
+ end
218
+ end
219
+
220
+ context "when it is multiline `pending('some reason') { do_something_fail }` form" do
221
+ let(:source) do
222
+ <<-END
223
+ describe 'example' do
224
+ it 'is expected to fail' do
225
+ pending('some reason') do
226
+ do_something_first
227
+ do_something_fail
228
+ end
229
+ end
230
+ end
231
+ END
232
+ end
233
+
234
+ let(:expected_source) do
235
+ <<-END
236
+ describe 'example' do
237
+ it 'is expected to fail' do
238
+ pending('some reason')
239
+ do_something_first
240
+ do_something_fail
241
+ end
242
+ end
243
+ END
244
+ end
245
+
246
+ it "converts into `pending('some reason'); do_something_fail` form" do
247
+ rewritten_source.should == expected_source
248
+ end
249
+ end
250
+
251
+ context 'when it is multiline `pending { do_something_fail }` form ' \
252
+ 'but the body is not indented' do
253
+ let(:source) do
254
+ <<-END
255
+ describe 'example' do
256
+ it 'is expected to fail' do
257
+ pending do
258
+ do_something_first
259
+ do_something_fail
260
+ end
261
+ end
262
+ end
263
+ END
264
+ end
265
+
266
+ let(:expected_source) do
267
+ <<-END
268
+ describe 'example' do
269
+ it 'is expected to fail' do
270
+ pending
271
+ do_something_first
272
+ do_something_fail
273
+ end
274
+ end
275
+ END
276
+ end
277
+
278
+ it 'converts into `pending; do_something_fail` form' do
279
+ rewritten_source.should == expected_source
280
+ end
281
+ end
282
+
283
+ context 'when it is multiline `pending { do_something_fail }` form ' \
284
+ 'but the body is outdented' do
285
+ let(:source) do
286
+ <<-END
287
+ describe 'example' do
288
+ it 'is expected to fail' do
289
+ pending do
290
+ do_something_first
291
+ do_something_fail
292
+ end
293
+ end
294
+ end
295
+ END
296
+ end
297
+
298
+ let(:expected_source) do
299
+ <<-END
300
+ describe 'example' do
301
+ it 'is expected to fail' do
302
+ pending
303
+ do_something_first
304
+ do_something_fail
305
+ end
306
+ end
307
+ END
308
+ end
309
+
310
+ it 'converts into `pending; do_something_fail` form' do
311
+ rewritten_source.should == expected_source
312
+ end
313
+ end
314
+
315
+ context 'when it is multiline `pending { do_something_fail }` form ' \
316
+ 'but anomalistically the beginning and the body of block are same line' do
317
+ let(:source) do
318
+ <<-END
319
+ describe 'example' do
320
+ it 'is expected to fail' do
321
+ pending do do_something_fail
322
+ end
323
+ end
324
+ end
325
+ END
326
+ end
327
+
328
+ let(:expected_source) do
329
+ <<-END
330
+ describe 'example' do
331
+ it 'is expected to fail' do
332
+ pending
333
+ do_something_fail
334
+ end
335
+ end
336
+ END
337
+ end
338
+
339
+ it 'converts into `pending; do_something_fail` form' do
340
+ rewritten_source.should == expected_source
341
+ end
342
+ end
343
+
344
+ context 'when it is multiline `pending { do_something_fail }` form ' \
345
+ 'but anomalistically the body and the end of block are same line' do
346
+ let(:source) do
347
+ <<-END
348
+ describe 'example' do
349
+ it 'is expected to fail' do
350
+ pending do
351
+ do_something_fail end
352
+ end
353
+ end
354
+ END
355
+ end
356
+
357
+ let(:expected_source) do
358
+ <<-END
359
+ describe 'example' do
360
+ it 'is expected to fail' do
361
+ pending
362
+ do_something_fail
363
+ end
364
+ end
365
+ END
366
+ end
367
+
368
+ it 'converts into `pending; do_something_fail` form' do
369
+ rewritten_source.should == expected_source
370
+ end
371
+ end
372
+ end
373
+ end
374
+ end
375
+ end