diff --git a/.github/workflows/phpmd.yml b/.github/workflows/phpmd.yml new file mode 100644 index 0000000..b4365f6 --- /dev/null +++ b/.github/workflows/phpmd.yml @@ -0,0 +1,29 @@ +name: PHPMD + +on: [push, pull_request] + +jobs: + phpcs: + name: Mess Detector + runs-on: [ubuntu-latest] + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Get composer cache directory + id: composer-cache + run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT + + - name: Cache dependencies + uses: actions/cache@v4 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: ${{ runner.os }}-composer- + + - name: Install dependencies + run: composer install --prefer-dist --no-progress --ignore-platform-req=ext-* + + - name: PHPMD + run: php vendor/bin/phpmd src/ github .phpmd.dist.xml --baseline-file .phpmd.dist.baseline.xml diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml new file mode 100644 index 0000000..6a6f016 --- /dev/null +++ b/.github/workflows/phpstan.yml @@ -0,0 +1,48 @@ +name: PHPStan + +on: [push, pull_request] + +jobs: + phpstan: + name: Analyze + runs-on: [ubuntu-latest] + + steps: + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: 7.4 + + - uses: actions/checkout@v4 + + - name: Get composer cache directory + id: composer-cache + run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT + + - name: Cache dependencies + uses: actions/cache@v4 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: ${{ runner.os }}-composer- + + - name: Install dependencies + run: composer install --prefer-dist --no-progress --ignore-platform-req=ext-* + + - name: Restore result cache + uses: actions/cache/restore@v4 + with: + path: .phpstan.cache + key: phpstan-result-cache-${{ github.run_id }} + restore-keys: | + phpstan-result-cache- + + - name: PHPStan Static Analysis + run: XDEBUG_MODE=off php vendor/bin/phpstan.phar analyze + + - name: Save result cache + uses: actions/cache/save@v4 + if: always() + with: + path: .phpstan.cache + key: phpstan-result-cache-${{ github.run_id }} \ No newline at end of file diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml new file mode 100644 index 0000000..7256908 --- /dev/null +++ b/.github/workflows/phpunit.yml @@ -0,0 +1,39 @@ +name: PHPUnit + +on: [push, pull_request] + +jobs: + unit-tests: + runs-on: ${{ matrix.operating-system }} + strategy: + matrix: + operating-system: [ubuntu-latest] + php-versions: ['7.4', '8.3'] + + steps: + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-versions }} + coverage: pcov #optional, setup coverage driver + env: + COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - uses: actions/checkout@v4 + + - name: Get composer cache directory + id: composer-cache + run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT + + - name: Cache dependencies + uses: actions/cache@v4 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: ${{ runner.os }}-composer- + + - name: Install dependencies + run: composer install --prefer-dist --no-progress --ignore-platform-req=ext-* + + - name: Run phpUnit + run: php vendor/bin/phpunit --configuration .phpunit.dist.xml diff --git a/.gitignore b/.gitignore index a14120a..fc32c58 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ /.idea /vendor +/.phpstan.cache +/.phpunit.cache .php-cs-fixer.cache +.phpmd.result-cache.php composer.lock diff --git a/.phpmd.dist.baseline.xml b/.phpmd.dist.baseline.xml new file mode 100644 index 0000000..a7c75f6 --- /dev/null +++ b/.phpmd.dist.baseline.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/.phpmd.dist.xml b/.phpmd.dist.xml new file mode 100644 index 0000000..5fc3105 --- /dev/null +++ b/.phpmd.dist.xml @@ -0,0 +1,23 @@ + + + + OpenMage ruleset + + + + + + + + + + + + + + + diff --git a/.phpstan.dist.neon b/.phpstan.dist.neon new file mode 100644 index 0000000..8c0d2cf --- /dev/null +++ b/.phpstan.dist.neon @@ -0,0 +1,12 @@ +includes: + - phar://phpstan.phar/conf/bleedingEdge.neon +parameters: + phpVersion: + min: 70400 + max: 80499 + fileExtensions: + - php + paths: + - src + tmpDir: .phpstan.cache + level: 9 diff --git a/.phpunit.dist.xml b/.phpunit.dist.xml new file mode 100644 index 0000000..766495c --- /dev/null +++ b/.phpunit.dist.xml @@ -0,0 +1,27 @@ + + + + + tests + + + + + + src + + + diff --git a/composer.json b/composer.json index 7bdf514..705353f 100644 --- a/composer.json +++ b/composer.json @@ -26,12 +26,38 @@ "symfony/finder": "*" }, "require-dev": { - "composer/composer": "^2.7", + "composer/composer": "^2.8", + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-strict-rules": "^2.0", + "phpstan/phpstan-symfony": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^9.6", + "phpmd/phpmd": "^2.15", "friendsofphp/php-cs-fixer": "^3.67" }, "extra": { "class": "OpenMage\\ComposerPlugin\\Plugin" }, + "scripts": { + "php-cs-fixer:test": "vendor/bin/php-cs-fixer fix --dry-run --diff", + "php-cs-fixer:fix": "vendor/bin/php-cs-fixer fix", + "phpmd": "vendor/bin/phpmd src text .phpmd.dist.xml --color --cache --baseline-file .phpmd.dist.baseline.xml", + "phpstan": "XDEBUG_MODE=off php vendor/bin/phpstan analyze", + "phpstan:baseline": "XDEBUG_MODE=off php vendor/bin/phpstan analyze -b .phpstan.dist.baseline.neon", + "phpunit:test": "XDEBUG_MODE=off php vendor/bin/phpunit --configuration .phpunit.dist.xml --no-coverage", + "phpunit:coverage": "XDEBUG_MODE=coverage php vendor/bin/phpunit --configuration .phpunit.dist.xml --testdox", + "phpunit:coverage-local": "XDEBUG_MODE=coverage php vendor/bin/phpunit --configuration .phpunit.dist.xml --coverage-html build/coverage-composer-plugin --testdox" + }, + "scripts-descriptions": { + "php-cs-fixer:test": "Run php-cs-fixer", + "php-cs-fixer:fix": "Run php-cs-fixer and fix issues", + "phpmd": "Run phpmd", + "phpstan": "Run phpstan", + "phpstan:baseline": "Run phpstan and update baseline", + "phpunit:test": "Run PHPUnit", + "phpunit:coverage": "Run PHPUnit with code coverage (requires XDEBUG enabled)", + "phpunit:coverage-local": "Run PHPUnit with local HTML code coverage (requires XDEBUG enabled)" + }, "funding": [ { "type": "opencollective", diff --git a/src/OpenMage/ComposerPlugin/Copy/AbstractCopyPlugin.php b/src/OpenMage/ComposerPlugin/Copy/AbstractCopyPlugin.php index d5b1a80..1ab8a48 100644 --- a/src/OpenMage/ComposerPlugin/Copy/AbstractCopyPlugin.php +++ b/src/OpenMage/ComposerPlugin/Copy/AbstractCopyPlugin.php @@ -13,6 +13,7 @@ use Composer\Package\BasePackage; use Composer\Script\Event; +use ErrorException; use Exception; use Symfony\Component\Filesystem\Exception\IOException; use Symfony\Component\Filesystem\Filesystem; @@ -28,21 +29,24 @@ abstract class AbstractCopyPlugin implements CopyInterface * * @var BasePackage[] */ - public array $installedComposerPackages = []; + public array $composerPackages = []; /** * Packages installad via Unpkg downloadd * * @var array> */ - public array $installedUnpkgPackages = []; + public array $unpkgPackages = []; /** * Composer event */ - protected Event $event; + protected ?Event $event; - public function __construct(Event $event) + /** + * @codeCoverageIgnore + */ + public function __construct(?Event $event) { $this->event = $event; } @@ -54,12 +58,8 @@ public function __construct(Event $event) */ public function processComposerInstall(): void { - if (!$this instanceof CopyFromComposerInterface) { - return; - } - $package = $this->getComposerPackage(); - if (!$package) { + if (!$package || !$this instanceof CopyFromComposerInterface) { return; } @@ -70,11 +70,12 @@ public function processComposerInstall(): void $this->getComposerSource(), ); - $filesystem = new Filesystem(); + $event = $this->getEvent(); + $filesystem = $this->getFileSystem(); if (!$filesystem->exists($copySourcePath) && $this instanceof CopyFromUnpkgInterface) { - if ($this->event->getIO()->isVerbose()) { - $this->event->getIO()->write(sprintf( + if ($event && $event->getIO()->isVerbose()) { + $event->getIO()->write(sprintf( 'Fallback to Unpkg %s for %s', $this->getUnpkgName(), $this->getComposerName(), @@ -95,11 +96,13 @@ public function processComposerInstall(): void try { $filesystem->copy($copySource, $copytarget); - if ($this->event->getIO()->isVeryVerbose()) { - $this->event->getIO()->write(sprintf('Copy %s to %s', $copySource, $copytarget)); + if ($event && $event->getIO()->isVeryVerbose()) { + $event->getIO()->write(sprintf('Copy %s to %s', $copySource, $copytarget)); + } + } catch (IOException $exception) { + if ($event) { + $event->getIO()->write($exception->getMessage()); } - } catch (IOException $IOException) { - $this->event->getIO()->write($IOException->getMessage()); } } } @@ -109,18 +112,15 @@ public function processComposerInstall(): void */ public function processUnpkgInstall(): void { - if (!$this instanceof CopyFromUnpkgInterface) { - return; - } - - if (!$this->getUnpkgVersion()) { + if (!$this instanceof CopyFromUnpkgInterface || !$this->getUnpkgVersion()) { return; } + $event = $this->getEvent(); $sourcePath = $this->getUnpkSourcePath(); - if ($this->event->getIO()->isVerbose()) { - $this->event->getIO()->write(sprintf( + if ($event && $event->getIO()->isVerbose()) { + $event->getIO()->write(sprintf( 'Trying to download %s %s from %s', $this->getUnpkgName(), $this->getUnpkgVersion(), @@ -132,25 +132,30 @@ public function processUnpkgInstall(): void $sourceFilePath = $sourcePath . $fileName; try { $content = file_get_contents($sourceFilePath); - } catch (\ErrorException $errorException) { - $this->event->getIO()->write($errorException->getMessage()); + } catch (ErrorException $errorException) { + if ($event) { + $event->getIO()->write($errorException->getMessage()); + } return; } if (!$content) { - $this->event->getIO()->write(sprintf('Could not read from %s', $sourceFilePath)); + if ($event) { + $event->getIO()->write(sprintf('Could not read from %s', $sourceFilePath)); + } return; } try { - $filesystem = new Filesystem(); $targetFilePath = $this->getCopyTargetPath() . '/' . $fileName; - $filesystem->dumpFile($targetFilePath, $content); - if ($this->event->getIO()->isVerbose()) { - $this->event->getIO()->write(sprintf('Added %s', $targetFilePath)); + $this->getFileSystem()->dumpFile($targetFilePath, $content); + if ($event && $event->getIO()->isVerbose()) { + $event->getIO()->write(sprintf('Added %s', $targetFilePath)); + } + } catch (IOException $exception) { + if ($event) { + $event->getIO()->write($exception->getMessage()); } - } catch (IOException $IOException) { - $this->event->getIO()->write($IOException->getMessage()); return; } } @@ -158,31 +163,38 @@ public function processUnpkgInstall(): void public function getComposerPackage(): ?BasePackage { - if ($this instanceof CopyFromComposerInterface) { - $vendorName = $this->getComposerName(); - $module = $this->getInstalledComposerPackage($vendorName); - if ($module) { - return $module; - } + if (!$this instanceof CopyFromComposerInterface) { + return null; + } + + $vendorName = $this->getComposerName(); + $module = $this->getInstalledComposerPackage($vendorName); + if ($module) { + return $module; + } + + $event = $this->getEvent(); + if (!$event) { + return null; + } - $locker = $this->event->getComposer()->getLocker(); - $repo = $locker->getLockedRepository(); + $locker = $event->getComposer()->getLocker(); + $repo = $locker->getLockedRepository(); - foreach ($repo->getPackages() as $package) { - if ($package->getName() === $vendorName) { - $this->setInstalledComposerPackage($vendorName, $package); - if ($this->event->getIO()->isVerbose()) { - $this->event->getIO()->write(sprintf('%s found with version %s', $vendorName, $package->getVersion())); - } - return $this->getInstalledComposerPackage($vendorName); + foreach ($repo->getPackages() as $package) { + if ($package->getName() === $vendorName) { + $this->setInstalledComposerPackage($vendorName, $package); + if ($event->getIO()->isVerbose()) { + $event->getIO()->write(sprintf('%s found with version %s', $vendorName, $package->getVersion())); } + return $this->getInstalledComposerPackage($vendorName); } } return null; } /** - * Get path to NPM dist + * Get path to Unpkg dist */ protected function getUnpkSourcePath(): string { @@ -212,8 +224,13 @@ protected function getCwd(): string */ protected function getVendorDirectoryFromComposer(): string { + $event = $this->getEvent(); + if (!$event) { + return ''; + } + /** @var string $vendorDir */ - $vendorDir = $this->event->getComposer()->getConfig()->get(self::VENDOR_DIR); + $vendorDir = $event->getComposer()->getConfig()->get(self::VENDOR_DIR); return $vendorDir; } @@ -222,7 +239,12 @@ protected function getVendorDirectoryFromComposer(): string */ protected function getMageRootDirectoryFromComposer(): string { - $composerExtra = $this->event->getComposer()->getPackage()->getExtra(); + $event = $this->getEvent(); + if (!$event) { + return ''; + } + + $composerExtra = $event->getComposer()->getPackage()->getExtra(); $magentoRootDir = ''; if (array_key_exists(self::EXTRA_MAGENTO_ROOT_DIR, $composerExtra) && @@ -245,11 +267,21 @@ private function getCopyTargetPath(): string protected function getInstalledComposerPackage(string $vendorName): ?BasePackage { - return $this->installedComposerPackages[$vendorName] ?? null; + return $this->composerPackages[$vendorName] ?? null; } private function setInstalledComposerPackage(string $vendorName, BasePackage $package): void { - $this->installedComposerPackages[$vendorName] = $package; + $this->composerPackages[$vendorName] = $package; + } + + public function getFileSystem(): Filesystem + { + return new Filesystem(); + } + + public function getEvent(): ?Event + { + return $this->event; } } diff --git a/src/OpenMage/ComposerPlugin/Copy/CopyFromComposerInterface.php b/src/OpenMage/ComposerPlugin/Copy/CopyFromComposerInterface.php index 14cd36f..6dad610 100644 --- a/src/OpenMage/ComposerPlugin/Copy/CopyFromComposerInterface.php +++ b/src/OpenMage/ComposerPlugin/Copy/CopyFromComposerInterface.php @@ -12,12 +12,12 @@ namespace OpenMage\ComposerPlugin\Copy; /** - * PluginInterface + * CopyFromComposerInterface */ interface CopyFromComposerInterface { /** - * Npm name + * Composer name */ public function getComposerName(): string; diff --git a/src/OpenMage/ComposerPlugin/Copy/CopyFromUnpkgInterface.php b/src/OpenMage/ComposerPlugin/Copy/CopyFromUnpkgInterface.php index 2441c99..b702b3e 100644 --- a/src/OpenMage/ComposerPlugin/Copy/CopyFromUnpkgInterface.php +++ b/src/OpenMage/ComposerPlugin/Copy/CopyFromUnpkgInterface.php @@ -12,22 +12,30 @@ namespace OpenMage\ComposerPlugin\Copy; /** - * PluginInterface + * CopyFromUnpkgInterface */ interface CopyFromUnpkgInterface { public const UNPKG_URL = 'https://unpkg.com/{{package}}@{{version}}/'; /** - * Npm name + * Unpkg name */ public function getUnpkgName(): string; + /** + * Unpkg version + */ public function getUnpkgVersion(): string; + /** + * Unpkg source + */ public function getUnpkgSource(): string; /** + * Unpkg files + * * @return string[] */ public function getUnpkgFiles(): array; diff --git a/src/OpenMage/ComposerPlugin/Copy/CopyInterface.php b/src/OpenMage/ComposerPlugin/Copy/CopyInterface.php index 7205e8a..6f292d1 100644 --- a/src/OpenMage/ComposerPlugin/Copy/CopyInterface.php +++ b/src/OpenMage/ComposerPlugin/Copy/CopyInterface.php @@ -12,7 +12,7 @@ namespace OpenMage\ComposerPlugin\Copy; /** - * PluginInterface + * CopyInterface */ interface CopyInterface { diff --git a/src/OpenMage/ComposerPlugin/Copy/Plugins/ChartJs.php b/src/OpenMage/ComposerPlugin/Copy/Plugins/ChartJs.php index 25ee99c..312b091 100644 --- a/src/OpenMage/ComposerPlugin/Copy/Plugins/ChartJs.php +++ b/src/OpenMage/ComposerPlugin/Copy/Plugins/ChartJs.php @@ -24,6 +24,9 @@ public function getUnpkgName(): string return 'chart.js'; } + /** + * @SuppressWarnings("PHPMD.StaticAccess") + */ public function getUnpkgVersion(): string { /** @var string $version */ diff --git a/src/OpenMage/ComposerPlugin/Copy/Plugins/JQuery.php b/src/OpenMage/ComposerPlugin/Copy/Plugins/JQuery.php index 21891a4..cd81171 100644 --- a/src/OpenMage/ComposerPlugin/Copy/Plugins/JQuery.php +++ b/src/OpenMage/ComposerPlugin/Copy/Plugins/JQuery.php @@ -30,7 +30,7 @@ public function getComposerSource(): string public function getComposerFiles(): array { - return ['*.map', '*.js']; + return ['*.js', '*.map']; } public function getCopyTarget(): string diff --git a/src/OpenMage/ComposerPlugin/Copy/Plugins/TinyMce.php b/src/OpenMage/ComposerPlugin/Copy/Plugins/TinyMce.php index 7cdec13..553eb09 100644 --- a/src/OpenMage/ComposerPlugin/Copy/Plugins/TinyMce.php +++ b/src/OpenMage/ComposerPlugin/Copy/Plugins/TinyMce.php @@ -14,7 +14,6 @@ use Composer\Package\BasePackage; use OpenMage\ComposerPlugin\Copy; use Symfony\Component\Filesystem\Exception\IOException; -use Symfony\Component\Filesystem\Filesystem; /** * Class TinyMce @@ -24,6 +23,21 @@ class TinyMce extends Copy\AbstractCopyPlugin implements Copy\CopyFromComposerIn public const TINYMCE_LICENSE_FILE = 'LICENSE_TINYMCE.txt'; public const TINYMCE_LICENSE_NOTE = 'LICENSE_TINYMCE_OPENMAGE.txt'; + public const TINYMCE_LICENSE_FILE_TEXT = <<event)) { + return; + } + $package = $this->getComposerPackage(); if (!$package instanceof BasePackage) { return; @@ -67,37 +85,20 @@ public function processComposerInstall(): void private function addTinyMceLicenseFile(): void { - $content = <<dumpFile($this->getCwd() . '/' . self::TINYMCE_LICENSE_FILE, $content); - if ($this->event->getIO()->isVerbose()) { + $this->getFileSystem()->dumpFile($this->getCwd() . '/' . self::TINYMCE_LICENSE_FILE, self::TINYMCE_LICENSE_FILE_TEXT); + if (!is_null($this->event) && $this->event->getIO()->isVerbose()) { $this->event->getIO()->write(sprintf('Added %s', self::TINYMCE_LICENSE_FILE)); } - } catch (IOException $IOException) { - $this->event->getIO()->write($IOException->getMessage()); + } catch (IOException $exception) { + if (!is_null($this->event)) { + $this->event->getIO()->write($exception->getMessage()); + } } } private function addTinyMceLicenseNote(): void { - $content = <<dumpFile($filePath, $content); - if ($this->event->getIO()->isVerbose()) { + $this->getFileSystem()->dumpFile($filePath, self::TINYMCE_LICENSE_NOTE_TEXT); + if (!is_null($this->event) && $this->event->getIO()->isVerbose()) { $this->event->getIO()->write(sprintf('Added %s', self::TINYMCE_LICENSE_NOTE)); } - } catch (IOException $IOException) { - $this->event->getIO()->write($IOException->getMessage()); + } catch (IOException $exception) { + if (!is_null($this->event)) { + $this->event->getIO()->write($exception->getMessage()); + } } } @@ -122,15 +125,15 @@ private function removedTinyMceLicenseFiles(): void $this->getComposerSource() . '/' . self::TINYMCE_LICENSE_NOTE, ]; - $filesystem = new Filesystem(); - try { - $filesystem->remove($files); - if ($this->event->getIO()->isVeryVerbose()) { + $this->getFileSystem()->remove($files); + if (!is_null($this->event) && $this->event->getIO()->isVeryVerbose()) { $this->event->getIO()->write(sprintf('Removed %s and %s', self::TINYMCE_LICENSE_FILE, self::TINYMCE_LICENSE_NOTE)); } - } catch (IOException $IOException) { - $this->event->getIO()->write($IOException->getMessage()); + } catch (IOException $exception) { + if (!is_null($this->event)) { + $this->event->getIO()->write($exception->getMessage()); + } } } } diff --git a/src/OpenMage/ComposerPlugin/Copy/Plugins/TinyMceLanguages.php b/src/OpenMage/ComposerPlugin/Copy/Plugins/TinyMceLanguages.php index 8c6143d..c69b270 100644 --- a/src/OpenMage/ComposerPlugin/Copy/Plugins/TinyMceLanguages.php +++ b/src/OpenMage/ComposerPlugin/Copy/Plugins/TinyMceLanguages.php @@ -26,6 +26,9 @@ public function getComposerName(): string return 'mklkj/tinymce-i18n'; } + /** + * @SuppressWarnings("PHPMD.StaticAccess") + */ public function getComposerSource(): string { /** @var string $version */ @@ -43,6 +46,9 @@ public function getCopyTarget(): string return 'js/lib/tinymce/langs'; } + /** + * @SuppressWarnings("PHPMD.StaticAccess") + */ public function processComposerInstall(): void { if (!InstalledVersions::isInstalled(self::TINYMCE)) { diff --git a/src/OpenMage/ComposerPlugin/Copy/Unpkg/Config.php b/src/OpenMage/ComposerPlugin/Copy/Unpkg/Config.php index f0c8a6c..8aa1080 100644 --- a/src/OpenMage/ComposerPlugin/Copy/Unpkg/Config.php +++ b/src/OpenMage/ComposerPlugin/Copy/Unpkg/Config.php @@ -43,34 +43,75 @@ public function getValidatedConfig($packageConfig): ?array return null; } - if (!array_key_exists(self::CONFIG_FILES, $packageConfig) || !is_array($packageConfig[self::CONFIG_FILES])) { + $files = $this->validateConfigFiles($packageConfig); + if (!$files) { return null; } - if (!array_key_exists(self::CONFIG_VERSION, $packageConfig) || !is_string($packageConfig[self::CONFIG_VERSION])) { + $version = $this->validateConfigVersion($packageConfig); + if (!$version) { return null; } - $source = ''; - if (array_key_exists(self::CONFIG_SOURCE, $packageConfig) && is_string($packageConfig[self::CONFIG_SOURCE])) { - $source = $packageConfig[self::CONFIG_SOURCE]; - } - - $target = ''; - if (array_key_exists(self::CONFIG_TARGET, $packageConfig) && is_string($packageConfig[self::CONFIG_TARGET])) { - $target = $packageConfig[self::CONFIG_TARGET]; - } + $source = $this->validateConfigSource($packageConfig); + $target = $this->validateConfigTarget($packageConfig); - /** @var string[] $files */ - $files = $packageConfig[self::CONFIG_FILES]; return [ - 'version' => $packageConfig[self::CONFIG_VERSION], + 'version' => $version, 'source' => $source, 'target' => $target, 'files' => $files, ]; } + /** + * @param array $packageConfig + * @return string[]|null + */ + private function validateConfigFiles(array $packageConfig): ?array + { + if (array_key_exists(self::CONFIG_FILES, $packageConfig) && is_array($packageConfig[self::CONFIG_FILES])) { + /** @var string[] $files */ + $files = $packageConfig[self::CONFIG_FILES]; + return $files; + } + return null; + } + + /** + * @param array $packageConfig + */ + private function validateConfigVersion(array $packageConfig): ?string + { + if (array_key_exists(self::CONFIG_VERSION, $packageConfig) && is_string($packageConfig[self::CONFIG_VERSION])) { + return trim($packageConfig[self::CONFIG_VERSION]); + } + return null; + } + + /** + * @param array $packageConfig + */ + private function validateConfigSource(array $packageConfig): string + { + if (array_key_exists(self::CONFIG_SOURCE, $packageConfig) && is_string($packageConfig[self::CONFIG_SOURCE])) { + return trim($packageConfig[self::CONFIG_SOURCE]); + } + return ''; + } + + /** + * @param array $packageConfig + */ + private function validateConfigTarget(array $packageConfig): string + { + if (array_key_exists(self::CONFIG_TARGET, $packageConfig) && is_string($packageConfig[self::CONFIG_TARGET])) { + $target = str_replace(['../', './'], '', $packageConfig[self::CONFIG_TARGET]); + return trim($target); + } + return ''; + } + public function getUnpkgName(): string { return $this->name; diff --git a/src/OpenMage/ComposerPlugin/Copy/Unpkg/Generic.php b/src/OpenMage/ComposerPlugin/Copy/Unpkg/Generic.php index cd1fa2f..930d62e 100644 --- a/src/OpenMage/ComposerPlugin/Copy/Unpkg/Generic.php +++ b/src/OpenMage/ComposerPlugin/Copy/Unpkg/Generic.php @@ -15,13 +15,13 @@ use OpenMage\ComposerPlugin\Copy; /** - * Class Npm + * Class Generic */ class Generic extends Copy\AbstractCopyPlugin implements Copy\CopyFromUnpkgInterface { private Config $config; - public function __construct(Event $event, Config $config) + public function __construct(?Event $event, Config $config) { $this->config = $config; diff --git a/src/OpenMage/ComposerPlugin/Plugin.php b/src/OpenMage/ComposerPlugin/Plugin.php index 5d7d8f1..bfc713f 100644 --- a/src/OpenMage/ComposerPlugin/Plugin.php +++ b/src/OpenMage/ComposerPlugin/Plugin.php @@ -27,11 +27,12 @@ */ class Plugin implements PluginInterface, EventSubscriberInterface { - protected Composer $composer; + protected ?Composer $composer = null; - protected IOInterface $io; + protected ?IOInterface $io = null; /** + * @codeCoverageIgnore * @see PluginInterface::activate */ public function activate(Composer $composer, IOInterface $io): void @@ -40,8 +41,14 @@ public function activate(Composer $composer, IOInterface $io): void $this->io = $io; } + /** + * @SuppressWarnings("PHPMD.UnusedFormalParameter") + */ public function deactivate(Composer $composer, IOInterface $io): void {} + /** + * @SuppressWarnings("PHPMD.UnusedFormalParameter") + */ public function uninstall(Composer $composer, IOInterface $io): void {} /** @@ -68,7 +75,7 @@ public static function getSubscribedEvents(): array * @see \OpenMage\ComposerPlugin\Copy\Plugins\TinyMce * @see \OpenMage\ComposerPlugin\Copy\Plugins\TinyMceLanguages */ - public function processCopy(Event $event): void + public function processCopy(?Event $event): void { $plugins = $this->getPlugins(__DIR__ . '/Copy/Plugins'); foreach ($plugins as $plugin) { @@ -85,7 +92,10 @@ public function processCopy(Event $event): void $pluginLoaded->processUnpkgInstall(); continue; } - $this->io->write('Could not load ' . $plugin); + + if ($this->io) { + $this->io->write('Could not load ' . $plugin); + } } $plugins = $this->getUnpkgPackagesFromConfig(); @@ -102,6 +112,10 @@ private function getUnpkgPackagesFromConfig(): array { $packages = []; + if (is_null($this->composer)) { + return $packages; + } + $extra = $this->composer->getPackage()->getExtra(); if (!isset($extra[CopyInterface::EXTRA_UNPKG_PACKAGES])) { @@ -111,7 +125,9 @@ private function getUnpkgPackagesFromConfig(): array $config = $extra[CopyInterface::EXTRA_UNPKG_PACKAGES]; if (!is_array($config)) { - $this->io->write(sprintf('Configuration is invalid for %s', CopyInterface::EXTRA_UNPKG_PACKAGES)); + if ($this->io) { + $this->io->write(sprintf('Configuration is invalid for %s', CopyInterface::EXTRA_UNPKG_PACKAGES)); + } return $packages; } @@ -119,7 +135,9 @@ private function getUnpkgPackagesFromConfig(): array $config = new Config(); $packageConfig = $config->getValidatedConfig($packageConfig); if (!$packageConfig) { - $this->io->write(sprintf('Configuration is invalid for %s', $packageName)); + if ($this->io) { + $this->io->write(sprintf('Configuration is invalid for %s', $packageName)); + } continue; } @@ -150,8 +168,8 @@ private function getPlugins(string $path): array private function getClassName(string $filename): string { - $directoriesAndFilename = explode('/', $filename); - $filename = array_pop($directoriesAndFilename); + $fullFilename = explode('/', $filename); + $filename = array_pop($fullFilename); $nameAndExtension = explode('.', $filename); return array_shift($nameAndExtension); } diff --git a/tests/unit/Copy/AbstractCopyPluginTest.php b/tests/unit/Copy/AbstractCopyPluginTest.php new file mode 100644 index 0000000..d817089 --- /dev/null +++ b/tests/unit/Copy/AbstractCopyPluginTest.php @@ -0,0 +1,40 @@ +subject = $this->getMockForAbstractClass(Subject::class, [], '', false); + } + + /** + * @covers \OpenMage\ComposerPlugin\Copy\AbstractCopyPlugin::getFileSystem() + */ + public function testGetFileSystem(): void + { + $this->assertInstanceOf(Filesystem::class, $this->subject->getFileSystem()); + } +} diff --git a/tests/unit/Copy/Plugins/ChartJsTest.php b/tests/unit/Copy/Plugins/ChartJsTest.php new file mode 100644 index 0000000..a64e5cb --- /dev/null +++ b/tests/unit/Copy/Plugins/ChartJsTest.php @@ -0,0 +1,108 @@ +subject = new Subject(null); + } + + /** + * @covers \OpenMage\ComposerPlugin\Copy\Plugins\ChartJs::getUnpkgName() + */ + public function testGetUnpkgName(): void + { + $this->assertSame('chart.js', $this->subject->getUnpkgName()); + } + + /** + * @covers \OpenMage\ComposerPlugin\Copy\Plugins\ChartJs::getUnpkgVersion() + * @covers \OpenMage\ComposerPlugin\Copy\Plugins\ChartJs::getComposerName() + */ + public function testGetUnpkgVersion(): void + { + try { + $this->assertIsString($this->subject->getUnpkgVersion()); + } catch (OutOfBoundsException $exception) { + $this->assertSame('Package "nnnick/chartjs" is not installed', $exception->getMessage()); + } + } + + /** + * @covers \OpenMage\ComposerPlugin\Copy\Plugins\ChartJs::getUnpkgSource() + */ + public function testGetUnpkgSource(): void + { + $this->assertSame('dist', $this->subject->getUnpkgSource()); + } + + + /** + * @covers \OpenMage\ComposerPlugin\Copy\Plugins\ChartJs::getUnpkgFiles() + */ + public function testGetUnpkgFiles(): void + { + $result = [ + 0 => 'chart.umd.js', + 1 => 'chart.umd.js.map', + 2 => 'helpers.js', + 3 => 'helpers.js.map', + ]; + $this->assertSame($result, $this->subject->getUnpkgFiles()); + } + + /** + * @covers \OpenMage\ComposerPlugin\Copy\Plugins\ChartJs::getComposerName() + */ + public function testGetComposerName(): void + { + $this->assertSame('nnnick/chartjs', $this->subject->getComposerName()); + } + + /** + * @covers \OpenMage\ComposerPlugin\Copy\Plugins\ChartJs::getComposerSource() + */ + public function testGetComposerSource(): void + { + $this->assertSame('dist', $this->subject->getComposerSource()); + } + + /** + * @covers \OpenMage\ComposerPlugin\Copy\Plugins\ChartJs::getComposerFiles() + */ + public function testGetComposerFiles(): void + { + $this->assertSame(['*.js', '*.map'], $this->subject->getComposerFiles()); + } + + /** + * @covers \OpenMage\ComposerPlugin\Copy\Plugins\ChartJs::getCopyTarget() + */ + public function testGetCopyTarget(): void + { + $this->assertSame('js/lib/chartjs', $this->subject->getCopyTarget()); + } +} diff --git a/tests/unit/Copy/Plugins/FlatpickrTest.php b/tests/unit/Copy/Plugins/FlatpickrTest.php new file mode 100644 index 0000000..d34c5d8 --- /dev/null +++ b/tests/unit/Copy/Plugins/FlatpickrTest.php @@ -0,0 +1,80 @@ +subject = new Subject(null); + } + + /** + * @covers \OpenMage\ComposerPlugin\Copy\Plugins\Flatpickr::getUnpkgName() + */ + public function testGetUnpkgName(): void + { + $this->assertSame('flatpickr', $this->subject->getUnpkgName()); + } + + /** + * @covers \OpenMage\ComposerPlugin\Copy\Plugins\Flatpickr::getUnpkgVersion() + */ + public function testGetUnpkgVersion(): void + { + try { + $this->assertIsString($this->subject->getUnpkgVersion()); + } catch (OutOfBoundsException $exception) { + $this->assertSame('Package "nnnick/chartjs" is not installed', $exception->getMessage()); + } + } + + /** + * @covers \OpenMage\ComposerPlugin\Copy\Plugins\Flatpickr::getUnpkgSource() + */ + public function testGetUnpkgSource(): void + { + $this->assertSame('dist', $this->subject->getUnpkgSource()); + } + + /** + * @covers \OpenMage\ComposerPlugin\Copy\Plugins\Flatpickr::getUnpkgFiles() + */ + public function testGetUnpkgFiles(): void + { + $result = [ + 0 => 'flatpickr.min.css', + 1 => 'flatpickr.min.js', + ]; + $this->assertSame($result, $this->subject->getUnpkgFiles()); + } + + /** + * @covers \OpenMage\ComposerPlugin\Copy\Plugins\Flatpickr::getCopyTarget() + */ + public function testGetCopyTarget(): void + { + $this->assertSame('js/lib/flatpickr', $this->subject->getCopyTarget()); + } +} diff --git a/tests/unit/Copy/Plugins/FlowJsTest.php b/tests/unit/Copy/Plugins/FlowJsTest.php new file mode 100644 index 0000000..6dc1157 --- /dev/null +++ b/tests/unit/Copy/Plugins/FlowJsTest.php @@ -0,0 +1,63 @@ +subject = new Subject(null); + } + + /** + * @covers \OpenMage\ComposerPlugin\Copy\Plugins\FlowJs::getComposerName() + */ + public function testGetComposerName(): void + { + $this->assertSame('flowjs/flowjs', $this->subject->getComposerName()); + } + + /** + * @covers \OpenMage\ComposerPlugin\Copy\Plugins\FlowJs::getComposerSource() + */ + public function testGetComposerSource(): void + { + $this->assertSame('dist', $this->subject->getComposerSource()); + } + + /** + * @covers \OpenMage\ComposerPlugin\Copy\Plugins\FlowJs::getComposerFiles() + */ + public function testGetComposerFiles(): void + { + $this->assertSame(['*.js'], $this->subject->getComposerFiles()); + } + + /** + * @covers \OpenMage\ComposerPlugin\Copy\Plugins\FlowJs::getCopyTarget() + */ + public function testGetCopyTarget(): void + { + $this->assertSame('js/lib/uploader', $this->subject->getCopyTarget()); + } +} diff --git a/tests/unit/Copy/Plugins/JQueryTest.php b/tests/unit/Copy/Plugins/JQueryTest.php new file mode 100644 index 0000000..cdc4921 --- /dev/null +++ b/tests/unit/Copy/Plugins/JQueryTest.php @@ -0,0 +1,63 @@ +subject = new Subject(null); + } + + /** + * @covers \OpenMage\ComposerPlugin\Copy\Plugins\JQuery::getComposerName() + */ + public function testGetComposerName(): void + { + $this->assertSame('components/jquery', $this->subject->getComposerName()); + } + + /** + * @covers \OpenMage\ComposerPlugin\Copy\Plugins\JQuery::getComposerSource() + */ + public function testGetComposerSource(): void + { + $this->assertSame('', $this->subject->getComposerSource()); + } + + /** + * @covers \OpenMage\ComposerPlugin\Copy\Plugins\JQuery::getComposerFiles() + */ + public function testGetComposerFiles(): void + { + $this->assertSame(['*.js', '*.map'], $this->subject->getComposerFiles()); + } + + /** + * @covers \OpenMage\ComposerPlugin\Copy\Plugins\JQuery::getCopyTarget() + */ + public function testGetCopyTarget(): void + { + $this->assertSame('js/lib/jquery', $this->subject->getCopyTarget()); + } +} diff --git a/tests/unit/Copy/Plugins/TinyMceLanguagesTest.php b/tests/unit/Copy/Plugins/TinyMceLanguagesTest.php new file mode 100644 index 0000000..bc8207f --- /dev/null +++ b/tests/unit/Copy/Plugins/TinyMceLanguagesTest.php @@ -0,0 +1,68 @@ +subject = new Subject(null); + } + + /** + * @covers \OpenMage\ComposerPlugin\Copy\Plugins\TinyMceLanguages::getComposerName() + */ + public function testGetComposerName(): void + { + $this->assertSame('mklkj/tinymce-i18n', $this->subject->getComposerName()); + } + + /** + * @covers \OpenMage\ComposerPlugin\Copy\Plugins\TinyMceLanguages::getComposerSource() + */ + public function testGetComposerSource(): void + { + try { + $this->assertSame('langs7', $this->subject->getComposerSource()); + } catch (OutOfBoundsException $exception) { + $this->assertSame('Package "tinymce/tinymce" is not installed', $exception->getMessage()); + } + } + + /** + * @covers \OpenMage\ComposerPlugin\Copy\Plugins\TinyMceLanguages::getComposerFiles() + */ + public function testGetComposerFiles(): void + { + $this->assertSame(['*.css', '*.js'], $this->subject->getComposerFiles()); + } + + /** + * @covers \OpenMage\ComposerPlugin\Copy\Plugins\TinyMceLanguages::getCopyTarget() + */ + public function testGetCopyTarget(): void + { + $this->assertSame('js/lib/tinymce/langs', $this->subject->getCopyTarget()); + } +} diff --git a/tests/unit/Copy/Plugins/TinyMceTest.php b/tests/unit/Copy/Plugins/TinyMceTest.php new file mode 100644 index 0000000..f954341 --- /dev/null +++ b/tests/unit/Copy/Plugins/TinyMceTest.php @@ -0,0 +1,63 @@ +subject = new Subject(null); + } + + /** + * @covers \OpenMage\ComposerPlugin\Copy\Plugins\TinyMce::getComposerName() + */ + public function testGetComposerName(): void + { + $this->assertSame('tinymce/tinymce', $this->subject->getComposerName()); + } + + /** + * @covers \OpenMage\ComposerPlugin\Copy\Plugins\TinyMce::getComposerSource() + */ + public function testGetComposerSource(): void + { + $this->assertSame('', $this->subject->getComposerSource()); + } + + /** + * @covers \OpenMage\ComposerPlugin\Copy\Plugins\TinyMce::getComposerFiles() + */ + public function testGetComposerFiles(): void + { + $this->assertSame(['*.css', '*.js'], $this->subject->getComposerFiles()); + } + + /** + * @covers \OpenMage\ComposerPlugin\Copy\Plugins\TinyMce::getCopyTarget() + */ + public function testGetCopyTarget(): void + { + $this->assertSame('js/lib/tinymce', $this->subject->getCopyTarget()); + } +} diff --git a/tests/unit/Copy/Unpkg/ConfigTest.php b/tests/unit/Copy/Unpkg/ConfigTest.php new file mode 100644 index 0000000..97c1c3f --- /dev/null +++ b/tests/unit/Copy/Unpkg/ConfigTest.php @@ -0,0 +1,201 @@ +subject = new Subject(null); + } + + /** + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Config::getValidatedConfig() + * @dataProvider provideGetValidatedConfig + */ + public function testGetValidatedConfig(?array $expectedResult, $packageConfig): void + { + $this->assertSame($expectedResult, $this->subject->getValidatedConfig($packageConfig)); + } + + public function provideGetValidatedConfig(): Generator + { + yield 'invalid' => [ + null, + null, + ]; + + yield 'empty' => [ + null, + [], + ]; + + yield 'no files' => [ + null, + [ + 'files' => null, + 'version' => '1', + ], + ]; + + yield 'no version' => [ + null, + [ + 'files' => [ + 'test.file', + ], + 'version' => null, + ], + ]; + + yield 'empty source/target' => [ + [ + 'version' => '1', + 'source' => '', + 'target' => '', + 'files' => [ + 'test.file', + ], + ], + [ + 'files' => [ + 'test.file', + ], + 'version' => '1', + ], + ]; + + yield 'complete' => [ + [ + 'version' => '1', + 'source' => 'source', + 'target' => 'target', + 'files' => [ + 'test.file', + ], + ], + [ + 'files' => [ + 'test.file', + ], + 'version' => '1', + 'source' => 'source', + 'target' => 'target', + ], + ]; + + yield 'target sub-directory' => [ + [ + 'version' => '1', + 'source' => 'source', + 'target' => 'target', + 'files' => [ + 'test.file', + ], + ], + [ + 'files' => [ + 'test.file', + ], + 'version' => '1', + 'source' => 'source', + 'target' => './../target', + ], + ]; + + yield 'target w/ spaces' => [ + [ + 'version' => '1', + 'source' => 'source', + 'target' => 'target', + 'files' => [ + 'test.file', + ], + ], + [ + 'files' => [ + 'test.file', + ], + 'version' => '1', + 'source' => 'source', + 'target' => ' target ', + ], + ]; + } + + /** + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Config::getUnpkgName() + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Config::setUnpkgName() + */ + public function testUnpkgName(): void + { + $source = ''; + $this->subject->setUnpkgName($source); + $this->assertSame($source, $this->subject->getUnpkgName()); + } + + /** + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Config::getUnpkgVersion() + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Config::setUnpkgVersion() + */ + public function testUnpkgVersion(): void + { + $source = ''; + $this->subject->setUnpkgVersion($source); + $this->assertSame($source, $this->subject->getUnpkgVersion()); + } + + /** + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Config::getUnpkgSource() + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Config::setUnpkgSource() + */ + public function testUnpkgSource(): void + { + $source = ''; + $this->subject->setUnpkgSource($source); + $this->assertSame($source, $this->subject->getUnpkgSource()); + } + + /** + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Config::getCopyTarget() + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Config::setCopyTarget() + */ + public function testCopyTarget(): void + { + $target = ''; + $this->subject->setCopyTarget($target); + $this->assertSame($target, $this->subject->getCopyTarget()); + } + + /** + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Config::getUnpkgFiles() + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Config::setUnpkgFiles() + */ + public function testUnpkgFiles(): void + { + $files = []; + $this->subject->setUnpkgFiles($files); + $this->assertSame($files, $this->subject->getUnpkgFiles()); + } +} diff --git a/tests/unit/Copy/Unpkg/GenericTest.php b/tests/unit/Copy/Unpkg/GenericTest.php new file mode 100644 index 0000000..c70c555 --- /dev/null +++ b/tests/unit/Copy/Unpkg/GenericTest.php @@ -0,0 +1,116 @@ +setUnpkgName('name'); + $config->setUnpkgVersion('version'); + $config->setUnpkgSource('source'); + $config->setUnpkgFiles([]); + $config->setCopyTarget('target'); + + + $this->subject = new Subject(null, $config); + } + + /** + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Config::getUnpkgName() + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Config::setCopyTarget() + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Config::setUnpkgFiles() + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Config::setUnpkgName() + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Config::setUnpkgSource() + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Config::setUnpkgVersion() + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Generic::__construct() + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Generic::getUnpkgName() + */ + public function testGetUnpkgName(): void + { + $this->assertSame('name', $this->subject->getUnpkgName()); + } + + /** + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Config::getUnpkgVersion() + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Config::setCopyTarget() + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Config::setUnpkgFiles() + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Config::setUnpkgFiles() + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Config::setUnpkgName() + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Config::setUnpkgSource() + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Config::setUnpkgVersion() + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Generic::__construct() + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Generic::getUnpkgVersion() + */ + public function testGetUnpkgVersion(): void + { + $this->assertSame('version', $this->subject->getUnpkgVersion()); + } + + /** + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Config::getUnpkgSource() + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Config::setCopyTarget() + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Config::setUnpkgFiles() + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Config::setUnpkgName() + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Config::setUnpkgSource() + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Config::setUnpkgVersion() + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Generic::__construct() + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Generic::getUnpkgSource() + */ + public function testGetUnpkgSource(): void + { + $this->assertSame('source', $this->subject->getUnpkgSource()); + } + + /** + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Config::getUnpkgFiles() + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Config::setCopyTarget() + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Config::setUnpkgFiles() + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Config::setUnpkgName() + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Config::setUnpkgSource() + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Config::setUnpkgVersion() + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Generic::__construct() + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Generic::getUnpkgFiles() + */ + public function testGetUnpkgFiles(): void + { + $this->assertSame([], $this->subject->getUnpkgFiles()); + } + + /** + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Config::getCopyTarget() + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Config::setCopyTarget() + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Config::setUnpkgFiles() + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Config::setUnpkgName() + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Config::setUnpkgSource() + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Config::setUnpkgVersion() + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Generic::__construct() + * @covers \OpenMage\ComposerPlugin\Copy\Unpkg\Generic::getCopyTarget() + */ + public function testGetCopyTarget(): void + { + $this->assertSame('target', $this->subject->getCopyTarget()); + } +} diff --git a/tests/unit/PluginTest.php b/tests/unit/PluginTest.php new file mode 100644 index 0000000..50790cd --- /dev/null +++ b/tests/unit/PluginTest.php @@ -0,0 +1,76 @@ +subject = new Subject(); + } + + /** + * @covers \OpenMage\ComposerPlugin\Plugin::getSubscribedEvents() + */ + public function testGetSubscribedEvents(): void + { + $events = [ + 'post-install-cmd' => [ + 0 => [ + 0 => 'processCopy', + ], + ], + 'post-update-cmd' => [ + 0 => [ + 0 => 'processCopy', + ], + ], + ]; + $this->assertSame($events, $this->subject->getSubscribedEvents()); + } + + /** + * @covers \OpenMage\ComposerPlugin\Copy\AbstractCopyPlugin::getComposerPackage() + * @covers \OpenMage\ComposerPlugin\Copy\AbstractCopyPlugin::getEvent() + * @covers \OpenMage\ComposerPlugin\Copy\AbstractCopyPlugin::getInstalledComposerPackage() + * @covers \OpenMage\ComposerPlugin\Copy\AbstractCopyPlugin::processComposerInstall() + * @covers \OpenMage\ComposerPlugin\Copy\AbstractCopyPlugin::processUnpkgInstall() + * @covers \OpenMage\ComposerPlugin\Copy\Plugins\ChartJs::getComposerName() + * @covers \OpenMage\ComposerPlugin\Copy\Plugins\Flatpickr::getUnpkgVersion() + * @covers \OpenMage\ComposerPlugin\Copy\Plugins\FlowJs::getComposerName() + * @covers \OpenMage\ComposerPlugin\Copy\Plugins\JQuery::getComposerName() + * @covers \OpenMage\ComposerPlugin\Copy\Plugins\TinyMce::processComposerInstall() + * @covers \OpenMage\ComposerPlugin\Copy\Plugins\TinyMceLanguages::getComposerName() + * @covers \OpenMage\ComposerPlugin\Copy\Plugins\TinyMceLanguages::processComposerInstall() + * @covers \OpenMage\ComposerPlugin\Plugin::getClassName() + * @covers \OpenMage\ComposerPlugin\Plugin::getFilenames() + * @covers \OpenMage\ComposerPlugin\Plugin::getFullNamespace() + * @covers \OpenMage\ComposerPlugin\Plugin::getPlugins() + * @covers \OpenMage\ComposerPlugin\Plugin::getUnpkgPackagesFromConfig() + * @covers \OpenMage\ComposerPlugin\Plugin::processCopy() + */ + public function testProcessCopy(): void + { + $this->assertNull($this->subject->processCopy(null)); + } +}