packages/deriver/tests/Unit/Deriver/Sources/SourceRefTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Deriver\Sources;
6
7use Deriver\Deriver\Sources\SourceRef;
8use Deriver\Exception\InvalidInputException;
9use PHPUnit\Framework\Attributes\CoversClass;
10use PHPUnit\Framework\Attributes\DataProvider;
11use PHPUnit\Framework\Attributes\Small;
12use PHPUnit\Framework\TestCase;
13
14#[CoversClass(SourceRef::class)]
15#[Small]
16final class SourceRefTest extends TestCase
17{
18 public function testIdPreservesTheSemanticContract(): void
19 {
20 $this->expectException(InvalidInputException::class);
21 $this->expectExceptionMessage('half-open');
22 new SourceRef('s', 'a.php', 4, 3);
23 }
24
25 #[DataProvider('providerInvalidCoordinates')]
26 public function testRejectsCoordinatesOutsideHalfOpenSourceRanges(int $start, int $end, int $line, int $column): void
27 {
28 $this->expectException(InvalidInputException::class);
29 $this->expectExceptionMessage('Source ranges must be half-open and coordinates positive.');
30 new SourceRef('snapshot', 'file.php', $start, $end, $line, $column);
31 }
32
33 /**
34 * @return iterable<string,array{int,int,int,int}>
35 */
36 public static function providerInvalidCoordinates(): iterable
37 {
38 yield 'negative start' => [-1,0,1,1];
39 yield 'end before start' => [2,1,1,1];
40 yield 'zero line' => [0,0,0,1];
41 yield 'negative line' => [0,0,-1,1];
42 yield 'zero column' => [0,0,1,0];
43 yield 'negative column' => [0,0,1,-1];
44 }
45
46 public function testIdIncludesSnapshotPathAndBothByteEndpoints(): void
47 {
48 $source = new SourceRef('snapshot', 'src/file.php', 7, 29, 3, 5);
49 self::assertSame('snapshot:src/file.php:7:29', $source->id());
50 self::assertSame('snapshot', $source->snapshotId);
51 self::assertSame('src/file.php', $source->path);
52 self::assertSame(7, $source->start);
53 self::assertSame(29, $source->end);
54 self::assertSame(3, $source->line);
55 self::assertSame(5, $source->column);
56 self::assertSame('empty:file.php:0:0', (new SourceRef('empty', 'file.php', 0, 0))->id());
57 }
58}
59