mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-07-09 18:05:36 +08:00
Add v3 artifact test
This commit is contained in:
351
tests/StaticPHP/Artifact/ArtifactDownloaderTest.php
Normal file
351
tests/StaticPHP/Artifact/ArtifactDownloaderTest.php
Normal file
@@ -0,0 +1,351 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Tests\StaticPHP\Artifact;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use StaticPHP\Artifact\Artifact;
|
||||
use StaticPHP\Artifact\ArtifactDownloader;
|
||||
use StaticPHP\Config\ArtifactConfig;
|
||||
use StaticPHP\Exception\WrongUsageException;
|
||||
use StaticPHP\Registry\ArtifactLoader;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class ArtifactDownloaderTest extends TestCase
|
||||
{
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
// Reset ArtifactConfig and ArtifactLoader static state
|
||||
$reflection = new \ReflectionClass(ArtifactConfig::class);
|
||||
$property = $reflection->getProperty('artifact_configs');
|
||||
$property->setAccessible(true);
|
||||
$property->setValue(null, []);
|
||||
|
||||
$loaderReflection = new \ReflectionClass(ArtifactLoader::class);
|
||||
$loaderProperty = $loaderReflection->getProperty('artifacts');
|
||||
$loaderProperty->setAccessible(true);
|
||||
$loaderProperty->setValue(null, null);
|
||||
}
|
||||
|
||||
protected function tearDown(): void
|
||||
{
|
||||
parent::tearDown();
|
||||
|
||||
$reflection = new \ReflectionClass(ArtifactConfig::class);
|
||||
$property = $reflection->getProperty('artifact_configs');
|
||||
$property->setAccessible(true);
|
||||
$property->setValue(null, []);
|
||||
|
||||
$loaderReflection = new \ReflectionClass(ArtifactLoader::class);
|
||||
$loaderProperty = $loaderReflection->getProperty('artifacts');
|
||||
$loaderProperty->setAccessible(true);
|
||||
$loaderProperty->setValue(null, null);
|
||||
}
|
||||
|
||||
// ==================== DOWNLOADERS constant ====================
|
||||
|
||||
public function testDownloadersConstantHasExpectedKeys(): void
|
||||
{
|
||||
$expectedKeys = ['bitbuckettag', 'filelist', 'git', 'ghrel', 'ghtar', 'ghtagtar', 'local', 'pie', 'pecl', 'url', 'php-release', 'hosted'];
|
||||
|
||||
foreach ($expectedKeys as $key) {
|
||||
$this->assertArrayHasKey($key, ArtifactDownloader::DOWNLOADERS, "Missing downloader key: {$key}");
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== Constructor options ====================
|
||||
|
||||
public function testConstructWithDefaultOptions(): void
|
||||
{
|
||||
$downloader = new ArtifactDownloader([], false);
|
||||
|
||||
$this->assertSame(0, $downloader->getRetry());
|
||||
$this->assertFalse($downloader->interactive);
|
||||
$this->assertEmpty($downloader->getArtifacts());
|
||||
}
|
||||
|
||||
public function testConstructWithParallelOption(): void
|
||||
{
|
||||
$downloader = new ArtifactDownloader(['parallel' => 4], false);
|
||||
|
||||
// parallel is internal but setParallel/getArtifacts reveals behavior; check via setParallel chainability
|
||||
// Indirect verification: setParallel with same value returns $this
|
||||
$this->assertSame($downloader, $downloader->setParallel(4));
|
||||
}
|
||||
|
||||
public function testConstructWithRetryOption(): void
|
||||
{
|
||||
$downloader = new ArtifactDownloader(['retry' => 3], false);
|
||||
|
||||
$this->assertSame(3, $downloader->getRetry());
|
||||
}
|
||||
|
||||
public function testConstructWithNegativeRetryClampedToZero(): void
|
||||
{
|
||||
$downloader = new ArtifactDownloader(['retry' => -5], false);
|
||||
|
||||
$this->assertSame(0, $downloader->getRetry());
|
||||
}
|
||||
|
||||
public function testConstructWithPreferSourceBoolOption(): void
|
||||
{
|
||||
// prefer-source=true sets default to FETCH_PREFER_SOURCE (0)
|
||||
$downloader = new ArtifactDownloader(['prefer-source' => true], false);
|
||||
|
||||
$this->assertSame(0, $downloader->getRetry()); // sanity check, object created fine
|
||||
}
|
||||
|
||||
public function testConstructWithPreferBinaryBoolOption(): void
|
||||
{
|
||||
$downloader = new ArtifactDownloader(['prefer-binary' => true], false);
|
||||
|
||||
$this->assertNotNull($downloader);
|
||||
}
|
||||
|
||||
public function testConstructWithPreferPreBuiltBoolOption(): void
|
||||
{
|
||||
$downloader = new ArtifactDownloader(['prefer-pre-built' => true], false);
|
||||
|
||||
$this->assertNotNull($downloader);
|
||||
}
|
||||
|
||||
public function testConstructWithSourceOnlyBoolOption(): void
|
||||
{
|
||||
$downloader = new ArtifactDownloader(['source-only' => true], false);
|
||||
|
||||
$this->assertNotNull($downloader);
|
||||
}
|
||||
|
||||
public function testConstructWithBinaryOnlyBoolOption(): void
|
||||
{
|
||||
$downloader = new ArtifactDownloader(['binary-only' => true], false);
|
||||
|
||||
$this->assertNotNull($downloader);
|
||||
}
|
||||
|
||||
public function testConstructWithIgnoreCacheBoolOption(): void
|
||||
{
|
||||
$downloader = new ArtifactDownloader(['ignore-cache' => true], false);
|
||||
|
||||
$this->assertNotNull($downloader);
|
||||
}
|
||||
|
||||
public function testConstructWithIgnoreCacheStringOptionParsesNames(): void
|
||||
{
|
||||
$downloader = new ArtifactDownloader(['ignore-cache' => 'openssl,zlib'], false);
|
||||
|
||||
$this->assertNotNull($downloader);
|
||||
}
|
||||
|
||||
public function testConstructWithIgnoreCacheSourcesBackwardCompat(): void
|
||||
{
|
||||
$downloader = new ArtifactDownloader(['ignore-cache-sources' => true], false);
|
||||
|
||||
$this->assertNotNull($downloader);
|
||||
}
|
||||
|
||||
public function testConstructWithCustomUrlOptionAddsToIgnoreCache(): void
|
||||
{
|
||||
$downloader = new ArtifactDownloader(
|
||||
['custom-url' => ['openssl:https://custom.example.com/openssl.tar.gz']],
|
||||
false
|
||||
);
|
||||
|
||||
$this->assertNotNull($downloader);
|
||||
}
|
||||
|
||||
public function testConstructWithCustomGitOption(): void
|
||||
{
|
||||
$downloader = new ArtifactDownloader(
|
||||
['custom-git' => ['php-src:master:https://github.com/php/php-src.git']],
|
||||
false
|
||||
);
|
||||
|
||||
$this->assertNotNull($downloader);
|
||||
}
|
||||
|
||||
public function testConstructWithCustomLocalOption(): void
|
||||
{
|
||||
$downloader = new ArtifactDownloader(
|
||||
['custom-local' => ['my-lib:/tmp/my-lib-source']],
|
||||
false
|
||||
);
|
||||
|
||||
$this->assertNotNull($downloader);
|
||||
}
|
||||
|
||||
public function testConstructWithNoAltOption(): void
|
||||
{
|
||||
$downloader = new ArtifactDownloader(['no-alt' => true], false);
|
||||
|
||||
$this->assertNotNull($downloader);
|
||||
}
|
||||
|
||||
// ==================== getRetry ====================
|
||||
|
||||
public function testGetRetryDefaultsToZero(): void
|
||||
{
|
||||
$downloader = new ArtifactDownloader([], false);
|
||||
|
||||
$this->assertSame(0, $downloader->getRetry());
|
||||
}
|
||||
|
||||
public function testGetRetryReturnsConfiguredValue(): void
|
||||
{
|
||||
$downloader = new ArtifactDownloader(['retry' => 5], false);
|
||||
|
||||
$this->assertSame(5, $downloader->getRetry());
|
||||
}
|
||||
|
||||
// ==================== getOption ====================
|
||||
|
||||
public function testGetOptionReturnsConfiguredValue(): void
|
||||
{
|
||||
$downloader = new ArtifactDownloader(['retry' => 2, 'parallel' => 3], false);
|
||||
|
||||
$this->assertSame(2, $downloader->getOption('retry'));
|
||||
$this->assertSame(3, $downloader->getOption('parallel'));
|
||||
}
|
||||
|
||||
public function testGetOptionReturnsDefaultWhenNotSet(): void
|
||||
{
|
||||
$downloader = new ArtifactDownloader([], false);
|
||||
|
||||
$this->assertNull($downloader->getOption('non-existent'));
|
||||
$this->assertSame('default-val', $downloader->getOption('non-existent', 'default-val'));
|
||||
}
|
||||
|
||||
// ==================== getArtifacts ====================
|
||||
|
||||
public function testGetArtifactsReturnsEmptyInitially(): void
|
||||
{
|
||||
$downloader = new ArtifactDownloader([], false);
|
||||
|
||||
$this->assertSame([], $downloader->getArtifacts());
|
||||
}
|
||||
|
||||
// ==================== add ====================
|
||||
|
||||
public function testAddWithArtifactObjectAddsToList(): void
|
||||
{
|
||||
$downloader = new ArtifactDownloader([], false);
|
||||
$artifact = new Artifact('my-pkg', ['source' => ['type' => 'url', 'url' => 'https://example.com/file.tar.gz']]);
|
||||
|
||||
$downloader->add($artifact);
|
||||
|
||||
$artifacts = $downloader->getArtifacts();
|
||||
$this->assertArrayHasKey('my-pkg', $artifacts);
|
||||
$this->assertSame($artifact, $artifacts['my-pkg']);
|
||||
}
|
||||
|
||||
public function testAddReturnsSelf(): void
|
||||
{
|
||||
$downloader = new ArtifactDownloader([], false);
|
||||
$artifact = new Artifact('my-pkg', ['source' => ['type' => 'url', 'url' => 'https://example.com/file.tar.gz']]);
|
||||
|
||||
$result = $downloader->add($artifact);
|
||||
|
||||
$this->assertSame($downloader, $result);
|
||||
}
|
||||
|
||||
public function testAddDoesNotAddDuplicateArtifact(): void
|
||||
{
|
||||
$downloader = new ArtifactDownloader([], false);
|
||||
$artifact = new Artifact('my-pkg', ['source' => ['type' => 'url', 'url' => 'https://example.com/file.tar.gz']]);
|
||||
|
||||
$downloader->add($artifact);
|
||||
$downloader->add($artifact);
|
||||
|
||||
$this->assertCount(1, $downloader->getArtifacts());
|
||||
}
|
||||
|
||||
public function testAddWithStringNameLooksUpFromArtifactLoader(): void
|
||||
{
|
||||
$this->injectArtifactConfig('my-lib', ['source' => ['type' => 'url', 'url' => 'https://example.com/file.tar.gz']]);
|
||||
|
||||
$downloader = new ArtifactDownloader([], false);
|
||||
$downloader->add('my-lib');
|
||||
|
||||
$artifacts = $downloader->getArtifacts();
|
||||
$this->assertArrayHasKey('my-lib', $artifacts);
|
||||
}
|
||||
|
||||
public function testAddWithStringNameThrowsForNonExistentArtifact(): void
|
||||
{
|
||||
$downloader = new ArtifactDownloader([], false);
|
||||
|
||||
$this->expectException(WrongUsageException::class);
|
||||
$this->expectExceptionMessage("Artifact 'non-existent' not found");
|
||||
|
||||
$downloader->add('non-existent');
|
||||
}
|
||||
|
||||
// ==================== addArtifacts ====================
|
||||
|
||||
public function testAddArtifactsAddsMultipleAtOnce(): void
|
||||
{
|
||||
$downloader = new ArtifactDownloader([], false);
|
||||
$a1 = new Artifact('pkg-a', ['source' => ['type' => 'url', 'url' => 'https://example.com/a.tar.gz']]);
|
||||
$a2 = new Artifact('pkg-b', ['source' => ['type' => 'url', 'url' => 'https://example.com/b.tar.gz']]);
|
||||
|
||||
$downloader->addArtifacts([$a1, $a2]);
|
||||
|
||||
$this->assertCount(2, $downloader->getArtifacts());
|
||||
$this->assertArrayHasKey('pkg-a', $downloader->getArtifacts());
|
||||
$this->assertArrayHasKey('pkg-b', $downloader->getArtifacts());
|
||||
}
|
||||
|
||||
public function testAddArtifactsReturnsSelf(): void
|
||||
{
|
||||
$downloader = new ArtifactDownloader([], false);
|
||||
|
||||
$result = $downloader->addArtifacts([]);
|
||||
|
||||
$this->assertSame($downloader, $result);
|
||||
}
|
||||
|
||||
// ==================== setParallel ====================
|
||||
|
||||
public function testSetParallelReturnsSelf(): void
|
||||
{
|
||||
$downloader = new ArtifactDownloader([], false);
|
||||
|
||||
$result = $downloader->setParallel(3);
|
||||
|
||||
$this->assertSame($downloader, $result);
|
||||
}
|
||||
|
||||
public function testSetParallelEnforcesMinimumOfOne(): void
|
||||
{
|
||||
$downloader = new ArtifactDownloader([], false);
|
||||
|
||||
$downloader->setParallel(0);
|
||||
// No direct getter for parallel, but verifying it doesn't throw
|
||||
$this->assertSame($downloader, $downloader->setParallel(0));
|
||||
}
|
||||
|
||||
public function testSetParallelAcceptsNormalValue(): void
|
||||
{
|
||||
$downloader = new ArtifactDownloader([], false);
|
||||
|
||||
$result = $downloader->setParallel(5);
|
||||
$this->assertSame($downloader, $result);
|
||||
}
|
||||
|
||||
// ==================== Helpers ====================
|
||||
|
||||
private function injectArtifactConfig(string $name, array $config): void
|
||||
{
|
||||
$reflection = new \ReflectionClass(ArtifactConfig::class);
|
||||
$property = $reflection->getProperty('artifact_configs');
|
||||
$property->setAccessible(true);
|
||||
$configs = $property->getValue(null) ?? [];
|
||||
$configs[$name] = $config;
|
||||
$property->setValue(null, $configs);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user