Skip to content

Commit

Permalink
Added mustNotBeBefore and mustNotBeBeforeInTimeZone
Browse files Browse the repository at this point in the history
  • Loading branch information
Christian Kolb committed Jun 17, 2024
1 parent 25a6538 commit 5c9ad4f
Show file tree
Hide file tree
Showing 6 changed files with 230 additions and 0 deletions.
18 changes: 18 additions & 0 deletions src/Exception/MomentIsBefore.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 MomentIsBefore extends \InvalidArgumentException
{
public function __construct()
{
parent::__construct('The moment is before but must not be.');
}
}
35 changes: 35 additions & 0 deletions src/Moment.php
Original file line number Diff line number Diff line change
Expand Up @@ -748,4 +748,39 @@ public function mustBeBeforeInTimeZone(
: new Exception\MomentIsNotBefore();
}
}

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

/**
* @param ?callable(): \Throwable $otherwiseThrow
*
* @throws \Throwable
* @throws Exception\MomentIsBefore
*/
public function mustNotBeBeforeInTimeZone(
Time | Weekday | Date | Month | Year $moment,
\DateTimeZone $timeZone,
?callable $otherwiseThrow = null,
): void {
if ($this->isBeforeInTimeZone($moment, $timeZone)) {
throw $otherwiseThrow !== null
? $otherwiseThrow()
: new Exception\MomentIsBefore();
}
}
}
85 changes: 85 additions & 0 deletions tests/Moment/MustNotBeBeforeInTimeZoneTest.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\MomentIsBefore;
use DigitalCraftsman\DateTimePrecision\Moment;
use DigitalCraftsman\DateTimePrecision\Month;
use DigitalCraftsman\DateTimePrecision\Test\Exception\CustomMomentIsBeforeInTimeZone;
use DigitalCraftsman\DateTimePrecision\Time;
use DigitalCraftsman\DateTimePrecision\Weekday;
use DigitalCraftsman\DateTimePrecision\Year;
use PHPUnit\Framework\TestCase;

/** @coversDefaultClass \DigitalCraftsman\DateTimePrecision\Moment */
final class MustNotBeBeforeInTimeZoneTest extends TestCase
{
/**
* @test
*
* @param ?class-string<\Throwable> $expectedResult
*
* @dataProvider dataProvider
*
* @covers ::mustNotBeBeforeInTimeZone
*/
public function must_not_be_before_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->mustNotBeBeforeInTimeZone(
$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('15:00:00'),
new \DateTimeZone('Europe/Berlin'),
null,
],
'default exception' => [
MomentIsBefore::class,
Moment::fromStringInTimeZone('2022-10-08 15:00:00', new \DateTimeZone('Europe/Berlin')),
Time::fromString('16:00:00'),
new \DateTimeZone('Europe/Berlin'),
null,
],
'custom exception' => [
CustomMomentIsBeforeInTimeZone::class,
Moment::fromStringInTimeZone('2022-10-08 15:00:00', new \DateTimeZone('Europe/Berlin')),
Time::fromString('16:00:00'),
new \DateTimeZone('Europe/Berlin'),
static fn () => new CustomMomentIsBeforeInTimeZone(),
],
];
}
}
74 changes: 74 additions & 0 deletions tests/Moment/MustNotBeBeforeTest.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\MomentIsBefore;
use DigitalCraftsman\DateTimePrecision\Moment;
use DigitalCraftsman\DateTimePrecision\Test\Exception\CustomMomentIsBefore;
use PHPUnit\Framework\TestCase;

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

$moment->mustNotBeBefore(
$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 16:00:00'),
Moment::fromString('2022-10-08 16:00:00'),
null,
],
'default exception' => [
MomentIsBefore::class,
Moment::fromString('2022-10-08 15:00:00'),
Moment::fromString('2022-10-08 16:00:00'),
null,
],
'custom exception' => [
CustomMomentIsBefore::class,
Moment::fromString('2022-10-08 15:00:00'),
Moment::fromString('2022-10-08 16:00:00'),
static fn () => new CustomMomentIsBefore(),
],
];
}
}
9 changes: 9 additions & 0 deletions tests/Test/Exception/CustomMomentIsBefore.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 CustomMomentIsBefore extends \InvalidArgumentException
{
}
9 changes: 9 additions & 0 deletions tests/Test/Exception/CustomMomentIsBeforeInTimeZone.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 CustomMomentIsBeforeInTimeZone extends \InvalidArgumentException
{
}

0 comments on commit 5c9ad4f

Please sign in to comment.