* * Full license available in separate LICENSE file */ /* * The only test written with the pipe operator, which needs PHP 8.5 to parse. phpunit.xml loads this file only on * PHP 8.5 and newer, so the rest of the suite still runs on PHP 8.2-8.4. */ use Ds\Map; use Kadet\Functional\Collections as c; use Kadet\Functional\Collections\Lazy as lazy; use Kadet\Functional\Exception\EmptyCollectionException; use Kadet\Functional\Predicates as p; use Kadet\Functional\Transforms as t; use PHPUnit\Framework\Attributes\RequiresPhp; final class PipeDeparture { public function __construct( public readonly string $id, public readonly string $line, public readonly string $destination, public readonly int $delay, ) { } } #[RequiresPhp('>= 8.5')] class PipeSyntaxTest extends \PHPUnit\Framework\TestCase { /** @return list */ private static function departures(): array { return [ new PipeDeparture('d1', '8', 'Stogi', 0), new PipeDeparture('d2', '8', 'Stogi', 120), new PipeDeparture('d3', '12', 'Oliwa', 30), new PipeDeparture('d4', '12', 'Oliwa', 300), new PipeDeparture('d5', '6', 'Łostowice', 0), ]; } public function testRealisticPipeline() { $late = self::departures() |> lazy\filter(p\property('delay', p\gt(60))) |> c\keyBy(t\property('id')) |> c\map(fn (PipeDeparture $departure) => "{$departure->line} → {$departure->destination}"); $this->assertInstanceOf(Map::class, $late); $this->assertSame(['d2' => '8 → Stogi', 'd4' => '12 → Oliwa'], $late->toArray()); } public function testFirstRequired() { $mostDelayed = self::departures() |> c\sortBy(t\property('delay'), descending: true) |> c\first(required: true); $this->assertSame('d4', $mostDelayed->id); } public function testFirstRequiredThrowsWhenNothingMatches() { $this->expectException(EmptyCollectionException::class); $this->expectExceptionMessage('first(): no element matched'); self::departures() |> c\first(p\property('line', p\same('2')), required: true); } public function testLazyChainReadsOnlyWhatIsNeeded() { $read = []; $line = self::departures() |> lazy\tap(function (PipeDeparture $departure) use (&$read) { $read[] = $departure->id; }) |> lazy\map(t\property('line')) |> c\find(fn (string $line) => $line === '12'); $this->assertSame('12', $line); $this->assertSame(['d1', 'd2', 'd3'], $read); } }