mirror of
https://github.com/danog/psalm.git
synced 2024-11-26 20:34:47 +01:00
223 lines
6.1 KiB
PHP
223 lines
6.1 KiB
PHP
<?php
|
|
|
|
namespace Psalm\Tests;
|
|
|
|
use Psalm\Internal\PluginManager\ComposerLock;
|
|
use RuntimeException;
|
|
|
|
use function json_encode;
|
|
|
|
use const JSON_THROW_ON_ERROR;
|
|
|
|
/** @group PluginManager */
|
|
class ComposerLockTest extends TestCase
|
|
{
|
|
/**
|
|
* @test
|
|
*/
|
|
public function packageIsPsalmPlugin(): void
|
|
{
|
|
$lock = new ComposerLock([$this->jsonFile((object)[])]);
|
|
|
|
$this->assertTrue($lock->isPlugin([
|
|
'name' => 'vendor/package',
|
|
'type' => 'psalm-plugin',
|
|
'extra' => [
|
|
'psalm' => [
|
|
'pluginClass' => 'Some\Class',
|
|
],
|
|
],
|
|
]), 'Non-plugin should not be considered a plugin');
|
|
|
|
$this->assertTrue($lock->isPlugin([
|
|
'name' => 'vendor/package',
|
|
'type' => 'library',
|
|
'extra' => [
|
|
'psalm' => [
|
|
'pluginClass' => 'Some\Class',
|
|
],
|
|
],
|
|
]), 'Non-plugin should not be considered a plugin');
|
|
|
|
$this->assertTrue($lock->isPlugin([
|
|
'name' => 'vendor/package',
|
|
'extra' => [
|
|
'psalm' => [
|
|
'pluginClass' => 'Some\Class',
|
|
],
|
|
],
|
|
]), 'Non-plugin should not be considered a plugin');
|
|
|
|
// counterexamples
|
|
|
|
$this->assertFalse($lock->isPlugin([]), 'Non-package should not be considered a plugin');
|
|
|
|
$this->assertFalse($lock->isPlugin([
|
|
'name' => 'vendor/package',
|
|
'type' => 'library',
|
|
]), 'Non-plugin should not be considered a plugin');
|
|
|
|
$this->assertFalse($lock->isPlugin([
|
|
'name' => 'vendor/package',
|
|
'type' => 'psalm-plugin',
|
|
]), 'Invalid plugin should not be considered a plugin');
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function seesNonDevPlugins(): void
|
|
{
|
|
$lock = new ComposerLock([$this->jsonFile((object)[
|
|
'packages' => [
|
|
(object)$this->pluginEntry('vendor/package', 'Vendor\Package\PluginClass'),
|
|
],
|
|
'packages-dev' => [],
|
|
])]);
|
|
|
|
$plugins = $lock->getPlugins();
|
|
$this->assertArrayHasKey('vendor/package', $plugins);
|
|
$this->assertSame('Vendor\Package\PluginClass', $plugins['vendor/package']);
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function seesDevPlugins(): void
|
|
{
|
|
$lock = new ComposerLock([$this->jsonFile((object)[
|
|
'packages' => [],
|
|
'packages-dev' => [
|
|
(object) $this->pluginEntry('vendor/package', 'Vendor\Package\PluginClass'),
|
|
],
|
|
])]);
|
|
|
|
$plugins = $lock->getPlugins();
|
|
$this->assertArrayHasKey('vendor/package', $plugins);
|
|
$this->assertSame('Vendor\Package\PluginClass', $plugins['vendor/package']);
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function skipsNonPlugins(): void
|
|
{
|
|
$nonPlugin = (object)[
|
|
'name' => 'vendor/package',
|
|
'type' => 'library',
|
|
];
|
|
|
|
$lock = new ComposerLock([$this->jsonFile((object)[
|
|
'packages' => [$nonPlugin],
|
|
'packages-dev' => [$nonPlugin],
|
|
])]);
|
|
$this->assertEmpty($lock->getPlugins());
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function failsOnInvalidJson(): void
|
|
{
|
|
$lock = new ComposerLock(['data:application/json,[']);
|
|
|
|
$this->expectException(RuntimeException::class);
|
|
$lock->getPlugins();
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function failsOnNonObjectJson(): void
|
|
{
|
|
$lock = new ComposerLock(['data:application/json,null']);
|
|
|
|
$this->expectException(RuntimeException::class);
|
|
$lock->getPlugins();
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function failsOnMissingPackagesEntry(): void
|
|
{
|
|
$noPackagesFile = $this->jsonFile((object)[
|
|
'packages-dev' => [],
|
|
]);
|
|
$lock = new ComposerLock([$noPackagesFile]);
|
|
$this->expectException(RuntimeException::class);
|
|
$lock->getPlugins();
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function failsOnMissingPackagesDevEntry(): void
|
|
{
|
|
$noPackagesDevFile = $this->jsonFile((object)[
|
|
'packages' => [],
|
|
]);
|
|
$lock = new ComposerLock([$noPackagesDevFile]);
|
|
$this->expectException(RuntimeException::class);
|
|
$lock->getPlugins();
|
|
}
|
|
|
|
/** @test */
|
|
public function mergesMultipleComposerLockFiles(): void
|
|
{
|
|
$lock = new ComposerLock([
|
|
$this->jsonFile([
|
|
'packages' => [
|
|
(object) $this->pluginEntry('vendor/packageA', 'Vendor\PackageA\PluginClass'),
|
|
],
|
|
'packages-dev' => [
|
|
(object) $this->pluginEntry('vendor/packageB', 'Vendor\PackageB\PluginClass'),
|
|
],
|
|
]),
|
|
$this->jsonFile([
|
|
'packages' => [
|
|
(object) $this->pluginEntry('vendor/packageC', 'Vendor\PackageC\PluginClass'),
|
|
],
|
|
'packages-dev' => [
|
|
(object) $this->pluginEntry('vendor/packageD', 'Vendor\PackageD\PluginClass'),
|
|
],
|
|
]),
|
|
]);
|
|
|
|
$this->assertSame(
|
|
[
|
|
'vendor/packageA' => 'Vendor\PackageA\PluginClass',
|
|
'vendor/packageB' => 'Vendor\PackageB\PluginClass',
|
|
'vendor/packageC' => 'Vendor\PackageC\PluginClass',
|
|
'vendor/packageD' => 'Vendor\PackageD\PluginClass',
|
|
],
|
|
$lock->getPlugins(),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @psalm-pure
|
|
*/
|
|
private function pluginEntry(string $package_name, string $package_class): array
|
|
{
|
|
return [
|
|
'name' => $package_name,
|
|
'type' => 'psalm-plugin',
|
|
'extra' => [
|
|
'psalm' => [
|
|
'pluginClass' => $package_class,
|
|
],
|
|
],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @param mixed $data
|
|
* @psalm-pure
|
|
*/
|
|
private function jsonFile($data): string
|
|
{
|
|
return 'data:application/json,' . json_encode($data, JSON_THROW_ON_ERROR);
|
|
}
|
|
}
|