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