Skip to content

Commit ebe9c06

Browse files
authored
Improve sorting algorithm (#114)
Improve sorting algorithm (#114)
1 parent 28f43f3 commit ebe9c06

File tree

8 files changed

+84
-12
lines changed

8 files changed

+84
-12
lines changed

tests/Unit/Updater/ChangelogTracker/ChangelogTrackerTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
* @uses \Beeyev\DisposableEmailFilter\Updater\Shared\Whitelist
2020
* @uses \Beeyev\DisposableEmailFilter\Updater\SourceBlacklistsLoader\Dto\SourceBlacklistItemDto
2121
* @uses \Beeyev\DisposableEmailFilter\Updater\SourceBlacklistsLoader\Dto\SourceBlacklistsDto
22+
* @uses \Beeyev\DisposableEmailFilter\Updater\Support\Utils
2223
*
2324
* @internal
2425
*/

tests/Unit/Updater/Support/DomainsExtractorTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ public function testSuccessfullyExtractsDomains(): void
2222

2323
self::assertSame(
2424
[
25-
'1dcv.com',
2625
'01dcv.com',
26+
'1dcv.com',
2727
'abc02.com',
2828
'abc03.com',
2929
'abc1.com',

tests/Unit/Updater/Support/UtilsTest.php

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,4 +70,59 @@ public function testHash(): void
7070
$hash = Utils::hash('lorem ipsum dolor sit amet');
7171
self::assertSame('201730d4278e576b25515bd90c6072d3', $hash);
7272
}
73+
74+
/**
75+
* @dataProvider domainProvider
76+
*/
77+
public function testNaturalSortOrdersDomainsCorrectly(array $input, array $expected): void
78+
{
79+
$result = Utils::naturalSort($input);
80+
self::assertSame($expected, $result);
81+
}
82+
83+
public function domainProvider(): array
84+
{
85+
return [
86+
'Numerical sorting with leading zeros' => [
87+
['47gmail.com', '047gmail.com', '47bmt.com'],
88+
['47bmt.com', '047gmail.com', '47gmail.com'],
89+
],
90+
'Mixed numerical/alpha segments' => [
91+
['img12.com', 'img2.com', 'img1.com'],
92+
['img1.com', 'img2.com', 'img12.com'],
93+
],
94+
'Natural equivalence with string fallback' => [
95+
['apple01.com', 'apple1.com', 'apple001.com'],
96+
['apple001.com', 'apple01.com', 'apple1.com'],
97+
],
98+
'Different TLDs with same name' => [
99+
['test.net', 'test.com', 'test.org'],
100+
['test.com', 'test.net', 'test.org'],
101+
],
102+
'Complex domain patterns' => [
103+
['1a.example.com', 'a1.example.com', '01a.example.com'],
104+
['01a.example.com', '1a.example.com', 'a1.example.com'],
105+
],
106+
'Subdomain sorting' => [
107+
['blog.47gmail.com', '047gmail.com', 'mail.47gmail.com'],
108+
['047gmail.com', 'blog.47gmail.com', 'mail.47gmail.com'],
109+
],
110+
'Numerical TLDs (uncommon but valid)' => [
111+
['example.42', 'example.7', 'example.007'],
112+
['example.007', 'example.7', 'example.42'],
113+
],
114+
'Empty' => [
115+
[],
116+
[],
117+
],
118+
'Single' => [
119+
['single.com'],
120+
['single.com'],
121+
],
122+
'Duplicates' => [
123+
['dup.com', 'dup.com'],
124+
['dup.com', 'dup.com'],
125+
],
126+
];
127+
}
73128
}

updater/ChangelogTracker/ChangelogTracker.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use Beeyev\DisposableEmailFilter\Updater\Shared\Whitelist;
1313
use Beeyev\DisposableEmailFilter\Updater\SourceBlacklistsLoader\Dto\SourceBlacklistItemDto;
1414
use Beeyev\DisposableEmailFilter\Updater\SourceBlacklistsLoader\Dto\SourceBlacklistsDto;
15+
use Beeyev\DisposableEmailFilter\Updater\Support\Utils;
1516

1617
/**
1718
* @phpstan-type LastSyncedBlacklists array{
@@ -162,9 +163,8 @@ private function getOverallAddedDomains(array $lastSyncedBlacklists): array
162163
}, $this->sourceBlacklistsDto->items))));
163164

164165
$result = array_diff($bDomains, $lastSyncedBlacklistDomains);
165-
natsort($result);
166166

167-
return array_values($result);
167+
return Utils::naturalSort($result);
168168
}
169169

170170
/**
@@ -183,9 +183,8 @@ private function getOverallRemovedDomains(array $lastSyncedBlacklists): array
183183
}, $this->sourceBlacklistsDto->items))));
184184

185185
$result = array_diff($lastSyncedBlacklistDomains, $bDomains);
186-
natsort($result);
187186

188-
return array_values($result);
187+
return Utils::naturalSort($result);
189188
}
190189

191190
/**

updater/PrepareBlacklistService.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Beeyev\DisposableEmailFilter\Updater\DataManipulation\ContentsManipulatorInterface;
1010
use Beeyev\DisposableEmailFilter\Updater\SourceBlacklistsLoader\Dto\SourceBlacklistsDto;
1111
use Beeyev\DisposableEmailFilter\Updater\Support\DomainsExtractor;
12+
use Beeyev\DisposableEmailFilter\Updater\Support\Utils;
1213

1314
/** @internal */
1415
final class PrepareBlacklistService
@@ -42,9 +43,7 @@ public function getPreparedBlacklist(): array
4243
$result = array_diff($blacklistData, $whitelistData);
4344
assert(count($result) > 0);
4445

45-
natsort($result);
46-
47-
return array_values($result);
46+
return Utils::naturalSort($result);
4847
}
4948

5049
/**

updater/ReleaseNotesUpdater/ReleaseNotesUpdater.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,6 @@ private function getDomainsPreview(array $domains): string
125125
$result[] = '... See full list in the source file.';
126126
}
127127

128-
return implode(PHP_EOL, $result); // @phpstan-ignore return.type
128+
return implode(PHP_EOL, $result);
129129
}
130130
}

updater/Support/DomainsExtractor.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,7 @@ public static function toArray(string $multilineDomainList): array
4444

4545
$result = array_unique($result);
4646

47-
natsort($result);
48-
49-
return array_values($result);
47+
return Utils::naturalSort($result);
5048
}
5149

5250
private static function isDomainValid(string $domain): bool

updater/Support/Utils.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,4 +85,24 @@ public static function hash(string $string): string
8585
{
8686
return md5($string);
8787
}
88+
89+
/**
90+
* @param array<string> $inputArray
91+
*
92+
* @return array<string>
93+
*/
94+
public static function naturalSort(array $inputArray): array
95+
{
96+
$sut = $inputArray;
97+
98+
uasort($sut, static function (string $a, string $b): int {
99+
if (($cmp = strnatcmp($a, $b)) !== 0) {
100+
return $cmp;
101+
}
102+
103+
return strcmp($a, $b);
104+
});
105+
106+
return array_values($sut);
107+
}
88108
}

0 commit comments

Comments
 (0)