How to mock current time in Perl 6?

Viewed 229

In Perl 5 one can easily simulate script running at specific timestamp:

BEGIN {
    *CORE::GLOBAL::time = sub () { $::time_mock // CORE::time };
}
use Test;
$::time_mock = 1545667200;
ok is-xmas, 'yay!';
$::time_mock = undef; # back to current time

And this works globally - every package, every method, everything that uses time() will see 1545667200 timestamp. Which is very convenient for testing time sensitive logic.

Is there a way to reproduce such behavior in Perl 6?

2 Answers

Here's a way to change how the "now" term works, and you may want to do the same thing to "time" (though time returns an Int, not an Instant object).

&term:<now>.wrap(
    -> |, :$set-mock-time {
        state $mock-time;
        $mock-time = Instant.from-posix($_) with $set-mock-time;
        $mock-time // callsame
});
say now; # Instant:1542374103.625357
sleep 0.5;
say now; # Instant:1542374104.127774
term:<now>(set-mock-time => 12345);
say now; # Instant:12355
sleep 0.5;
say now; # Instant:12355

On top of that, depending on what exactly you want to do, perhaps Test::Scheduler could be interesting: https://github.com/jnthn/p6-test-scheduler

Related