1
0
mirror of https://github.com/php/pie.git synced 2026-03-23 23:12:17 +01:00

Added a bunch of unit tests for existing code

This commit is contained in:
James Titcumb
2024-04-24 09:24:24 +01:00
parent f3bbf035d3
commit c60458ffac
11 changed files with 304 additions and 4 deletions

View File

@@ -6,7 +6,6 @@
cacheDirectory=".phpunit.cache"
executionOrder="depends,defects"
requireCoverageMetadata="true"
beStrictAboutCoverageMetadata="true"
beStrictAboutOutputDuringTests="true"
failOnRisky="true"
failOnWarning="true">

View File

@@ -16,7 +16,7 @@ final class Package
public const TYPE_PHP_MODULE = 'php-ext';
public const TYPE_ZEND_EXTENSION = 'php-ext-zend';
private function __construct(
public function __construct(
public readonly string $name,
public readonly string $version,
public readonly string|null $downloadUrl,

View File

@@ -23,10 +23,10 @@ class UnableToResolveRequirement extends RuntimeException
public static function toPhpOrZendExtension(PackageInterface $locatedComposerPackage, string $requiredPackageName, string|null $requiredVersion): self
{
return new self(sprintf(
'Package %s was not of type php-ext or php-ext-zend (requested %s%s)',
'Package %s was not of type php-ext or php-ext-zend (requested %s%s).',
$locatedComposerPackage->getName(),
$requiredPackageName,
$requiredVersion !== null ? sprintf(' for version %s.', $requiredVersion) : '.',
$requiredVersion !== null ? sprintf(' for version %s', $requiredVersion) : '',
));
}
}

BIN
test/assets/test-zip.zip Normal file

Binary file not shown.

View File

@@ -0,0 +1,48 @@
<?php
declare(strict_types=1);
namespace Php\PieUnitTest\DependencyResolver;
use Composer\Package\PackageInterface;
use Php\Pie\DependencyResolver\UnableToResolveRequirement;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\TestCase;
#[CoversClass(UnableToResolveRequirement::class)]
final class UnableToResolveRequirementTest extends TestCase
{
public function testToPhpOrZendExtensionWithVersion(): void
{
$package = $this->createMock(PackageInterface::class);
$package->method('getName')->willReturn('baz/bat');
$exception = UnableToResolveRequirement::toPhpOrZendExtension($package, 'foo/bar', '^1.2');
self::assertSame('Package baz/bat was not of type php-ext or php-ext-zend (requested foo/bar for version ^1.2).', $exception->getMessage());
}
public function testToPhpOrZendExtensionWithoutVersion(): void
{
$package = $this->createMock(PackageInterface::class);
$package->method('getName')->willReturn('baz/bat');
$exception = UnableToResolveRequirement::toPhpOrZendExtension($package, 'foo/bar', null);
self::assertSame('Package baz/bat was not of type php-ext or php-ext-zend (requested foo/bar).', $exception->getMessage());
}
public function testFromRequirementWithVersion(): void
{
$exception = UnableToResolveRequirement::fromRequirement('foo/bar', '^1.2');
self::assertSame('Unable to find an installable package foo/bar for version ^1.2.', $exception->getMessage());
}
public function testFromRequirementWithoutVersion(): void
{
$exception = UnableToResolveRequirement::fromRequirement('foo/bar', null);
self::assertSame('Unable to find an installable package foo/bar.', $exception->getMessage());
}
}

View File

@@ -0,0 +1,56 @@
<?php
declare(strict_types=1);
namespace Php\PieUnitTest\Downloading;
use Composer\Util\AuthHelper;
use GuzzleHttp\Psr7\Request;
use Php\Pie\DependencyResolver\Package;
use Php\Pie\Downloading\AddAuthenticationHeader;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\TestCase;
use RuntimeException;
use function uniqid;
#[CoversClass(AddAuthenticationHeader::class)]
final class AddAuthenticationHeaderTest extends TestCase
{
public function testAuthorizationHeaderIsAdded(): void
{
$downloadUrl = 'http://test-uri/' . uniqid('path', true);
$request = new Request('GET', $downloadUrl);
$authHelper = $this->createMock(AuthHelper::class);
$authHelper->expects(self::once())
->method('addAuthenticationHeader')
->with([], 'github.com', $downloadUrl)
->willReturn(['Authorization: whatever ABC123']);
$requestWithAuthHeader = (new AddAuthenticationHeader())->withAuthHeaderFromComposer(
$request,
new Package('foo/bar', '1.2.3', $downloadUrl),
$authHelper,
);
self::assertSame('whatever ABC123', $requestWithAuthHeader->getHeaderLine('Authorization'));
}
public function testExceptionIsThrownWhenPackageDoesNotHaveDownloadUrl(): void
{
$downloadUrl = 'http://test-uri/' . uniqid('path', true);
$request = new Request('GET', $downloadUrl);
$authHelper = $this->createMock(AuthHelper::class);
$addAuthenticationHeader = new AddAuthenticationHeader();
$package = new Package('foo/bar', '1.2.3', null);
$this->expectException(RuntimeException::class);
$this->expectExceptionMessage('The package foo/bar does not have a download URL');
$addAuthenticationHeader->withAuthHeaderFromComposer($request, $package, $authHelper);
}
}

View File

@@ -0,0 +1,54 @@
<?php
declare(strict_types=1);
namespace Php\PieUnitTest\Downloading;
use GuzzleHttp\Client;
use GuzzleHttp\Handler\MockHandler;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Psr7\Response;
use Php\Pie\Downloading\DownloadZip;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\TestCase;
use function file_get_contents;
use function mkdir;
use function strlen;
use function sys_get_temp_dir;
use function uniqid;
use const DIRECTORY_SEPARATOR;
#[CoversClass(DownloadZip::class)]
final class DownloadZipTest extends TestCase
{
public function testDownloadZipAndReturnLocalPath(): void
{
$fakeZipContent = uniqid('fakeZipContent', true);
$mockHandler = new MockHandler([
new Response(
200,
[
'Content-type' => 'application/octet-stream',
'Content-length' => (string) (strlen($fakeZipContent)),
],
$fakeZipContent,
),
]);
$guzzleMockClient = new Client(['handler' => HandlerStack::create($mockHandler)]);
$localPath = sys_get_temp_dir() . DIRECTORY_SEPARATOR . uniqid('pie_test_', true);
mkdir($localPath, 0777, true);
$downloadedZipFile = (new DownloadZip($guzzleMockClient))
->downloadZipAndReturnLocalPath(
new Request('GET', 'http://test-uri/'),
$localPath,
);
self::assertSame($fakeZipContent, file_get_contents($downloadedZipFile));
}
}

View File

@@ -0,0 +1,28 @@
<?php
declare(strict_types=1);
namespace Php\PieUnitTest\Downloading;
use Php\Pie\DependencyResolver\Package;
use Php\Pie\Downloading\DownloadedPackage;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\TestCase;
use function uniqid;
#[CoversClass(DownloadedPackage::class)]
final class DownloadedPackageTest extends TestCase
{
public function testFromPackageAndExtractedPath(): void
{
$package = new Package('foo/bar', '1.2.3', null);
$extractedSourcePath = uniqid('/path/to/downloaded/package', true);
$downloadedPackage = DownloadedPackage::fromPackageAndExtractedPath($package, $extractedSourcePath);
self::assertSame($extractedSourcePath, $downloadedPackage->extractedSourcePath);
self::assertSame($package, $downloadedPackage->package);
}
}

View File

@@ -0,0 +1,48 @@
<?php
declare(strict_types=1);
namespace Php\PieUnitTest\Downloading;
use Php\Pie\Downloading\ExtractZip;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\TestCase;
use RuntimeException;
use ZipArchive;
use function file_get_contents;
use function mkdir;
use function sprintf;
use function sys_get_temp_dir;
use function uniqid;
use const DIRECTORY_SEPARATOR;
/** @covers \Php\Pie\Downloading\ExtractZip */
#[CoversClass(ExtractZip::class)]
final class ExtractZipTest extends TestCase
{
public function testZipFileCanBeExtracted(): void
{
$localPath = sys_get_temp_dir() . DIRECTORY_SEPARATOR . uniqid('pie_test_', true);
mkdir($localPath, 0777, true);
$extr = new ExtractZip();
$extractedPath = $extr->to(__DIR__ . '/../../assets/test-zip.zip', $localPath);
// The test-zip.zip should contain a deterministic file content for this:
self::assertSame('Hello there! Test UUID b925c59b-3e6f-4e45-8029-19431df18de4', file_get_contents($extractedPath . DIRECTORY_SEPARATOR . 'test-file.txt'));
}
public function testFailureToExtractZipWithInvalidZip(): void
{
$localPath = sys_get_temp_dir() . DIRECTORY_SEPARATOR . uniqid('pie_test_DO_NOT_EXIST_', true);
$extr = new ExtractZip();
$this->expectException(RuntimeException::class);
$this->expectExceptionMessage(sprintf('Could not open ZIP [%d]: %s', ZipArchive::ER_NOZIP, __FILE__));
$extr->to(__FILE__, $localPath);
}
}

View File

@@ -7,8 +7,12 @@ namespace Php\PieUnitTest\TargetPhp;
use Php\Pie\TargetPhp\PhpBinaryPath;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Process\Process;
use function file_exists;
use function is_executable;
use function sprintf;
use function trim;
use const PHP_MAJOR_VERSION;
use const PHP_MINOR_VERSION;
@@ -24,4 +28,26 @@ final class PhpBinaryPathTest extends TestCase
PhpBinaryPath::fromCurrentProcess()->version(),
);
}
public function testFromPhpConfigExecutable(): void
{
$process = (new Process(['which', 'php-config']));
$exitCode = $process->run();
$phpConfigExecutable = trim($process->getOutput());
if ($exitCode !== 0 || ! file_exists($phpConfigExecutable) || ! is_executable($phpConfigExecutable)) {
self::markTestSkipped('Needs php-config in path to run this test');
}
$phpBinary = PhpBinaryPath::fromPhpConfigExecutable($phpConfigExecutable);
// NOTE: this makes an assumption that the `php-config` in path is the same as the version being executed
// In most cases, this will be the cases (e.g. in CI, running locally), but if you're trying to test this and
// the versions are not matching, that's probably why.
// @todo improve this assertion in future, if it becomes problematic
self::assertSame(
sprintf('%s.%s.%s', PHP_MAJOR_VERSION, PHP_MINOR_VERSION, PHP_RELEASE_VERSION),
$phpBinary->version(),
);
}
}

View File

@@ -0,0 +1,41 @@
<?php
declare(strict_types=1);
namespace Php\PieUnitTest\TargetPhp;
use Composer\Package\BasePackage;
use Php\Pie\TargetPhp\PhpBinaryPath;
use Php\Pie\TargetPhp\ResolveTargetPhpToPlatformRepository;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\TestCase;
use function array_filter;
use function array_key_first;
use function assert;
use function count;
#[CoversClass(ResolveTargetPhpToPlatformRepository::class)]
final class ResolveTargetPhpToPlatformRepositoryTest extends TestCase
{
public function testPlatformRepositoryIsReturned(): void
{
$php = PhpBinaryPath::fromCurrentProcess();
$platformRepository = (new ResolveTargetPhpToPlatformRepository())($php);
$phpPackages = array_filter(
$platformRepository->getPackages(),
static function (BasePackage $package): bool {
return $package->getPrettyName() === 'php';
},
);
self::assertCount(1, $phpPackages);
assert(count($phpPackages) > 0);
$phpPackage = $phpPackages[array_key_first($phpPackages)];
self::assertSame($php->version(), $phpPackage->getPrettyVersion());
}
}