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