packages/deriver/tests/Unit/Deriver/MicroEvaluatorTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Deriver;
6
7use Deriver\Deriver\Evaluation;
8use Deriver\Deriver\EvaluationOperation;
9use Deriver\Deriver\Evaluator\Term;
10use Deriver\Deriver\MicroEvaluator;
11use Deriver\Deriver\Sources\SourceRef;
12use Deriver\Exception\InvalidInputException;
13use PHPUnit\Framework\Attributes\CoversNothing;
14use PHPUnit\Framework\Attributes\DataProvider;
15use PHPUnit\Framework\TestCase;
16
17#[CoversNothing]
18final class MicroEvaluatorTest extends TestCase
19{
20    public function testEvaluateUsesThePublicLazyInputContract(): void
21    {
22        $seen = [];
23        $evaluation = new Evaluation(EvaluationOperation::Function, 'identity', new SourceRef('s', 'a.php', 0, 10), static function (int|string $key) use (&$seen): Term {
24            $seen[] = $key;
25            return Term::constant(21);
26        });
27        $evaluator = new MicroEvaluator('app.identity', '1', EvaluationOperation::Function, '\\IDENTITY', static fn (Evaluation $input): Term => $input->input(0));
28        self::assertSame('identity', $evaluator->name);
29        self::assertSame(21, $evaluator->evaluate($evaluation)?->native());
30        self::assertSame([0], $seen);
31    }
32
33    #[DataProvider('providerInvalidDefinitions')]
34    public function testRejectsInvalidDefinitions(string $id, string $version, string $name, ?int $start, ?int $end): void
35    {
36        $this->expectException(InvalidInputException::class);
37        new MicroEvaluator($id, $version, EvaluationOperation::Function, $name, static fn (): ?Term => null, start: $start, end: $end);
38    }
39
40    /**
41     * @return iterable<string, array{string, string, string, ?int, ?int}>
42     */
43    public static function providerInvalidDefinitions(): iterable
44    {
45        yield 'missing identity' => ['', '1', 'f', null, null];
46        yield 'missing version' => ['f', '', 'f', null, null];
47        yield 'empty function' => ['f', '1', '\\', null, null];
48        yield 'negative start' => ['f', '1', 'f', -1, 3];
49        yield 'reversed range' => ['f', '1', 'f', 4, 3];
50    }
51}
52