Skip to content

Commit

Permalink
fix: Correctly check the PHARs equality (#1049)
Browse files Browse the repository at this point in the history
  • Loading branch information
theofidry authored Oct 11, 2023
1 parent 1edcb8e commit b8065e6
Show file tree
Hide file tree
Showing 4 changed files with 171 additions and 16 deletions.
1 change: 1 addition & 0 deletions src/Console/PharInfoRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ public static function renderCompression(PharInfo $pharInfo, IO $io): void
);

$count = $pharInfo->getFilesCompressionCount();
// Rename "none" to "None"
$count['None'] = $count[CompressionAlgorithm::NONE->name];
unset($count[CompressionAlgorithm::NONE->name]);
$count = array_filter($count);
Expand Down
32 changes: 27 additions & 5 deletions src/Phar/PharInfo.php
Original file line number Diff line number Diff line change
Expand Up @@ -158,14 +158,36 @@ public function getFileName(): string
return $this->fileName;
}

/**
* @deprecated
*/
public function equals(self $pharInfo): bool
{
return
$pharInfo->getFilesCompressionCount() === $this->getFilesCompressionCount()
&& $pharInfo->getNormalizedMetadata() === $this->getNormalizedMetadata();
$this->contentEquals($pharInfo)
&& $this->getCompression() === $pharInfo->getCompression()
&& $this->getNormalizedMetadata() === $pharInfo->getNormalizedMetadata();
}

/**
* Checks if the content of the given PHAR equals the current one. Note that by content is meant
* the list of files and their content. The files compression or the PHAR metadata are not considered.
*/
private function contentEquals(self $pharInfo): bool
{
// The signature only checks if the contents are equal (same files, each files same content), but do
// not check the compression of the files.
// As a result, we also need to check the compression of each file.
if ($this->getSignature() != $pharInfo->getSignature()) {
return false;
}

foreach ($this->meta->filesMeta as $file => ['compression' => $compressionAlgorithm]) {
['compression' => $otherCompressionAlgorithm] = $this->getFileMeta($file);

if ($otherCompressionAlgorithm !== $compressionAlgorithm) {
return false;
}
}

return true;
}

public function getCompression(): CompressionAlgorithm
Expand Down
106 changes: 95 additions & 11 deletions tests/Console/Command/DiffTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,21 @@ private static function listDiffPharsProvider(): iterable
// Comparing the two archives... (do not check the signatures)
[OK] The two archives are identical
Archive: simple-phar-foo.phar
Archive Compression: None
Files Compression: None
Signature: SHA-1
Signature Hash: 311080EF8E479CE18D866B744B7D467880BFBF57
Metadata: None
Contents: 1 file (6.64KB)
Archive: simple-phar-bar.phar
Archive Compression: None
Files Compression: None
Signature: SHA-1
Signature Hash: 9ADC09F73909EDF14F8A4ABF9758B6FFAD1BBC51
Metadata: None
Contents: 1 file (6.64KB)
// Comparing the two archives contents...
Expand All @@ -432,7 +446,7 @@ private static function listDiffPharsProvider(): iterable


OUTPUT,
1,
2,
];

yield 'same files different content' => [
Expand All @@ -442,15 +456,29 @@ private static function listDiffPharsProvider(): iterable
// Comparing the two archives... (do not check the signatures)
[OK] The two archives are identical
Archive: simple-phar-bar.phar
Archive Compression: None
Files Compression: None
Signature: SHA-1
Signature Hash: 9ADC09F73909EDF14F8A4ABF9758B6FFAD1BBC51
Metadata: None
Contents: 1 file (6.64KB)
Archive: simple-phar-baz.phar
Archive Compression: None
Files Compression: None
Signature: SHA-1
Signature Hash: 122A636B8BB0348C9514833D70281EF6306A5BF5
Metadata: None
Contents: 1 file (6.61KB)
// Comparing the two archives contents...
[OK] The contents are identical


OUTPUT,
ExitCode::SUCCESS,
ExitCode::FAILURE,
];
}

Expand All @@ -465,7 +493,21 @@ public static function gitDiffPharsProvider(): iterable
// Comparing the two archives... (do not check the signatures)
[OK] The two archives are identical
Archive: simple-phar-foo.phar
Archive Compression: None
Files Compression: None
Signature: SHA-1
Signature Hash: 311080EF8E479CE18D866B744B7D467880BFBF57
Metadata: None
Contents: 1 file (6.64KB)
Archive: simple-phar-bar.phar
Archive Compression: None
Files Compression: None
Signature: SHA-1
Signature Hash: 9ADC09F73909EDF14F8A4ABF9758B6FFAD1BBC51
Metadata: None
Contents: 1 file (6.64KB)
// Comparing the two archives contents...
Expand All @@ -485,7 +527,21 @@ public static function gitDiffPharsProvider(): iterable
// Comparing the two archives... (do not check the signatures)
[OK] The two archives are identical
Archive: simple-phar-bar.phar
Archive Compression: None
Files Compression: None
Signature: SHA-1
Signature Hash: 9ADC09F73909EDF14F8A4ABF9758B6FFAD1BBC51
Metadata: None
Contents: 1 file (6.64KB)
Archive: simple-phar-baz.phar
Archive Compression: None
Files Compression: None
Signature: SHA-1
Signature Hash: 122A636B8BB0348C9514833D70281EF6306A5BF5
Metadata: None
Contents: 1 file (6.61KB)
// Comparing the two archives contents...
Expand All @@ -500,7 +556,7 @@ public static function gitDiffPharsProvider(): iterable
+echo 'Hello world!';

OUTPUT,
1,
ExitCode::FAILURE,
];
}

Expand All @@ -515,15 +571,29 @@ public static function GNUDiffPharsProvider(): iterable
// Comparing the two archives... (do not check the signatures)
[OK] The two archives are identical
Archive: simple-phar-foo.phar
Archive Compression: None
Files Compression: None
Signature: SHA-1
Signature Hash: 311080EF8E479CE18D866B744B7D467880BFBF57
Metadata: None
Contents: 1 file (6.64KB)
Archive: simple-phar-bar.phar
Archive Compression: None
Files Compression: None
Signature: SHA-1
Signature Hash: 9ADC09F73909EDF14F8A4ABF9758B6FFAD1BBC51
Metadata: None
Contents: 1 file (6.64KB)
// Comparing the two archives contents...
Only in simple-phar-bar.phar: bar.php
Only in simple-phar-foo.phar: foo.php

OUTPUT,
1,
2,
];

yield 'same files different content' => [
Expand All @@ -534,7 +604,21 @@ public static function GNUDiffPharsProvider(): iterable
// Comparing the two archives... (do not check the signatures)
[OK] The two archives are identical
Archive: simple-phar-bar.phar
Archive Compression: None
Files Compression: None
Signature: SHA-1
Signature Hash: 9ADC09F73909EDF14F8A4ABF9758B6FFAD1BBC51
Metadata: None
Contents: 1 file (6.64KB)
Archive: simple-phar-baz.phar
Archive Compression: None
Files Compression: None
Signature: SHA-1
Signature Hash: 122A636B8BB0348C9514833D70281EF6306A5BF5
Metadata: None
Contents: 1 file (6.61KB)
// Comparing the two archives contents...
Expand All @@ -560,7 +644,7 @@ public static function GNUDiffPharsProvider(): iterable
> echo 'Hello world!';

OUTPUT,
1,
2,
];
}
}
48 changes: 48 additions & 0 deletions tests/Phar/PharInfoTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,54 @@ public function test_it_throws_an_error_when_a_phar_cannot_be_created_due_to_unv
new PharInfo($file);
}

/**
* @dataProvider equalProvider
*/
public function test_it_can_test_if_two_phars_are_equal(
string $fileA,
string $fileB,
bool $expected,
): void {
$pharInfoA = new PharInfo(realpath($fileA));
$pharInfoB = new PharInfo(realpath($fileB));

$actual = $pharInfoA->equals($pharInfoB);

self::assertSame($expected, $actual);
}

public static function equalProvider(): iterable
{
yield 'identical PHARs' => [
self::FIXTURES_DIR.'/phar/simple-phar.phar',
self::FIXTURES_DIR.'/phar/simple-phar.phar',
true,
];

yield 'identical PHARs with different compression' => [
self::FIXTURES_DIR.'/phar/simple-phar.phar',
self::FIXTURES_DIR.'/phar/simple-phar.phar.gz',
false,
];

yield 'different files' => [
self::FIXTURES_DIR.'/diff/simple-phar-foo.phar',
self::FIXTURES_DIR.'/diff/simple-phar-bar.phar',
false,
];

yield 'same files with different content' => [
self::FIXTURES_DIR.'/diff/simple-phar-bar.phar',
self::FIXTURES_DIR.'/diff/simple-phar-baz.phar',
false,
];

// TODO: missing cases:
// - same PHARs and diff. metadata
// - same PHARs and same total compression file count but not the same files compression
// (to assert the compression comparison is justified instead of using the existing ::getFilesCompressionCount()).
}

private static function getStub(string $path): string
{
// We trim the last line returns since phpStorm may interfere with the copied file appending it on save.
Expand Down

0 comments on commit b8065e6

Please sign in to comment.