packages/sql-catalog/tests/Unit/Core/Analysis/EvaluationBudgetTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Core\Analysis;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\TestCase;
9use SqlCatalog\Core\Analysis\EvaluationBudget;
10
11#[CoversClass(EvaluationBudget::class)]
12final class EvaluationBudgetTest extends TestCase
13{
14    public function testSpendReportsWhenTheBudgetRunsOut(): void
15    {
16        $budget = new EvaluationBudget(1);
17        self::assertTrue($budget->spend());
18        self::assertFalse($budget->spend());
19    }
20
21    public function testIsExhaustedOnceMoreWasSpentThanAllowed(): void
22    {
23        $budget = new EvaluationBudget(1);
24        $budget->spend();
25        self::assertFalse($budget->isExhausted());
26        $budget->spend();
27        self::assertTrue($budget->isExhausted());
28    }
29
30    public function testIsSpentOnlyOnceFourTimesTheStepBudgetWasSpent(): void
31    {
32        $budget = new EvaluationBudget(2);
33        self::assertFalse($budget->isSpent());
34
35        array_map(static fn (int $step): bool => $budget->spend(), range(1, 8));
36        self::assertSame(8, $budget->spent());
37        self::assertTrue($budget->isExhausted());
38        self::assertFalse($budget->isSpent());
39
40        $budget->spend();
41        self::assertTrue($budget->isSpent());
42    }
43
44    public function testIsSpentIsClearedByAReset(): void
45    {
46        $budget = new EvaluationBudget(1);
47        array_map(static fn (int $step): bool => $budget->spend(), range(1, 5));
48        self::assertTrue($budget->isSpent());
49
50        $budget->reset();
51        self::assertFalse($budget->isSpent());
52    }
53
54    public function testTheReadingAllowanceIsFourTimesTheSearch(): void
55    {
56        self::assertSame(4, EvaluationBudget::READING_ALLOWANCE);
57    }
58
59    public function testSpentCountsTheStepsTaken(): void
60    {
61        $budget = new EvaluationBudget();
62        $budget->spend();
63        $budget->spend();
64        self::assertSame(2, $budget->spent());
65    }
66
67    public function testResetStartsANewFile(): void
68    {
69        $budget = new EvaluationBudget(1);
70        $budget->spend();
71        $budget->spend();
72        $budget->reset();
73        self::assertSame(0, $budget->spent());
74        self::assertFalse($budget->isExhausted());
75    }
76
77    public function testTheDefaultsBoundStepsDepthAndLoopPasses(): void
78    {
79        $budget = new EvaluationBudget();
80
81        self::assertSame(20000, $budget->maxSteps);
82        self::assertSame(4, $budget->maxDepth);
83        self::assertSame(2, $budget->maxLoopPasses);
84    }
85}
86