Skip to content

Commit 2577183

Browse files
committed
tests(archive): add integration tests
1 parent 765b67c commit 2577183

File tree

2 files changed

+137
-0
lines changed

2 files changed

+137
-0
lines changed

phpunit.xml.dist

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
<testsuite name="Unit">
1818
<directory>tests/Unit</directory>
1919
</testsuite>
20+
<testsuite name="Integration">
21+
<directory>tests/Integration</directory>
22+
</testsuite>
2023
<testsuite name="Arch">
2124
<directory>tests/Arch</directory>
2225
</testsuite>
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Internal\DLoad\Tests\Integration\Module\Archive;
6+
7+
use Internal\DLoad\Module\Archive\ArchiveFactory;
8+
use PHPUnit\Framework\Attributes\DataProvider;
9+
use PHPUnit\Framework\Attributes\Group;
10+
use PHPUnit\Framework\TestCase;
11+
12+
/**
13+
* Integration tests for Archive module
14+
*
15+
* These tests verify that the Archive module components work together correctly.
16+
* They require the phar extension to be enabled and temporary files to be created.
17+
*/
18+
#[Group('integration')]
19+
final class ArchiveIntegrationTest extends TestCase
20+
{
21+
private string $tempDir;
22+
private ArchiveFactory $factory;
23+
24+
public static function provideArchiveTypes(): \Generator
25+
{
26+
yield 'zip' => ['zip', 'Internal\DLoad\Module\Archive\Internal\ZipPharArchive'];
27+
yield 'tar.gz' => ['tar.gz', 'Internal\DLoad\Module\Archive\Internal\TarPharArchive'];
28+
yield 'phar' => ['phar', 'Internal\DLoad\Module\Archive\Internal\PharArchive'];
29+
}
30+
31+
#[DataProvider('provideArchiveTypes')]
32+
public function testFactoryCreateReturnsCorrectImplementation(
33+
string $extension,
34+
string $className,
35+
): void {
36+
// Skip if we can't verify the implementation type
37+
if (!\class_exists($className)) {
38+
self::markTestSkipped("Class $className not available");
39+
}
40+
41+
// Arrange - create mock file with extension
42+
$file = $this->createMock(\SplFileInfo::class);
43+
$file->method('getFilename')->willReturn('test.' . $extension);
44+
$file->method('isFile')->willReturn(true);
45+
$file->method('isReadable')->willReturn(true);
46+
47+
// Act - create archive handler
48+
try {
49+
$archive = $this->factory->create($file);
50+
51+
// Assert - check implementation type
52+
self::assertInstanceOf($className, $archive);
53+
} catch (\InvalidArgumentException $e) {
54+
// If creation fails due to real file requirements, just verify supported extensions
55+
$extensions = $this->factory->getSupportedExtensions();
56+
self::assertContains($extension, $extensions);
57+
}
58+
}
59+
60+
public function testFactoryExtendWithCustomImplementation(): void
61+
{
62+
// Arrange - create custom archive mock
63+
$customArchive = $this->createMock('Internal\DLoad\Module\Archive\Archive');
64+
65+
// Register custom implementation for .custom extension
66+
$this->factory->extend(
67+
static fn(\SplFileInfo $file) =>
68+
\str_ends_with($file->getFilename(), '.custom') ? $customArchive : null,
69+
['custom'],
70+
);
71+
72+
// Create mock file with custom extension
73+
$file = $this->createMock(\SplFileInfo::class);
74+
$file->method('getFilename')->willReturn('test.custom');
75+
$file->method('isFile')->willReturn(true);
76+
$file->method('isReadable')->willReturn(true);
77+
78+
// Act
79+
$archive = $this->factory->create($file);
80+
81+
// Assert
82+
self::assertSame($customArchive, $archive);
83+
}
84+
85+
protected function setUp(): void
86+
{
87+
// Skip tests if phar extension is not available
88+
if (!\class_exists(\PharData::class)) {
89+
self::markTestSkipped('Phar extension is not available');
90+
}
91+
92+
// Create temporary directory for test files in project runtime
93+
$projectRoot = \dirname(__DIR__, 4); // Four levels up from this file
94+
$this->tempDir = $projectRoot . '/runtime/tests/archive-integration-' . \uniqid();
95+
\mkdir($this->tempDir, 0777, true);
96+
97+
// Create factory
98+
$this->factory = new ArchiveFactory();
99+
}
100+
101+
protected function tearDown(): void
102+
{
103+
// Clean up temporary directory
104+
if (\is_dir($this->tempDir)) {
105+
$this->removeDirectory($this->tempDir);
106+
}
107+
}
108+
109+
/**
110+
* Recursively remove a directory and its contents
111+
*/
112+
private function removeDirectory(string $dir): void
113+
{
114+
if (!\is_dir($dir)) {
115+
return;
116+
}
117+
118+
$items = \scandir($dir);
119+
foreach ($items as $item) {
120+
if ($item === '.' || $item === '..') {
121+
continue;
122+
}
123+
124+
$path = $dir . '/' . $item;
125+
if (\is_dir($path)) {
126+
$this->removeDirectory($path);
127+
} else {
128+
\unlink($path);
129+
}
130+
}
131+
132+
\rmdir($dir);
133+
}
134+
}

0 commit comments

Comments
 (0)