packages/deriver/tests/Unit/Deriver/Evaluator/Execution/Memory/ReferenceConstraintTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Deriver\Evaluator\Execution\Memory;
6
7use Deriver\Deriver\Evaluator\Execution\Memory\Location;
8use Deriver\Deriver\Evaluator\Execution\Memory\Memory;
9use Deriver\Deriver\Evaluator\Execution\Memory\ReferenceConstraint;
10use Deriver\Deriver\Evaluator\Term;
11use PHPUnit\Framework\Attributes\CoversClass;
12use PHPUnit\Framework\Attributes\Small;
13use PHPUnit\Framework\Attributes\UsesClass;
14use PHPUnit\Framework\TestCase;
15
16/**
17 * @covers \Deriver\Deriver\Evaluator\Execution\Memory\ReferenceConstraint
18 */
19#[CoversClass(ReferenceConstraint::class)]
20#[UsesClass(Location::class)]
21#[UsesClass(Memory::class)]
22#[UsesClass(\Deriver\Deriver\Evaluator\Scalar\Arrays::class)]
23#[UsesClass(\Deriver\Deriver\Evaluator\Scalar\Operations::class)]
24#[UsesClass(Term::class)]
25#[Small]
26final class ReferenceConstraintTest extends TestCase
27{
28    public function testFindDropsTheConstraintAfterThePropertyIsUnset(): void
29    {
30        $memory = new Memory();
31        $property = new Location('object:one', ['id']);
32        $memory->write($property, Term::constant(1));
33        $memory->propertyTypes['object:one']['id'] = 'int';
34        $reference = new Location($memory->reference($property));
35        self::assertSame(['int'], (new ReferenceConstraint())->find($memory, $reference));
36        $memory->remove($property);
37        self::assertSame([], (new ReferenceConstraint())->find($memory, $reference));
38    }
39    public function testCellDoesNotAllocateStorageForAnOrdinaryElement(): void
40    {
41        $memory = new Memory();
42        $location = $memory->allocate(Term::fromNative([1]));
43        self::assertNull((new ReferenceConstraint())->cell($memory, new Location($location->root, [0])));
44        self::assertCount(1, $memory->cells);
45    }
46    public function testFindIncludesTheDirectPropertyBeforeItsFirstReferenceEscape(): void
47    {
48        $memory = new Memory();
49        $memory->cells['object:b'] = Term::array(['x' => Term::constant(1)]);
50        $memory->propertyTypes['object:b']['x'] = 'int';
51        self::assertSame(['int'], (new ReferenceConstraint())->find($memory, new Location('object:b', ['x'])));
52        self::assertSame(\Deriver\Deriver\Evaluator\TermKind::Constant, $memory->cells['object:b']->operands['x']->kind);
53    }
54}
55