mirror of
https://github.com/danog/psalm-plugin-phpunit.git
synced 2025-01-22 13:51:22 +01:00
Store external dataprovider references in afterClassLikeVisit
This fixes false-positive UndefinedClass issues when Psalm is run on a single test file with cold cache. Fixes psalm/psalm-plugin-phpunit#57
This commit is contained in:
parent
ab21faac5c
commit
8f98135364
@ -7,11 +7,11 @@ namespace Psalm\PhpUnitPlugin\Hooks;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use PhpParser\Node\Stmt\ClassLike;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use Psalm\CodeLocation;
|
||||
use Psalm\Codebase;
|
||||
use Psalm\DocComment;
|
||||
use Psalm\Exception\DocblockParseException;
|
||||
use Psalm\FileSource;
|
||||
use Psalm\Internal\PhpVisitor\ReflectorVisitor;
|
||||
use Psalm\IssueBuffer;
|
||||
use Psalm\Issue;
|
||||
use Psalm\Plugin\Hook\AfterClassLikeAnalysisInterface;
|
||||
@ -76,6 +76,24 @@ class TestCaseHandler implements
|
||||
if (self::hasInitializers($class_storage, $class_node)) {
|
||||
$class_storage->custom_metadata[__NAMESPACE__] = ['hasInitializers' => true];
|
||||
}
|
||||
|
||||
$file_path = $statements_source->getFilePath();
|
||||
$file_storage = $codebase->file_storage_provider->get($file_path);
|
||||
|
||||
foreach ($class_node->getMethods() as $method) {
|
||||
$specials = self::getSpecials($method);
|
||||
if (!isset($specials['dataProvider'])) {
|
||||
continue;
|
||||
}
|
||||
foreach ($specials['dataProvider'] as $provider) {
|
||||
if (false !== strpos($provider, '::')) {
|
||||
[$class_name] = explode('::', $provider);
|
||||
$fq_class_name = Type::getFQCLNFromString($class_name, $statements_source->getAliases());
|
||||
$codebase->scanner->queueClassLikeForScanning($fq_class_name, $file_path);
|
||||
$file_storage->referenced_classlikes[strtolower($fq_class_name)] = $fq_class_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -7,7 +7,7 @@ Feature: TestCase
|
||||
Given I have the following config
|
||||
"""
|
||||
<?xml version="1.0"?>
|
||||
<psalm totallyTyped="true">
|
||||
<psalm totallyTyped="true" %s>
|
||||
<projectFiles>
|
||||
<directory name="."/>
|
||||
<ignoreFiles> <directory name="../../vendor"/> </ignoreFiles>
|
||||
@ -1176,6 +1176,38 @@ Feature: TestCase
|
||||
| Type | Message |
|
||||
| InvalidArgument | Argument 1 of NS\MyTestCase::testSomething expects int, string provided by NS\External::provide():(iterable<string, array<int, string>>) |
|
||||
|
||||
@ExternalProviders
|
||||
Scenario: External providers are available even when Psalm is asked to analyze single test case
|
||||
Given I have the following code in "test.php"
|
||||
"""
|
||||
<?php
|
||||
namespace NS;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class MyTestCase extends TestCase {
|
||||
/** @dataProvider External::provide */
|
||||
public function testSomething(int $_p): void {}
|
||||
}
|
||||
"""
|
||||
And I have the following code in "ext.php"
|
||||
"""
|
||||
<?php
|
||||
namespace NS;
|
||||
|
||||
class External {
|
||||
/** @return iterable<string, array<int,int>> */
|
||||
public function provide(): iterable {
|
||||
yield "dataset name" => [1];
|
||||
}
|
||||
}
|
||||
"""
|
||||
And I have the following classmap
|
||||
| Class | File |
|
||||
| NS\MyTestCase | test.php |
|
||||
| NS\External | ext.php |
|
||||
When I run Psalm on "test.php"
|
||||
Then I see no errors
|
||||
|
||||
@List
|
||||
Scenario: Providers returning list are ok
|
||||
Given I have the following code
|
||||
|
Loading…
x
Reference in New Issue
Block a user