Skip to content

Commit

Permalink
Added mustBeBeforeOrEqualTo and mustBeBeforeOrEqualToInTimeZone
Browse files Browse the repository at this point in the history
  • Loading branch information
Christian Kolb committed Jun 17, 2024
1 parent 5c9ad4f commit 0089e82
Show file tree
Hide file tree
Showing 6 changed files with 230 additions and 0 deletions.
18 changes: 18 additions & 0 deletions src/Exception/MomentIsNotBeforeOrEqualTo.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace DigitalCraftsman\DateTimePrecision\Exception;

/**
* @psalm-immutable
*
* @codeCoverageIgnore
*/
final class MomentIsNotBeforeOrEqualTo extends \InvalidArgumentException
{
public function __construct()
{
parent::__construct('The moment is not before or equal to but must be.');
}
}
35 changes: 35 additions & 0 deletions src/Moment.php
Original file line number Diff line number Diff line change
Expand Up @@ -783,4 +783,39 @@ public function mustNotBeBeforeInTimeZone(
: new Exception\MomentIsBefore();
}
}

/**
* @param ?callable(): \Throwable $otherwiseThrow
*
* @throws \Throwable
* @throws Exception\MomentIsNotBeforeOrEqualTo
*/
public function mustBeBeforeOrEqualTo(
self $moment,
?callable $otherwiseThrow = null,
): void {
if ($this->isNotBeforeOrEqualTo($moment)) {
throw $otherwiseThrow !== null
? $otherwiseThrow()
: new Exception\MomentIsNotBeforeOrEqualTo();
}
}

/**
* @param ?callable(): \Throwable $otherwiseThrow
*
* @throws \Throwable
* @throws Exception\MomentIsNotBeforeOrEqualTo
*/
public function mustBeBeforeOrEqualToInTimeZone(
Time | Weekday | Date | Month | Year $moment,
\DateTimeZone $timeZone,
?callable $otherwiseThrow = null,
): void {
if ($this->isNotBeforeOrEqualToInTimeZone($moment, $timeZone)) {
throw $otherwiseThrow !== null
? $otherwiseThrow()
: new Exception\MomentIsNotBeforeOrEqualTo();
}
}
}
85 changes: 85 additions & 0 deletions tests/Moment/MustBeBeforeOrEqualToInTimeZoneTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?php

declare(strict_types=1);

namespace DigitalCraftsman\DateTimePrecision\Moment;

use DigitalCraftsman\DateTimePrecision\Date;
use DigitalCraftsman\DateTimePrecision\Exception\MomentIsNotBeforeOrEqualTo;
use DigitalCraftsman\DateTimePrecision\Moment;
use DigitalCraftsman\DateTimePrecision\Month;
use DigitalCraftsman\DateTimePrecision\Test\Exception\CustomMomentIsNotBeforeOrEqualToInTimeZone;
use DigitalCraftsman\DateTimePrecision\Time;
use DigitalCraftsman\DateTimePrecision\Weekday;
use DigitalCraftsman\DateTimePrecision\Year;
use PHPUnit\Framework\TestCase;

/** @coversDefaultClass \DigitalCraftsman\DateTimePrecision\Moment */
final class MustBeBeforeOrEqualToInTimeZoneTest extends TestCase
{
/**
* @test
*
* @param ?class-string<\Throwable> $expectedResult
*
* @dataProvider dataProvider
*
* @covers ::mustBeBeforeOrEqualToInTimeZone
*/
public function must_be_before_or_equal_to_in_time_zone_works(
?string $expectedResult,
Moment $moment,
Time | Weekday | Date | Month | Year $comparator,
\DateTimeZone $timeZone,
?callable $otherwiseThrow,
): void {
// -- Act & Assert
if ($expectedResult !== null) {
$this->expectException($expectedResult);
} else {
$this->expectNotToPerformAssertions();
}

$moment->mustBeBeforeOrEqualToInTimeZone(
$comparator,
$timeZone,
$otherwiseThrow,
);
}

/**
* @return array<string, array{
* 0: ?string,
* 1: Moment,
* 2: Time | Weekday | Date | Month | Year,
* 3: \DateTimeZone,
* 4: ?callable(): \Throwable
* }>
*/
public static function dataProvider(): array
{
return [
'without exception' => [
null,
Moment::fromStringInTimeZone('2022-10-08 15:00:00', new \DateTimeZone('Europe/Berlin')),
Time::fromString('16:00:00'),
new \DateTimeZone('Europe/Berlin'),
null,
],
'default exception' => [
MomentIsNotBeforeOrEqualTo::class,
Moment::fromStringInTimeZone('2022-10-08 16:00:00', new \DateTimeZone('Europe/Berlin')),
Time::fromString('15:00:00'),
new \DateTimeZone('Europe/Berlin'),
null,
],
'custom exception' => [
CustomMomentIsNotBeforeOrEqualToInTimeZone::class,
Moment::fromStringInTimeZone('2022-10-08 16:00:00', new \DateTimeZone('Europe/Berlin')),
Time::fromString('15:00:00'),
new \DateTimeZone('Europe/Berlin'),
static fn () => new CustomMomentIsNotBeforeOrEqualToInTimeZone(),
],
];
}
}
74 changes: 74 additions & 0 deletions tests/Moment/MustBeBeforeOrEqualToTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php

declare(strict_types=1);

namespace DigitalCraftsman\DateTimePrecision\Moment;

use DigitalCraftsman\DateTimePrecision\Exception\MomentIsNotBeforeOrEqualTo;
use DigitalCraftsman\DateTimePrecision\Moment;
use DigitalCraftsman\DateTimePrecision\Test\Exception\CustomMomentIsNotBeforeOrEqualTo;
use PHPUnit\Framework\TestCase;

/** @coversDefaultClass \DigitalCraftsman\DateTimePrecision\Moment */
final class MustBeBeforeOrEqualToTest extends TestCase
{
/**
* @test
*
* @param ?class-string<\Throwable> $expectedResult
*
* @dataProvider dataProvider
*
* @covers ::mustBeBeforeOrEqualTo
*/
public function must_be_before_or_equal_to_works(
?string $expectedResult,
Moment $moment,
Moment $comparator,
?callable $otherwiseThrow,
): void {
// -- Act & Assert
if ($expectedResult !== null) {
$this->expectException($expectedResult);
} else {
$this->expectNotToPerformAssertions();
}

$moment->mustBeBeforeOrEqualTo(
$comparator,
$otherwiseThrow,
);
}

/**
* @return array<string, array{
* 0: ?string,
* 1: Moment,
* 2: Moment,
* 3: ?callable(): \Throwable
* }>
*/
public static function dataProvider(): array
{
return [
'without exception' => [
null,
Moment::fromString('2022-10-08 15:00:00'),
Moment::fromString('2022-10-08 16:00:00'),
null,
],
'default exception' => [
MomentIsNotBeforeOrEqualTo::class,
Moment::fromString('2022-10-08 16:00:00'),
Moment::fromString('2022-10-08 15:00:00'),
null,
],
'custom exception' => [
CustomMomentIsNotBeforeOrEqualTo::class,
Moment::fromString('2022-10-08 16:00:00'),
Moment::fromString('2022-10-08 15:00:00'),
static fn () => new CustomMomentIsNotBeforeOrEqualTo(),
],
];
}
}
9 changes: 9 additions & 0 deletions tests/Test/Exception/CustomMomentIsNotBeforeOrEqualTo.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

namespace DigitalCraftsman\DateTimePrecision\Test\Exception;

final class CustomMomentIsNotBeforeOrEqualTo extends \InvalidArgumentException
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

namespace DigitalCraftsman\DateTimePrecision\Test\Exception;

final class CustomMomentIsNotBeforeOrEqualToInTimeZone extends \InvalidArgumentException
{
}

0 comments on commit 0089e82

Please sign in to comment.