Skip to content
Extraits de code Groupes Projets
Valider 5445b1cb rédigé par JamesRezo's avatar JamesRezo :tada:
Parcourir les fichiers

test: passe phpstan

parent d035ec42
Aucune branche associée trouvée
Aucune étiquette associée trouvée
1 requête de fusion!13Add CI
Ce commit fait partie de la requête de fusion !13. Les commentaires créés ici seront créés dans le contexte de cette requête de fusion.
Affichage de
avec 155 ajouts et 149 suppressions
......@@ -9,9 +9,6 @@ use Composer\Plugin\Capable;
use Composer\Plugin\PluginInterface;
use Composer\Script\Event;
/**
* @codeCoverageIgnore
*/
class SpipInstallerPlugin implements PluginInterface, EventSubscriberInterface, Capable
{
public function activate(Composer $composer, IOInterface $io)
......
......@@ -6,6 +6,7 @@ use Composer\Composer;
use Composer\Util\Filesystem;
use SpipLeague\Composer\Extensions\CollectionInterface;
use SpipLeague\Composer\Extensions\Specification;
use SpipLeague\Composer\Git\RemoteUrlsInterface;
use SpipLeague\Composer\SpipPaths;
use SpipLeague\Composer\Switch\Operation\AddSpecification;
use SpipLeague\Composer\Switch\Operation\AddToRequire;
......@@ -22,13 +23,10 @@ class Analyzer
{
private Filesystem $filesystem;
private CollectionInterface $distribution;
private Composer $composer;
public function __construct(
CollectionInterface $distribution,
Composer $composer,
private CollectionInterface $distribution,
private Composer $composer,
private RemoteUrlsInterface $changer,
) {
$this->distribution = $distribution;
$this->composer = $composer;
......@@ -41,11 +39,10 @@ class Analyzer
private function getExtensions(): array
{
$extensions = [];
/** @var array{spip?:array{extensions?:mixed}} $extra */
$extra = $this->composer->getPackage()
->getExtra();
if (isset($extra['spip']['extensions']) && \is_array($extra['spip']['extensions'])) {
$extensions = $extra['spip']['extensions'];
if (isset($extra['spip']) && \is_array($extra['spip']) && \is_array($extra['spip']['extensions'])) {
$extensions = \array_filter($extra['spip']['extensions'], fn($x) => \is_string($x));
}
return $extensions;
......@@ -61,12 +58,12 @@ class Analyzer
yield new RemoveDirectory($this->filesystem, $specification->getPath());
}
if (!\in_array($specification->computeVendorName(), $extensions)) {
yield new AddToSpipExtraExtensions($specification->computeVendorName());
if (!\in_array($specification->computeVendorName($this->changer), $extensions)) {
yield new AddToSpipExtraExtensions($specification->computeVendorName($this->changer));
}
if (!\in_array($specification->computeVendorName(), $vendorNames)) {
yield new AddToRequire($specification->computeVendorName(), $specification->computeConstraint());
if (!\in_array($specification->computeVendorName($this->changer), $vendorNames)) {
yield new AddToRequire($specification->computeVendorName($this->changer), $specification->computeConstraint());
}
yield new RemoveSpecification($specification->getPrefix());
......
......@@ -15,17 +15,11 @@ class AddSpecification implements OperationInterface
$this->specification = $specification;
}
/**
* @codeCoverageIgnore
*/
public function getMessage(): string
{
return 'AddSpecification ' . $this->specification->getPrefix();
}
/**
* @codeCoverageIgnore
*/
public function getType(): string
{
return 'distribution';
......
......@@ -17,25 +17,16 @@ class AddToRequire implements OperationInterface
$this->constraint = $constraint;
}
/**
* @codeCoverageIgnore
*/
public function getMessage(): string
{
return 'AddToRequire ' . $this->vendorName . ':' . $this->constraint;
}
/**
* @codeCoverageIgnore
*/
public function getType(): string
{
return 'requires';
}
/**
* @codeCoverageIgnore
*/
public function mark(CollectionInterface $distribution, Composer $composer): ?self
{
return $this;
......
......@@ -14,17 +14,11 @@ class AddToSpipExtraExtensions implements OperationInterface
$this->vendorName = $vendorName;
}
/**
* @codeCoverageIgnore
*/
public function getMessage(): string
{
return 'AddToSpipExtraExtensions ' . $this->vendorName;
}
/**
* @codeCoverageIgnore
*/
public function getType(): string
{
return 'extensions';
......@@ -33,10 +27,9 @@ class AddToSpipExtraExtensions implements OperationInterface
public function mark(CollectionInterface $distribution, Composer $composer): ?self
{
$extensions = [];
/** @var array{spip?:array{extensions?:mixed}} $extra */
$extra = $composer->getPackage()
->getExtra();
if (isset($extra['spip']['extensions']) && \is_array($extra['spip']['extensions'])) {
if (isset($extra['spip']) && \is_array($extra['spip']) && \is_array($extra['spip']['extensions'])) {
$extensions = $extra['spip']['extensions'];
}
......@@ -46,16 +39,16 @@ class AddToSpipExtraExtensions implements OperationInterface
public function do(CollectionInterface $distribution, Composer $composer): string
{
$extensions = [];
/** @var array{spip?:array{extensions?:mixed}} $extra */
$extra = $composer->getPackage()
->getExtra();
if (isset($extra['spip']['extensions']) && \is_array($extra['spip']['extensions'])) {
if (isset($extra['spip']) && \is_array($extra['spip']) && \is_array($extra['spip']['extensions'])) {
$extensions = $extra['spip']['extensions'];
}
if (\in_array($this->vendorName, $extensions)) {
return 'nothing to do';
}
/** @var string[] $extensions */
$extensions[] = $this->vendorName;
$composer->getConfig()
->getConfigSource()
......
......@@ -24,17 +24,11 @@ class RemoveDirectory implements OperationInterface
$this->ifEmpty = $ifEmpty;
}
/**
* @codeCoverageIgnore
*/
public function getMessage(): string
{
return 'RemoveDirectory ' . $this->directory;
}
/**
* @codeCoverageIgnore
*/
public function getType(): string
{
return 'directories';
......
......@@ -17,17 +17,11 @@ class RemoveFromRequire implements OperationInterface
$this->vendorName = $vendorName;
}
/**
* @codeCoverageIgnore
*/
public function getMessage(): string
{
return 'RemoveFromRequire ' . $this->vendorName;
}
/**
* @codeCoverageIgnore
*/
public function getType(): string
{
return 'requires';
......
......@@ -17,17 +17,11 @@ class RemoveFromSpipExtraExtensions implements OperationInterface
$this->vendorName = $vendorName;
}
/**
* @codeCoverageIgnore
*/
public function getMessage(): string
{
return 'RemoveFromSpipExtraExtensions ' . $this->vendorName;
}
/**
* @codeCoverageIgnore
*/
public function getType(): string
{
return 'extensions';
......@@ -36,10 +30,9 @@ class RemoveFromSpipExtraExtensions implements OperationInterface
public function mark(CollectionInterface $distribution, Composer $composer): ?self
{
$extensions = [];
/** @var array{spip?:array{extensions?:mixed}} $extra */
$extra = $composer->getPackage()
->getExtra();
if (isset($extra['spip']['extensions']) && \is_array($extra['spip']['extensions'])) {
if (isset($extra['spip']) && \is_array($extra['spip']) && \is_array($extra['spip']['extensions'])) {
$extensions = $extra['spip']['extensions'];
}
......@@ -49,19 +42,20 @@ class RemoveFromSpipExtraExtensions implements OperationInterface
public function do(CollectionInterface $distribution, Composer $composer): string
{
$extensions = [];
/** @var array{spip?:array{extensions?:mixed}} $extra */
$extra = $composer->getPackage()
->getExtra();
if (isset($extra['spip']['extensions']) && \is_array($extra['spip']['extensions'])) {
if (isset($extra['spip']) && \is_array($extra['spip']) && \is_array($extra['spip']['extensions'])) {
$extensions = $extra['spip']['extensions'];
}
if (!\in_array($this->vendorName, $extensions)) {
return 'nothing to do';
}
/** @var string[] $extensions */
$extensions = \array_diff($extensions, [$this->vendorName]);
$composer->getConfig()
->getConfigSource()
->addProperty('extra.spip.extensions', \array_diff($extensions, [$this->vendorName]));
->addProperty('extra.spip.extensions', $extensions);
return 'extensions ' . $this->vendorName . ' removed';
}
......
......@@ -14,17 +14,11 @@ class RemoveSpecification implements OperationInterface
$this->prefix = $prefix;
}
/**
* @codeCoverageIgnore
*/
public function getMessage(): string
{
return 'RemoveSpecification ' . $this->prefix;
}
/**
* @codeCoverageIgnore
*/
public function getType(): string
{
return 'distribution';
......
......@@ -39,6 +39,11 @@ class Switcher
}
}
/**
* @param callable():Composer $reset
*
* @return \Generator<string>
*/
public function flush(callable $reset): \Generator
{
foreach ($this->operations as $type => $operations) {
......
......@@ -31,7 +31,10 @@ class PreferredInstallTest extends TestCase
$this->preferredInstall = new PreferredInstall($composer);
}
public static function dataGetFromConfig()
/**
* @return array<string,mixed>
*/
public static function dataGetFromConfig(): array
{
return [
'spip/*' => [
......@@ -90,8 +93,14 @@ class PreferredInstallTest extends TestCase
];
}
/**
* @param string[] $expected
* @param array<string,string> $preferred
* @param array<string,Link> $requires
* @param array{spip?:array{template?:string,private_template?:string,back_office?:string,extensions?:string[]}} $extra
*/
#[DataProvider('dataGetFromConfig')]
public function testGetFromConfig($expected, $preferred, $requires, $extra)
public function testGetFromConfig(array $expected, array $preferred, array $requires, array $extra): void
{
$this->package->setRequires($requires);
$this->package->setExtra($extra);
......
......@@ -27,37 +27,41 @@ class CollectionTest extends TestCase
protected function setUp(): void
{
$this->validStub = new SpecificationStub('valid', 'stub/valid', '1.0.0');
$this->testCollection = new Collection([$this->validStub]);
$this->testCollection = new Collection([$this->validStub], 'dummy.json');
$this->changer = new RemoteUrls(new ProcessExecutor(new NullIO()));
}
public function testInvalidSpecification()
public function testInvalidSpecification(): void
{
// Given
$this->expectException(InvalidSpecificationException::class);
$this->expectExceptionMessage('A collection must contain at least one valid specification.');
// When
new Collection([new SpecificationStub()]);
new Collection([new SpecificationStub()], 'dummy.json');
// Then
// An exception is thrown
}
public function testInvalidSpecificationByArrayAccess()
public function testInvalidSpecificationByArrayAccess(): void
{
// Given
$this->expectException(InvalidSpecificationException::class);
$this->expectExceptionMessage('A collection must only contain valid specifications.');
// When
$this->testCollection[] = 'invalid';
/** @phpstan-ignore assign.propertyType */
$this->testCollection[] = 'invalid'; /** @phpstan-ignore offsetAssign.valueType */
// Then
// An exception is thrown
}
public static function dataGetByArrayAccess()
/**
* @return array<string,mixed>
*/
public static function dataGetByArrayAccess(): array
{
return [
'notexists' => [
......@@ -72,17 +76,20 @@ class CollectionTest extends TestCase
}
#[DataProvider('dataGetByArrayAccess')]
public function testGetByArrayAccess($expected, $prefix)
public function testGetByArrayAccess(?string $expected, string $prefix): void
{
// Given
// When
$actual = $this->testCollection[$prefix];
// Then
$this->assertEquals($expected, $actual?->computeVendorName());
$this->assertEquals($expected, $actual?->computeVendorName($this->changer));
}
public static function dataUnsetByArrayAccess()
/**
* @return array<string,mixed>
*/
public static function dataUnsetByArrayAccess(): array
{
return [
'notexists' => [
......@@ -97,7 +104,7 @@ class CollectionTest extends TestCase
}
#[DataProvider('dataUnsetByArrayAccess')]
public function testUnsetByArrayAccess($expected, $prefix)
public function testUnsetByArrayAccess(int $expected, string $prefix): void
{
// Given
// When
......@@ -107,7 +114,10 @@ class CollectionTest extends TestCase
$this->assertCount($expected, $this->testCollection);
}
public static function dataSetByArrayAccess()
/**
* @return array<string,mixed>
*/
public static function dataSetByArrayAccess(): array
{
return [
'new' => [
......@@ -122,7 +132,7 @@ class CollectionTest extends TestCase
}
#[DataProvider('dataSetByArrayAccess')]
public function testSetByArrayAccess($expected, $prefix)
public function testSetByArrayAccess(int $expected, string $prefix): void
{
// Given
// When
......@@ -130,10 +140,10 @@ class CollectionTest extends TestCase
// Then
$this->assertCount($expected, $this->testCollection);
$this->assertArrayHasKey($prefix, $this->testCollection);
$this->assertNotNull($this->testCollection[$prefix]);
}
public function testJsonSerialization()
public function testJsonSerialization(): void
{
// Given
// When
......@@ -147,7 +157,10 @@ class CollectionTest extends TestCase
);
}
public static function dataFromJsonFile()
/**
* @return array<string,mixed>
*/
public static function dataFromJsonFile(): array
{
return [
'two' => [
......@@ -159,38 +172,38 @@ class CollectionTest extends TestCase
}
#[DataProvider('dataFromJsonFile')]
public function testFromJsonFile($expected, $file, $prefix)
public function testFromJsonFile(int $expected, string $file, string $prefix): void
{
// Given
// When
$actual = Collection::fromJsonFile($this->changer, $file);
$actual = Collection::fromJsonFile($file);
// Then
$this->assertCount($expected, $actual);
$this->assertTrue(isset($actual[$prefix]));
}
public function todo_testMissingFromJsonFile()
public function todo_testMissingFromJsonFile(): void
{
// Given
$this->expectException(\LogicException::class);
$this->expectExceptionMessageMatches(',File "plugins-dist.json" is missing,');
// When
Collection::fromJsonFile($this->changer);
Collection::fromJsonFile();
// Then
// An exception is thrown
}
public function testMalformedFromJsonFile()
public function testMalformedFromJsonFile(): void
{
// Given
$this->expectException(\LogicException::class);
$this->expectExceptionMessageMatches(',Fixtures/malformed.json" malformed,');
// When
Collection::fromJsonFile($this->changer, __DIR__ . '/../Fixtures/malformed.json');
Collection::fromJsonFile(__DIR__ . '/../Fixtures/malformed.json');
// Then
// An exception is thrown
......
......@@ -29,7 +29,10 @@ class SpecificationTest extends TestCase
$this->composer->setPackage($this->package);
}
public static function dataInvalidSpecification()
/**
* @return array<string,mixed>
*/
public static function dataInvalidSpecification(): array
{
return [
'empty prefix' => [
......@@ -52,8 +55,11 @@ class SpecificationTest extends TestCase
];
}
/**
* @param array{path:string,source:string,branch?:string,tag?:string} $fromJson
*/
#[DataProvider('dataInvalidSpecification')]
public function testInvalidSpecification($expected, $prefix, $fromJson)
public function testInvalidSpecification(string $expected, string $prefix, array $fromJson): void
{
// Given
$this->expectException(InvalidSpecificationException::class);
......@@ -66,7 +72,10 @@ class SpecificationTest extends TestCase
// An exception is thrown
}
public static function dataComputeVendorName()
/**
* @return array<string,mixed>
*/
public static function dataComputeVendorName(): array
{
return [
'setChanger' => [
......@@ -81,28 +90,28 @@ class SpecificationTest extends TestCase
}
#[DataProvider('dataComputeVendorName')]
public function testComputeVendorName($expected, $changer)
public function testComputeVendorName(string $expected, bool $changer): void
{
// Given
$specification = new Specification('prefix', [
'path' => SpipPaths::EXTENSIONS . '/prefix',
'source' => 'https://github.com/vendor/prefix.git',
]);
if ($changer) {
$specification->setChanger(new RemoteUrlsStub(
'git@github.com:vendor/prefix.git',
'https://github.com/vendor/prefix.git',
));
}
// When
$actual = $specification->computeVendorName();
$actual = $specification->computeVendorName($changer ? new RemoteUrlsStub(
'git@github.com:vendor/prefix.git',
'https://github.com/vendor/prefix.git') : new RemoteUrlsStub(),
);
// Then
$this->assertSame($expected, $actual);
}
public static function dataComputeConstraint()
/**
* @return array<string,mixed>
*/
public static function dataComputeConstraint(): array
{
return [
'noBranchOrTag' => [
......@@ -131,15 +140,17 @@ class SpecificationTest extends TestCase
];
}
/**
* @param array{path:string,source:string,branch?:string,tag?:string} $branchTag
*/
#[DataProvider('dataComputeConstraint')]
public function testComputeConstraint($expected, $branchTag)
public function testComputeConstraint(string $expected, array $branchTag): void
{
// Given
$specification = new Specification('prefix', \array_merge([
'path' => SpipPaths::EXTENSIONS . '/prefix',
'source' => 'https://github.com/vendor/prefix.git',
], $branchTag));
$specification->setChanger(new RemoteUrlsStub(''));
// When
$actual = $specification->computeConstraint();
......@@ -148,7 +159,10 @@ class SpecificationTest extends TestCase
$this->assertSame($expected, $actual);
}
public static function dataJsonSerialization()
/**
* @return array<string,mixed>
*/
public static function dataJsonSerialization(): array
{
return [
'noBranchOrTag' => [
......@@ -177,15 +191,17 @@ class SpecificationTest extends TestCase
];
}
/**
* @param array{path:string,source:string,branch?:string,tag?:string} $branchTag
*/
#[DataProvider('dataJsonSerialization')]
public function testJsonSerialization($expected, $branchTag)
public function testJsonSerialization(string $expected, array $branchTag): void
{
// Given
$specification = new Specification('prefix', \array_merge([
'path' => SpipPaths::EXTENSIONS . '/prefix',
'source' => 'https://github.com/vendor/prefix.git',
], $branchTag));
$specification->setChanger(new RemoteUrlsStub(''));
// When
$actual = \json_encode($specification);
......@@ -194,7 +210,7 @@ class SpecificationTest extends TestCase
$this->assertSame($expected, $actual);
}
public function testCreateFromComposer()
public function testCreateFromComposer(): void
{
// Given
Platform::putEnv('COMPOSER', 'tests/Fixtures/create-from-composer/composer.json');
......@@ -208,7 +224,7 @@ class SpecificationTest extends TestCase
Platform::clearEnv('COMPOSER');
}
public function testFailCreateFromComposer()
public function testFailCreateFromComposer(): void
{
// Given
$this->expectException(InvalidSpecificationException::class);
......
......@@ -9,8 +9,8 @@ class CollectionDummy implements CollectionInterface
{
use CollectionTrait;
public function getFile(): ?string
public function getFile(): string
{
return \null;
return '';
}
}
......@@ -20,14 +20,12 @@ class CollectionMock implements CollectionInterface
*/
protected array $collection = [];
private string $file;
public function __construct(string $file)
public function __construct(private string $file)
{
$this->file = $file;
}
public function getFile(): ?string
public function getFile(): string
{
return $this->file;
}
......@@ -77,6 +75,10 @@ class CollectionMock implements CollectionInterface
return $this->collection[$offset] ?? null;
}
/**
* @param mixed $offset
* @param mixed $value
*/
public function offsetSet(mixed $offset, mixed $value): void
{
if (!$value instanceof SpecificationInterface) {
......
......@@ -21,7 +21,8 @@ class RemoteUrlsStub implements RemoteUrlsInterface
public function __construct(string ...$urls)
{
while (!empty($urls)) {
$this->ssh[] = \array_shift($urls);
$url = \array_shift($urls);
$this->ssh[] = $url;
$this->https[] = !empty($urls) ? \array_shift($urls) : '';
}
}
......
......@@ -3,6 +3,7 @@
namespace SpipLeague\Test\Composer\Fixtures;
use SpipLeague\Composer\Extensions\SpecificationInterface;
use SpipLeague\Composer\Git\RemoteUrlsInterface;
class SpecificationMock implements SpecificationInterface
{
......@@ -41,7 +42,12 @@ class SpecificationMock implements SpecificationInterface
return $this->path;
}
public function computeVendorName(): string
public function getSource(): string
{
return $this->source;
}
public function computeVendorName(RemoteUrlsInterface $changer): string
{
return $this->vendorName;
}
......
......@@ -3,27 +3,16 @@
namespace SpipLeague\Test\Composer\Fixtures;
use SpipLeague\Composer\Extensions\SpecificationInterface;
use SpipLeague\Composer\Git\RemoteUrlsInterface;
class SpecificationStub implements SpecificationInterface
{
private string $prefix;
private string $vendorName;
private string $constraint;
private string $path;
public function __construct(
string $prefix = '',
string $vendorName = '',
string $constraint = '',
string $path = 'path',
private string $prefix = '',
private string $vendorName = '',
private string $constraint = '',
private string $path = 'path',
) {
$this->prefix = $prefix;
$this->vendorName = $vendorName;
$this->constraint = $constraint;
$this->path = $path;
}
public function getPrefix(): string
......@@ -36,7 +25,12 @@ class SpecificationStub implements SpecificationInterface
return $this->path;
}
public function computeVendorName(): string
public function getSource(): string
{
return 'source';
}
public function computeVendorName(RemoteUrlsInterface $changer): string
{
return $this->vendorName;
}
......
......@@ -19,7 +19,10 @@ class RemoteUrlsTest extends TestCase
$this->changer = new RemoteUrls(new ProcessExecutor(new NullIO()));
}
public static function dataHttpsToSsh()
/**
* @return array<string,mixed>
*/
public static function dataHttpsToSsh(): array
{
return [
'empty-url' => [
......@@ -38,12 +41,15 @@ class RemoteUrlsTest extends TestCase
}
#[DataProvider('dataHttpsToSsh')]
public function testToSsh($expected, $url)
public function testToSsh(string $expected, string $url): void
{
$this->assertSame($expected, $this->changer->toSsh($url));
}
public static function dataSshToHttps()
/**
* @return array<string,mixed>
*/
public static function dataSshToHttps(): array
{
return [
'empty-url' => [
......@@ -62,22 +68,22 @@ class RemoteUrlsTest extends TestCase
}
#[DataProvider('dataSshToHttps')]
public function testToHttps($expected, $url)
public function testToHttps(string $expected, string $url): void
{
$this->assertSame($expected, $this->changer->toHttps($url));
}
public function testGetRemote()
public function testGetRemote(): void
{
$this->assertSame('git -C test remote get-url origin', $this->changer->getRemote('test'));
}
public function testSetRemote()
public function testSetRemote(): void
{
$this->assertSame('git -C test remote set-url origin test-url', $this->changer->setRemote('test', 'test-url'));
}
public function testGetProcessor()
public function testGetProcessor(): void
{
$this->assertInstanceOf(ProcessExecutor::class, $this->changer->getProcessor());
}
......
......@@ -33,7 +33,10 @@ class SpipInstallerTest extends TestCase
$this->installer = new SpipInstaller($io, $composer);
}
public static function dataPluginTypes()
/**
* @return array<string,mixed>
*/
public static function dataPluginTypes(): array
{
return [
'library' => [
......@@ -60,7 +63,7 @@ class SpipInstallerTest extends TestCase
}
#[DataProvider('dataPluginTypes')]
public function testSupports($expected, $type)
public function testSupports(string $expected, string $type): void
{
$package = new Package('spip/test', '1.0.0', '1.0.0.0');
$package->setType($type);
......@@ -68,7 +71,10 @@ class SpipInstallerTest extends TestCase
$this->assertEquals($expected, $this->installer->supports($package->getType()));
}
public static function dataPluginPaths()
/**
* @return array<string,mixed>
*/
public static function dataPluginPaths(): array
{
return [
'library' => [
......@@ -111,7 +117,7 @@ class SpipInstallerTest extends TestCase
}
#[DataProvider('dataPluginPaths')]
public function testGetInstallPath($expected, $name, $type)
public function testGetInstallPath(string $expected, string $name, string $type): void
{
$package = new Package($name, '1.0.0', '1.0.0.0');
$package->setType($type);
......@@ -119,7 +125,7 @@ class SpipInstallerTest extends TestCase
$this->assertSame($expected, $this->installer->getInstallPath($package));
}
public function testUnsupportedType()
public function testUnsupportedType(): void
{
$this->expectException(InvalidArgumentException::class);
$package = new Package('spip/test', '1.0.0', '1.0.0.0');
......
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Veuillez vous inscrire ou vous pour commenter