From edd58eb57f636b355e18bdc1fed2f6709fbc64e1 Mon Sep 17 00:00:00 2001 From: Francis Lavoie Date: Sat, 3 Feb 2024 17:58:34 -0500 Subject: [PATCH 1/8] Add `travelForward` & `travelBackward` --- .gitignore | 1 + README.md | 6 ++++-- src/DefaultClock.php | 20 ++++++++++++++++++++ tests/DefaultClockTest.php | 35 +++++++++++++++++++++++++++++++++++ 4 files changed, 60 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index aea6faab..d4a82ab1 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ /tools/ecs/* !/tools/ecs/composer.json !/tools/ecs/ecs.php +/.idea diff --git a/README.md b/README.md index 5d88c118..016add01 100644 --- a/README.md +++ b/README.md @@ -84,7 +84,7 @@ All objects read the current time from a `Clock` implementation. The following i - `SystemClock` returns the system time; it's the default clock - `FixedClock`: returns a pre-configured time - `OffsetClock`: adds an offset to another clock -- `ScaleClock`: makes another clock fast forward by a scale factor +- `ScaleClock`: makes another clock fast-forward by a scale factor These classes belong to the `Brick\DateTime\Clock` namespace. @@ -127,7 +127,9 @@ DefaultClock::reset(); // do not forget to reset the clock to the system clock! There are also useful shortcut methods to use clocks in your tests, inspired by [timecop](https://github.com/travisjeffery/timecop): - `freeze()` freezes time to a specific point in time -- `travel()` travels to a specific point in time, but allows time to continue moving forward from there +- `travel()` travels to an `Instant` in time, but allows time to continue moving forward from there +- `travelForward()` travels forward by a `Duration` +- `travelBackward()` travels backward by a `Duration` - `scale()` makes time move at a given pace #### Freeze the time to a specific point diff --git a/src/DefaultClock.php b/src/DefaultClock.php index 69b58b57..8999ed13 100644 --- a/src/DefaultClock.php +++ b/src/DefaultClock.php @@ -76,6 +76,26 @@ public static function travel(Instant $instant): void self::set(new OffsetClock($clock, $offset)); } + /** + * Travels forward by a duration, but allows time to continue moving forward from there. + * + * If the current default clock is frozen, you must `reset()` it first, or the time will stay frozen. + */ + public static function travelForward(Duration $duration): void + { + self::set(new OffsetClock(self::get(), $duration->abs())); + } + + /** + * Travels backward by a duration, but allows time to continue moving forward from there. + * + * If the current default clock is frozen, you must `reset()` it first, or the time will stay frozen. + */ + public static function travelBackward(Duration $duration): void + { + self::set(new OffsetClock(self::get(), $duration->abs()->negated())); + } + /** * Makes time move at a given pace. * diff --git a/tests/DefaultClockTest.php b/tests/DefaultClockTest.php index 21565cc7..0f78c66a 100644 --- a/tests/DefaultClockTest.php +++ b/tests/DefaultClockTest.php @@ -6,6 +6,7 @@ use Brick\DateTime\Clock\FixedClock; use Brick\DateTime\DefaultClock; +use Brick\DateTime\Duration; use Brick\DateTime\Instant; /** @@ -37,6 +38,40 @@ public function testTravel(): void self::assertInstantIs(-998, 0, Instant::now()); } + public function testTravelForward(): void + { + $fixedClock = new FixedClock(Instant::of(1000, 0)); + DefaultClock::set($fixedClock); + self::assertInstantIs(1000, 0, Instant::now()); + + DefaultClock::travelForward(Duration::ofSeconds(1000)); + self::assertInstantIs(2000, 0, Instant::now()); + + // Absolute value of the duration + DefaultClock::travelForward(Duration::ofSeconds(-1000)); + self::assertInstantIs(3000, 0, Instant::now()); + + $fixedClock->move(2); + self::assertInstantIs(3002, 0, Instant::now()); + } + + public function testTravelBackward(): void + { + $fixedClock = new FixedClock(Instant::of(1000, 0)); + DefaultClock::set($fixedClock); + self::assertInstantIs(1000, 0, Instant::now()); + + DefaultClock::travelBackward(Duration::ofSeconds(1000)); + self::assertInstantIs(0, 0, Instant::now()); + + // Absolute value of duration + DefaultClock::travelBackward(Duration::ofSeconds(-1000)); + self::assertInstantIs(-1000, 0, Instant::now()); + + $fixedClock->move(2); + self::assertInstantIs(-998, 0, Instant::now()); + } + public function testScale(): void { $fixedClock = new FixedClock(Instant::of(1000, 0)); From 39fe10a437c0e23a0a2683c1c7d532ae83712716 Mon Sep 17 00:00:00 2001 From: Francis Lavoie Date: Sat, 3 Feb 2024 18:27:15 -0500 Subject: [PATCH 2/8] Change to `travelBy` --- src/DefaultClock.php | 16 +++------------- tests/DefaultClockTest.php | 26 +++++--------------------- 2 files changed, 8 insertions(+), 34 deletions(-) diff --git a/src/DefaultClock.php b/src/DefaultClock.php index 8999ed13..82388290 100644 --- a/src/DefaultClock.php +++ b/src/DefaultClock.php @@ -77,23 +77,13 @@ public static function travel(Instant $instant): void } /** - * Travels forward by a duration, but allows time to continue moving forward from there. + * Travels forward in time by a duration (or backward if the duration is negative). * * If the current default clock is frozen, you must `reset()` it first, or the time will stay frozen. */ - public static function travelForward(Duration $duration): void + public static function travelBy(Duration $duration): void { - self::set(new OffsetClock(self::get(), $duration->abs())); - } - - /** - * Travels backward by a duration, but allows time to continue moving forward from there. - * - * If the current default clock is frozen, you must `reset()` it first, or the time will stay frozen. - */ - public static function travelBackward(Duration $duration): void - { - self::set(new OffsetClock(self::get(), $duration->abs()->negated())); + self::set(new OffsetClock(self::get(), $duration)); } /** diff --git a/tests/DefaultClockTest.php b/tests/DefaultClockTest.php index 0f78c66a..f4b5de54 100644 --- a/tests/DefaultClockTest.php +++ b/tests/DefaultClockTest.php @@ -44,32 +44,16 @@ public function testTravelForward(): void DefaultClock::set($fixedClock); self::assertInstantIs(1000, 0, Instant::now()); - DefaultClock::travelForward(Duration::ofSeconds(1000)); + // Travel forward + DefaultClock::travelBy(Duration::ofSeconds(1000)); self::assertInstantIs(2000, 0, Instant::now()); - // Absolute value of the duration - DefaultClock::travelForward(Duration::ofSeconds(-1000)); - self::assertInstantIs(3000, 0, Instant::now()); - - $fixedClock->move(2); - self::assertInstantIs(3002, 0, Instant::now()); - } - - public function testTravelBackward(): void - { - $fixedClock = new FixedClock(Instant::of(1000, 0)); - DefaultClock::set($fixedClock); + // Travel backward + DefaultClock::travelBy(Duration::ofSeconds(-1000)); self::assertInstantIs(1000, 0, Instant::now()); - DefaultClock::travelBackward(Duration::ofSeconds(1000)); - self::assertInstantIs(0, 0, Instant::now()); - - // Absolute value of duration - DefaultClock::travelBackward(Duration::ofSeconds(-1000)); - self::assertInstantIs(-1000, 0, Instant::now()); - $fixedClock->move(2); - self::assertInstantIs(-998, 0, Instant::now()); + self::assertInstantIs(1002, 0, Instant::now()); } public function testScale(): void From 8dee0a949d5456fd8ef56667a3cce197aff834e9 Mon Sep 17 00:00:00 2001 From: Francis Lavoie Date: Sun, 4 Feb 2024 02:39:01 -0500 Subject: [PATCH 3/8] Update README.md --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 016add01..6f6ea4ae 100644 --- a/README.md +++ b/README.md @@ -128,8 +128,7 @@ There are also useful shortcut methods to use clocks in your tests, inspired by - `freeze()` freezes time to a specific point in time - `travel()` travels to an `Instant` in time, but allows time to continue moving forward from there -- `travelForward()` travels forward by a `Duration` -- `travelBackward()` travels backward by a `Duration` +- `travelBy()` travels in time by a `Duration`, which may be forward (positive) or backward (negative) - `scale()` makes time move at a given pace #### Freeze the time to a specific point From c30592809f423547b386de2d5f45722d3c26a3ad Mon Sep 17 00:00:00 2001 From: Francis Lavoie Date: Sun, 4 Feb 2024 02:40:00 -0500 Subject: [PATCH 4/8] Update DefaultClock.php --- src/DefaultClock.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DefaultClock.php b/src/DefaultClock.php index 82388290..553d57c6 100644 --- a/src/DefaultClock.php +++ b/src/DefaultClock.php @@ -77,7 +77,7 @@ public static function travel(Instant $instant): void } /** - * Travels forward in time by a duration (or backward if the duration is negative). + * Travels in time by a duration, which may be forward (positive) or backward (negative). * * If the current default clock is frozen, you must `reset()` it first, or the time will stay frozen. */ From f40b8f2d44b48da6d0b2976f5e45e83b9b0a03fc Mon Sep 17 00:00:00 2001 From: Francis Lavoie Date: Tue, 6 Feb 2024 06:27:14 -0500 Subject: [PATCH 5/8] Add `travelTo`, deprecate `travel` --- README.md | 8 ++++---- src/DefaultClock.php | 12 ++++++++++++ tests/DefaultClockTest.php | 2 +- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 6f6ea4ae..6fb86d77 100644 --- a/README.md +++ b/README.md @@ -127,7 +127,7 @@ DefaultClock::reset(); // do not forget to reset the clock to the system clock! There are also useful shortcut methods to use clocks in your tests, inspired by [timecop](https://github.com/travisjeffery/timecop): - `freeze()` freezes time to a specific point in time -- `travel()` travels to an `Instant` in time, but allows time to continue moving forward from there +- `travelTo()` travels to an `Instant` in time, but allows time to continue moving forward from there - `travelBy()` travels in time by a `Duration`, which may be forward (positive) or backward (negative) - `scale()` makes time move at a given pace @@ -154,7 +154,7 @@ DefaultClock::reset(); use Brick\DateTime\DefaultClock; use Brick\DateTime\Instant; -DefaultClock::travel(Instant::of(2000000000)); +DefaultClock::travelTo(Instant::of(2000000000)); $a = Instant::now(); sleep(1); $b = Instant::now(); @@ -170,7 +170,7 @@ DefaultClock::reset(); use Brick\DateTime\DefaultClock; use Brick\DateTime\Instant; -DefaultClock::travel(Instant::of(2000000000)); +DefaultClock::travelTo(Instant::of(2000000000)); DefaultClock::scale(60); // 1 second becomes 60 seconds $a = Instant::now(); sleep(1); @@ -182,7 +182,7 @@ echo $b, PHP_EOL; // 2033-05-18T03:34:20.06632Z DefaultClock::reset(); ``` -As you can see, you can even combine `travel()` and `scale()` methods. +As you can see, you can even combine `travelTo()` and `scale()` methods. Be very careful to **`reset()` the DefaultClock after each of your tests!** If you're using PHPUnit, a good place to do this is in the `tearDown()` method. diff --git a/src/DefaultClock.php b/src/DefaultClock.php index 553d57c6..4640b0f4 100644 --- a/src/DefaultClock.php +++ b/src/DefaultClock.php @@ -67,8 +67,20 @@ public static function freeze(Instant $instant): void * Travels to a specific point in time, but allows time to continue moving forward from there. * * If the current default clock is frozen, you must `reset()` it first, or the time will stay frozen. + * + * @deprecated use travelTo() instead. */ public static function travel(Instant $instant): void + { + self::travelTo($instant); + } + + /** + * Travels to a specific point in time, but allows time to continue moving forward from there. + * + * If the current default clock is frozen, you must `reset()` it first, or the time will stay frozen. + */ + public static function travelTo(Instant $instant): void { $clock = self::get(); $offset = Duration::between($clock->getTime(), $instant); diff --git a/tests/DefaultClockTest.php b/tests/DefaultClockTest.php index f4b5de54..c449092d 100644 --- a/tests/DefaultClockTest.php +++ b/tests/DefaultClockTest.php @@ -31,7 +31,7 @@ public function testTravel(): void DefaultClock::set($fixedClock); self::assertInstantIs(1000, 0, Instant::now()); - DefaultClock::travel(Instant::of(-1000)); + DefaultClock::travelTo(Instant::of(-1000)); self::assertInstantIs(-1000, 0, Instant::now()); $fixedClock->move(2); From 0f1717f0ee83fa880223d0dd296e88855f985407 Mon Sep 17 00:00:00 2001 From: Francis Lavoie Date: Tue, 6 Feb 2024 06:33:27 -0500 Subject: [PATCH 6/8] Fix CS, bump actions/checkout version --- .github/workflows/coding-style.yml | 2 +- .github/workflows/psalm.yml | 2 +- .github/workflows/tests.yml | 2 +- src/DefaultClock.php | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/coding-style.yml b/.github/workflows/coding-style.yml index a1f75289..6afa3c37 100644 --- a/.github/workflows/coding-style.yml +++ b/.github/workflows/coding-style.yml @@ -11,7 +11,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Setup PHP uses: shivammathur/setup-php@v2 diff --git a/.github/workflows/psalm.yml b/.github/workflows/psalm.yml index 11a15562..7cb1f4b2 100644 --- a/.github/workflows/psalm.yml +++ b/.github/workflows/psalm.yml @@ -11,7 +11,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Setup PHP uses: shivammathur/setup-php@v2 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 95a3f4c7..a17dbe42 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -26,7 +26,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Setup PHP uses: shivammathur/setup-php@v2 diff --git a/src/DefaultClock.php b/src/DefaultClock.php index 4640b0f4..d40b3155 100644 --- a/src/DefaultClock.php +++ b/src/DefaultClock.php @@ -67,7 +67,7 @@ public static function freeze(Instant $instant): void * Travels to a specific point in time, but allows time to continue moving forward from there. * * If the current default clock is frozen, you must `reset()` it first, or the time will stay frozen. - * + * * @deprecated use travelTo() instead. */ public static function travel(Instant $instant): void From 22c656f8690c0c215f57650684a336b2820fa9a2 Mon Sep 17 00:00:00 2001 From: Francis Lavoie Date: Tue, 6 Feb 2024 06:38:21 -0500 Subject: [PATCH 7/8] Coverage --- tests/DefaultClockTest.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/DefaultClockTest.php b/tests/DefaultClockTest.php index c449092d..3e46edfc 100644 --- a/tests/DefaultClockTest.php +++ b/tests/DefaultClockTest.php @@ -34,8 +34,12 @@ public function testTravel(): void DefaultClock::travelTo(Instant::of(-1000)); self::assertInstantIs(-1000, 0, Instant::now()); + // TODO: Remove deprecated function + DefaultClock::travel(Instant::of(-2000)); + self::assertInstantIs(-2000, 0, Instant::now()); + $fixedClock->move(2); - self::assertInstantIs(-998, 0, Instant::now()); + self::assertInstantIs(-1998, 0, Instant::now()); } public function testTravelForward(): void From 74b24f8df85d7d3aa0d020d2b98c97e498ea5784 Mon Sep 17 00:00:00 2001 From: Francis Lavoie Date: Wed, 24 Apr 2024 09:28:35 -0400 Subject: [PATCH 8/8] Nits --- .gitignore | 1 - tests/DefaultClockTest.php | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 35681bf9..9fad048f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ -/.idea /vendor /composer.lock /.phpunit.cache diff --git a/tests/DefaultClockTest.php b/tests/DefaultClockTest.php index 3e46edfc..824ca1ac 100644 --- a/tests/DefaultClockTest.php +++ b/tests/DefaultClockTest.php @@ -42,7 +42,7 @@ public function testTravel(): void self::assertInstantIs(-1998, 0, Instant::now()); } - public function testTravelForward(): void + public function testTravelBy(): void { $fixedClock = new FixedClock(Instant::of(1000, 0)); DefaultClock::set($fixedClock);