Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
91 / 91
n/a
0 / 0
CRAP
n/a
0 / 0
1<?php
2
3// ╔════════════════════════════════════════════════════════════╗
4// ║ MIT Licence (#Expat) - https://opensource.org/licenses/MIT ║
5// ║ Copyright 2026 Frederic Poeydomenge <dyno@phexium.com>     ║
6// ╚════════════════════════════════════════════════════════════╝
7
8declare(strict_types=1);
9
10pest()->group('unit');
11
12use Phexium\Plugin\Clock\Adapter\FrozenClock;
13use Phexium\Plugin\Clock\Adapter\OffsetClock;
14
15describe('Time retrieval', function (): void {
16    it('returns inner clock time without offset', function (): void {
17        $inner = new FrozenClock('2025-01-01T12:00:00+00:00');
18        $clock = new OffsetClock($inner);
19
20        $result = $clock->now();
21
22        expect($result->format(DateTimeInterface::ATOM))->toBe('2025-01-01T12:00:00+00:00');
23    });
24});
25
26describe('Offset', function (): void {
27    it('advances time by seconds', function (): void {
28        $inner = new FrozenClock('2025-01-01T12:00:00+00:00');
29        $clock = new OffsetClock($inner);
30
31        $clock->advanceSeconds(60);
32
33        expect($clock->now()->format(DateTimeInterface::ATOM))->toBe('2025-01-01T12:01:00+00:00');
34    });
35
36    it('advances time with DateInterval', function (): void {
37        $inner = new FrozenClock('2025-01-01T12:00:00+00:00');
38        $clock = new OffsetClock($inner);
39
40        $clock->advance(new DateInterval('P1DT2H30M45S'));
41
42        expect($clock->now()->format(DateTimeInterface::ATOM))->toBe('2025-01-02T14:30:45+00:00');
43    });
44
45    it('advances time with inverted DateInterval', function (): void {
46        $inner = new FrozenClock('2025-01-01T12:00:00+00:00');
47        $clock = new OffsetClock($inner);
48        $interval = new DateInterval('P1DT2H30M45S');
49        $interval->invert = 1;
50
51        $clock->advance($interval);
52
53        expect($clock->now()->format(DateTimeInterface::ATOM))->toBe('2024-12-31T09:29:15+00:00');
54    });
55
56    it('accumulates multiple advances', function (): void {
57        $inner = new FrozenClock('2025-01-01T12:00:00+00:00');
58        $clock = new OffsetClock($inner);
59
60        $clock->advanceSeconds(30);
61        $clock->advanceSeconds(30);
62
63        expect($clock->now()->format(DateTimeInterface::ATOM))->toBe('2025-01-01T12:01:00+00:00');
64    });
65
66    it('rewinds time by seconds', function (): void {
67        $inner = new FrozenClock('2025-01-01T12:00:00+00:00');
68        $clock = new OffsetClock($inner);
69
70        $clock->rewindSeconds(60);
71
72        expect($clock->now()->format(DateTimeInterface::ATOM))->toBe('2025-01-01T11:59:00+00:00');
73    });
74
75    it('rewinds time with DateInterval', function (): void {
76        $inner = new FrozenClock('2025-01-01T12:00:00+00:00');
77        $clock = new OffsetClock($inner);
78
79        $clock->rewind(new DateInterval('P1DT2H30M45S'));
80
81        expect($clock->now()->format(DateTimeInterface::ATOM))->toBe('2024-12-31T09:29:15+00:00');
82    });
83
84    it('rewinds time with inverted DateInterval', function (): void {
85        $inner = new FrozenClock('2025-01-01T12:00:00+00:00');
86        $clock = new OffsetClock($inner);
87        $interval = new DateInterval('P1DT2H30M45S');
88        $interval->invert = 1;
89
90        $clock->rewind($interval);
91
92        expect($clock->now()->format(DateTimeInterface::ATOM))->toBe('2025-01-02T14:30:45+00:00');
93    });
94
95    it('accumulates multiple rewinds', function (): void {
96        $inner = new FrozenClock('2025-01-01T12:00:00+00:00');
97        $clock = new OffsetClock($inner);
98
99        $clock->rewindSeconds(30);
100        $clock->rewindSeconds(30);
101
102        expect($clock->now()->format(DateTimeInterface::ATOM))->toBe('2025-01-01T11:59:00+00:00');
103    });
104
105    it('combines advance and rewind', function (): void {
106        $inner = new FrozenClock('2025-01-01T12:00:00+00:00');
107        $clock = new OffsetClock($inner);
108
109        $clock->advanceSeconds(120);
110        $clock->rewindSeconds(60);
111
112        expect($clock->now()->format(DateTimeInterface::ATOM))->toBe('2025-01-01T12:01:00+00:00');
113    });
114
115    it('resets offset to zero', function (): void {
116        $inner = new FrozenClock('2025-01-01T12:00:00+00:00');
117        $clock = new OffsetClock($inner);
118
119        $clock->advanceSeconds(3600);
120        $clock->reset();
121
122        expect($clock->now()->format(DateTimeInterface::ATOM))->toBe('2025-01-01T12:00:00+00:00');
123    });
124
125    it('advances by large amounts', function (): void {
126        $inner = new FrozenClock('2025-01-01T12:00:00+00:00');
127        $clock = new OffsetClock($inner);
128
129        $clock->advanceSeconds(24 * 60 * 60);
130
131        expect($clock->now()->format('Y-m-d'))->toBe('2025-01-02');
132    });
133
134    it('advances with days in DateInterval', function (): void {
135        $inner = new FrozenClock('2025-01-01T12:00:00+00:00');
136        $clock = new OffsetClock($inner);
137
138        $clock->advance(new DateInterval('P7D'));
139
140        expect($clock->now()->format(DateTimeInterface::ATOM))->toBe('2025-01-08T12:00:00+00:00');
141    });
142});