packages/deriver/tests/Integration/PreparedDependenciesTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Integration;
6
7use Deriver\Deriver\Candidate\Snapshot;
8use Deriver\Deriver\Evaluator\Call\Evaluators;
9use Deriver\Deriver\Evaluator\EvaluatorConfig;
10use Deriver\Deriver\Evaluator\Index\DefinitionIndex;
11use Deriver\Deriver\Evaluator\Request\ReturnQuery;
12use Deriver\Deriver\Evaluator\TargetProfile;
13use Deriver\Deriver\Lowerer\Declaration\Index;
14use Deriver\Deriver\Parser\Parser;
15use Deriver\Deriver\Parser\ParserConfig;
16use Deriver\Deriver\Publication\CandidateQuery;
17use Deriver\Deriver\Resolver\Resolver;
18use Deriver\Deriver\Sources\Source;
19use PHPUnit\Framework\Attributes\CoversNothing;
20use PHPUnit\Framework\TestCase;
21
22#[CoversNothing]
23final class PreparedDependenciesTest extends TestCase
24{
25    public function testCapturedInputsDoNotCompileUnrelatedFunctionsAndQueriesReuseTheirGraphs(): void
26    {
27        $php = '<?php function factory(){$value=7; return fn()=>$value+1;}' . implode('', array_map(static fn (int $index): string => ' function unrelated' . $index . '(){return 99;}', range(0, 199)));
28        $source = new Source('app.php', $php);
29        $program = new Index('prepared', [(new Resolver())->resolve((new Parser(new ParserConfig('8.3')))->parse($source))]);
30        $closures = array_values(array_filter($program->symbols(), static fn (string $symbol): bool => str_starts_with($symbol, 'closure:')));
31        self::assertCount(1, $closures);
32        $before = $program->graphCount();
33        $target = new TargetProfile();
34        $queries = new CandidateQuery(new DefinitionIndex($program), new EvaluatorConfig($target), new Evaluators($target), new Snapshot('prepared', [], [], $target, 'environment'));
35        $first = $queries->derive(new ReturnQuery($closures[0]));
36        $count = $program->graphCount();
37        $second = $queries->derive(new ReturnQuery($closures[0]));
38        self::assertSame(0, $before);
39        self::assertSame(8, $first[0]->result);
40        self::assertSame(8, $second[0]->result);
41        self::assertSame(2, $count);
42        self::assertSame($count, $program->graphCount());
43        self::assertSame($first[0]->evidence[0]->root->id, $second[0]->evidence[0]->root->id);
44    }
45
46    public function testGlobalInputsCompileOnlyScriptsWhichCanSupplyTheRequestedName(): void
47    {
48        $sources = [new Source('app.php', '<?php function target(){global $wanted; return $wanted;}'), new Source('values.php', '<?php $wanted=7;'), ...array_map(static fn (int $index): Source => new Source('other' . $index . '.php', '<?php $unrelated=99;'), range(0, 99))];
49        $parser = new Parser(new ParserConfig('8.3'));
50        $program = new Index('prepared', array_map(static fn (Source $source) => (new Resolver())->resolve($parser->parse($source)), $sources));
51        $target = new TargetProfile();
52        $queries = new CandidateQuery(new DefinitionIndex($program), new EvaluatorConfig($target), new Evaluators($target), new Snapshot('prepared', [], [], $target, 'environment'));
53        $result = $queries->derive(new ReturnQuery('target'));
54        self::assertSame(7, $result[0]->result);
55        self::assertSame(2, $program->graphCount());
56    }
57
58}
59