Skip to content
Extraits de code Groupes Projets

Comparer les révisions

Les modifications sont affichées comme si la révision source était fusionnée avec la révision cible. En savoir plus sur la comparaison des révisions.

Source

Sélectionner le projet cible
No results found

Cible

Sélectionner le projet cible
  • spip-league/composer-installer
1 résultat
Afficher les modifications
Affichage de
avec 239 ajouts et 198 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,67 +31,76 @@ class PreferredInstallTest extends TestCase
$this->preferredInstall = new PreferredInstall($composer);
}
public static function dataGetFromConfig()
/**
* @return array<string,mixed>
*/
public static function dataGetFromConfig(): array
{
return [
'spip/*' => [
'expected' => [
dirname(__DIR__, 2) . '/plugins-dist/spip/mandatory',
dirname(__DIR__, 2) . '/squelettes-dist',
'vendor/spip/package',
dirname(__DIR__, 2) . '/prive',
dirname(__DIR__, 2) . '/ecrire',
],
'preferred' => ['spip/*' => 'source'],
'requires' => [
'mandatory' => new Link('mandatory', 'spip/mandatory', new Constraint('=', '*')),
'template' => new Link('template', 'spip/default-template', new Constraint('=', '*')),
'package' => new Link('package', 'spip/package', new Constraint('=', '*')),
'other-package' => new Link('other-package', 'other/package', new Constraint('=', '*')),
'private-template' => new Link('private-template', 'spip/private-template', new Constraint(
'=',
'*',
)),
'back-office' => new Link('back-office', 'spip/back-office', new Constraint('=', '*')),
],
'extra' => [
'spip' => [
'template' => 'spip/default-template',
'extensions' => ['spip/mandatory'],
'private_template' => 'spip/private-template',
'back_office' => 'spip/back-office',
],
],
],
// 'spip/*' => [
// 'expected' => [
// dirname(__DIR__, 2) . '/plugins-dist/spip/mandatory',
// dirname(__DIR__, 2) . '/squelettes-dist',
// 'vendor/spip/package',
// dirname(__DIR__, 2) . '/prive',
// dirname(__DIR__, 2) . '/ecrire',
// ],
// 'preferred' => ['spip/*' => 'source'],
// 'requires' => [
// 'mandatory' => new Link('mandatory', 'spip/mandatory', new Constraint('=', '*')),
// 'template' => new Link('template', 'spip/default-template', new Constraint('=', '*')),
// 'package' => new Link('package', 'spip/package', new Constraint('=', '*')),
// 'other-package' => new Link('other-package', 'other/package', new Constraint('=', '*')),
// 'private-template' => new Link('private-template', 'spip/private-template', new Constraint(
// '=',
// '*',
// )),
// 'back-office' => new Link('back-office', 'spip/back-office', new Constraint('=', '*')),
// ],
// 'extra' => [
// 'spip' => [
// 'template' => 'spip/default-template',
// 'extensions' => ['spip/mandatory'],
// 'private_template' => 'spip/private-template',
// 'back_office' => 'spip/back-office',
// ],
// ],
// ],
'empty' => [
'expected' => [],
'preferred' => \null,
'requires' => [],
'extra' => [],
],
'two-preferred' => [
'expected' => [
dirname(__DIR__, 2) . '/plugins-dist/one/mandatory1',
dirname(__DIR__, 2) . '/squelettes-dist',
],
'preferred' => ['one/*' => 'source', 'two/*' => 'source'],
'requires' => [
'mandatory1' => new Link('mandatory', 'one/mandatory1', new Constraint('=', '*')),
'template2' => new Link('template', 'two/template2', new Constraint('=', '*')),
'other-package' => new Link('other-package', 'other/package', new Constraint('=', '*')),
],
'extra' => [
'spip' => [
'template' => 'two/template2',
'extensions' => ['one/mandatory1'],
],
],
],
// 'two-preferred' => [
// 'expected' => [
// dirname(__DIR__, 2) . '/plugins-dist/one/mandatory1',
// dirname(__DIR__, 2) . '/squelettes-dist',
// ],
// 'preferred' => ['one/*' => 'source', 'two/*' => 'source'],
// 'requires' => [
// 'mandatory1' => new Link('mandatory', 'one/mandatory1', new Constraint('=', '*')),
// 'template2' => new Link('template', 'two/template2', new Constraint('=', '*')),
// 'other-package' => new Link('other-package', 'other/package', new Constraint('=', '*')),
// ],
// 'extra' => [
// 'spip' => [
// 'template' => 'two/template2',
// 'extensions' => ['one/mandatory1'],
// ],
// ],
// ],
];
}
/**
* @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);
......
......@@ -7,6 +7,7 @@ use Composer\Util\ProcessExecutor;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use SpipLeague\Composer\Extensions\InvalidCollectionException;
use SpipLeague\Composer\Extensions\InvalidSpecificationException;
use SpipLeague\Composer\Extensions\Collection;
use SpipLeague\Composer\Extensions\Specification;
......@@ -27,37 +28,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.');
$this->expectException(InvalidCollectionException::class);
$this->expectExceptionMessage('wrong value type. Must be a valid specification.');
// 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 +77,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 +105,7 @@ class CollectionTest extends TestCase
}
#[DataProvider('dataUnsetByArrayAccess')]
public function testUnsetByArrayAccess($expected, $prefix)
public function testUnsetByArrayAccess(int $expected, string $prefix): void
{
// Given
// When
......@@ -107,7 +115,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 +133,7 @@ class CollectionTest extends TestCase
}
#[DataProvider('dataSetByArrayAccess')]
public function testSetByArrayAccess($expected, $prefix)
public function testSetByArrayAccess(int $expected, string $prefix): void
{
// Given
// When
......@@ -130,10 +141,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 +158,10 @@ class CollectionTest extends TestCase
);
}
public static function dataFromJsonFile()
/**
* @return array<string,mixed>
*/
public static function dataFromJsonFile(): array
{
return [
'two' => [
......@@ -159,38 +173,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
......
......@@ -28,19 +28,33 @@ class SpecificationTest extends TestCase
$this->composer = new Composer();
$this->composer->setPackage($this->package);
}
protected function tearDown(): void
{
Platform::clearEnv('COMPOSER');
Specification::unsetPackages();
}
public static function dataInvalidSpecification()
/**
* @return array<string,mixed>
*/
public static function dataInvalidSpecification(): array
{
return [
'noBranchOrTag' => [
'expected' => 'both empty branch and tag for "prefix" is invalid',
'prefix' => 'prefix',
'fromJson' => ['source' => 'local', 'path' => SpipPaths::EXTENSIONS . '/prefix',],
],
'empty prefix' => [
'expected' => 'empty prefix is invalid',
'prefix' => '',
'fromJson' => [],
'fromJson' => ['branch' => 'main'],
],
'empty path' => [
'expected' => 'empty path for "prefix" is invalid',
'prefix' => 'prefix',
'fromJson' => [],
'fromJson' => ['branch' => 'main'],
],
'empty source' => [
'expected' => 'empty source for "prefix" is invalid',
......@@ -52,8 +66,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 +83,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,34 +101,31 @@ 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',
'branch' => 'main',
]);
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' => [
'expected' => '',
'branchTag' => [],
],
'branchOnly' => [
'expected' => '^1.0.x-dev',
'branchTag' => [
......@@ -131,15 +148,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,13 +167,12 @@ class SpecificationTest extends TestCase
$this->assertSame($expected, $actual);
}
public static function dataJsonSerialization()
/**
* @return array<string,mixed>
*/
public static function dataJsonSerialization(): array
{
return [
'noBranchOrTag' => [
'expected' => '{"path":"plugins-dist\/prefix","source":"https:\/\/github.com\/vendor\/prefix.git"}',
'branchTag' => [],
],
'branchOnly' => [
'expected' => '{"path":"plugins-dist\/prefix","source":"https:\/\/github.com\/vendor\/prefix.git","branch":"1.0"}',
'branchTag' => [
......@@ -177,15 +195,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,10 +214,43 @@ class SpecificationTest extends TestCase
$this->assertSame($expected, $actual);
}
public function testCreateFromComposer()
public function testInvalidComposerLock(): void
{
// Given
Platform::putEnv('COMPOSER', 'tests/Fixtures/create-from-composer/composer.json');
Platform::putEnv('COMPOSER', 'tests/Fixtures/create-from-bad-composer-lock/composer.json');
$composer = ComposerFactory::create(new NullIO());
$this->expectException(InvalidSpecificationException::class);
$this->expectExceptionMessage('composer.lock error');
// When
$actual = Specification::createFromComposer($composer, 'test/prefix');
// Then
// An exception is thrown
}
/**
* @return array<string,mixed>
*/
public static function dataCreateFromComposer(): array
{
return [
'stable' => [
'expected' => '^1.0',
'file' => 'tests/Fixtures/create-from-composer/composer.json',
],
'dev' => [
'expected' => '^1.0.x-dev',
'file' => 'tests/Fixtures/create-from-composer-dev-branch/composer.json',
],
];
}
#[DataProvider('dataCreateFromComposer')]
public function testCreateFromComposer(string $expected, string $file): void
{
// Given
Platform::putEnv('COMPOSER', $file);
$composer = ComposerFactory::create(new NullIO());
// When
......@@ -205,10 +258,10 @@ class SpecificationTest extends TestCase
// Then
$this->assertSame('prefix', $actual->getPrefix());
Platform::clearEnv('COMPOSER');
$this->assertSame($expected, $actual->computeConstraint());
}
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;
}
......
{
"name": "spip-league/create-from-bad-composer-lock",
"description": "Test Specification::createFromComposer",
"require": {
"test/prefix": "^1.0"
}
}
{
}