如何在Perl 6中模拟当前时间?

Paw*_*bkr 10 perl6

在Perl 5中,可以轻松模拟在特定时间戳运行的脚本:

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
Run Code Online (Sandbox Code Playgroud)

这是全局工作 - 每个包,每个方法,使用time()的所有内容都将看到1545667200时间戳.这对于测试时间敏感逻辑非常方便.

有没有办法在Perl 6中重现这种行为?

tim*_*imo 9

这是一种改变"现在"术语如何工作的方法,你可能希望对"时间"做同样的事情(虽然时间返回一个Int,而不是一个Instant对象).

&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
Run Code Online (Sandbox Code Playgroud)

最重要的是,根据你想要做什么,也许Test :: Scheduler可能很有趣:https://github.com/jnthn/p6-test-scheduler

  • 谢谢!完美的工作.但是有一个问题 - DateTime.now使用了nqp :: time_n()并需要额外的换行(与Perl 5不同,其中mocking time()足以修改DateTime.now CPAN包值). (2认同)