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

10
在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

这适用于全局 - 每个软件包、每个方法、使用 time() 的所有内容都将看到 1545667200 时间戳。对于测试时间敏感逻辑非常方便。

在 Perl 6 中是否有一种复制这种行为的方法?

2个回答

9
这里有一种改变“now”术语工作方式的方法,你可能希望对“time”进行相同的操作(尽管time返回一个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

此外,根据你想要做的具体内容,也许Test::Scheduler可能会很有趣:https://github.com/jnthn/p6-test-scheduler

2
谢谢!完美运作。然而有一个问题 - DateTime.now 在幕后使用 nqp::time_n(),需要额外的包装(与 Perl 5 不同,那里模拟 time() 足以修改 DateTime.now CPAN 包值)。 - Pawel Pabian bbkr
https://github.com/FCO/test-time 可以实现这个功能,并且使用了 Test::Schedule。 - SmokeMachine

3

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接