77namespace test \unit \Ingenerator \PHPUtils \DateTime \Clock ;
88
99
10+ use Closure ;
11+ use DateTimeImmutable ;
1012use Ingenerator \PHPUtils \DateTime \Clock \RealtimeClock ;
13+ use Ingenerator \PHPUtils \DateTime \DateIntervalFactory ;
14+ use PHPUnit \Framework \Attributes \DataProvider ;
1115use PHPUnit \Framework \TestCase ;
1216
1317class RealtimeClockTest extends TestCase
@@ -21,10 +25,10 @@ public function test_it_is_initialisable()
2125 public function test_it_returns_current_time ()
2226 {
2327 $ time = $ this ->newSubject ()->getDateTime ();
24- $ this ->assertInstanceOf (\ DateTimeImmutable::class, $ time );
28+ $ this ->assertInstanceOf (DateTimeImmutable::class, $ time );
2529 // Allow for time changing during the test
2630 $ this ->assertEqualsWithDelta (
27- new \ DateTimeImmutable ,
31+ new DateTimeImmutable ,
2832 $ time ,
2933 1 ,
3034 'Should be roughly the real time '
@@ -82,10 +86,61 @@ public function test_time_continues_during_the_life_of_an_instance()
8286 );
8387 }
8488
89+ public static function provider_relative_times ():array
90+ {
91+ return [
92+ 'in the past, with time component ' => [
93+ fn (RealtimeClock $ clock ) => $ clock ->ago (DateIntervalFactory::years (6 )),
94+ '-6 year ' ,
95+ false ,
96+ ],
97+ 'in the past, with date only ' => [
98+ fn (RealtimeClock $ clock ) => $ clock ->ago (DateIntervalFactory::months (6 ), date_only: true ),
99+ '-6 months 00:00:00.000000 ' ,
100+ true ,
101+ ],
102+ 'in the future, with time component ' => [
103+ fn (RealtimeClock $ clock ) => $ clock ->future (DateIntervalFactory::years (2 )),
104+ '+2 year ' ,
105+ false ,
106+ ],
107+ 'in the future, with date only ' => [
108+ fn (RealtimeClock $ clock ) => $ clock ->future (DateIntervalFactory::months (1 ), date_only: true ),
109+ '+1 months 00:00:00.000000 ' ,
110+ true ,
111+ ],
112+ ];
113+
114+ }
115+
116+ #[DataProvider('provider_relative_times ' )]
117+ public function test_it_returns_relative_times (Closure $ test_method , string $ expect_result , bool $ expect_zero_time )
118+ {
119+ $ subject = $ this ->newSubject ();
120+ // Capture the time before and after we do the calculation - time will pass during the test so we need to just
121+ // know that it's between the offset we would expect immediately before, and the offset we'd expect immediately
122+ // after.
123+ $ expect_before = new DateTimeImmutable ($ expect_result );
124+ $ result = $ test_method ($ subject );
125+ $ expect_after = new DateTimeImmutable ($ expect_result );
126+
127+ $ this ->assertGreaterThanOrEqual ($ expect_before , $ result );
128+ $ this ->assertLessThanOrEqual ($ expect_after , $ result );
129+
130+ if ($ expect_zero_time ) {
131+ $ this ->assertSame ('00:00:00.000000 ' , $ result ->format ('H:i:s.u ' ));
132+ }
133+ }
85134
86135 protected function newSubject ()
87136 {
88137 return new RealtimeClock ();
89138 }
90139
140+ protected function assertBetween (mixed $ expect_min , mixed $ expect_max , mixed $ actual , string $ msg )
141+ {
142+ $ this ->assertGreaterThanOrEqual ($ expect_min , $ actual , $ msg );
143+ $ this ->assertLessThanOrEqual ($ expect_max , $ actual , $ msg );
144+ }
145+
91146}
0 commit comments