TestClock::now()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
1
<?php declare(strict_types=1);
2
3
namespace Stratadox\CardGame\Infrastructure\Test;
4
5
use Closure;
6
use DateInterval;
7
use DateTimeImmutable;
8
use DateTimeInterface;
9
use Stratadox\Clock\RewindableClock;
10
use Stratadox\Clock\RewindableDateTimeClock;
11
use Stratadox\Clock\UnmovingClock;
12
13
final class TestClock implements RewindableClock
14
{
15
    /** @var RewindableClock */
16
    private $clock;
17
    /** @var Closure|null */
18
    private $method;
19
20
    private function __construct(RewindableClock $clock)
21
    {
22
        $this->clock = $clock;
23
    }
24
25
    public static function make(): self
26
    {
27
        return new self(RewindableDateTimeClock::using(
28
            UnmovingClock::standingStillAt(new DateTimeImmutable())
29
        ));
30
    }
31
32
    public static function from(RewindableClock $clock): self
33
    {
34
        return new self($clock);
35
    }
36
37
    public function eachPassingSecondApply(Closure $method): void
38
    {
39
        $this->method = $method;
40
    }
41
42
    public function now(): DateTimeInterface
43
    {
44
        return $this->clock->now();
45
    }
46
47
    public function rewind(DateInterval $interval): RewindableClock
48
    {
49
        $this->clock = $this->clock->rewind($interval);
50
        return $this;
51
    }
52
53
    public function fastForward(DateInterval $interval): RewindableClock
54
    {
55
        // @todo
56
        // use expiry dates instead, and apply expiration actions when handling
57
        // the next command
58
        // ..can we do that? How to update read models after auto-combat, then?
59
        $before = $this->clock->now();
60
        $this->clock = $this->clock->fastForward($interval);
61
62
        $since = $this->clock->now()->getTimestamp() - $before->getTimestamp();
63
        if ($this->method !== null) {
64
            for ($i = 0; $i < $since; $i++) {
65
                ($this->method)($i);
66
            }
67
        }
68
        return $this;
69
    }
70
}
71