While looking at the list of tests for an extension I found 3000+ ScopeStructureTest which are generated from the php files in mediawiki/core (more precisely `$wgAutoloadLocalClasses`): * those tests take 21 seconds to complete on my machine. * None were generated for the extension being tested, those tests are thus solely affected by mediawiki/core. `tests/phpunit/structure` is included in the `extensions` and `skins` PHPUnit testsuites and any patches made to them would run that 21 seconds suite even though its only testing mediawiki/core. Move the test outside of `structure` so it is no longer run for `extensions` and `skins`. Bug: T225730 Change-Id: I628210b8b270773f3dad12bbde9d72f0328fcceb (cherry picked from commit d10835b8bc933a49724010f0c39dfeaccfa9108c)
74 lines
1.9 KiB
PHP
74 lines
1.9 KiB
PHP
<?php
|
|
|
|
use PhpParser\Node;
|
|
use PhpParser\Node\Expr;
|
|
use PhpParser\Node\Stmt;
|
|
use PhpParser\ParserFactory;
|
|
use PhpParser\PhpVersion;
|
|
|
|
/**
|
|
* @coversNothing
|
|
*/
|
|
class ScopeStructureTest extends MediaWikiUnitTestCase {
|
|
|
|
public static function provideAutoloadNoFileScope() {
|
|
global $wgAutoloadLocalClasses;
|
|
$files = array_unique( $wgAutoloadLocalClasses );
|
|
$args = [];
|
|
foreach ( $files as $file ) {
|
|
$args[$file] = [ $file ];
|
|
}
|
|
return $args;
|
|
}
|
|
|
|
/**
|
|
* Confirm that all files in $wgAutoloadLocalClasses have no file-scope code
|
|
* apart from specific exemptions.
|
|
*
|
|
* This is slow (~15s).
|
|
*
|
|
* @dataProvider provideAutoloadNoFileScope
|
|
*/
|
|
public function testAutoloadNoFileScope( $file ) {
|
|
// This value should match the PHP version specified in composer.json,
|
|
// PHPVersionCheck.php, and .phan/config.php
|
|
$version = PhpVersion::fromComponents( 8, 1 );
|
|
$parser = ( new ParserFactory )->createForVersion( $version );
|
|
$ast = $parser->parse( file_get_contents( $file ) );
|
|
foreach ( $ast as $node ) {
|
|
if ( $node instanceof Stmt\ClassLike
|
|
|| $node instanceof Stmt\Namespace_
|
|
|| $node instanceof Stmt\Use_
|
|
|| $node instanceof Stmt\Nop
|
|
|| $node instanceof Stmt\Declare_
|
|
|| $node instanceof Stmt\Function_
|
|
) {
|
|
continue;
|
|
}
|
|
if ( $node instanceof Stmt\Expression ) {
|
|
$expr = $node->expr;
|
|
if ( $expr instanceof Expr\FuncCall ) {
|
|
if ( $expr->name instanceof Node\Name ) {
|
|
if ( in_array( $expr->name->toString(), [
|
|
'class_alias',
|
|
'define'
|
|
] ) ) {
|
|
continue;
|
|
}
|
|
}
|
|
} elseif ( $expr instanceof Expr\Include_ ) {
|
|
if ( $expr->type === Expr\Include_::TYPE_REQUIRE_ONCE ) {
|
|
continue;
|
|
}
|
|
} elseif ( $expr instanceof Expr\Assign ) {
|
|
if ( $expr->var->name === 'maintClass' ) {
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
$line = $node->getLine();
|
|
$this->assertNull( $node, "Found file scope code in $file at line $line" );
|
|
}
|
|
$this->assertTrue( true );
|
|
}
|
|
}
|