diff --git a/.github/workflows/testing-suite.yml b/.github/workflows/testing-suite.yml
index f042fcf..ee38286 100644
--- a/.github/workflows/testing-suite.yml
+++ b/.github/workflows/testing-suite.yml
@@ -4,20 +4,28 @@ jobs:
PHP:
strategy:
matrix:
- image: [
- 'srcoder/development-php:php74-fpm',
- 'srcoder/development-php:php80-fpm',
- 'srcoder/development-php:php81-fpm'
- ]
+ php-version: [8.1, 8.2, 8.3, 8.4]
runs-on: ubuntu-latest
container:
- image: ${{ matrix.image }}
+ image: ${{ matrix.php-version == '8.1' && 'srcoder/development-php:php81-fpm' ||
+ matrix.php-version == '8.2' && 'srcoder/development-php:php82-fpm' ||
+ matrix.php-version == '8.3' && 'srcoder/development-php:php83-fpm' ||
+ matrix.php-version == '8.4' && 'srcoder/development-php:php84-fpm' }}
steps:
- name: Checkout
uses: actions/checkout@v2
- - name: Testing Suite
+
+ - name: Install Dependencies
run: |
composer2 install --dev --prefer-dist --no-scripts --no-progress --optimize-autoloader --no-interaction -vvv
composer2 show
- composer2 exec -v grumphp run
+ shell: bash
+
+ - name: Run GrumPHP Tasks
+ run: |
+ if [[ "${{ matrix.php-version }}" == "8.1" || "${{ matrix.php-version }}" == "8.2" ]]; then
+ composer2 exec -v grumphp -- run --tasks=composer,jsonlint,xmllint,yamllint,phpcs,phplint,phpmd,phpstan,securitychecker_enlightn
+ else
+ composer2 exec -v grumphp -- run
+ fi
shell: bash
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9cf2274..97e641b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,30 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+## [3.0.0] - Unreleased
+### Added
+- Added `phpunit/phpunit` to suggested dependencies in `composer.json`.
+- Added `youwe/coding-standard-phpstorm` to suggested dependencies in `composer.json`.
+- Added support to honor upstream version constraints
+- Github action for php 8.3 and php 8.4 to run unit tests against PHPUnit 12.
+- Testing suite now attempts to install phpunit upstream if it isn't available yet
+ - Existing upstream versions are honored if already installed
+ - Upstream projects not having phpunit installed will install phpunit with an @stable version
+
+### Changed
+- Unit tests as part of the testing suite are rewritten for PHPUnit 12
+- Updated GitHub Action workflows to support PHP 8.1, 8.2, and 8.3.
+- `composer.json`: Dropped support for PHP < 8.1.
+- Moved phpunit from require to require-dev
+- Changed PHPMD suppressions in docblocks to quote the rule name, due to changes in later versions of PHPStan that create false positives on these docblocks if not quoted.
+
+### Removed
+- Removed support for EOL PHP versions. Projects running PHP < 8.1 can stick to version 2 of the testing-suite.
+- Removed support for Composer 1. Projects still relying on Composer 1 can stick to version 2 of the testing-suite.
+- Removed `youwe/coding-standard-phpstorm` as dependency (it is still listed in suggest)
+- Removed `phpunit/phpunit` as direct dependency (it is still in require-dev and installed upstream through the `youwe/dependency-installer`)
+- Github actions for php < 8.1
+
## 2.19.1
### Changed
- `^0.30` restricts updates to only versions within the `0.30.x` range, preventing upgrades to 0.32.0 for
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index a697639..9706ba4 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,3 +1,11 @@
+Before opening a PR with changes, make sure all the linting steps are successful.
+
+The require-dev dependency for phpunit is set to @stable for the github actions, but the tests themselves\
+assume they are running against PHPUnit 12 and php >= 8.3. The github actions only run phpunit tests against\
+a php 8.3 container.
+
If a PR is approved please ask one of the following maintainers to get it merged:
-[Igor Wulff](https://github.com/igorwulff)
-[Dan Wallis](https://github.com/fredden)
+
+- [Igor Wulff](https://github.com/igorwulff)
+- [Leon Helmus](https://github.com/leonhelmus)
+- [Rutger Rademakers](https://github.com/rutgerrademaker)
diff --git a/composer.json b/composer.json
index 3720dee..b5b4582 100644
--- a/composer.json
+++ b/composer.json
@@ -24,22 +24,25 @@
}
],
"require": {
- "php": "^7.2 || ^8.0",
- "composer-plugin-api": "^1.1 || ^2.0",
+ "php": "^8.1",
+ "composer-plugin-api": "^2.0",
"enlightn/security-checker": "^1.5 || ^2.0",
"kint-php/kint": "@stable",
"php-parallel-lint/php-parallel-lint": "^1.2",
"phpro/grumphp-shim": "^1.13",
"phpstan/phpstan": "@stable",
- "phpunit/phpunit": "@stable",
"youwe/coding-standard": "^3.5.0",
- "youwe/coding-standard-phpstorm": "^2.3.0",
"youwe/composer-dependency-installer": "^1.4.0",
"youwe/composer-file-installer": "^1.2.0"
},
+ "suggest": {
+ "phpunit/phpunit": ">= 9.6",
+ "youwe/coding-standard-phpstorm": "^2.3.0"
+ },
"require-dev": {
"composer/composer": "@stable",
- "mikey179/vfsstream": "@stable"
+ "mikey179/vfsstream": "@stable",
+ "phpunit/phpunit": "@stable"
},
"replace": {
"sensiolabs/security-checker": "*"
diff --git a/phpstan.neon b/phpstan.neon
index 9d11dfb..35d0f21 100644
--- a/phpstan.neon
+++ b/phpstan.neon
@@ -1,5 +1,6 @@
parameters:
excludePaths:
- src/installers.php
+ - tests/*
ignoreErrors:
- '#Property Mediact\\TestingSuite\\Composer\\Installer\\ConfigInstaller::\$io is never read, only written\.#'
diff --git a/src/ConfigResolver.php b/src/ConfigResolver.php
index 7c2da85..9560402 100644
--- a/src/ConfigResolver.php
+++ b/src/ConfigResolver.php
@@ -21,11 +21,11 @@ class ConfigResolver
* Constructor.
*
* @param ProjectTypeResolver $typeResolver
- * @param string $template
+ * @param string|null $template
*/
public function __construct(
ProjectTypeResolver $typeResolver,
- string $template = null
+ ?string $template = null,
) {
$this->typeResolver = $typeResolver;
$this->template = $template ?? $this->template;
diff --git a/src/Factory/ProcessFactory.php b/src/Factory/ProcessFactory.php
index 99b0429..27ba599 100644
--- a/src/Factory/ProcessFactory.php
+++ b/src/Factory/ProcessFactory.php
@@ -23,6 +23,7 @@ class ProcessFactory implements ProcessFactoryInterface
public function create(string $commandLine): Process
{
// See https://github.com/composer/composer/blob/1.10.17/src/Composer/Util/ProcessExecutor.php#L68:L72
+ // @phpstan-ignore-next-line because phpstan can see it's available, but we cannot guarantee symfony >= 4.2 upstream
return method_exists(Process::class, 'fromShellCommandline')
? Process::fromShellCommandline($commandLine) // Symfony >= 4.2
: new Process($commandLine); // Symfony < 4.2
diff --git a/src/Installer/ArchiveExcludeInstaller.php b/src/Installer/ArchiveExcludeInstaller.php
index acfe782..1cfd755 100644
--- a/src/Installer/ArchiveExcludeInstaller.php
+++ b/src/Installer/ArchiveExcludeInstaller.php
@@ -12,12 +12,13 @@
use Composer\Factory;
use Composer\IO\IOInterface;
use Composer\Json\JsonFile;
+use Exception;
use Youwe\FileMapping\FileMappingInterface;
use Youwe\TestingSuite\Composer\MappingResolver;
/**
- * @SuppressWarnings(PHPMD.ShortVariable)
- * @SuppressWarnings(PHPMD.StaticAccess)
+ * @SuppressWarnings("PHPMD.ShortVariable")
+ * @SuppressWarnings("PHPMD.StaticAccess")
*/
class ArchiveExcludeInstaller implements InstallerInterface
{
@@ -41,7 +42,7 @@ class ArchiveExcludeInstaller implements InstallerInterface
'/.env.dev',
'/.gitattributes',
'/.gitignore',
- '/tests'
+ '/tests',
];
/**
@@ -50,15 +51,15 @@ class ArchiveExcludeInstaller implements InstallerInterface
* @param MappingResolver $resolver
* @param IOInterface $io
* @param JsonFile|null $file
- * @param string $destination
+ * @param string |null $destination
* @param array|null $defaults
*/
public function __construct(
MappingResolver $resolver,
IOInterface $io,
- JsonFile $file = null,
- string $destination = null,
- array $defaults = null
+ ?JsonFile $file = null,
+ ?string $destination = null,
+ ?array $defaults = null,
) {
$this->resolver = $resolver;
$this->io = $io;
@@ -71,6 +72,7 @@ public function __construct(
* Install.
*
* @return void
+ * @throws Exception
*/
public function install(): void
{
@@ -94,7 +96,7 @@ function (FileMappingInterface $mapping): string {
},
iterator_to_array(
$this->resolver->resolve()
- )
+ ),
)
);
@@ -107,7 +109,7 @@ function (FileMappingInterface $mapping): string {
$this->io->write(
sprintf(
'Added: %s to archive exclude in composer.json',
- $file
+ $file,
)
);
}
diff --git a/src/Installer/ConfigInstaller.php b/src/Installer/ConfigInstaller.php
index 3b5dbdd..203261b 100644
--- a/src/Installer/ConfigInstaller.php
+++ b/src/Installer/ConfigInstaller.php
@@ -10,13 +10,13 @@
namespace Youwe\TestingSuite\Composer\Installer;
use Composer\Factory;
-use Composer\IO\IOInterface;
use Composer\Json\JsonFile;
+use Seld\JsonLint\ParsingException;
use Youwe\TestingSuite\Composer\ConfigResolver;
/**
- * @SuppressWarnings(PHPMD.ShortVariable)
- * @SuppressWarnings(PHPMD.StaticAccess)
+ * @SuppressWarnings("PHPMD.ShortVariable")
+ * @SuppressWarnings("PHPMD.StaticAccess")
*/
class ConfigInstaller implements InstallerInterface
{
@@ -34,7 +34,7 @@ class ConfigInstaller implements InstallerInterface
*/
public function __construct(
ConfigResolver $resolver,
- JsonFile $file = null
+ ?JsonFile $file = null,
) {
$this->resolver = $resolver;
$this->file = $file ?? new JsonFile(Factory::getComposerFile());
@@ -44,6 +44,7 @@ public function __construct(
* Install.
*
* @return void
+ * @throws ParsingException
*/
public function install(): void
{
@@ -52,7 +53,7 @@ public function install(): void
$config = array_replace_recursive(
$this->resolver->resolve(),
- $config
+ $config,
);
$definition['config'] = $config;
diff --git a/src/Installer/FilesInstaller.php b/src/Installer/FilesInstaller.php
index 2f2da5d..fd80ba8 100644
--- a/src/Installer/FilesInstaller.php
+++ b/src/Installer/FilesInstaller.php
@@ -15,7 +15,7 @@
use Youwe\TestingSuite\Composer\MappingResolver;
/**
- * @SuppressWarnings(PHPMD.ShortVariable)
+ * @SuppressWarnings("PHPMD.ShortVariable")
*/
class FilesInstaller implements InstallerInterface
{
@@ -38,7 +38,7 @@ class FilesInstaller implements InstallerInterface
public function __construct(
MappingResolver $mappingResolver,
ComposerFileInstaller $fileInstaller,
- IOInterface $io
+ IOInterface $io,
) {
$this->mappingResolver = $mappingResolver;
$this->fileInstaller = $fileInstaller;
@@ -63,7 +63,7 @@ public function install(): void
$this->io->write(
sprintf(
'Installed: %s',
- $mapping->getRelativeDestination()
+ $mapping->getRelativeDestination(),
)
);
}
@@ -72,7 +72,7 @@ public function install(): void
/**
* @param FileMappingInterface $unixFileMapping
*
- * @SuppressWarnings(PHPMD.CyclomaticComplexity)
+ * @SuppressWarnings("PHPMD.CyclomaticComplexity")
*
* @return void
*/
@@ -87,9 +87,9 @@ private function resolveYouwePathing(FileMappingInterface $unixFileMapping): voi
[
'./vendor/mediact/coding-standard-magento2/src/MediactMagento2',
'./vendor/mediact/coding-standard/src/MediaCT',
- './vendor/youwe/coding-standard-magento2/src/Magento2'
+ './vendor/youwe/coding-standard-magento2/src/Magento2',
],
- 'YouweMagento2'
+ 'YouweMagento2',
);
} elseif ($name === "phpmd.xml") {
$this->updatePath(
@@ -97,49 +97,55 @@ private function resolveYouwePathing(FileMappingInterface $unixFileMapping): voi
[
'./vendor/mediact/coding-standard-magento2/src/MediactMagento2/phpmd.xml',
'./vendor/mediact/coding-standard/src/MediaCT/phpmd.xml',
- './vendor/youwe/coding-standard-magento2/src/Magento2/phpmd.xml'
+ './vendor/youwe/coding-standard-magento2/src/Magento2/phpmd.xml',
],
- './vendor/youwe/coding-standard-magento2/src/YouweMagento2/phpmd.xml'
+ './vendor/youwe/coding-standard-magento2/src/YouweMagento2/phpmd.xml',
);
} elseif ($name === "grumphp.yml") {
$this->updatePath(
$unixFileMapping->getDestination(),
[
'vendor/mediact/testing-suite/config/default/grumphp.yml',
- 'vendor/youwe/testing-suite/config/default/grumphp.yml'
+ 'vendor/youwe/testing-suite/config/default/grumphp.yml',
],
- 'vendor/youwe/testing-suite/config/magento2/grumphp.yml'
+ 'vendor/youwe/testing-suite/config/magento2/grumphp.yml',
);
}
} elseif ($this->mappingResolver->getTypeResolver()->resolve() === 'magento') {
if ($name === "phpcs.xml") {
$this->updatePath(
$unixFileMapping->getDestination(),
- ['./vendor/mediact/coding-standard-magento1/src/MediactMagento1'],
- './vendor/youwe/coding-standard-magento1/src/Magento1'
+ [
+ './vendor/mediact/coding-standard-magento1/src/MediactMagento1',
+ ],
+ './vendor/youwe/coding-standard-magento1/src/Magento1',
);
}
} else {
if ($name === "phpcs.xml") {
$this->updatePath(
$unixFileMapping->getDestination(),
- ['./vendor/mediact/coding-standard/src/MediaCT'],
- './vendor/youwe/coding-standard/src/Global'
+ [
+ './vendor/mediact/coding-standard/src/MediaCT',
+ ],
+ './vendor/youwe/coding-standard/src/Global',
);
} elseif ($name === "phpmd.xml") {
$this->updatePath(
$unixFileMapping->getDestination(),
[
'./vendor/mediact/coding-standard/src/MediaCT/phpmd.xml',
- './vendor/youwe/coding-standard-magento2/src/Magento2/phpmd.xml'
+ './vendor/youwe/coding-standard-magento2/src/Magento2/phpmd.xml',
],
- './vendor/youwe/coding-standard/src/Global/phpmd.xml'
+ './vendor/youwe/coding-standard/src/Global/phpmd.xml',
);
} elseif ($name === "grumphp.yml") {
$this->updatePath(
$unixFileMapping->getDestination(),
- ['vendor/mediact/testing-suite/config/default/grumphp.yml'],
- 'vendor/youwe/testing-suite/config/default/grumphp.yml'
+ [
+ 'vendor/mediact/testing-suite/config/default/grumphp.yml',
+ ],
+ 'vendor/youwe/testing-suite/config/default/grumphp.yml',
);
}
}
@@ -155,13 +161,13 @@ private function resolveYouwePathing(FileMappingInterface $unixFileMapping): voi
private function updatePath(
string $destination,
array $oldPaths,
- string $newPath
+ string $newPath,
): void {
$file = file_get_contents($destination);
$newFile = str_replace(
$oldPaths,
$newPath,
- $file
+ $file,
);
file_put_contents($destination, $newFile);
}
diff --git a/src/Installer/PackagesInstaller.php b/src/Installer/PackagesInstaller.php
index c3f9258..dced981 100644
--- a/src/Installer/PackagesInstaller.php
+++ b/src/Installer/PackagesInstaller.php
@@ -16,7 +16,7 @@
use Youwe\TestingSuite\Composer\ProjectTypeResolver;
/**
- * @SuppressWarnings(PHPMD.ShortVariable)
+ * @SuppressWarnings("PHPMD.ShortVariable")
*/
class PackagesInstaller implements InstallerInterface
{
@@ -33,39 +33,40 @@ class PackagesInstaller implements InstallerInterface
private $io;
/** @var array */
- private $mapping = [
- MappingResolver::DEFAULT_MAPPING_TYPE => [],
+ public $mapping = [
+ MappingResolver::DEFAULT_MAPPING_TYPE => [
+ 'phpunit/phpunit' => [
+ 'version' => '@stable',
+ 'updateDependencies' => true,
+ 'allowVersionOverride' => false,
+ ],
+ ],
'magento1' => [
- [
- 'name' => 'youwe/coding-standard-magento1',
+ 'youwe/coding-standard-magento1' => [
'version' => '^1.3.0',
- 'dev' => true
- ]
+ 'updateDependencies' => true,
+ ],
],
'magento2' => [
- [
- 'name' => 'youwe/coding-standard-magento2',
+ 'youwe/coding-standard-magento2' => [
'version' => '^2.0.0',
- 'dev' => true
+ 'updateDependencies' => true,
],
- [
- 'name' => 'phpstan/extension-installer',
+ 'phpstan/extension-installer' => [
'version' => '^1.3',
- 'dev' => true
+ 'updateDependencies' => true,
],
- [
- 'name' => 'bitexpert/phpstan-magento',
+ 'bitexpert/phpstan-magento' => [
'version' => '~0.30',
- 'dev' => true
+ 'updateDependencies' => true,
],
],
'laravel' => [
- [
- 'name' => 'elgentos/laravel-coding-standard',
+ 'elgentos/laravel-coding-standard' => [
'version' => '^1.0.0',
- 'dev' => true
- ]
- ]
+ 'updateDependencies' => true,
+ ],
+ ],
];
/**
@@ -81,8 +82,8 @@ public function __construct(
Composer $composer,
ProjectTypeResolver $typeResolver,
IOInterface $io,
- DependencyInstaller $installer = null,
- array $mapping = null
+ ?DependencyInstaller $installer = null,
+ ?array $mapping = null,
) {
$this->composer = $composer;
$this->typeResolver = $typeResolver;
@@ -99,19 +100,21 @@ public function __construct(
public function install(): void
{
$type = $this->typeResolver->resolve();
- if (!isset($this->mapping[$type])) {
- return;
- }
+ $projectTypePackages = $this->mapping[$type] ?? [];
+ $packagesToInstall = array_replace_recursive($this->mapping[MappingResolver::DEFAULT_MAPPING_TYPE], $projectTypePackages);
- foreach ($this->mapping[$type] as $package) {
- if (!$this->isPackageRequired($package['name'], $package['version'])) {
+ foreach ($packagesToInstall as $name => $package) {
+ if (!$this->isPackageRequired($name, $package['version'])) {
$this->io->write(
- sprintf('Requiring package %s', $package['name'])
+ sprintf('Requiring package %s', $name)
);
$this->installer->installPackage(
- $package['name'],
- $package['version']
+ $name,
+ $package['version'],
+ $package['dev'] ?? true,
+ $package['updateDependencies'] ?? false,
+ $package['allowVersionOverride'] ?? true,
);
}
}
@@ -121,6 +124,7 @@ public function install(): void
* Whether a package has been required.
*
* @param string $packageName
+ * @param string $version
*
* @return bool
*/
diff --git a/src/MappingResolver.php b/src/MappingResolver.php
index 388b0ed..03110b0 100644
--- a/src/MappingResolver.php
+++ b/src/MappingResolver.php
@@ -40,14 +40,14 @@ public function resolve(): FileMappingReaderInterface
__DIR__ . '/../templates/mapping/files',
sprintf(
__DIR__ . '/../templates/mapping/project/%s',
- $this->typeResolver->resolve()
- )
+ $this->typeResolver->resolve(),
+ ),
];
return new UnixFileMappingReader(
__DIR__ . '/../templates/files',
getcwd(),
- ...$files
+ ...$files,
);
}
diff --git a/src/Plugin.php b/src/Plugin.php
index 83d423d..a71f5a2 100644
--- a/src/Plugin.php
+++ b/src/Plugin.php
@@ -16,7 +16,7 @@
use Youwe\TestingSuite\Composer\Installer\InstallerInterface;
/**
- * @SuppressWarnings(PHPMD.ShortVariable)
+ * @SuppressWarnings("PHPMD.ShortVariable")
*/
class Plugin implements PluginInterface, EventSubscriberInterface
{
@@ -44,7 +44,7 @@ public function __construct(InstallerInterface ...$installers)
public function activate(Composer $composer, IOInterface $io)
{
$this->addInstallers(
- ...include __DIR__ . '/installers.php'
+ ...include __DIR__ . '/installers.php',
);
}
@@ -105,11 +105,11 @@ public static function getSubscribedEvents(): array
{
return [
'post-install-cmd' => [
- 'install'
+ 'install',
],
'post-update-cmd' => [
- 'install'
- ]
+ 'install',
+ ],
];
}
}
diff --git a/src/ProjectTypeResolver.php b/src/ProjectTypeResolver.php
index 40ad900..b6eb66b 100644
--- a/src/ProjectTypeResolver.php
+++ b/src/ProjectTypeResolver.php
@@ -21,7 +21,7 @@ class ProjectTypeResolver
*/
public const COMPOSER_CONFIG_KEYS = [
'youwe-testing-suite',
- 'mediact-testing-suite'
+ 'mediact-testing-suite',
];
/**
@@ -40,7 +40,7 @@ class ProjectTypeResolver
'magento-project' => 'magento2',
'alumio-project' => 'alumio',
'laravel-project' => 'laravel',
- 'pimcore-project' => 'pimcore'
+ 'pimcore-project' => 'pimcore',
];
public const DEFAULT_PROJECT_TYPE = 'default';
@@ -51,7 +51,7 @@ class ProjectTypeResolver
* @param Composer $composer
* @param array|null $mapping
*/
- public function __construct(Composer $composer, array $mapping = null)
+ public function __construct(Composer $composer, ?array $mapping = null)
{
$this->composer = $composer;
$this->mapping = $mapping ?? $this->mapping;
diff --git a/src/installers.php b/src/installers.php
index d322159..d9a1e64 100644
--- a/src/installers.php
+++ b/src/installers.php
@@ -27,7 +27,7 @@
$mappingResolver = new MappingResolver($typeResolver);
$configResolver = new ConfigResolver($typeResolver);
$fileInstaller = new FileInstaller(
- new UnixFileMappingReader('', '')
+ new UnixFileMappingReader('', ''),
);
$processFactory = new ProcessFactory();
@@ -35,5 +35,5 @@
new FilesInstaller($mappingResolver, $fileInstaller, $io),
new ArchiveExcludeInstaller($mappingResolver, $io),
new PackagesInstaller($composer, $typeResolver, $io),
- new ConfigInstaller($configResolver)
+ new ConfigInstaller($configResolver),
];
diff --git a/tests/ConfigResolverTest.php b/tests/ConfigResolverTest.php
index b43fb6a..938901b 100644
--- a/tests/ConfigResolverTest.php
+++ b/tests/ConfigResolverTest.php
@@ -10,21 +10,21 @@
namespace Youwe\TestingSuite\Composer\Tests;
use org\bovigo\vfs\vfsStream;
+use PHPUnit\Framework\Attributes\CoversMethod;
+use PHPUnit\Framework\MockObject\Exception;
use PHPUnit\Framework\TestCase;
use Youwe\TestingSuite\Composer\ConfigResolver;
use Youwe\TestingSuite\Composer\ProjectTypeResolver;
/**
- * @coversDefaultClass \Youwe\TestingSuite\Composer\ConfigResolver
- * @SuppressWarnings(PHPMD)
+ * @phpcs:disable GlobalPhpUnit.Coverage.CoversTag.CoversTagMissing
*/
+#[CoversMethod(ConfigResolver::class, '__construct')]
+#[CoversMethod(ConfigResolver::class, 'resolve')]
class ConfigResolverTest extends TestCase
{
/**
- * @return void
- *
- * @covers ::__construct
- * @covers ::resolve
+ * @throws Exception
*/
public function testResolve(): void
{
@@ -33,7 +33,7 @@ public function testResolve(): void
$filesystem = vfsStream::setup(
sha1(__METHOD__),
null,
- [$jsonFile => $jsonData]
+ [$jsonFile => $jsonData],
);
$template = $filesystem->url() . '/%s.json';
diff --git a/tests/Factory/ProcessFactoryTest.php b/tests/Factory/ProcessFactoryTest.php
index fcf0464..6d84b75 100644
--- a/tests/Factory/ProcessFactoryTest.php
+++ b/tests/Factory/ProcessFactoryTest.php
@@ -9,27 +9,24 @@
namespace Youwe\TestingSuite\Composer\Tests\Factory;
+use PHPUnit\Framework\Attributes\CoversMethod;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Process\Process;
use Youwe\TestingSuite\Composer\Factory\ProcessFactory;
/**
- * @coversDefaultClass \Youwe\TestingSuite\Composer\Factory\ProcessFactory
+ * @phpcs:disable GlobalPhpUnit.Coverage.CoversTag.CoversTagMissing
*/
+#[CoversMethod(ProcessFactory::class, 'create')]
class ProcessFactoryTest extends TestCase
{
- /**
- * @return void
- *
- * @covers ::create
- */
- public function testCreate()
+ public function testCreate(): void
{
$factory = new ProcessFactory();
$this->assertInstanceOf(
Process::class,
- $factory->create('foo')
+ $factory->create('foo'),
);
}
}
diff --git a/tests/Installer/ArchiveExcludeInstallerTest.php b/tests/Installer/ArchiveExcludeInstallerTest.php
index 241fec1..93136ad 100644
--- a/tests/Installer/ArchiveExcludeInstallerTest.php
+++ b/tests/Installer/ArchiveExcludeInstallerTest.php
@@ -13,7 +13,9 @@
use Composer\Json\JsonFile;
use org\bovigo\vfs\vfsStream;
use org\bovigo\vfs\vfsStreamDirectory;
-use PHPUnit\Framework\MockObject\MockObject;
+use PHPUnit\Framework\Attributes\CoversMethod;
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\MockObject\Exception;
use PHPUnit\Framework\TestCase;
use Youwe\FileMapping\FileMappingInterface;
use Youwe\FileMapping\FileMappingReaderInterface;
@@ -21,32 +23,23 @@
use Youwe\TestingSuite\Composer\MappingResolver;
/**
- * @coversDefaultClass \Youwe\TestingSuite\Composer\Installer\ArchiveExcludeInstaller
- * @SuppressWarnings(PHPMD)
+ * @phpcs:disable GlobalPhpUnit.Coverage.CoversTag.CoversTagMissing
*/
+#[CoversMethod(ArchiveExcludeInstaller::class, '__construct')]
+#[CoversMethod(ArchiveExcludeInstaller::class, 'install')]
class ArchiveExcludeInstallerTest extends TestCase
{
/**
- * @param array $existingFiles
- * @param array $files
- * @param array $defaults
- * @param array $definition
- * @param array $expected
- *
- * @return void
- *
- * @dataProvider dataProvider
- *
- * @covers ::__construct
- * @covers ::install
+ * @throws Exception
*/
+ #[DataProvider('dataProvider')]
public function testInstall(
array $existingFiles,
array $files,
array $defaults,
array $definition,
- array $expected
- ) {
+ array $expected,
+ ): void {
$file = $this->createMock(JsonFile::class);
$resolver = $this->createMock(MappingResolver::class);
$io = $this->createMock(IOInterface::class);
@@ -73,39 +66,36 @@ public function testInstall(
$io,
$file,
$filesystem->url(),
- $defaults
+ $defaults,
);
$installer->install();
}
- /**
- * @return array
- */
- public function dataProvider(): array
+ public static function dataProvider(): array
{
return [
[
[
'foo-file.txt',
'bar-file.txt',
- 'default.txt'
+ 'default.txt',
],
[
'foo-file.txt',
'bar-file.txt',
- 'baz-file.txt'
+ 'baz-file.txt',
],
[
'/default.txt',
- '/other-default.txt'
+ '/other-default.txt',
],
[
'archive' => [
'exclude' => [
- 'existing.txt'
- ]
- ]
+ 'existing.txt',
+ ],
+ ],
],
[
'archive' => [
@@ -113,22 +103,19 @@ public function dataProvider(): array
'/existing.txt',
'/default.txt',
'/foo-file.txt',
- '/bar-file.txt'
- ]
- ]
- ]
- ]
+ '/bar-file.txt',
+ ],
+ ],
+ ],
+ ],
];
}
/**
- * @param array $files
- *
- * @return FileMappingReaderInterface
+ * @throws Exception
*/
private function createReaderMock(array $files): FileMappingReaderInterface
{
- /** @var FileMappingReaderInterface|MockObject $mock */
$mock = $this->createMock(FileMappingReaderInterface::class);
$valids = array_fill(0, count($files), true);
@@ -136,7 +123,6 @@ private function createReaderMock(array $files): FileMappingReaderInterface
$mappings = array_map(
function (string $file): FileMappingInterface {
- /** @var FileMappingInterface|MockObject $mapping */
$mapping = $this->createMock(FileMappingInterface::class);
$mapping
->expects(self::any())
@@ -166,11 +152,6 @@ function (string $file): FileMappingInterface {
return $mock;
}
- /**
- * @param array $files
- *
- * @return vfsStreamDirectory
- */
private function createFilesystem(array $files): vfsStreamDirectory
{
return vfsStream::setup(
diff --git a/tests/Installer/ConfigInstallerTest.php b/tests/Installer/ConfigInstallerTest.php
index 70b3937..341322b 100644
--- a/tests/Installer/ConfigInstallerTest.php
+++ b/tests/Installer/ConfigInstallerTest.php
@@ -9,23 +9,22 @@
namespace Youwe\TestingSuite\Composer\Tests\Installer;
-use Composer\IO\IOInterface;
use Composer\Json\JsonFile;
+use PHPUnit\Framework\Attributes\CoversMethod;
+use PHPUnit\Framework\MockObject\Exception;
use PHPUnit\Framework\TestCase;
use Youwe\TestingSuite\Composer\ConfigResolver;
use Youwe\TestingSuite\Composer\Installer\ConfigInstaller;
/**
- * @coversDefaultClass \Youwe\TestingSuite\Composer\Installer\ConfigInstaller
- * @SuppressWarnings(PHPMD)
+ * @phpcs:disable GlobalPhpUnit.Coverage.CoversTag.CoversTagMissing
*/
+#[CoversMethod(ConfigInstaller::class, '__construct')]
+#[CoversMethod(ConfigInstaller::class, 'install')]
class ConfigInstallerTest extends TestCase
{
/**
- * @return void
- *
- * @covers ::__construct
- * @covers ::install
+ * @throws Exception
*/
public function testInstall(): void
{
@@ -35,11 +34,11 @@ public function testInstall(): void
$installer = new ConfigInstaller($resolver, $file);
$resolverOutput = [
- 'sort-packages' => true
+ 'sort-packages' => true,
];
$configWrite = [
- 'config' => $resolverOutput
+ 'config' => $resolverOutput,
];
$file
@@ -70,7 +69,7 @@ public function dataProvider(): array
[],
[
'sort-packages' => true
- ]
+ ],
],
[
[],
@@ -78,10 +77,10 @@ public function dataProvider(): array
'extra' => [
'grumphp' => [
'config-default-path' => 'vendor/youwe/testing-suite/config/default/grumphp.yml'
- ]
- ]
- ]
- ]
+ ],
+ ],
+ ],
+ ],
];
}
}
diff --git a/tests/Installer/FilesInstallerTest.php b/tests/Installer/FilesInstallerTest.php
index 545c7d0..334f58c 100644
--- a/tests/Installer/FilesInstallerTest.php
+++ b/tests/Installer/FilesInstallerTest.php
@@ -12,7 +12,9 @@
use Composer\IO\IOInterface;
use org\bovigo\vfs\vfsStream;
use org\bovigo\vfs\vfsStreamDirectory;
-use PHPUnit\Framework\MockObject\MockObject;
+use PHPUnit\Framework\Attributes\CoversMethod;
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\MockObject\Exception;
use PHPUnit\Framework\TestCase;
use Youwe\Composer\FileInstaller;
use Youwe\FileMapping\FileMappingInterface;
@@ -21,27 +23,21 @@
use Youwe\TestingSuite\Composer\MappingResolver;
/**
- * @coversDefaultClass FilesInstaller
- * @SuppressWarnings(PHPMD)
+ * @phpcs:disable GlobalPhpUnit.Coverage.CoversTag.CoversTagMissing
*/
+#[CoversMethod(FileInstaller::class, '__construct')]
+#[CoversMethod(FileInstaller::class, 'install')]
class FilesInstallerTest extends TestCase
{
/**
- * @param array $existingFiles
- * @param array $files
- * @param int $expectedInstalls
- *
- * @return void
- * @dataProvider dataProvider
- *
- * @covers ::__construct
- * @covers ::install
+ * @throws Exception
*/
+ #[DataProvider('dataProvider')]
public function testInstall(
array $existingFiles,
array $files,
- int $expectedInstalls
- ) {
+ int $expectedInstalls,
+ ): void {
$filesystem = $this->createFilesystem($existingFiles);
$reader = $this->createReaderMock($files, $filesystem->url());
$resolver = $this->createMock(MappingResolver::class);
@@ -61,10 +57,7 @@ public function testInstall(
$installer->install();
}
- /**
- * @return array
- */
- public function dataProvider(): array
+ public static function dataProvider(): array
{
return [
[
@@ -74,22 +67,18 @@ public function dataProvider(): array
[
'foo-file.txt',
'bar-file.txt',
- 'baz-file.txt'
+ 'baz-file.txt',
],
2
- ]
+ ],
];
}
/**
- * @param array $files
- * @param string $destination
- *
- * @return FileMappingReaderInterface
+ * @throws Exception
*/
private function createReaderMock(array $files, string $destination): FileMappingReaderInterface
{
- /** @var FileMappingReaderInterface|MockObject $mock */
$mock = $this->createMock(FileMappingReaderInterface::class);
$valids = array_fill(0, count($files), true);
@@ -97,7 +86,6 @@ private function createReaderMock(array $files, string $destination): FileMappin
$mappings = array_map(
function (string $file) use ($destination): FileMappingInterface {
- /** @var FileMappingInterface|MockObject $mapping */
$mapping = $this->createMock(FileMappingInterface::class);
$mapping
->expects(self::any())
@@ -127,17 +115,12 @@ function (string $file) use ($destination): FileMappingInterface {
return $mock;
}
- /**
- * @param array $files
- *
- * @return vfsStreamDirectory
- */
private function createFilesystem(array $files): vfsStreamDirectory
{
return vfsStream::setup(
sha1(__METHOD__),
null,
- array_map('strval', array_flip($files))
+ array_map('strval', array_flip($files)),
);
}
}
diff --git a/tests/Installer/PackagesInstallerTest.php b/tests/Installer/PackagesInstallerTest.php
index 9e8210f..2d76d6a 100644
--- a/tests/Installer/PackagesInstallerTest.php
+++ b/tests/Installer/PackagesInstallerTest.php
@@ -11,121 +11,189 @@
use Composer\Composer;
use Composer\IO\IOInterface;
-use Composer\Package\Link;
-use Composer\Package\Package;
+use PHPUnit\Framework\Attributes\CoversMethod;
+use PHPUnit\Framework\MockObject\Exception;
use PHPUnit\Framework\TestCase;
use Youwe\Composer\DependencyInstaller\DependencyInstaller;
use Youwe\TestingSuite\Composer\Installer\PackagesInstaller;
+use Youwe\TestingSuite\Composer\MappingResolver;
use Youwe\TestingSuite\Composer\ProjectTypeResolver;
/**
- * @coversDefaultClass \Youwe\TestingSuite\Composer\Installer\PackagesInstaller
- * @SuppressWarnings(PHPMD)
+ * @phpcs:disable GlobalPhpUnit.Coverage.CoversTag.CoversTagMissing
*/
+#[CoversMethod(PackagesInstaller::class, '__construct')]
+#[CoversMethod(PackagesInstaller::class, 'install')]
+#[CoversMethod(PackagesInstaller::class, 'isPackageRequired')]
class PackagesInstallerTest extends TestCase
{
/**
- * @param string $type
- * @param array $requires
- * @param array|null $expected
- *
- * @return void
- * @dataProvider dataProvider
- *
- * @covers ::__construct
- * @covers ::install
- * @covers ::isPackageRequired
+ * @throws Exception
*/
- public function testInstall(
- string $type,
- array $requires,
- array $expected = null
- ) {
+ public function testCanInstallWithMocks(): void
+ {
$composer = $this->createMock(Composer::class);
$typeResolver = $this->createMock(ProjectTypeResolver::class);
$depInstaller = $this->createMock(DependencyInstaller::class);
$io = $this->createMock(IOInterface::class);
- $typeResolver
- ->expects(self::any())
- ->method('resolve')
- ->willReturn($type);
-
$installer = new PackagesInstaller(
$composer,
$typeResolver,
$io,
- $depInstaller
+ $depInstaller,
);
- if ($expected) {
- $depInstaller
- ->expects(self::exactly(count($expected)))
- ->method('installPackage')
- ->withConsecutive(...$expected);
- } else {
- $depInstaller
- ->expects(self::never())
- ->method('installPackage');
- }
+ $depInstaller
+ ->expects($this->atLeastOnce())
+ ->method('installPackage');
$installer->install();
}
/**
- * @return array
+ * @throws Exception
*/
- public function dataProvider(): array
+ public function testCanMergeDefaultPackagesWhenInstalling(): void
{
- return [
- [
- 'magento1',
- $this->createLinkMocks(['foo/bar']),
- [['youwe/coding-standard-magento1']]
+ $composer = $this->createMock(Composer::class);
+ $typeResolver = $this->createMock(ProjectTypeResolver::class);
+ $depInstaller = $this->createMock(DependencyInstaller::class);
+ $io = $this->createMock(IOInterface::class);
+
+ // Simulate magento 1 project
+ $typeResolver
+ ->method('resolve')
+ ->willReturn('magento1');
+
+ $mapping = [
+ MappingResolver::DEFAULT_MAPPING_TYPE => [
+ 'phpunit/phpunit' => [
+ 'version' => '@stable',
+ 'dev' => true,
+ 'updateDependencies' => true,
+ 'allowVersionOverride' => false,
+ ],
],
- [
- 'magento1',
- $this->createLinkMocks(
- ['foo/bar', 'youwe/coding-standard-magento1']
- ),
- [['youwe/coding-standard-magento1']]
+ 'magento1' => [
+ 'youwe/coding-standard-magento1' => [
+ 'version' => '^1.3.0',
+ 'dev' => true,
+ 'updateDependencies' => false,
+ 'allowVersionOverride' => true,
+ ],
],
- [
- 'magento2',
- $this->createLinkMocks(['foo/bar']),
- [['youwe/coding-standard-magento2']]
+ ];
+
+ $installer = new PackagesInstaller(
+ $composer,
+ $typeResolver,
+ $io,
+ $depInstaller,
+ $mapping
+ );
+
+ $depInstaller
+ ->expects($this->exactly(2))
+ ->method('installPackage')
+ ->willReturnCallback(
+ function ($package, $version, $dev, $updateDependencies, $allowVersionOverride) {
+ static $calls = 0;
+ $calls++;
+
+ if ($calls === 1) {
+ $this->assertEquals('phpunit/phpunit', $package);
+ $this->assertEquals('@stable', $version);
+ $this->assertTrue($dev);
+ $this->assertTrue($updateDependencies);
+ $this->assertFalse($allowVersionOverride);
+ }
+
+ if ($calls === 2) {
+ $this->assertEquals('youwe/coding-standard-magento1', $package);
+ $this->assertEquals('^1.3.0', $version);
+ $this->assertTrue($dev);
+ $this->assertFalse($updateDependencies);
+ $this->assertTrue($allowVersionOverride);
+ }
+
+ if ($calls > 2) {
+ $this->fail('Unexpected number of calls');
+ }
+ }
+ );
+
+ $installer->install();
+ }
+
+ public function testCanMergeRecursivelyWhenInstalling(): void
+ {
+ $composer = $this->createMock(Composer::class);
+ $typeResolver = $this->createMock(ProjectTypeResolver::class);
+ $depInstaller = $this->createMock(DependencyInstaller::class);
+ $io = $this->createMock(IOInterface::class);
+
+ $mapping = [
+ MappingResolver::DEFAULT_MAPPING_TYPE => [
+ 'phpunit/phpunit' => [
+ 'version' => '@stable',
+ 'dev' => true,
+ 'updateDependencies' => true,
+ 'allowVersionOverride' => false,
+ ],
],
- [
- 'default',
- $this->createLinkMocks(['foo/bar']),
- null
+ 'magento2' => [
+ 'phpunit/phpunit' => [
+ 'version' => '^10.6.5',
+ 'dev' => false,
+ 'allowVersionOverride' => true,
+ ],
],
- [
- 'unknown',
- $this->createLinkMocks(['foo/bar']),
- null
- ]
];
+
+ $typeResolver
+ ->method('resolve')
+ ->willReturn('magento2');
+
+ $installer = new PackagesInstaller(
+ $composer,
+ $typeResolver,
+ $io,
+ $depInstaller,
+ $mapping,
+ );
+
+ $depInstaller
+ ->expects($this->exactly(1))
+ ->method('installPackage')
+ ->with('phpunit/phpunit', '^10.6.5', false, true, true);
+
+ $installer->install();
}
- /**
- * @param string[] $targets
- *
- * @return Link[]
- */
- private function createLinkMocks(array $targets): array
+ public function testPhpUnitIsInstalledForUnknownProjectType(): void
{
- return array_map(
- function (string $target): Link {
- /** @var Link $mock */
- $mock = $this->createConfiguredMock(
- Link::class,
- ['getTarget' => $target]
- );
-
- return $mock;
- },
- $targets
+ $composer = $this->createMock(Composer::class);
+ $typeResolver = $this->createMock(ProjectTypeResolver::class);
+ $depInstaller = $this->createMock(DependencyInstaller::class);
+ $io = $this->createMock(IOInterface::class);
+
+ $typeResolver
+ ->method('resolve')
+ ->willReturn('foobar');
+
+ $installer = new PackagesInstaller(
+ $composer,
+ $typeResolver,
+ $io,
+ $depInstaller,
);
+
+ $depInstaller
+ ->expects($this->exactly(1))
+ ->method('installPackage')
+ ->with('phpunit/phpunit', '@stable', true, true, false);
+
+ $installer->install();
}
}
diff --git a/tests/MappingResolverTest.php b/tests/MappingResolverTest.php
index 10014d1..ce46631 100644
--- a/tests/MappingResolverTest.php
+++ b/tests/MappingResolverTest.php
@@ -9,21 +9,22 @@
namespace Youwe\TestingSuite\Composer\Tests;
+use PHPUnit\Framework\Attributes\CoversMethod;
+use PHPUnit\Framework\MockObject\Exception;
use PHPUnit\Framework\TestCase;
use Youwe\FileMapping\FileMappingReaderInterface;
use Youwe\TestingSuite\Composer\MappingResolver;
use Youwe\TestingSuite\Composer\ProjectTypeResolver;
/**
- * @coversDefaultClass \Youwe\TestingSuite\Composer\MappingResolver
+ * @phpcs:disable GlobalPhpUnit.Coverage.CoversTag.CoversTagMissing
*/
+#[CoversMethod(MappingResolver::class, '__construct')]
+#[CoversMethod(MappingResolver::class, 'resolve')]
class MappingResolverTest extends TestCase
{
/**
- * @return void
- *
- * @covers ::__construct
- * @covers ::resolve
+ * @throws Exception
*/
public function testResolve()
{
diff --git a/tests/PluginTest.php b/tests/PluginTest.php
index 826b004..56c7082 100644
--- a/tests/PluginTest.php
+++ b/tests/PluginTest.php
@@ -11,29 +11,30 @@
use Composer\Composer;
use Composer\IO\IOInterface;
+use PHPUnit\Framework\Attributes\CoversMethod;
+use PHPUnit\Framework\MockObject\Exception;
use PHPUnit\Framework\TestCase;
use ReflectionProperty;
use Youwe\TestingSuite\Composer\Installer\InstallerInterface;
use Youwe\TestingSuite\Composer\Plugin;
/**
- * @coversDefaultClass \Youwe\TestingSuite\Composer\Plugin
- * @SuppressWarnings(PHPMD)
+ * @phpcs:disable GlobalPhpUnit.Coverage.CoversTag.CoversTagMissing
*/
+#[CoversMethod(Plugin::class, 'activate')]
+#[CoversMethod(Plugin::class, 'install')]
+#[CoversMethod(Plugin::class, 'getSubscribedEvents')]
class PluginTest extends TestCase
{
/**
- * @return void
- *
- * @covers ::activate
- * @covers ::addInstallers
+ * @throws Exception
*/
- public function testActivate()
+ public function testActivate(): void
{
$plugin = new Plugin();
$plugin->activate(
$this->createMock(Composer::class),
- $this->createMock(IOInterface::class)
+ $this->createMock(IOInterface::class),
);
$reflection = new ReflectionProperty(Plugin::class, 'installers');
@@ -41,17 +42,14 @@ public function testActivate()
$this->assertContainsOnlyInstancesOf(
InstallerInterface::class,
- $reflection->getValue($plugin)
+ $reflection->getValue($plugin),
);
}
/**
- * @return void
- *
- * @covers ::__construct
- * @covers ::install
+ * @throws Exception
*/
- public function testInstall()
+ public function testInstall(): void
{
$installers = [
$this->createMock(InstallerInterface::class),
@@ -68,12 +66,7 @@ public function testInstall()
$plugin->install();
}
- /**
- * @return void
- *
- * @covers ::getSubscribedEvents
- */
- public function testGetSubscribesEvents()
+ public function testGetSubscribesEvents(): void
{
$plugin = new Plugin();
diff --git a/tests/ProjectTypeResolverTest.php b/tests/ProjectTypeResolverTest.php
index 01b2459..5221b89 100644
--- a/tests/ProjectTypeResolverTest.php
+++ b/tests/ProjectTypeResolverTest.php
@@ -12,25 +12,23 @@
use Composer\Composer;
use Composer\Config;
use Composer\Package\RootPackageInterface;
+use PHPUnit\Framework\Attributes\CoversMethod;
+use PHPUnit\Framework\Attributes\TestWith;
+use PHPUnit\Framework\MockObject\Exception;
use PHPUnit\Framework\TestCase;
use Youwe\TestingSuite\Composer\ProjectTypeResolver;
-/**
- * @coversDefaultClass \Youwe\TestingSuite\Composer\ProjectTypeResolver
- */
+#[CoversMethod(ProjectTypeResolver::class, '__construct')]
+#[CoversMethod(ProjectTypeResolver::class, 'resolve')]
class ProjectTypeResolverTest extends TestCase
{
/**
- * @param string $packageType
- * @param string $expected
- *
- * @return void
- *
- * @dataProvider dataProvider
- *
- * @covers ::__construct
- * @covers ::resolve
+ * @throws Exception
*/
+ #[TestWith(['some-type', 'default'])]
+ #[TestWith(['magento-module', 'magento1'])]
+ #[TestWith(['magento2-module', 'magento2'])]
+ #[TestWith(['alumio-project', 'alumio'])]
public function testToString(string $packageType, string $expected): void
{
$composer = $this->createMock(Composer::class);
@@ -56,12 +54,6 @@ public function testToString(string $packageType, string $expected): void
$this->assertEquals($expected, $decider->resolve());
}
- /**
- * @return void
- *
- * @covers ::__construct
- * @covers ::resolve
- */
public function testToStringOverwrite(): void
{
$composer = $this->createMock(Composer::class);
@@ -91,17 +83,4 @@ public function testToStringOverwrite(): void
$decider = new ProjectTypeResolver($composer);
$this->assertEquals('magento2', $decider->resolve());
}
-
- /**
- * @return array
- */
- public function dataProvider(): array
- {
- return [
- ['some-type', 'default'],
- ['magento-module', 'magento1'],
- ['magento2-module', 'magento2'],
- ['alumio-project', 'alumio'],
- ];
- }
}