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