From 4b00584659fe8010434ba5e91c3144079ed89596 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20M=C3=B6ller?= Date: Sat, 4 Jan 2020 21:14:10 +0100 Subject: [PATCH] Enhancement: Add Range --- .php_cs | 7 +- CHANGELOG.md | 2 + src/Exception/InvalidRange.php | 37 ++++++ src/Period.php | 19 +++ src/Range.php | 92 ++++++++++++++ src/Year.php | 12 +- test/Unit/Exception/InvalidRangeTest.php | 50 ++++++++ test/Unit/RangeTest.php | 154 +++++++++++++++++++++++ test/Unit/YearTest.php | 46 +++++++ 9 files changed, 416 insertions(+), 3 deletions(-) create mode 100644 src/Exception/InvalidRange.php create mode 100644 src/Period.php create mode 100644 src/Range.php create mode 100644 test/Unit/Exception/InvalidRangeTest.php create mode 100644 test/Unit/RangeTest.php diff --git a/.php_cs b/.php_cs index db93883c..cbc0984b 100644 --- a/.php_cs +++ b/.php_cs @@ -15,10 +15,13 @@ use Ergebnis\License; use Ergebnis\PhpCsFixer\Config; $holder = License\Holder::fromString('Andreas Möller'); -$year = License\Year::fromString('2020'); +$range = License\Range::since( + License\Year::fromString('2020'), + new \DateTimeZone('UTC') +); $header = <<toString()} {$holder->toString()} +Copyright (c) {$range->toString()} {$holder->toString()} For the full copyright and license information, please view the LICENSE file that was distributed with this source code. diff --git a/CHANGELOG.md b/CHANGELOG.md index bd117246..8aafe476 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,10 +12,12 @@ For a full diff see [`675601b...master`][675601b...master]. * Added `Holder` ([#7]), by [@localheinz] * Added `Year` ([#10]), by [@localheinz] +* Added `Range` ([#12]), by [@localheinz] [675601b...master]: https://github.com/ergebnis/license/compare/675601b...master [#7]: https://github.com/ergebnis/license/pull/7 [#10]: https://github.com/ergebnis/license/pull/10 +[#12]: https://github.com/ergebnis/license/pull/12 [@localheinz]: https://github.com/localheinz diff --git a/src/Exception/InvalidRange.php b/src/Exception/InvalidRange.php new file mode 100644 index 00000000..cbe5a827 --- /dev/null +++ b/src/Exception/InvalidRange.php @@ -0,0 +1,37 @@ +toString(), + $end->toString() + )); + } + + public static function startYearGreaterThanCurrentYear(Year $start, Year $current): self + { + return new self(\sprintf( + 'Start year "%s" can not be greater than current year "%s".', + $start->toString(), + $current->toString() + )); + } +} diff --git a/src/Period.php b/src/Period.php new file mode 100644 index 00000000..d66a82d4 --- /dev/null +++ b/src/Period.php @@ -0,0 +1,19 @@ +value = $value; + } + + /** + * @param Year $start + * @param Year $end + * + * @throws Exception\InvalidRange + * + * @return Period + */ + public static function including(Year $start, Year $end): Period + { + if ($start->greaterThan($end)) { + throw Exception\InvalidRange::startYearGreaterThanEndYear( + $start, + $end + ); + } + + if ($start->equals($end)) { + return $start; + } + + return new self(\sprintf( + '%s-%s', + $start->toString(), + $end->toString() + )); + } + + /** + * @param Year $start + * @param \DateTimeZone $timeZone + * + * @throws Exception\InvalidRange + * + * @return Period + */ + public static function since(Year $start, \DateTimeZone $timeZone): Period + { + $now = new \DateTimeImmutable( + 'now', + $timeZone + ); + + $current = Year::fromString($now->format('Y')); + + if ($start->greaterThan($current)) { + throw Exception\InvalidRange::startYearGreaterThanCurrentYear( + $start, + $current + ); + } + + if ($start->equals($current)) { + return $start; + } + + return new self(\sprintf( + '%s-%s', + $start->toString(), + $current->toString() + )); + } + + public function toString(): string + { + return $this->value; + } +} diff --git a/src/Year.php b/src/Year.php index 886f3a74..01bf2230 100644 --- a/src/Year.php +++ b/src/Year.php @@ -13,7 +13,7 @@ namespace Ergebnis\License; -final class Year +final class Year implements Period { private $value; @@ -38,6 +38,16 @@ public static function fromString(string $value): self return new self($value); } + public function greaterThan(self $other): bool + { + return $this->value > $other->value; + } + + public function equals(self $other): bool + { + return $this->value === $other->value; + } + public function toString(): string { return $this->value; diff --git a/test/Unit/Exception/InvalidRangeTest.php b/test/Unit/Exception/InvalidRangeTest.php new file mode 100644 index 00000000..99ca5278 --- /dev/null +++ b/test/Unit/Exception/InvalidRangeTest.php @@ -0,0 +1,50 @@ +toString(), + $end->toString() + ); + + self::assertSame($expected, $exception->getMessage()); + } +} diff --git a/test/Unit/RangeTest.php b/test/Unit/RangeTest.php new file mode 100644 index 00000000..b0a78788 --- /dev/null +++ b/test/Unit/RangeTest.php @@ -0,0 +1,154 @@ +expectException(Exception\InvalidRange::class); + + Range::including( + $start, + $end + ); + } + + public function testIncludingReturnsRangeWhenStartYearEqualsEndYear(): void + { + $start = Year::fromString('2020'); + $end = Year::fromString('2020'); + + $range = Range::including( + $start, + $end + ); + + self::assertInstanceOf(Year::class, $range); + self::assertSame($start->toString(), $range->toString()); + } + + public function testIncludingReturnsRangeWhenStartYearIsLessThanEndYear(): void + { + $start = Year::fromString('2019'); + $end = Year::fromString('2020'); + + $years = Range::including( + $start, + $end + ); + + $expected = \sprintf( + '%s-%s', + $start->toString(), + $end->toString() + ); + + self::assertInstanceOf(Range::class, $years); + self::assertSame($expected, $years->toString()); + } + + /** + * @dataProvider provideTimeZone + * + * @param \DateTimeZone $timeZone + */ + public function testSinceReturnsYearWhenStartYearEqualsCurrentYear(\DateTimeZone $timeZone): void + { + $now = new \DateTimeImmutable( + 'now', + $timeZone + ); + + $start = Year::fromString($now->format('Y')); + + $year = Range::since( + $start, + $timeZone + ); + + self::assertInstanceOf(Year::class, $year); + self::assertSame($start->toString(), $year->toString()); + } + + /** + * @dataProvider provideTimeZone + * + * @param \DateTimeZone $timeZone + */ + public function testSinceReturnsRangeWhenStartYearIsLessThanCurrentYear(\DateTimeZone $timeZone): void + { + $twoYearsAgo = new \DateTimeImmutable( + '-2 years', + $timeZone + ); + + $now = new \DateTimeImmutable( + 'now', + $timeZone + ); + + $start = Year::fromString($twoYearsAgo->format('Y')); + + $range = Range::since( + $start, + $timeZone + ); + + self::assertInstanceOf(Range::class, $range); + + $expected = \sprintf( + '%s-%s', + $start->toString(), + $now->format('Y') + ); + + self::assertSame($expected, $range->toString()); + } + + public function provideTimeZone(): \Generator + { + $values = [ + 'America/New_York', + 'Europe/Berlin', + 'UTC', + ]; + + foreach ($values as $key => $value) { + yield $key => [ + new \DateTimeZone($value), + ]; + } + } +} diff --git a/test/Unit/YearTest.php b/test/Unit/YearTest.php index b4c59e73..478573a2 100644 --- a/test/Unit/YearTest.php +++ b/test/Unit/YearTest.php @@ -90,4 +90,50 @@ public function provideValidValue(): \Generator ]; } } + + public function testEqualsReturnsFalseWhenValueIsDifferent(): void + { + $faker = self::faker()->unique(); + + $one = Year::fromString($faker->year); + $two = Year::fromString($faker->year); + + self::assertFalse($one->equals($two)); + } + + public function testEqualsReturnsTrueWhenValueIsSame(): void + { + $value = self::faker()->year; + + $one = Year::fromString($value); + $two = Year::fromString($value); + + self::assertTrue($one->equals($two)); + } + + public function testGreaterThanReturnsFalseWhenValueIsEqual(): void + { + $value = self::faker()->year; + + $one = Year::fromString($value); + $two = Year::fromString($value); + + self::assertFalse($one->greaterThan($two)); + } + + public function testGreaterThanReturnsFalseWhenValueIsLess(): void + { + $one = Year::fromString('2019'); + $two = Year::fromString('2020'); + + self::assertFalse($one->greaterThan($two)); + } + + public function testGreaterThanReturnsTrueWhenValueIsGreater(): void + { + $one = Year::fromString('2020'); + $two = Year::fromString('2019'); + + self::assertTrue($one->greaterThan($two)); + } }