packages/sql-catalog/tests/Unit/Core/Analysis/FunctionScopeTest.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\FunctionScope;
10
11#[CoversClass(FunctionScope::class)]
12final class FunctionScopeTest extends TestCase
13{
14 public function testEnterMovesIntoTheFollowedFunction(): void
15 {
16 $scope = (new FunctionScope('a.php'))->enter('App\\R::find', 'App\\R', 'b.php');
17 self::assertSame('b.php', $scope->file);
18 self::assertSame('App\\R::find', $scope->function);
19 self::assertSame('App\\R', $scope->className);
20 }
21
22 public function testEnterKeepsTheCurrentFileWhenTheCalleeNamesNone(): void
23 {
24 self::assertSame('a.php', (new FunctionScope('a.php'))->enter('f', null, '')->file);
25 }
26
27 public function testDepthCountsTheCallsFollowedFromTheBodyTheWalkStartedIn(): void
28 {
29 $scope = new FunctionScope('a.php', 'root', null, ['root']);
30
31 self::assertSame(0, $scope->depth());
32 self::assertSame(2, $scope->enter('f', null, '')->enter('g', null, '')->depth());
33 }
34
35 public function testDepthIsZeroBeforeAnythingIsFollowed(): void
36 {
37 self::assertSame(0, (new FunctionScope('a.php'))->depth());
38 }
39
40 public function testIsFollowingDetectsRecursion(): void
41 {
42 $scope = (new FunctionScope('a.php'))->enter('f', null, '');
43 self::assertTrue($scope->isFollowing('f'));
44 self::assertFalse($scope->isFollowing('g'));
45 }
46
47 public function testTopLevelCodeIsNamedForIt(): void
48 {
49 self::assertSame(FunctionScope::MAIN, (new FunctionScope('a.php'))->function);
50 }
51}
52