transpec 0.2.6 → 1.0.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/.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
@@ -0,0 +1,599 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+ require 'transpec/syntax/have'
5
+
6
+ module Transpec
7
+ class Syntax
8
+ describe Have do
9
+ include ::AST::Sexp
10
+ include_context 'parsed objects'
11
+ include_context 'should object'
12
+ include_context 'expect object'
13
+
14
+ describe '#have_node' do
15
+ let(:source) do
16
+ <<-END
17
+ describe 'example' do
18
+ it 'has 2 items' do
19
+ subject.should have(2).items
20
+ end
21
+ end
22
+ END
23
+ end
24
+
25
+ let(:have_object) { should_object.have_matcher }
26
+
27
+ it 'returns #have node' do
28
+ method_name = have_object.have_node.children[1]
29
+ method_name.should == :have
30
+ end
31
+ end
32
+
33
+ describe '#size_node' do
34
+ let(:source) do
35
+ <<-END
36
+ describe 'example' do
37
+ it 'has 2 items' do
38
+ subject.should have(2).items
39
+ end
40
+ end
41
+ END
42
+ end
43
+
44
+ let(:have_object) { should_object.have_matcher }
45
+
46
+ it 'returns node of collection size' do
47
+ have_object.size_node.should == s(:int, 2)
48
+ end
49
+ end
50
+
51
+ describe '#items_node' do
52
+ let(:source) do
53
+ <<-END
54
+ describe 'example' do
55
+ it 'has 2 items' do
56
+ subject.should have(2).items
57
+ end
58
+ end
59
+ END
60
+ end
61
+
62
+ let(:have_object) { should_object.have_matcher }
63
+
64
+ it 'returns #items node' do
65
+ method_name = have_object.items_node.children[1]
66
+ method_name.should == :items
67
+ end
68
+ end
69
+
70
+ describe '#convert_to_standard_expectation!' do
71
+ let(:record) { have_object.report.records.last }
72
+
73
+ context 'when it is `collection.should have(2).items` form' do
74
+ let(:source) do
75
+ <<-END
76
+ describe 'example' do
77
+ it 'has 2 items' do
78
+ collection.should have(2).items
79
+ end
80
+ end
81
+ END
82
+ end
83
+
84
+ let(:expected_source) do
85
+ <<-END
86
+ describe 'example' do
87
+ it 'has 2 items' do
88
+ collection.size.should == 2
89
+ end
90
+ end
91
+ END
92
+ end
93
+
94
+ let(:have_object) { should_object.have_matcher }
95
+
96
+ it 'converts into `collection.size.should == 2` form' do
97
+ have_object.convert_to_standard_expectation!
98
+ rewritten_source.should == expected_source
99
+ end
100
+
101
+ it 'adds record "`collection.should have(n).items` -> `collection.size.should == n`"' do
102
+ have_object.convert_to_standard_expectation!
103
+ record.original_syntax.should == 'collection.should have(n).items'
104
+ record.converted_syntax.should == 'collection.size.should == n'
105
+ end
106
+
107
+ context 'and Should#expectize! is invoked before it' do
108
+ let(:expected_source) do
109
+ <<-END
110
+ describe 'example' do
111
+ it 'has 2 items' do
112
+ expect(collection.size).to eq(2)
113
+ end
114
+ end
115
+ END
116
+ end
117
+
118
+ before do
119
+ should_object.expectize!
120
+ should_object.have_matcher.convert_to_standard_expectation!
121
+ end
122
+
123
+ it 'converts into `expect(collection.size).to eq(2)` form' do
124
+ rewritten_source.should == expected_source
125
+ end
126
+
127
+ it 'adds record "`collection.should have(n).items` -> `expect(collection.size).to eq(n)`"' do
128
+ record.original_syntax.should == 'collection.should have(n).items'
129
+ record.converted_syntax.should == 'expect(collection.size).to eq(n)'
130
+ end
131
+ end
132
+ end
133
+
134
+ context 'when it is `collection.should have_at_least(2).items` form' do
135
+ let(:source) do
136
+ <<-END
137
+ describe 'example' do
138
+ it 'has 2 items' do
139
+ collection.should have_at_least(2).items
140
+ end
141
+ end
142
+ END
143
+ end
144
+
145
+ let(:expected_source) do
146
+ <<-END
147
+ describe 'example' do
148
+ it 'has 2 items' do
149
+ collection.size.should >= 2
150
+ end
151
+ end
152
+ END
153
+ end
154
+
155
+ let(:have_object) { should_object.have_matcher }
156
+
157
+ it 'converts into `collection.size.should >= 2` form' do
158
+ have_object.convert_to_standard_expectation!
159
+ rewritten_source.should == expected_source
160
+ end
161
+
162
+ it 'adds record "`collection.should have_at_least(n).items` -> `collection.size.should >= n`"' do
163
+ have_object.convert_to_standard_expectation!
164
+ record.original_syntax.should == 'collection.should have_at_least(n).items'
165
+ record.converted_syntax.should == 'collection.size.should >= n'
166
+ end
167
+ end
168
+
169
+ context 'when it is `collection.should have_at_most(2).items` form' do
170
+ let(:source) do
171
+ <<-END
172
+ describe 'example' do
173
+ it 'has 2 items' do
174
+ collection.should have_at_most(2).items
175
+ end
176
+ end
177
+ END
178
+ end
179
+
180
+ let(:expected_source) do
181
+ <<-END
182
+ describe 'example' do
183
+ it 'has 2 items' do
184
+ collection.size.should <= 2
185
+ end
186
+ end
187
+ END
188
+ end
189
+
190
+ let(:have_object) { should_object.have_matcher }
191
+
192
+ it 'converts into `collection.size.should >= 2` form' do
193
+ have_object.convert_to_standard_expectation!
194
+ rewritten_source.should == expected_source
195
+ end
196
+
197
+ it 'adds record "`collection.should have_at_most(n).items` -> `collection.size.should <= n`"' do
198
+ have_object.convert_to_standard_expectation!
199
+ record.original_syntax.should == 'collection.should have_at_most(n).items'
200
+ record.converted_syntax.should == 'collection.size.should <= n'
201
+ end
202
+ end
203
+
204
+ context 'when it is `expect(collection).to have(2).items` form' do
205
+ let(:source) do
206
+ <<-END
207
+ describe 'example' do
208
+ it 'has 2 items' do
209
+ expect(collection).to have(2).items
210
+ end
211
+ end
212
+ END
213
+ end
214
+
215
+ let(:expected_source) do
216
+ <<-END
217
+ describe 'example' do
218
+ it 'has 2 items' do
219
+ expect(collection.size).to eq(2)
220
+ end
221
+ end
222
+ END
223
+ end
224
+
225
+ let(:have_object) { expect_object.have_matcher }
226
+
227
+ it 'converts into `expect(collection.size).to eq(2)` form' do
228
+ have_object.convert_to_standard_expectation!
229
+ rewritten_source.should == expected_source
230
+ end
231
+
232
+ it 'adds record "`expect(collection).to have(n).items` -> `expect(collection.size).to eq(n)`"' do
233
+ have_object.convert_to_standard_expectation!
234
+ record.original_syntax.should == 'expect(collection).to have(n).items'
235
+ record.converted_syntax.should == 'expect(collection.size).to eq(n)'
236
+ end
237
+
238
+ context 'with runtime information' do
239
+ include_context 'dynamic analysis objects'
240
+
241
+ context 'when the collection responds to only #count' do
242
+ let(:source) do
243
+ <<-END
244
+ class SomeCollection
245
+ def count
246
+ 2
247
+ end
248
+ end
249
+
250
+ describe SomeCollection do
251
+ it 'has 2 items' do
252
+ expect(subject).to have(2).items
253
+ end
254
+ end
255
+ END
256
+ end
257
+
258
+ let(:expected_source) do
259
+ <<-END
260
+ class SomeCollection
261
+ def count
262
+ 2
263
+ end
264
+ end
265
+
266
+ describe SomeCollection do
267
+ it 'has 2 items' do
268
+ expect(subject.count).to eq(2)
269
+ end
270
+ end
271
+ END
272
+ end
273
+
274
+ it 'converts into `expect(collection.count).to eq(2)` form' do
275
+ have_object.convert_to_standard_expectation!
276
+ rewritten_source.should == expected_source
277
+ end
278
+
279
+ it 'adds record "`expect(collection).to have(n).items` -> `expect(collection.size).to eq(n)`"' do
280
+ have_object.convert_to_standard_expectation!
281
+ record.original_syntax.should == 'expect(collection).to have(n).items'
282
+ record.converted_syntax.should == 'expect(collection.size).to eq(n)'
283
+ end
284
+ end
285
+ end
286
+ end
287
+
288
+ context 'when it is `expect(collection).to have_at_least(2).items` form' do
289
+ let(:source) do
290
+ <<-END
291
+ describe 'example' do
292
+ it 'has 2 items' do
293
+ expect(collection).to have_at_least(2).items
294
+ end
295
+ end
296
+ END
297
+ end
298
+
299
+ let(:expected_source) do
300
+ <<-END
301
+ describe 'example' do
302
+ it 'has 2 items' do
303
+ expect(collection.size).to be >= 2
304
+ end
305
+ end
306
+ END
307
+ end
308
+
309
+ let(:have_object) { expect_object.have_matcher }
310
+
311
+ it 'converts into `expect(collection.size).to be >= 2` form' do
312
+ have_object.convert_to_standard_expectation!
313
+ rewritten_source.should == expected_source
314
+ end
315
+
316
+ it 'adds record "`expect(collection).to have_at_least(n).items` -> `expect(collection.size).to be >= n`"' do
317
+ have_object.convert_to_standard_expectation!
318
+ record.original_syntax.should == 'expect(collection).to have_at_least(n).items'
319
+ record.converted_syntax.should == 'expect(collection.size).to be >= n'
320
+ end
321
+ end
322
+
323
+ context 'when it is `expect(collection).to have_at_most(2).items` form' do
324
+ let(:source) do
325
+ <<-END
326
+ describe 'example' do
327
+ it 'has 2 items' do
328
+ expect(collection).to have_at_most(2).items
329
+ end
330
+ end
331
+ END
332
+ end
333
+
334
+ let(:expected_source) do
335
+ <<-END
336
+ describe 'example' do
337
+ it 'has 2 items' do
338
+ expect(collection.size).to be <= 2
339
+ end
340
+ end
341
+ END
342
+ end
343
+
344
+ let(:have_object) { expect_object.have_matcher }
345
+
346
+ it 'converts into `expect(collection.size).to be <= 2` form' do
347
+ have_object.convert_to_standard_expectation!
348
+ rewritten_source.should == expected_source
349
+ end
350
+
351
+ it 'adds record "`expect(collection).to have_at_most(n).items` -> `expect(collection.size).to be <= n`"' do
352
+ have_object.convert_to_standard_expectation!
353
+ record.original_syntax.should == 'expect(collection).to have_at_most(n).items'
354
+ record.converted_syntax.should == 'expect(collection.size).to be <= n'
355
+ end
356
+ end
357
+
358
+ context 'when it is `expect(subject).to have(2).words` form' do
359
+ let(:have_object) { expect_object.have_matcher }
360
+
361
+ context 'with runtime information' do
362
+ include_context 'dynamic analysis objects'
363
+
364
+ context 'when the subject responds to #words' do
365
+ context 'and #words responds to #size' do
366
+ let(:source) do
367
+ <<-END
368
+ class String
369
+ def words
370
+ split(' ')
371
+ end
372
+ end
373
+
374
+ describe 'a string' do
375
+ it 'has 2 words' do
376
+ expect(subject).to have(2).words
377
+ end
378
+ end
379
+ END
380
+ end
381
+
382
+ let(:expected_source) do
383
+ <<-END
384
+ class String
385
+ def words
386
+ split(' ')
387
+ end
388
+ end
389
+
390
+ describe 'a string' do
391
+ it 'has 2 words' do
392
+ expect(subject.words.size).to eq(2)
393
+ end
394
+ end
395
+ END
396
+ end
397
+
398
+ it 'converts into `expect(subject.words.size).to eq(2)` form' do
399
+ have_object.convert_to_standard_expectation!
400
+ rewritten_source.should == expected_source
401
+ end
402
+
403
+ it 'adds record "`expect(obj).to have(n).words` -> `expect(obj.words.size).to eq(n)`"' do
404
+ have_object.convert_to_standard_expectation!
405
+ record.original_syntax.should == 'expect(obj).to have(n).words'
406
+ record.converted_syntax.should == 'expect(obj.words.size).to eq(n)'
407
+ end
408
+ end
409
+
410
+ context 'and #words responds to only #count' do
411
+ let(:source) do
412
+ <<-END
413
+ class String
414
+ def words
415
+ Words.new
416
+ end
417
+ end
418
+
419
+ class Words
420
+ def count
421
+ 2
422
+ end
423
+ end
424
+
425
+ describe 'a string' do
426
+ it 'has 2 words' do
427
+ expect(subject).to have(2).words
428
+ end
429
+ end
430
+ END
431
+ end
432
+
433
+ let(:expected_source) do
434
+ <<-END
435
+ class String
436
+ def words
437
+ Words.new
438
+ end
439
+ end
440
+
441
+ class Words
442
+ def count
443
+ 2
444
+ end
445
+ end
446
+
447
+ describe 'a string' do
448
+ it 'has 2 words' do
449
+ expect(subject.words.count).to eq(2)
450
+ end
451
+ end
452
+ END
453
+ end
454
+
455
+ it 'converts into `expect(subject.words.count).to eq(2)` form' do
456
+ have_object.convert_to_standard_expectation!
457
+ rewritten_source.should == expected_source
458
+ end
459
+
460
+ it 'adds record "`expect(obj).to have(n).words` -> `expect(obj.words.count).to eq(n)`"' do
461
+ have_object.convert_to_standard_expectation!
462
+ record.original_syntax.should == 'expect(obj).to have(n).words'
463
+ record.converted_syntax.should == 'expect(obj.words.count).to eq(n)'
464
+ end
465
+ end
466
+ end
467
+
468
+ context 'when the subject does not respond to #words' do
469
+ context 'and the subject responds to any of #size, #count, #length' do
470
+ let(:source) do
471
+ <<-END
472
+ describe ['an', 'array'] do
473
+ it 'has 2 words' do
474
+ expect(subject).to have(2).words
475
+ end
476
+ end
477
+ END
478
+ end
479
+
480
+ let(:expected_source) do
481
+ <<-END
482
+ describe ['an', 'array'] do
483
+ it 'has 2 words' do
484
+ expect(subject.size).to eq(2)
485
+ end
486
+ end
487
+ END
488
+ end
489
+
490
+ it 'converts into `expect(subject.size).to eq(2)` form' do
491
+ have_object.convert_to_standard_expectation!
492
+ rewritten_source.should == expected_source
493
+ end
494
+
495
+ it 'adds record "`expect(collection).to have(n).items` -> `expect(collection.size).to eq(n)`"' do
496
+ have_object.convert_to_standard_expectation!
497
+ record.original_syntax.should == 'expect(collection).to have(n).items'
498
+ record.converted_syntax.should == 'expect(collection.size).to eq(n)'
499
+ end
500
+ end
501
+
502
+ context 'and the subject responds to none of #size, #count, #length' do
503
+ let(:source) do
504
+ <<-END
505
+ class Sentence
506
+ private
507
+ def words
508
+ [1, 2]
509
+ end
510
+ end
511
+
512
+ describe Sentence do
513
+ it 'has 2 words' do
514
+ expect(subject).to have(2).words
515
+ end
516
+ end
517
+ END
518
+ end
519
+
520
+ let(:expected_source) do
521
+ <<-END
522
+ class Sentence
523
+ private
524
+ def words
525
+ [1, 2]
526
+ end
527
+ end
528
+
529
+ describe Sentence do
530
+ it 'has 2 words' do
531
+ expect(subject.send(:words).size).to eq(2)
532
+ end
533
+ end
534
+ END
535
+ end
536
+
537
+ it 'converts into `expect(subject.send(:words).size).to eq(2)` form' do
538
+ have_object.convert_to_standard_expectation!
539
+ rewritten_source.should == expected_source
540
+ end
541
+
542
+ it 'adds record "`expect(obj).to have(n).words` -> `expect(obj.send(:words).size).to eq(n)`"' do
543
+ have_object.convert_to_standard_expectation!
544
+ record.original_syntax.should == 'expect(obj).to have(n).words'
545
+ record.converted_syntax.should == 'expect(obj.send(:words).size).to eq(n)'
546
+ end
547
+ end
548
+ end
549
+ end
550
+
551
+ context 'without runtime information' do
552
+ let(:source) do
553
+ <<-END
554
+ class String
555
+ def words
556
+ split(' ')
557
+ end
558
+ end
559
+
560
+ describe 'a string' do
561
+ it 'has 2 words' do
562
+ expect(subject).to have(2).words
563
+ end
564
+ end
565
+ END
566
+ end
567
+
568
+ let(:expected_source) do
569
+ <<-END
570
+ class String
571
+ def words
572
+ split(' ')
573
+ end
574
+ end
575
+
576
+ describe 'a string' do
577
+ it 'has 2 words' do
578
+ expect(subject.size).to eq(2)
579
+ end
580
+ end
581
+ END
582
+ end
583
+
584
+ it 'converts into `expect(subject.size).to eq(2)` form' do
585
+ have_object.convert_to_standard_expectation!
586
+ rewritten_source.should == expected_source
587
+ end
588
+
589
+ it 'adds record "`expect(collection).to have(n).items` -> `expect(collection.size).to eq(n)`"' do
590
+ have_object.convert_to_standard_expectation!
591
+ record.original_syntax.should == 'expect(collection).to have(n).items'
592
+ record.converted_syntax.should == 'expect(collection.size).to eq(n)'
593
+ end
594
+ end
595
+ end
596
+ end
597
+ end
598
+ end
599
+ end