238 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			PHP
		
	
	
			
		
		
	
	
			238 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			PHP
		
	
	
<?php
 | 
						||
declare(strict_types = 1);
 | 
						||
 | 
						||
namespace LanguageServer\Tests\Server;
 | 
						||
 | 
						||
use PHPUnit\Framework\TestCase;
 | 
						||
use LanguageServer\Tests\MockProtocolStream;
 | 
						||
use LanguageServer\{
 | 
						||
    Server, LanguageClient, PhpDocumentLoader, DefinitionResolver
 | 
						||
};
 | 
						||
use LanguageServer\Index\{ProjectIndex, DependenciesIndex, Index};
 | 
						||
use LanguageServer\ContentRetriever\FileSystemContentRetriever;
 | 
						||
use LanguageServer\Protocol\{Position, Location, Range};
 | 
						||
use function LanguageServer\pathToUri;
 | 
						||
 | 
						||
abstract class ServerTestCase extends TestCase
 | 
						||
{
 | 
						||
    /**
 | 
						||
     * @var Server\TextDocument
 | 
						||
     */
 | 
						||
    protected $textDocument;
 | 
						||
 | 
						||
    /**
 | 
						||
     * @var Server\Workspace
 | 
						||
     */
 | 
						||
    protected $workspace;
 | 
						||
 | 
						||
    /**
 | 
						||
     * @var PhpDocumentLoader
 | 
						||
     */
 | 
						||
    protected $documentLoader;
 | 
						||
 | 
						||
    /**
 | 
						||
     * Map from FQN to Location of definition
 | 
						||
     *
 | 
						||
     * @var Location[]
 | 
						||
     */
 | 
						||
    private $definitionLocations;
 | 
						||
 | 
						||
    /**
 | 
						||
     * Map from FQN to array of reference Locations
 | 
						||
     *
 | 
						||
     * @var Location[][]
 | 
						||
     */
 | 
						||
    private $referenceLocations;
 | 
						||
 | 
						||
    public function setUp()
 | 
						||
    {
 | 
						||
        $sourceIndex       = new Index;
 | 
						||
        $dependenciesIndex = new DependenciesIndex;
 | 
						||
        $projectIndex      = new ProjectIndex($sourceIndex, $dependenciesIndex);
 | 
						||
        $projectIndex->setComplete();
 | 
						||
 | 
						||
        $definitionResolver   = new DefinitionResolver($projectIndex);
 | 
						||
        $client               = new LanguageClient(new MockProtocolStream, new MockProtocolStream);
 | 
						||
        $this->documentLoader = new PhpDocumentLoader(new FileSystemContentRetriever, $projectIndex, $definitionResolver);
 | 
						||
        $this->textDocument   = new Server\TextDocument($this->documentLoader, $definitionResolver, $client, $projectIndex);
 | 
						||
        $this->workspace      = new Server\Workspace($client, $projectIndex, $dependenciesIndex, $sourceIndex, null, $this->documentLoader);
 | 
						||
 | 
						||
        $globalSymbolsUri    = pathToUri(realpath(__DIR__ . '/../../fixtures/global_symbols.php'));
 | 
						||
        $globalReferencesUri = pathToUri(realpath(__DIR__ . '/../../fixtures/global_references.php'));
 | 
						||
        $symbolsUri          = pathToUri(realpath(__DIR__ . '/../../fixtures/symbols.php'));
 | 
						||
        $referencesUri       = pathToUri(realpath(__DIR__ . '/../../fixtures/references.php'));
 | 
						||
        $useUri              = pathToUri(realpath(__DIR__ . '/../../fixtures/use.php'));
 | 
						||
 | 
						||
        $this->documentLoader->load($symbolsUri)->wait();
 | 
						||
        $this->documentLoader->load($referencesUri)->wait();
 | 
						||
        $this->documentLoader->load($globalSymbolsUri)->wait();
 | 
						||
        $this->documentLoader->load($globalReferencesUri)->wait();
 | 
						||
        $this->documentLoader->load($useUri)->wait();
 | 
						||
 | 
						||
        // @codingStandardsIgnoreStart
 | 
						||
        $this->definitionLocations = [
 | 
						||
 | 
						||
            // Global
 | 
						||
            'TEST_DEFINE_CONSTANT'                   => new Location($globalSymbolsUri,    new Range(new Position(104, 0), new Position(104, 37))),
 | 
						||
            'TEST_CONST'                             => new Location($globalSymbolsUri,    new Range(new Position( 9,  6), new Position( 9,  22))),
 | 
						||
            'TestClass'                              => new Location($globalSymbolsUri,    new Range(new Position(20,  0), new Position(61,   1))),
 | 
						||
            'ChildClass'                             => new Location($globalSymbolsUri,    new Range(new Position(99,  0), new Position(99,  37))),
 | 
						||
            'TestTrait'                              => new Location($globalSymbolsUri,    new Range(new Position(63,  0), new Position(66,   1))),
 | 
						||
            'TestInterface'                          => new Location($globalSymbolsUri,    new Range(new Position(68,  0), new Position(71,   1))),
 | 
						||
            'TestClass::TEST_CLASS_CONST'            => new Location($globalSymbolsUri,    new Range(new Position(27, 10), new Position(27,  32))),
 | 
						||
            'TestClass::testProperty'                => new Location($globalSymbolsUri,    new Range(new Position(41, 11), new Position(41,  24))),
 | 
						||
            'TestClass::staticTestProperty'          => new Location($globalSymbolsUri,    new Range(new Position(34, 18), new Position(34,  37))),
 | 
						||
            'TestClass::staticTestMethod()'          => new Location($globalSymbolsUri,    new Range(new Position(46,  4), new Position(49,   5))),
 | 
						||
            'TestClass::testMethod()'                => new Location($globalSymbolsUri,    new Range(new Position(57,  4), new Position(60,   5))),
 | 
						||
            'test_function()'                        => new Location($globalSymbolsUri,    new Range(new Position(78,  0), new Position(81,   1))),
 | 
						||
            'UnusedClass'                            => new Location($globalSymbolsUri,    new Range(new Position(111, 0), new Position(118,  1))),
 | 
						||
            'UnusedClass::unusedProperty'            => new Location($globalSymbolsUri,    new Range(new Position(113,11), new Position(113, 26))),
 | 
						||
            'UnusedClass::unusedMethod'              => new Location($globalSymbolsUri,    new Range(new Position(115, 4), new Position(117,  5))),
 | 
						||
            'whatever()'                             => new Location($globalReferencesUri, new Range(new Position(21,  0), new Position(23,   1))),
 | 
						||
 | 
						||
            // Namespaced
 | 
						||
            'TestNamespace'                                => new Location($symbolsUri,    new Range(new Position( 2, 0), new Position( 2, 24))),
 | 
						||
            'SecondTestNamespace'                          => new Location($useUri,        new Range(new Position( 2, 0), new Position( 2, 30))),
 | 
						||
            'TestNamespace\\TEST_CONST'                    => new Location($symbolsUri,    new Range(new Position( 9,  6), new Position( 9, 22))),
 | 
						||
            'TestNamespace\\TestClass'                     => new Location($symbolsUri,    new Range(new Position(20,  0), new Position(61,  1))),
 | 
						||
            'TestNamespace\\ChildClass'                    => new Location($symbolsUri,    new Range(new Position(99,  0), new Position(99, 37))),
 | 
						||
            'TestNamespace\\TestTrait'                     => new Location($symbolsUri,    new Range(new Position(63,  0), new Position(66,  1))),
 | 
						||
            'TestNamespace\\TestInterface'                 => new Location($symbolsUri,    new Range(new Position(68,  0), new Position(71,  1))),
 | 
						||
            'TestNamespace\\TestClass::TEST_CLASS_CONST'   => new Location($symbolsUri,    new Range(new Position(27, 10), new Position(27,  32))),
 | 
						||
            'TestNamespace\\TestClass::testProperty'       => new Location($symbolsUri,    new Range(new Position(41, 11), new Position(41,  24))),
 | 
						||
            'TestNamespace\\TestClass::staticTestProperty' => new Location($symbolsUri,    new Range(new Position(34, 18), new Position(34,  37))),
 | 
						||
            'TestNamespace\\TestClass::staticTestMethod()' => new Location($symbolsUri,    new Range(new Position(46,  4), new Position(49,   5))),
 | 
						||
            'TestNamespace\\TestClass::testMethod()'       => new Location($symbolsUri,    new Range(new Position(57,  4), new Position(60,   5))),
 | 
						||
            'TestNamespace\\test_function()'               => new Location($symbolsUri,    new Range(new Position(78,  0), new Position(81,   1))),
 | 
						||
            'TestNamespace\\whatever()'                    => new Location($referencesUri, new Range(new Position(21,  0), new Position(23,   1))),
 | 
						||
            'TestNamespace\\Example'                       => new Location($symbolsUri,    new Range(new Position(101, 0), new Position(104,  1))),
 | 
						||
            'TestNamespace\\Example::__construct'          => new Location($symbolsUri,    new Range(new Position(102, 4), new Position(102, 36))),
 | 
						||
            'TestNamespace\\Example::__destruct'           => new Location($symbolsUri,    new Range(new Position(103, 4), new Position(103, 35)))
 | 
						||
        ];
 | 
						||
 | 
						||
        $this->referenceLocations = [
 | 
						||
 | 
						||
            // Namespaced
 | 
						||
            'TestNamespace' => [
 | 
						||
                0 => new Location($referencesUri, new Range(new Position(31, 13), new Position(31, 40))), // use function TestNamespace\test_function;
 | 
						||
                1 => new Location($useUri,        new Range(new Position( 4,  4), new Position( 4, 27))), // use TestNamespace\TestClass;
 | 
						||
                2 => new Location($useUri,        new Range(new Position( 5,  4), new Position( 5, 18)))  // use TestNamespace\{TestTrait, TestInterface};
 | 
						||
            ],
 | 
						||
            'TestNamespace\\TEST_CONST' => [
 | 
						||
                0 => new Location($referencesUri, new Range(new Position(29,  5), new Position(29, 15)))
 | 
						||
            ],
 | 
						||
            'TestNamespace\\TestClass' => [
 | 
						||
                0 => new Location($symbolsUri,    new Range(new Position(48, 13), new Position(48, 17))), // echo self::TEST_CLASS_CONST;
 | 
						||
                1 => new Location($symbolsUri   , new Range(new Position(99, 25), new Position(99, 34))), // class ChildClass extends TestClass {}
 | 
						||
                2 => new Location($referencesUri, new Range(new Position( 4, 11), new Position( 4, 20))), // $obj = new TestClass();
 | 
						||
                3 => new Location($referencesUri, new Range(new Position( 7,  0), new Position( 7,  9))), // TestClass::staticTestMethod();
 | 
						||
                4 => new Location($referencesUri, new Range(new Position( 8,  5), new Position( 8, 14))), // echo TestClass::$staticTestProperty;
 | 
						||
                5 => new Location($referencesUri, new Range(new Position( 9,  5), new Position( 9, 14))), // TestClass::TEST_CLASS_CONST;
 | 
						||
                6 => new Location($referencesUri, new Range(new Position(21, 18), new Position(21, 27))), // function whatever(TestClass $param)
 | 
						||
                7 => new Location($referencesUri, new Range(new Position(21, 37), new Position(21, 46))), // function whatever(TestClass $param): TestClass
 | 
						||
                8 => new Location($referencesUri, new Range(new Position(39,  0), new Position(39,  9))), // TestClass::$staticTestProperty[123]->testProperty;
 | 
						||
                9 => new Location($useUri,        new Range(new Position( 4,  4), new Position( 4, 27))), // use TestNamespace\TestClass;
 | 
						||
            ],
 | 
						||
            'TestNamespace\\TestChild' => [
 | 
						||
                0 => new Location($referencesUri, new Range(new Position(42,  5), new Position(42, 25))), // echo $child->testProperty;
 | 
						||
            ],
 | 
						||
            'TestNamespace\\TestInterface' => [
 | 
						||
                0 => new Location($symbolsUri,    new Range(new Position(20, 27), new Position(20, 40))), // class TestClass implements TestInterface
 | 
						||
                1 => new Location($symbolsUri,    new Range(new Position(57, 48), new Position(57, 61))), // public function testMethod($testParameter): TestInterface
 | 
						||
                2 => new Location($referencesUri, new Range(new Position(33, 20), new Position(33, 33)))  // if ($abc instanceof TestInterface)
 | 
						||
            ],
 | 
						||
            'TestNamespace\\TestClass::TEST_CLASS_CONST' => [
 | 
						||
                0 => new Location($symbolsUri,    new Range(new Position(48, 13), new Position(48, 35))), // echo self::TEST_CLASS_CONSTANT
 | 
						||
                1 => new Location($referencesUri, new Range(new Position( 9,  5), new Position( 9, 32)))
 | 
						||
            ],
 | 
						||
            'TestNamespace\\TestClass::testProperty' => [
 | 
						||
                0 => new Location($symbolsUri,    new Range(new Position(59,  8), new Position(59, 27))), // $this->testProperty = $testParameter;
 | 
						||
                1 => new Location($referencesUri, new Range(new Position( 6,  5), new Position( 6, 23))), // echo $obj->testProperty;
 | 
						||
                2 => new Location($referencesUri, new Range(new Position(38,  0), new Position(38, 18))), // $obj->testProperty->testMethod();
 | 
						||
                3 => new Location($referencesUri, new Range(new Position(39,  0), new Position(39, 49)))  // TestClass::$staticTestProperty[123]->testProperty;
 | 
						||
            ],
 | 
						||
            'TestNamespace\\TestClass::staticTestProperty' => [
 | 
						||
                0 => new Location($referencesUri, new Range(new Position( 8,  16), new Position( 8, 35))), // echo TestClass::$staticTestProperty;
 | 
						||
                1 => new Location($referencesUri, new Range(new Position(39,  11), new Position(39, 30)))  // TestClass::$staticTestProperty[123]->testProperty;
 | 
						||
            ],
 | 
						||
            'TestNamespace\\TestClass::staticTestMethod()' => [
 | 
						||
                0 => new Location($referencesUri, new Range(new Position( 7,  0), new Position( 7, 27)))
 | 
						||
            ],
 | 
						||
            'TestNamespace\\TestClass::testMethod()' => [
 | 
						||
                0 => new Location($referencesUri, new Range(new Position( 5,  0), new Position( 5, 16))), // $obj->testMethod();
 | 
						||
                1 => new Location($referencesUri, new Range(new Position(38,  0), new Position(38, 30))), // $obj->testProperty->testMethod();
 | 
						||
                2 => new Location($referencesUri, new Range(new Position(42,  5), new Position(42, 23)))  // $child->testMethod();
 | 
						||
            ],
 | 
						||
            'TestNamespace\\test_function()' => [
 | 
						||
                0 => new Location($referencesUri, new Range(new Position(10,  0), new Position(10, 13))),
 | 
						||
                1 => new Location($referencesUri, new Range(new Position(31, 13), new Position(31, 40)))
 | 
						||
            ],
 | 
						||
 | 
						||
            // Global
 | 
						||
            'TEST_DEFINE_CONSTANT' => [
 | 
						||
                0 => new Location($globalSymbolsUri,    new Range(new Position(106, 6), new Position(106, 26)))
 | 
						||
            ],
 | 
						||
            'TEST_CONST' => [
 | 
						||
                0 => new Location($referencesUri,       new Range(new Position(29,  5), new Position(29, 15))),
 | 
						||
                1 => new Location($globalReferencesUri, new Range(new Position(29,  5), new Position(29, 15)))
 | 
						||
            ],
 | 
						||
            'TestClass' => [
 | 
						||
                0 => new Location($globalSymbolsUri,    new Range(new Position(48, 13), new Position(48, 17))), // echo self::TEST_CLASS_CONST;
 | 
						||
                1 => new Location($globalSymbolsUri,    new Range(new Position(99, 25), new Position(99, 34))), // class ChildClass extends TestClass {}
 | 
						||
                2 => new Location($globalReferencesUri, new Range(new Position( 4, 11), new Position( 4, 20))), // $obj = new TestClass();
 | 
						||
                3 => new Location($globalReferencesUri, new Range(new Position( 7,  0), new Position( 7,  9))), // TestClass::staticTestMethod();
 | 
						||
                4 => new Location($globalReferencesUri, new Range(new Position( 8,  5), new Position( 8, 14))), // echo TestClass::$staticTestProperty;
 | 
						||
                5 => new Location($globalReferencesUri, new Range(new Position( 9,  5), new Position( 9, 14))), // TestClass::TEST_CLASS_CONST;
 | 
						||
                6 => new Location($globalReferencesUri, new Range(new Position(21, 18), new Position(21, 27))), // function whatever(TestClass $param)
 | 
						||
                7 => new Location($globalReferencesUri, new Range(new Position(21, 37), new Position(21, 46))), // function whatever(TestClass $param): TestClass
 | 
						||
                8 => new Location($globalReferencesUri, new Range(new Position(39,  0), new Position(39,  9))), // TestClass::$staticTestProperty[123]->testProperty;
 | 
						||
            ],
 | 
						||
            'TestChild' => [
 | 
						||
                0 => new Location($globalReferencesUri, new Range(new Position(42,  5), new Position(42, 25))), // echo $child->testProperty;
 | 
						||
            ],
 | 
						||
            'TestInterface' => [
 | 
						||
                0 => new Location($globalSymbolsUri,    new Range(new Position(20, 27), new Position(20, 40))), // class TestClass implements TestInterface
 | 
						||
                1 => new Location($globalSymbolsUri,    new Range(new Position(57, 49), new Position(57, 61))), // public function testMethod($testParameter) : TestInterface
 | 
						||
                2 => new Location($globalReferencesUri, new Range(new Position(33, 20), new Position(33, 33)))  // if ($abc instanceof TestInterface)
 | 
						||
            ],
 | 
						||
            'TestClass::TEST_CLASS_CONST' => [
 | 
						||
                0 => new Location($globalSymbolsUri,    new Range(new Position(48, 13), new Position(48, 35))), // echo self::TEST_CLASS_CONSTANT
 | 
						||
                1 => new Location($globalReferencesUri, new Range(new Position( 9,  5), new Position( 9, 32)))
 | 
						||
            ],
 | 
						||
            'TestClass::testProperty' => [
 | 
						||
                0 => new Location($globalSymbolsUri,    new Range(new Position(59,  8), new Position(59, 27))), // $this->testProperty = $testParameter;
 | 
						||
                1 => new Location($globalReferencesUri, new Range(new Position( 6,  5), new Position( 6, 23))), // echo $obj->testProperty;
 | 
						||
                2 => new Location($globalReferencesUri, new Range(new Position(38,  0), new Position(38, 18))), // $obj->testProperty->testMethod();
 | 
						||
                3 => new Location($globalReferencesUri, new Range(new Position(39,  0), new Position(39, 49)))  // TestClass::$staticTestProperty[123]->testProperty;
 | 
						||
            ],
 | 
						||
            'TestClass::staticTestProperty' => [
 | 
						||
                0 => new Location($globalReferencesUri, new Range(new Position( 8,  16), new Position( 8, 35))), // echo TestClass::$staticTestProperty;
 | 
						||
                1 => new Location($globalReferencesUri, new Range(new Position(39,  11), new Position(39, 30)))  // TestClass::$staticTestProperty[123]->testProperty;
 | 
						||
            ],
 | 
						||
            'TestClass::staticTestMethod()' => [
 | 
						||
                0 => new Location($globalReferencesUri, new Range(new Position( 7,  0), new Position( 7, 27)))
 | 
						||
            ],
 | 
						||
            'TestClass::testMethod()' => [
 | 
						||
                0 => new Location($globalReferencesUri, new Range(new Position( 5,  0), new Position( 5, 16))), // $obj->testMethod();
 | 
						||
                1 => new Location($globalReferencesUri, new Range(new Position(38,  0), new Position(38, 30))), // $obj->testProperty->testMethod();
 | 
						||
                2 => new Location($globalReferencesUri, new Range(new Position(42,  5), new Position(42, 23)))  // $child->testMethod();
 | 
						||
            ],
 | 
						||
            'test_function()' => [
 | 
						||
                0 => new Location($globalReferencesUri, new Range(new Position(10,  0), new Position(10, 13))),
 | 
						||
                1 => new Location($globalReferencesUri, new Range(new Position(31, 13), new Position(31, 40)))
 | 
						||
            ]
 | 
						||
        ];
 | 
						||
        // @codingStandardsIgnoreEnd
 | 
						||
    }
 | 
						||
 | 
						||
    protected function getDefinitionLocation(string $fqn): Location
 | 
						||
    {
 | 
						||
        return $this->definitionLocations[$fqn];
 | 
						||
    }
 | 
						||
 | 
						||
    protected function getReferenceLocations(string $fqn): array
 | 
						||
    {
 | 
						||
        return $this->referenceLocations[$fqn];
 | 
						||
    }
 | 
						||
}
 |