mirror of
https://github.com/Vateron-Media/XC_VM.git
synced 2026-09-25 12:01:55 +02:00
enigma, episode, episodes, process_monitor and stream_view referenced migrated classes (UserRepository, BouquetService, StreamRepository, RequestManager, SettingsManager, ...) by short name with either no `use` or a `use` placed *below* the first usage. PHP imports outside the top scope are positional, so the short name resolved to a now-nonexistent global class — a runtime fatal on those admin pages (php -l passes; not covered by PHPStan/PHPUnit). The migration's automated `use` insertion missed them due to the interleaved HTML / short-tag (<? , <?=) structure, and the later php-cs-fixer pass stripped some as 'unused' because it could not see usage inside short-tag blocks. - Consolidate every needed `use XcVm\...;` into a single top-of-file PHP block. - Exclude Public/Views and Modules/*/views from php-cs-fixer (no_unused_imports is unreliable on short-tag templates); their import correctness is enforced by the new check_procedural_use gate instead. Verified: php -l (short_open_tag=1) clean; PHPStan no errors; PHPUnit green.
69 lines
2.0 KiB
PHP
69 lines
2.0 KiB
PHP
<?php
|
|
|
|
use PHPUnit\Framework\TestCase;
|
|
use XcVm\Cli\CommandInterface;
|
|
|
|
/**
|
|
* Guard for Фаза 2: console.php discovers commands by FQCN built from the scan
|
|
* directory's PSR-4 namespace (no basename==classname, no manual require, no
|
|
* global 'CommandInterface' string). This test mirrors that discovery without
|
|
* booting the full CLI (which needs the ioncube XC_VM class) and asserts the
|
|
* command surface stays stable.
|
|
*/
|
|
final class ConsoleDiscoveryTest extends TestCase {
|
|
private const DIRS = [
|
|
'Cli/Commands' => 'XcVm\\Cli\\Commands\\',
|
|
'Cli/CronJobs' => 'XcVm\\Cli\\CronJobs\\',
|
|
];
|
|
|
|
/** @return array{0:string[],1:string[]} [resolved FQCNs, concrete commands implementing the interface] */
|
|
private function discover(): array {
|
|
$resolved = [];
|
|
$commands = [];
|
|
foreach (self::DIRS as $dir => $ns) {
|
|
$path = MAIN_HOME . $dir;
|
|
$this->assertDirectoryExists($path);
|
|
foreach (glob($path . '/*.php') as $file) {
|
|
$fqcn = $ns . basename($file, '.php');
|
|
if (!class_exists($fqcn)) {
|
|
continue;
|
|
}
|
|
$resolved[] = $fqcn;
|
|
$ref = new ReflectionClass($fqcn);
|
|
if (!$ref->isAbstract() && $ref->implementsInterface(CommandInterface::class)) {
|
|
$commands[] = $fqcn;
|
|
}
|
|
}
|
|
}
|
|
return [$resolved, $commands];
|
|
}
|
|
|
|
public function testEveryCliFileResolvesByFqcn(): void {
|
|
$files = 0;
|
|
foreach (self::DIRS as $dir => $ns) {
|
|
$files += count(glob(MAIN_HOME . $dir . '/*.php'));
|
|
}
|
|
[$resolved] = $this->discover();
|
|
$this->assertSame(
|
|
$files,
|
|
count($resolved),
|
|
'Every Cli/Commands + Cli/CronJobs file must resolve to a class by FQCN.'
|
|
);
|
|
}
|
|
|
|
public function testDiscoversAStableSetOfCommands(): void {
|
|
[, $commands] = $this->discover();
|
|
// The concrete command surface should not silently shrink.
|
|
$this->assertGreaterThanOrEqual(
|
|
40,
|
|
count($commands),
|
|
'Far fewer commands than expected — discovery likely broke.'
|
|
);
|
|
foreach ($commands as $fqcn) {
|
|
$this->assertTrue(
|
|
(new ReflectionClass($fqcn))->implementsInterface(CommandInterface::class)
|
|
);
|
|
}
|
|
}
|
|
}
|