@@ -377,6 +377,116 @@ expect(foo).to be_invalid.or be_even
377377
378378* https://www.rubydoc.info/gems/rubocop-rspec_rails/RuboCop/Cop/RSpecRails/NegationBeValid
379379
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+
380490== RSpecRails/TravelAround
381491
382492|===
0 commit comments