@@ -377,6 +377,116 @@ expect(foo).to be_invalid.or be_even
377
377
378
378
* https://www.rubydoc.info/gems/rubocop-rspec_rails/RuboCop/Cop/RSpecRails/NegationBeValid
379
379
380
+ == RSpecRails/Timecop
381
+
382
+ |===
383
+ | Enabled by default | Safe | Supports autocorrection | Version Added | Version Changed
384
+
385
+ | Pending
386
+ | Yes
387
+ | Always (Unsafe)
388
+ | <<next>>
389
+ | -
390
+ |===
391
+
392
+ Enforces use of ActiveSupport TimeHelpers instead of Timecop.
393
+
394
+ ## Migration
395
+ `Timecop.freeze` should be replaced with `freeze_time` when used
396
+ without arguments. Where a `duration` has been passed to `freeze`, it
397
+ should be replaced with `travel`. Likewise, where a `time` has been
398
+ passed to `freeze`, it should be replaced with `travel_to`.
399
+
400
+ `Timecop.scale` should be replaced by explicitly calling `travel` or
401
+ `travel_to` with the expected `durations` or `times`, respectively,
402
+ rather than relying on allowing time to continue to flow.
403
+
404
+ `Timecop.return` should be replaced with `travel_back`, when used
405
+ without a block. `travel_back` accepts a block starting with Rails 6.1.
406
+ For earlier Rails, where `return` is used with a block, it should
407
+ be replaced by explicitly calling `freeze_time` with a block, and
408
+ passing the `time` to temporarily return to.
409
+
410
+ `Timecop.travel` should be replaced by `travel` or `travel_to` when
411
+ passed a `duration` or `time`, respectively. As with `Timecop.scale`,
412
+ rather than relying on time continuing to flow, it should be travelled
413
+ to explicitly.
414
+
415
+ All other usages of `Timecop` are similarly disallowed.
416
+
417
+ ## RSpec Caveats
418
+
419
+ Note that if using RSpec, `TimeHelpers` are not included by default,
420
+ and must be manually included by updating `rails_helper` accordingly:
421
+
422
+ ```ruby
423
+ RSpec.configure do |config|
424
+ config.include ActiveSupport::Testing::TimeHelpers
425
+ end
426
+ ```
427
+
428
+ Moreover, because `TimeHelpers` relies on Minitest teardown hooks,
429
+ `rails_helper` must be required (instead of `spec_helper`), or a
430
+ similar adapter layer must be in effect.
431
+
432
+ === Examples
433
+
434
+ [source,ruby]
435
+ ----
436
+ # bad
437
+ Timecop
438
+
439
+ # bad
440
+ Timecop.freeze
441
+ Timecop.freeze(duration)
442
+ Timecop.freeze(time)
443
+
444
+ # good
445
+ freeze_time
446
+ travel(duration)
447
+ travel_to(time)
448
+
449
+ # bad
450
+ Timecop.freeze { assert true }
451
+ Timecop.freeze(duration) { assert true }
452
+ Timecop.freeze(time) { assert true }
453
+
454
+ # good
455
+ freeze_time { assert true }
456
+ travel(duration) { assert true }
457
+ travel_to(time) { assert true }
458
+
459
+ # bad
460
+ Timecop.travel(duration)
461
+ Timecop.travel(time)
462
+
463
+ # good
464
+ travel(duration)
465
+ travel_to(time)
466
+
467
+ # bad
468
+ Timecop.return
469
+ Timecop.return { assert true }
470
+
471
+ # good
472
+ travel_back
473
+ travel_back { assert true }
474
+
475
+ # bad
476
+ Timecop.scale(factor)
477
+ Timecop.scale(factor) { assert true }
478
+
479
+ # good
480
+ travel(duration)
481
+ travel_to(time)
482
+ travel(duration) { assert true }
483
+ travel_to(time) { assert true }
484
+ ----
485
+
486
+ === References
487
+
488
+ * https://www.rubydoc.info/gems/rubocop-rspec_rails/RuboCop/Cop/RSpecRails/Timecop
489
+
380
490
== RSpecRails/TravelAround
381
491
382
492
|===
0 commit comments