packages/sql-fixture/tests/Unit/Plan/PlanStructureExceptionTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Plan;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\Attributes\Test;
9use PHPUnit\Framework\Attributes\UsesClass;
10use PHPUnit\Framework\TestCase;
11use SqlFixture\Plan\ColumnRef;
12use SqlFixture\Plan\PlanStructureException;
13
14#[CoversClass(PlanStructureException::class)]
15#[UsesClass(ColumnRef::class)]
16#[UsesClass(\SqlFixture\Plan\FixturePlan::class)]
17#[UsesClass(\SqlFixture\Plan\PlanParser::class)]
18#[UsesClass(\SqlFixture\Plan\PlanPrinter::class)]
19#[UsesClass(\SqlFixture\Plan\PlanSyntaxException::class)]
20#[UsesClass(\SqlFixture\Plan\Relation::class)]
21#[UsesClass(\SqlFixture\Plan\RelationKind::class)]
22#[UsesClass(\SqlFixture\Plan\RelationSide::class)]
23#[UsesClass(\SqlFixture\Plan\Parsing\PlanStatements::class)]
24#[UsesClass(\SqlFixture\Plan\Parsing\RelationCursor::class)]
25#[UsesClass(\SqlFixture\Plan\Parsing\RelationReader::class)]
26#[UsesClass(\SqlFixture\Plan\Printing\PlanTables::class)]
27#[UsesClass(\SqlFixture\Plan\Printing\RelationGroups::class)]
28#[UsesClass(\SqlFixture\Plan\Printing\StatementPrinter::class)]
29#[UsesClass(\SqlFixture\Plan\Validation\PlanValidation::class)]
30#[UsesClass(\SqlFixture\Plan\Validation\TableName::class)]
31#[UsesClass(\SqlFixture\Plan\Exception\DuplicateColumnBindingException::class)]
32#[UsesClass(\SqlFixture\Plan\Exception\CyclicDependencyException::class)]
33#[UsesClass(\SqlFixture\Plan\Exception\UnboundedSelfReferenceException::class)]
34#[UsesClass(\SqlFixture\Plan\Choice\ChoiceValidation::class)]
35#[UsesClass(\SqlFixture\Plan\Choice\PlanContents::class)]
36final class PlanStructureExceptionTest extends TestCase
37{
38 #[Test]
39 public function testColumnsBoundTwiceNamesTheColumnAndBothParents(): void
40 {
41 $message = (new \SqlFixture\Plan\Exception\DuplicateColumnBindingException(
42 ColumnRef::of('b', 'x'),
43 ColumnRef::of('a', 'id'),
44 ColumnRef::of('c', 'id')
45 ))->getMessage();
46
47 self::assertSame(
48 'b.x is bound to a.id and to c.id. A column can reference one parent, so one of '
49 . 'the two relations has to go.',
50 $message
51 );
52 }
53
54 #[Test]
55 public function testCycleShowsTheLoopClosingBackOnItself(): void
56 {
57 $message = (new \SqlFixture\Plan\Exception\CyclicDependencyException(['a', 'b', 'c']))->getMessage();
58
59 self::assertSame(
60 'The plan contains cyclic dependencies among: a, b, c. No generation order satisfies them.',
61 $message
62 );
63 }
64
65 #[Test]
66 public function testUnboundedSelfReferenceSuggestsTheOptionalMarker(): void
67 {
68 $message = (new \SqlFixture\Plan\Exception\UnboundedSelfReferenceException(
69 'category',
70 'category.id < category.parent_id'
71 ))->getMessage();
72
73 self::assertSame(
74 'The relation category.id < category.parent_id makes every category row need '
75 . 'another one, without end. Mark the child optional with ? so the chain can stop.',
76 $message
77 );
78 }
79
80}
81