Skip to content

Commit 4002a2c

Browse files
chore: upgrade symfony/console to ^7||^8 (#105)
This upgrade brings the project up to date with the latest Symfony Console versions. Changes include: - Updated composer.json to require symfony/console ^7||^8 - Added return type declaration and return statement to SplitCommand::execute() for Symfony Console 7/8 compatibility --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 80a12c4 commit 4002a2c

4 files changed

Lines changed: 273 additions & 12 deletions

File tree

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"guzzlehttp/psr7": "^2.0",
2020
"deviantintegral/jms-serializer-uri-handler": "^1.1",
2121
"deviantintegral/null-date-time": "^1.0",
22-
"symfony/console": "^5.0||^6.0"
22+
"symfony/console": "^7||^8"
2323
},
2424
"require-dev": {
2525
"friendsofphp/php-cs-fixer": "3.92.0",

phpunit.xml.dist

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,13 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" backupGlobals="false" bootstrap="vendor/autoload.php" colors="true" processIsolation="false" stopOnFailure="false" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/12.5/phpunit.xsd" cacheDirectory=".phpunit.cache" backupStaticProperties="false">
3-
<coverage>
4-
<report>
5-
<clover outputFile="build/logs/clover.xml"/>
6-
</report>
7-
</coverage>
2+
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" backupGlobals="false" bootstrap="vendor/autoload.php" colors="true" processIsolation="false" stopOnFailure="false" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/12.5/phpunit.xsd" cacheDirectory=".phpunit.cache" backupStaticProperties="false" failOnWarning="false">
83
<testsuites>
94
<testsuite name="Unit">
105
<directory suffix="Test.php">./tests/src/Unit</directory>
116
</testsuite>
7+
<testsuite name="Functional">
8+
<directory suffix="Test.php">./tests/src/Functional</directory>
9+
</testsuite>
1210
</testsuites>
13-
<logging>
14-
<junit outputFile="build/logs/results.xml"/>
15-
</logging>
1611
<source>
1712
<include>
1813
<directory suffix=".php">./src</directory>

src/Command/SplitCommand.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
*/
1818
class SplitCommand extends Command
1919
{
20-
protected function configure()
20+
protected function configure(): void
2121
{
2222
parent::configure();
2323
$this->setName('har:split')
@@ -29,7 +29,7 @@ protected function configure()
2929
->addOption('force', 'f', InputOption::VALUE_NONE, 'Overwrite destination files that already exist.');
3030
}
3131

32-
protected function execute(InputInterface $input, OutputInterface $output)
32+
protected function execute(InputInterface $input, OutputInterface $output): int
3333
{
3434
$io = new SymfonyStyle($input, $output);
3535
$source = $input->getArgument('har');
@@ -60,6 +60,8 @@ protected function execute(InputInterface $input, OutputInterface $output)
6060
$io->progressAdvance();
6161
}
6262
$io->progressFinish();
63+
64+
return Command::SUCCESS;
6365
}
6466

6567
private function getSplitDestination(
Lines changed: 264 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,264 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Deviantintegral\Har\Tests\Functional;
6+
7+
use Deviantintegral\Har\Command\SplitCommand;
8+
use Deviantintegral\Har\Serializer;
9+
use Deviantintegral\Har\Tests\Unit\HarTestBase;
10+
use Symfony\Component\Console\Command\Command;
11+
use Symfony\Component\Console\Tester\CommandTester;
12+
13+
class SplitCommandTest extends HarTestBase
14+
{
15+
private string $tempDir;
16+
private CommandTester $commandTester;
17+
18+
protected function setUp(): void
19+
{
20+
parent::setUp();
21+
22+
// Create a temporary directory for test outputs
23+
$this->tempDir = sys_get_temp_dir().'/har_test_'.uniqid();
24+
mkdir($this->tempDir, recursive: true);
25+
26+
// Set up the command tester
27+
$command = new SplitCommand();
28+
$this->commandTester = new CommandTester($command);
29+
}
30+
31+
protected function tearDown(): void
32+
{
33+
// Clean up temporary directory
34+
if (is_dir($this->tempDir)) {
35+
$this->recursiveRemoveDirectory($this->tempDir);
36+
}
37+
38+
parent::tearDown();
39+
}
40+
41+
public function testSplitMultipleEntries(): void
42+
{
43+
$harFile = __DIR__.'/../../fixtures/www.softwareishard.com-multiple-entries.har';
44+
45+
$this->commandTester->execute([
46+
'har' => $harFile,
47+
'destination' => $this->tempDir,
48+
]);
49+
50+
// Should succeed
51+
$this->assertSame(Command::SUCCESS, $this->commandTester->getStatusCode());
52+
53+
// Should create 11 files (one per entry)
54+
$files = glob($this->tempDir.'/*.har');
55+
$this->assertCount(11, $files);
56+
57+
// Verify file names are sequential
58+
$expectedFiles = [];
59+
for ($i = 1; $i <= 11; ++$i) {
60+
$expectedFiles[] = $this->tempDir.'/'.$i.'.har';
61+
}
62+
natsort($files);
63+
$files = array_values($files); // Re-index array after sorting
64+
$this->assertEquals($expectedFiles, $files);
65+
66+
// Verify each file is valid HAR with single entry
67+
$serializer = new Serializer();
68+
foreach ($files as $file) {
69+
$contents = file_get_contents($file);
70+
$har = $serializer->deserializeHar($contents);
71+
$this->assertCount(1, $har->getLog()->getEntries(), 'Each split file should have exactly one entry');
72+
}
73+
}
74+
75+
public function testSplitSingleEntry(): void
76+
{
77+
$harFile = __DIR__.'/../../fixtures/www.softwareishard.com-single-entry.har';
78+
79+
$this->commandTester->execute([
80+
'har' => $harFile,
81+
'destination' => $this->tempDir,
82+
]);
83+
84+
$this->assertSame(Command::SUCCESS, $this->commandTester->getStatusCode());
85+
86+
// Should create 1 file
87+
$files = glob($this->tempDir.'/*.har');
88+
$this->assertCount(1, $files);
89+
$this->assertFileExists($this->tempDir.'/1.har');
90+
91+
// Verify the file is valid HAR
92+
$serializer = new Serializer();
93+
$contents = file_get_contents($this->tempDir.'/1.har');
94+
$har = $serializer->deserializeHar($contents);
95+
$this->assertCount(1, $har->getLog()->getEntries());
96+
}
97+
98+
public function testSplitWithMd5Option(): void
99+
{
100+
$harFile = __DIR__.'/../../fixtures/www.softwareishard.com-multiple-entries.har';
101+
102+
$this->commandTester->execute([
103+
'har' => $harFile,
104+
'destination' => $this->tempDir,
105+
'--md5' => true,
106+
]);
107+
108+
$this->assertSame(Command::SUCCESS, $this->commandTester->getStatusCode());
109+
110+
// Should create 11 files
111+
$files = glob($this->tempDir.'/*.har');
112+
$this->assertCount(11, $files);
113+
114+
// Verify file names are MD5 hashes
115+
foreach ($files as $file) {
116+
$basename = basename($file, '.har');
117+
$this->assertMatchesRegularExpression('/^[a-f0-9]{32}$/', $basename, 'Filename should be MD5 hash');
118+
}
119+
120+
// Verify each file is valid HAR
121+
$serializer = new Serializer();
122+
foreach ($files as $file) {
123+
$contents = file_get_contents($file);
124+
$har = $serializer->deserializeHar($contents);
125+
$this->assertCount(1, $har->getLog()->getEntries());
126+
127+
// Verify the filename matches the MD5 of the request URL
128+
$url = (string) $har->getLog()->getEntries()[0]->getRequest()->getUrl();
129+
$expectedHash = md5($url);
130+
$basename = basename($file, '.har');
131+
$this->assertEquals($expectedHash, $basename);
132+
}
133+
}
134+
135+
public function testSplitWithForceOption(): void
136+
{
137+
$harFile = __DIR__.'/../../fixtures/www.softwareishard.com-single-entry.har';
138+
139+
// First split
140+
$this->commandTester->execute([
141+
'har' => $harFile,
142+
'destination' => $this->tempDir,
143+
]);
144+
$this->assertSame(Command::SUCCESS, $this->commandTester->getStatusCode());
145+
146+
$outputFile = $this->tempDir.'/1.har';
147+
$this->assertFileExists($outputFile);
148+
$originalContent = file_get_contents($outputFile);
149+
150+
// Modify the file to verify it gets overwritten
151+
file_put_contents($outputFile, 'modified content');
152+
$this->assertEquals('modified content', file_get_contents($outputFile));
153+
154+
// Split again with --force
155+
$this->commandTester->execute([
156+
'har' => $harFile,
157+
'destination' => $this->tempDir,
158+
'--force' => true,
159+
]);
160+
$this->assertSame(Command::SUCCESS, $this->commandTester->getStatusCode());
161+
162+
// Verify the file was overwritten with original content
163+
$newContent = file_get_contents($outputFile);
164+
$this->assertEquals($originalContent, $newContent);
165+
$this->assertNotEquals('modified content', $newContent);
166+
}
167+
168+
public function testSplitFailsWhenFileExistsWithoutForce(): void
169+
{
170+
$harFile = __DIR__.'/../../fixtures/www.softwareishard.com-single-entry.har';
171+
172+
// First split
173+
$this->commandTester->execute([
174+
'har' => $harFile,
175+
'destination' => $this->tempDir,
176+
]);
177+
$this->assertSame(Command::SUCCESS, $this->commandTester->getStatusCode());
178+
179+
// Try to split again without --force
180+
$this->expectException(\RuntimeException::class);
181+
$this->expectExceptionMessageMatches('/exists\. Use --force to overwrite/');
182+
183+
$this->commandTester->execute([
184+
'har' => $harFile,
185+
'destination' => $this->tempDir,
186+
]);
187+
}
188+
189+
public function testSplitToCurrentDirectoryByDefault(): void
190+
{
191+
$harFile = __DIR__.'/../../fixtures/www.softwareishard.com-single-entry.har';
192+
193+
// Save current directory
194+
$originalDir = getcwd();
195+
196+
try {
197+
// Change to temp directory
198+
chdir($this->tempDir);
199+
200+
// Execute without destination argument
201+
$this->commandTester->execute([
202+
'har' => $harFile,
203+
]);
204+
205+
$this->assertSame(Command::SUCCESS, $this->commandTester->getStatusCode());
206+
207+
// File should be created in current directory (tempDir)
208+
$this->assertFileExists($this->tempDir.'/1.har');
209+
} finally {
210+
// Restore original directory
211+
chdir($originalDir);
212+
}
213+
}
214+
215+
public function testSplitPreservesHarStructure(): void
216+
{
217+
$harFile = __DIR__.'/../../fixtures/www.softwareishard.com-multiple-entries.har';
218+
219+
// Load original HAR
220+
$serializer = new Serializer();
221+
$originalContents = file_get_contents($harFile);
222+
$originalHar = $serializer->deserializeHar($originalContents);
223+
$originalEntries = $originalHar->getLog()->getEntries();
224+
225+
$this->commandTester->execute([
226+
'har' => $harFile,
227+
'destination' => $this->tempDir,
228+
]);
229+
230+
// Load split files and compare each entry
231+
for ($i = 0; $i < \count($originalEntries); ++$i) {
232+
$splitFile = $this->tempDir.'/'.($i + 1).'.har';
233+
$this->assertFileExists($splitFile);
234+
235+
$splitContents = file_get_contents($splitFile);
236+
$splitHar = $serializer->deserializeHar($splitContents);
237+
$splitEntry = $splitHar->getLog()->getEntries()[0];
238+
239+
// Compare request URLs to verify correct entry
240+
$this->assertEquals(
241+
(string) $originalEntries[$i]->getRequest()->getUrl(),
242+
(string) $splitEntry->getRequest()->getUrl()
243+
);
244+
}
245+
}
246+
247+
private function recursiveRemoveDirectory(string $directory): void
248+
{
249+
if (!is_dir($directory)) {
250+
return;
251+
}
252+
253+
$items = array_diff(scandir($directory), ['.', '..']);
254+
foreach ($items as $item) {
255+
$path = $directory.'/'.$item;
256+
if (is_dir($path)) {
257+
$this->recursiveRemoveDirectory($path);
258+
} else {
259+
unlink($path);
260+
}
261+
}
262+
rmdir($directory);
263+
}
264+
}

0 commit comments

Comments
 (0)