Skip to content

Commit 1940635

Browse files
author
Stephan Wentz
committed
fix: Add fromTo generator
1 parent d8be666 commit 1940635

File tree

6 files changed

+112
-9
lines changed

6 files changed

+112
-9
lines changed

phpstan.neon.dist

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
parameters:
22
level: max
3+
treatPhpDocTypesAsCertain: false
34
paths:
45
- src
56
- tests
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Brainbits\Period\Exception;
6+
7+
use Brainbits\Period\Period;
8+
use InvalidArgumentException;
9+
10+
use function sprintf;
11+
12+
final class MismatchingPeriods extends InvalidArgumentException implements PeriodException
13+
{
14+
public static function differ(Period $period, Period $otherPeriod): self
15+
{
16+
return new self(sprintf(
17+
'Both periods must have the same class, %s and %s given.',
18+
$period::class,
19+
$otherPeriod::class,
20+
));
21+
}
22+
}

src/PeriodFactory.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
namespace Brainbits\Period;
66

77
use Brainbits\Period\Exception\InvalidPeriodIdentifier;
8+
use Brainbits\Period\Exception\MismatchingPeriods;
89
use DateTimeImmutable;
10+
use Generator;
911
use Psr\Clock\ClockInterface;
1012

1113
use function sprintf;
@@ -210,4 +212,25 @@ public function fromIdentifier(string $periodIdentifier): Period
210212
default => throw InvalidPeriodIdentifier::unknownPeriodIdentifier($periodIdentifier),
211213
};
212214
}
215+
216+
/**
217+
* @param T $period
218+
* @param T $toPeriod
219+
*
220+
* @return Generator<T>
221+
*
222+
* @template T of Period
223+
*/
224+
public function fromTo(Period $period, Period $toPeriod): Generator
225+
{
226+
if ($period::class !== $toPeriod::class) {
227+
throw MismatchingPeriods::differ($period, $toPeriod);
228+
}
229+
230+
do {
231+
yield $period;
232+
233+
$period = $this->next($period);
234+
} while ($period->getPeriodString() < $toPeriod->getPeriodString());
235+
}
213236
}

src/Twig/Extension/PeriodExtension.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public function parsePeriodIdentifier(string $periodIdentifier): Period
5959
return $this->periodFactory->fromIdentifier($periodIdentifier);
6060
}
6161

62-
public function monthPeriod($periodString): MonthPeriod|null
62+
public function monthPeriod(string $periodString): MonthPeriod|null
6363
{
6464
return $periodString ? MonthPeriod::createFromPeriodString($periodString) : null;
6565
}

tests/PeriodFactoryTest.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace Brainbits\PeriodTest;
66

77
use Brainbits\Period\DayPeriod;
8+
use Brainbits\Period\Exception\MismatchingPeriods;
89
use Brainbits\Period\MonthPeriod;
910
use Brainbits\Period\Period;
1011
use Brainbits\Period\PeriodFactory;
@@ -20,6 +21,8 @@
2021
use PHPUnit\Framework\Attributes\DataProvider;
2122
use PHPUnit\Framework\TestCase;
2223

24+
use function iterator_to_array;
25+
2326
#[CoversClass(PeriodFactory::class)]
2427
final class PeriodFactoryTest extends TestCase
2528
{
@@ -656,4 +659,34 @@ public function testTranslationPeriods(Period $period, string $expected): void
656659
{
657660
self::assertSame($expected, $this->factory->getTranslationKey($period));
658661
}
662+
663+
public function testFromToThrowMismatchingException(): void
664+
{
665+
$this->expectException(MismatchingPeriods::class);
666+
// phpcs:ignore Generic.Files.LineLength.TooLong
667+
$this->expectExceptionMessage('Both periods must have the same class, Brainbits\Period\MonthPeriod and Brainbits\Period\WeekPeriod given.');
668+
669+
$fromTo = $this->factory->fromTo(
670+
new MonthPeriod(new DateTimeImmutable('2024-03')),
671+
new WeekPeriod(new DateTimeImmutable('2024-07')),
672+
);
673+
674+
iterator_to_array($fromTo);
675+
}
676+
677+
public function testFromTo(): void
678+
{
679+
$fromTo = $this->factory->fromTo(
680+
new MonthPeriod(new DateTimeImmutable('2024-03')),
681+
new MonthPeriod(new DateTimeImmutable('2024-07')),
682+
);
683+
684+
$result = iterator_to_array($fromTo);
685+
self::assertCount(4, $result);
686+
self::assertContainsOnlyInstancesOf(MonthPeriod::class, $result);
687+
self::assertSame('2024-03', $result[0]->getPeriodString());
688+
self::assertSame('2024-04', $result[1]->getPeriodString());
689+
self::assertSame('2024-05', $result[2]->getPeriodString());
690+
self::assertSame('2024-06', $result[3]->getPeriodString());
691+
}
659692
}

tests/Twig/Extension/PeriodExtensionTest.php

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,18 +36,42 @@ public function setUp(): void
3636

3737
public function testGetFunctions(): void
3838
{
39-
$this->assertContainsOnlyInstancesOf(TwigFunction::class, $this->extension->getFunctions());
39+
$this->assertContainsOnlyInstancesOf(
40+
TwigFunction::class,
41+
$this->extension->getFunctions(),
42+
);
4043
}
4144

4245
public function testParsePeriodIdentifier(): void
4346
{
44-
$this->assertEquals($this->periodFactory->currentDay(), $this->extension->parsePeriodIdentifier('day#2018-06-15'));
45-
$this->assertEquals($this->periodFactory->currentWeek(), $this->extension->parsePeriodIdentifier('week#2018-24'));
46-
$this->assertEquals($this->periodFactory->currentMonth(), $this->extension->parsePeriodIdentifier('month#2018-06'));
47-
$this->assertEquals($this->periodFactory->currentYear(), $this->extension->parsePeriodIdentifier('year#2018'));
48-
$this->assertEquals($this->periodFactory->currentRunningWeek(), $this->extension->parsePeriodIdentifier('running-week#2018-24'));
49-
$this->assertEquals($this->periodFactory->currentRunningMonth(), $this->extension->parsePeriodIdentifier('running-month#2018-06'));
50-
$this->assertEquals($this->periodFactory->currentRunningYear(), $this->extension->parsePeriodIdentifier('running-year#2018'));
47+
$this->assertEquals(
48+
$this->periodFactory->currentDay(),
49+
$this->extension->parsePeriodIdentifier('day#2018-06-15'),
50+
);
51+
$this->assertEquals(
52+
$this->periodFactory->currentWeek(),
53+
$this->extension->parsePeriodIdentifier('week#2018-24'),
54+
);
55+
$this->assertEquals(
56+
$this->periodFactory->currentMonth(),
57+
$this->extension->parsePeriodIdentifier('month#2018-06'),
58+
);
59+
$this->assertEquals(
60+
$this->periodFactory->currentYear(),
61+
$this->extension->parsePeriodIdentifier('year#2018'),
62+
);
63+
$this->assertEquals(
64+
$this->periodFactory->currentRunningWeek(),
65+
$this->extension->parsePeriodIdentifier('running-week#2018-24'),
66+
);
67+
$this->assertEquals(
68+
$this->periodFactory->currentRunningMonth(),
69+
$this->extension->parsePeriodIdentifier('running-month#2018-06'),
70+
);
71+
$this->assertEquals(
72+
$this->periodFactory->currentRunningYear(),
73+
$this->extension->parsePeriodIdentifier('running-year#2018'),
74+
);
5175
}
5276

5377
public function testMonthPeriod(): void

0 commit comments

Comments
 (0)