packages/deriver/tests/Unit/Deriver/Evaluator/Predicate/BranchTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Deriver\Evaluator\Predicate;
6
7use Deriver\Deriver\Evaluator\Call\Evaluators;
8use Deriver\Deriver\Evaluator\Enumeration\Choices;
9use Deriver\Deriver\Evaluator\Evaluator;
10use Deriver\Deriver\Evaluator\EvaluatorConfig;
11use Deriver\Deriver\Evaluator\Index\DefinitionIndex;
12use Deriver\Deriver\Evaluator\Micro\Request;
13use Deriver\Deriver\Evaluator\Predicate\Branch;
14use Deriver\Deriver\Evaluator\Request\Budget;
15use Deriver\Deriver\Evaluator\Scope\Context;
16use Deriver\Deriver\Evaluator\Scope\Frame;
17use Deriver\Deriver\Evaluator\Term;
18use Deriver\Deriver\Lowerer\Declaration\Index;
19use Deriver\Deriver\Parser\Parser;
20use Deriver\Deriver\Parser\ParserConfig;
21use Deriver\Deriver\Resolver\Resolver;
22use Deriver\Deriver\Sources\Source;
23use PHPUnit\Framework\Attributes\CoversNothing;
24use PHPUnit\Framework\TestCase;
25
26#[CoversNothing]
27final class BranchTest extends TestCase
28{
29 public function testConditionDefaultsToBothBranchesWithoutOpeningItsInput(): void
30 {
31 $source = 'function subject(){return missing();}';
32 $tree = (new Resolver())->resolve((new Parser(new ParserConfig('8.3')))->parse(new Source('a.php', '<?php ' . $source)));
33 $index = new DefinitionIndex(new Index('s', [$tree]));
34 $config = new EvaluatorConfig();
35 $engine = new Evaluator(new Context($index, $config, new Evaluators($config->target), new Budget()));
36 $graph = $index->graph('subject');
37 self::assertNotNull($graph);
38 $frame = new Frame($graph, 'source:subject');
39 $result = (new Branch($engine))->condition($frame, $graph->returns()[0][1], 32);
40 self::assertCount(2, iterator_to_array((new Choices())->alternatives($result)));
41 self::assertSame(0, $engine->context->referenceExpansions);
42 }
43
44 public function testEvaluateRequiresNoInstructionOrInputForDefaultSelection(): void
45 {
46 $source = 'function subject(){return 42;}';
47 $tree = (new Resolver())->resolve((new Parser(new ParserConfig('8.3')))->parse(new Source('a.php', '<?php ' . $source)));
48 $index = new DefinitionIndex(new Index('s', [$tree]));
49 $config = new EvaluatorConfig();
50 $engine = new Evaluator(new Context($index, $config, new Evaluators($config->target), new Budget()));
51 $graph = $index->graph('subject');
52 self::assertNotNull($graph);
53 $frame = new Frame($graph, 'source:subject');
54 $site = new \Deriver\Deriver\Evaluator\Micro\Site('branch', '', $graph->body->source, static fn (): Term => Term::constant(99), static fn (): Term => Term::constant(false));
55 $result = (new Branch($engine))->evaluate(new Request($engine, $frame, null, 32, site: $site));
56 self::assertSame([true,false], array_map(static fn (array $row) => $row[0]->native(), iterator_to_array((new Choices())->alternatives($result))));
57 }
58 public function testInputRejectsAnAbsentConditionOperand(): void
59 {
60 $source = 'function subject(){return 42;}';
61 $tree = (new Resolver())->resolve((new Parser(new ParserConfig('8.3')))->parse(new Source('a.php', '<?php ' . $source)));
62 $index = new DefinitionIndex(new Index('s', [$tree]));
63 $config = new EvaluatorConfig();
64 $engine = new Evaluator(new Context($index, $config, new Evaluators($config->target), new Budget()));
65 $graph = $index->graph('subject');
66 self::assertNotNull($graph);
67 $frame = new Frame($graph, 'source:subject');
68 $this->expectException(\Deriver\Exception\EvaluationContractException::class);
69 (new Branch($engine))->input($frame, $graph->returns()[0][1], 1, 32, true);
70 }
71
72}
73