file_provider = new FakeFileProvider(); $config = new TestConfig(); $providers = new Providers( $this->file_provider, new ParserInstanceCacheProvider(), null, null, new FakeFileReferenceCacheProvider(), new ProjectCacheProvider(), ); $this->codebase = new Codebase($config, $providers); $this->project_analyzer = new ProjectAnalyzer( $config, $providers, null, [], 1, null, $this->codebase, ); $this->project_analyzer->setPhpVersion('7.3', 'tests'); $this->project_analyzer->getCodebase()->store_node_types = true; $this->codebase->config->throw_exception = false; } /** * @return list */ protected function getCompletionLabels(string $content, string $class_name, string $gap): array { $this->addFile('somefile.php', $content); $this->analyzeFile('somefile.php', new Context()); $items = $this->codebase->getCompletionItemsForClassishThing($class_name, $gap, true); return array_map(fn($item) => $item->label, $items); } /** * @return iterable */ public function providerGaps(): iterable { return [ 'object-gap' => ['->'], 'static-gap' => ['::'], ]; } /** * @dataProvider providerGaps */ public function testSimpleOnceClass(string $gap): void { $content = <<<'EOF' getCompletionLabels($content, 'B\A', $gap); $expected_labels = [ '->' => [ 'magicObjProp1', 'magicObjProp2', 'magicObjMethod', 'publicObjProp', 'protectedObjProp', 'privateObjProp', 'publicObjMethod', 'protectedObjMethod', 'privateObjMethod', 'publicStaticMethod', 'protectedStaticMethod', 'privateStaticMethod', ], '::' => [ 'magicStaticMethod', 'publicStaticProp', 'protectedStaticProp', 'privateStaticProp', 'publicStaticMethod', 'protectedStaticMethod', 'privateStaticMethod', ], ]; $this->assertEqualsCanonicalizing($expected_labels[$gap], $actual_labels); } /** * @dataProvider providerGaps */ public function testAbstractClass(string $gap): void { $content = <<<'EOF' getCompletionLabels($content, 'B\A', $gap); $expected_labels = [ '->' => [ 'magicObjProp1', 'magicObjProp2', 'magicObjMethod', 'publicObjProp', 'protectedObjProp', 'privateObjProp', 'abstractPublicMethod', 'abstractProtectedMethod', 'publicObjMethod', 'protectedObjMethod', 'privateObjMethod', 'publicStaticMethod', 'protectedStaticMethod', 'privateStaticMethod', ], '::' => [ 'magicStaticMethod', 'publicStaticProp', 'protectedStaticProp', 'privateStaticProp', 'publicStaticMethod', 'protectedStaticMethod', 'privateStaticMethod', ], ]; $this->assertEqualsCanonicalizing($expected_labels[$gap], $actual_labels); } /** * @dataProvider providerGaps */ public function testUseTrait(string $gap): void { $content = <<<'EOF' getCompletionLabels($content, 'B\A', $gap); $expected_labels = [ '->' => [ 'magicObjProp1', 'magicObjProp2', 'magicObjMethod', 'publicObjProp', 'protectedObjProp', 'privateObjProp', 'abstractPublicMethod', 'abstractProtectedMethod', 'publicObjMethod', 'protectedObjMethod', 'privateObjMethod', 'publicStaticMethod', 'protectedStaticMethod', 'privateStaticMethod', ], '::' => [ 'magicStaticMethod', 'publicStaticProp', 'protectedStaticProp', 'privateStaticProp', 'publicStaticMethod', 'protectedStaticMethod', 'privateStaticMethod', ], ]; $this->assertEqualsCanonicalizing($expected_labels[$gap], $actual_labels); } /** * @dataProvider providerGaps */ public function testUseTraitWithAbstractClass(string $gap): void { $content = <<<'EOF' getCompletionLabels($content, 'B\A', $gap); $expected_labels = [ '->' => [ 'magicObjProp1', 'magicObjProp2', 'magicObjMethod', 'publicObjProp', 'protectedObjProp', 'privateObjProp', 'abstractPublicMethod', 'abstractProtectedMethod', 'publicObjMethod', 'protectedObjMethod', 'privateObjMethod', 'publicStaticMethod', 'protectedStaticMethod', 'privateStaticMethod', ], '::' => [ 'magicStaticMethod', 'publicStaticProp', 'protectedStaticProp', 'privateStaticProp', 'publicStaticMethod', 'protectedStaticMethod', 'privateStaticMethod', ], ]; $this->assertEqualsCanonicalizing($expected_labels[$gap], $actual_labels); } /** * @dataProvider providerGaps */ public function testClassWithExtends(string $gap): void { $content = <<<'EOF' getCompletionLabels($content, 'B\A', $gap); $expected_labels = [ '->' => [ 'magicObjProp1', 'magicObjProp2', 'magicObjMethod', 'publicObjProp', 'protectedObjProp', 'publicObjMethod', 'protectedObjMethod', 'publicStaticMethod', 'protectedStaticMethod', ], '::' => [ 'magicStaticMethod', 'publicStaticProp', 'protectedStaticProp', 'publicStaticMethod', 'protectedStaticMethod', ], ]; $this->assertEqualsCanonicalizing($expected_labels[$gap], $actual_labels); } /** * @dataProvider providerGaps */ public function testAstractClassWithInterface(string $gap): void { $content = <<<'EOF' getCompletionLabels($content, 'B\A', $gap); $expected_labels = [ '->' => [ 'publicObjMethod', 'protectedObjMethod', ], '::' => [], ]; $this->assertEqualsCanonicalizing($expected_labels[$gap], $actual_labels); } /** * @dataProvider providerGaps */ public function testClassWithAnnotationMixin(string $gap): void { $content = <<<'EOF' getCompletionLabels($content, 'B\A', $gap); $expected_labels = [ '->' => [ 'magicObjProp1', 'magicObjProp2', 'magicObjMethod', 'publicObjProp', 'publicObjMethod', 'publicStaticMethod', ], '::' => [], ]; $this->assertEqualsCanonicalizing($expected_labels[$gap], $actual_labels); } public function testResolveCollisionWithMixin(): void { $content = <<<'EOF' getCompletionLabels($content, 'B\A', '->'); $expected_labels = [ 'myObjProp', ]; $this->assertEqualsCanonicalizing($expected_labels, $actual_labels); } }