Skip to content

Commit

Permalink
Add initial package testing
Browse files Browse the repository at this point in the history
  • Loading branch information
paulbalandan committed Aug 7, 2024
1 parent 4851283 commit 0b3a946
Show file tree
Hide file tree
Showing 5 changed files with 217 additions and 0 deletions.
54 changes: 54 additions & 0 deletions .github/workflows/package-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: Package Tests

on:
schedule:
- cron: '0 0 * * *'
pull_request:
push:
branches:
- 1.x

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true

permissions:
contents: read

jobs:
tests:
name: Package Tests
runs-on: ubuntu-22.04

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.3
coverage: none

- name: Get composer cache directory
id: cache-dir
shell: bash
run: |
echo "COMPOSER_CACHE_DIR=$(composer config cache-dir)" >> $GITHUB_OUTPUT
- name: Cache Composer dependencies
uses: actions/cache@v4
with:
path: ${{ steps.cache-dir.outputs.COMPOSER_CACHE_DIR }}
key: ${{ github.workflow }}-PHP_8.3-${{ hashFiles('**/composer.json') }}
restore-keys: |
${{ github.workflow }}-PHP_8.3-
- name: Install dependencies
run: composer update --ansi --no-scripts

- name: Run Package Tests
run: |
vendor/bin/phpunit --color=always --group=package-test --no-coverage
env:
TACHYCARDIA_MONITOR_GA: enabled
6 changes: 6 additions & 0 deletions phpstan-baseline.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,11 @@
'count' => 1,
'path' => __DIR__ . '/src/Nexus/Option/Choice.php',
];
$ignoreErrors[] = [
// identifier: return.type
'message' => '#^Method Nexus\\\\Tests\\\\AutoReview\\\\ComposerJsonTest\\:\\:getComposer\\(\\) should return array\\<string, mixed\\> but returns mixed\\.$#',
'count' => 1,
'path' => __DIR__ . '/tests/AutoReview/ComposerJsonTest.php',
];

return ['parameters' => ['ignoreErrors' => $ignoreErrors]];
1 change: 1 addition & 0 deletions src/Nexus/Clock/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"psr/clock-implementation": "1.0"
},
"minimum-stability": "dev",
"prefer-stable": true,
"autoload": {
"psr-4": {
"Nexus\\Clock\\": ""
Expand Down
1 change: 1 addition & 0 deletions src/Nexus/Option/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"php": "^8.2"
},
"minimum-stability": "dev",
"prefer-stable": true,
"autoload": {
"psr-4": {
"Nexus\\Option\\": ""
Expand Down
155 changes: 155 additions & 0 deletions tests/AutoReview/ComposerJsonTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
<?php

declare(strict_types=1);

/**
* This file is part of the Nexus framework.
*
* (c) John Paul E. Balandan, CPA <[email protected]>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/

namespace Nexus\Tests\AutoReview;

use PHPUnit\Framework\Attributes\CoversNothing;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Group;
use PHPUnit\Framework\TestCase;

/**
* @internal
*/
#[CoversNothing]
#[Group('package-test')]
final class ComposerJsonTest extends TestCase
{
/**
* @var list<string>
*/
private static array $packages = [];

public function testRootComposerJsonReplacesPackages(): void
{
$rootComposer = $this->getComposer(__DIR__.'/../../composer.json');

self::assertArrayHasKey('replace', $rootComposer);
self::assertIsArray($rootComposer['replace']);

foreach (self::getPackageDirectories() as $directory) {
$package = $this->getPackageName($directory);

self::assertArrayHasKey($package, $rootComposer['replace']);
self::assertSame('self.version', $rootComposer['replace'][$package]);
}
}

#[DataProvider('providePackageHasComposerJsonCases')]
public function testPackageHasComposerJson(string $package): void
{
$composerJson = \sprintf('%s/composer.json', $package);
self::assertFileExists($composerJson);

$composerJson = $this->getComposer($composerJson);
self::assertArrayHasKey('minimum-stability', $composerJson);
self::assertSame('dev', $composerJson['minimum-stability']);

self::assertArrayHasKey('prefer-stable', $composerJson);
self::assertTrue($composerJson['prefer-stable']);

self::assertArrayHasKey('support', $composerJson);
self::assertIsArray($composerJson['support']);
self::assertArrayHasKey('issues', $composerJson['support']);
self::assertArrayHasKey('source', $composerJson['support']);
self::assertSame('https://github.com/NexusPHP/framework/issues', $composerJson['support']['issues']);
self::assertSame('https://github.com/NexusPHP/framework', $composerJson['support']['source']);
}

/**
* @return iterable<string, array{string}>
*/
public static function providePackageHasComposerJsonCases(): iterable
{
foreach (self::getPackageDirectories() as $directory) {
yield $directory => [$directory];
}
}

/**
* @return array<string, mixed>
*/
private function getComposer(string $path): array
{
try {
$realpath = realpath($path);

if (false === $realpath) {
throw new \InvalidArgumentException(\sprintf(
'The composer.json at "%s" does not exist.',
$path,
));
}

$contents = @file_get_contents($realpath);

if (false === $contents) {
throw new \InvalidArgumentException(\sprintf(
'The composer.json at "%s" is not readable.',
substr($realpath, \strlen((string) getcwd())),
));
}

return json_decode($contents, true, 512, JSON_THROW_ON_ERROR);
} catch (\InvalidArgumentException|\JsonException $e) {
self::fail(\sprintf('Retrieving the contents failed: %s', $e->getMessage()));
}
}

/**
* @return list<string>
*/
private static function getPackageDirectories(): array
{
if ([] !== self::$packages) {
return self::$packages;
}

$finder = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator(
'src/Nexus',
\FilesystemIterator::KEY_AS_FILENAME | \FilesystemIterator::UNIX_PATHS,
),
);
$finder->setMaxDepth(3);

/**
* @var \SplFileInfo $splFileInfo
*/
foreach ($finder as $file => $splFileInfo) {
if ('composer.json' === $file) {
self::$packages[] = \dirname($splFileInfo->getPathname());
}
}

return self::$packages;
}

private function getPackageName(string $package): string
{
static $specialCases = [
'PHPStan' => 'phpstan-nexus',
];

$package = basename($package);

return \sprintf(
'nexusphp/%s',
$specialCases[$package] ?? strtolower(preg_replace(
'/(?<!^)((?=[A-Z][^A-Z])|(?<![A-Z])(?=[A-Z]))/u',
'_',
$package,
) ?? $package),
);
}
}

0 comments on commit 0b3a946

Please sign in to comment.