Skip to content

Commit

Permalink
* replace $firstKeyFromTableFilterByTrue() with match(true) expr …
Browse files Browse the repository at this point in the history
…like `switch(true)` stmt and merge `is_int($cursor)` branch with the default one as they yield the same `''` @ `encodeNextCursor()`

* remove the branch for `$prefix === null` as it had `?? ''` before
* now testing `$cursor` against `'0'` instead of `$prefix` as it would be `''` for cursor `0`
@ `decodeCursor()`
@ `App\Http\PostsQuery\BaseQuery`

* covering some source mutations @ `Tests\Feature\App\Http\PostsQuery\BaseQuery`

* ignore mutation `MethodCallRemoval` on any `$this->debugbar->` @ infection.json5
@ be
  • Loading branch information
n0099 committed Sep 18, 2024
1 parent e87f758 commit 19520b9
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 24 deletions.
32 changes: 15 additions & 17 deletions be/app/Http/PostsQuery/BaseQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -126,20 +126,16 @@ public function encodeNextCursor(Collection $postsKeyByTypePluralName): string
])
->map(static fn(array $cursors) => collect($cursors)
->map(static function (int|string $cursor): string {
if (\is_int($cursor) && $cursor === 0) {
// quick exit to keep 0 as is
if ($cursor === 0) { // quick exit to keep 0 as is
// to prevent packed 0 with the default format 'P' after 0x00 trimming is an empty string
// that will be confused with post types without a cursor that is a blank encoded cursor ',,'
return '0';
}

$firstKeyFromTableFilterByTrue = static fn(array $table, string $default): string =>
array_keys(array_filter($table, static fn(bool $f) => $f === true))[0] ?? $default;
$prefix = $firstKeyFromTableFilterByTrue([
'-' => \is_int($cursor) && $cursor < 0,
'' => \is_int($cursor),
'S' => \is_string($cursor),
], '');
$prefix = match (true) {
\is_int($cursor) && $cursor < 0 => '-',

Check warning on line 135 in be/app/Http/PostsQuery/BaseQuery.php

View workflow job for this annotation

GitHub Actions / runs-on (ubuntu-latest) / phpunit-infection

Escaped Mutant for Mutator "LessThan": --- Original +++ New @@ @@ return '0'; } $prefix = match (true) { - \is_int($cursor) && $cursor < 0 => '-', + \is_int($cursor) && $cursor <= 0 => '-', \is_string($cursor) => 'S', default => '', };

Check warning on line 135 in be/app/Http/PostsQuery/BaseQuery.php

View workflow job for this annotation

GitHub Actions / runs-on (windows-latest) / phpunit-infection

Escaped Mutant for Mutator "LessThan": --- Original +++ New @@ @@ return '0'; } $prefix = match (true) { - \is_int($cursor) && $cursor < 0 => '-', + \is_int($cursor) && $cursor <= 0 => '-', \is_string($cursor) => 'S', default => '', };

Check warning on line 135 in be/app/Http/PostsQuery/BaseQuery.php

View workflow job for this annotation

GitHub Actions / runs-on (macos-latest) / phpunit-infection

Escaped Mutant for Mutator "LessThan": --- Original +++ New @@ @@ return '0'; } $prefix = match (true) { - \is_int($cursor) && $cursor < 0 => '-', + \is_int($cursor) && $cursor <= 0 => '-', \is_string($cursor) => 'S', default => '', };
\is_string($cursor) => 'S',
default => '',
};

$value = \is_int($cursor)
// remove trailing 0x00 for an unsigned int or 0xFF for a signed negative int
Expand Down Expand Up @@ -174,25 +170,27 @@ public function decodeCursor(string $encodedCursors): Collection
->combine(Str::of($encodedCursors)
->explode(',')
->map(static function (string $encodedCursor): int|string|null {
/**
* @var string $cursor
* @var string $prefix
*/
[$prefix, $cursor] = array_pad(explode(':', $encodedCursor), 2, null);

Check warning on line 177 in be/app/Http/PostsQuery/BaseQuery.php

View workflow job for this annotation

GitHub Actions / runs-on (ubuntu-latest) / phpunit-infection

Escaped Mutant for Mutator "IncrementInteger": --- Original +++ New @@ @@ * @var string $cursor * @var string $prefix */ - [$prefix, $cursor] = array_pad(explode(':', $encodedCursor), 2, null); + [$prefix, $cursor] = array_pad(explode(':', $encodedCursor), 3, null); if ($cursor === null) { // no prefix being provided means the value of cursor is a positive int $cursor = $prefix;

Check warning on line 177 in be/app/Http/PostsQuery/BaseQuery.php

View workflow job for this annotation

GitHub Actions / runs-on (windows-latest) / phpunit-infection

Escaped Mutant for Mutator "IncrementInteger": --- Original +++ New @@ @@ * @var string $cursor * @var string $prefix */ - [$prefix, $cursor] = array_pad(explode(':', $encodedCursor), 2, null); + [$prefix, $cursor] = array_pad(explode(':', $encodedCursor), 3, null); if ($cursor === null) { // no prefix being provided means the value of cursor is a positive int $cursor = $prefix;

Check warning on line 177 in be/app/Http/PostsQuery/BaseQuery.php

View workflow job for this annotation

GitHub Actions / runs-on (macos-latest) / phpunit-infection

Escaped Mutant for Mutator "IncrementInteger": --- Original +++ New @@ @@ * @var string $cursor * @var string $prefix */ - [$prefix, $cursor] = array_pad(explode(':', $encodedCursor), 2, null); + [$prefix, $cursor] = array_pad(explode(':', $encodedCursor), 3, null); if ($cursor === null) { // no prefix being provided means the value of cursor is a positive int $cursor = $prefix;
if ($cursor === null) { // no prefix being provided means the value of cursor is a positive int
$cursor = $prefix;
$prefix = '';
}
return match ($prefix) {
null => null, // original encoded cursor is an empty string
'0' => 0, // keep 0 as is
return $cursor === '0' ? 0 : match ($prefix) { // keep 0 as is
'S' => $cursor, // string literal is not base64 encoded
default => ((array) (

Check warning on line 184 in be/app/Http/PostsQuery/BaseQuery.php

View workflow job for this annotation

GitHub Actions / runs-on (ubuntu-latest) / phpunit-infection

Escaped Mutant for Mutator "CastArray": --- Original +++ New @@ @@ // keep 0 as is 'S' => $cursor, // string literal is not base64 encoded - default => ((array) unpack(format: 'P', string: str_pad( + default => unpack(format: 'P', string: str_pad( // re-add removed trailing 0x00 or 0xFF base64_decode( // https://en.wikipedia.org/wiki/Base64#URL_applications @@ @@ ), length: 8, pad_string: $prefix === '-' ? "\xff" : "\x00" - )))[1], + ))[1], }; })->chunk(2)->map(static fn(Collection $i) => $i->values()))->mapWithKeys(fn(Collection $cursors, string $postType) => [$postType => $cursors->mapWithKeys(fn(int|string|null $cursor, int $index) => [$index === 0 ? Helper::POST_TYPE_TO_ID[$postType] : $this->orderByField => $cursor])])->reject(static fn(Collection $cursors) => $cursors->every(static fn(int|string|null $cursor) => $cursor === null))->map(static fn(Collection $cursors) => new Cursor($cursors->toArray())); }

Check warning on line 184 in be/app/Http/PostsQuery/BaseQuery.php

View workflow job for this annotation

GitHub Actions / runs-on (windows-latest) / phpunit-infection

Escaped Mutant for Mutator "CastArray": --- Original +++ New @@ @@ // keep 0 as is 'S' => $cursor, // string literal is not base64 encoded - default => ((array) unpack(format: 'P', string: str_pad( + default => unpack(format: 'P', string: str_pad( // re-add removed trailing 0x00 or 0xFF base64_decode( // https://en.wikipedia.org/wiki/Base64#URL_applications @@ @@ ), length: 8, pad_string: $prefix === '-' ? "\xff" : "\x00" - )))[1], + ))[1], }; })->chunk(2)->map(static fn(Collection $i) => $i->values()))->mapWithKeys(fn(Collection $cursors, string $postType) => [$postType => $cursors->mapWithKeys(fn(int|string|null $cursor, int $index) => [$index === 0 ? Helper::POST_TYPE_TO_ID[$postType] : $this->orderByField => $cursor])])->reject(static fn(Collection $cursors) => $cursors->every(static fn(int|string|null $cursor) => $cursor === null))->map(static fn(Collection $cursors) => new Cursor($cursors->toArray())); }

Check warning on line 184 in be/app/Http/PostsQuery/BaseQuery.php

View workflow job for this annotation

GitHub Actions / runs-on (macos-latest) / phpunit-infection

Escaped Mutant for Mutator "CastArray": --- Original +++ New @@ @@ // keep 0 as is 'S' => $cursor, // string literal is not base64 encoded - default => ((array) unpack(format: 'P', string: str_pad( + default => unpack(format: 'P', string: str_pad( // re-add removed trailing 0x00 or 0xFF base64_decode( // https://en.wikipedia.org/wiki/Base64#URL_applications @@ @@ ), length: 8, pad_string: $prefix === '-' ? "\xff" : "\x00" - )))[1], + ))[1], }; })->chunk(2)->map(static fn(Collection $i) => $i->values()))->mapWithKeys(fn(Collection $cursors, string $postType) => [$postType => $cursors->mapWithKeys(fn(int|string|null $cursor, int $index) => [$index === 0 ? Helper::POST_TYPE_TO_ID[$postType] : $this->orderByField => $cursor])])->reject(static fn(Collection $cursors) => $cursors->every(static fn(int|string|null $cursor) => $cursor === null))->map(static fn(Collection $cursors) => new Cursor($cursors->toArray())); }
unpack(
'P',
str_pad( // re-add removed trailing 0x00 or 0xFF
format: 'P',
string: str_pad( // re-add removed trailing 0x00 or 0xFF
base64_decode(
// https://en.wikipedia.org/wiki/Base64#URL_applications
str_replace(['-', '_'], ['+', '/'], $cursor),
),
8,
$prefix === '-' ? "\xFF" : "\x00",
length: 8,

Check warning on line 192 in be/app/Http/PostsQuery/BaseQuery.php

View workflow job for this annotation

GitHub Actions / runs-on (ubuntu-latest) / phpunit-infection

Escaped Mutant for Mutator "IncrementInteger": --- Original +++ New @@ @@ // https://en.wikipedia.org/wiki/Base64#URL_applications str_replace(['-', '_'], ['+', '/'], $cursor) ), - length: 8, + length: 9, pad_string: $prefix === '-' ? "\xff" : "\x00" )))[1], };

Check warning on line 192 in be/app/Http/PostsQuery/BaseQuery.php

View workflow job for this annotation

GitHub Actions / runs-on (windows-latest) / phpunit-infection

Escaped Mutant for Mutator "IncrementInteger": --- Original +++ New @@ @@ // https://en.wikipedia.org/wiki/Base64#URL_applications str_replace(['-', '_'], ['+', '/'], $cursor) ), - length: 8, + length: 9, pad_string: $prefix === '-' ? "\xff" : "\x00" )))[1], };

Check warning on line 192 in be/app/Http/PostsQuery/BaseQuery.php

View workflow job for this annotation

GitHub Actions / runs-on (macos-latest) / phpunit-infection

Escaped Mutant for Mutator "IncrementInteger": --- Original +++ New @@ @@ // https://en.wikipedia.org/wiki/Base64#URL_applications str_replace(['-', '_'], ['+', '/'], $cursor) ), - length: 8, + length: 9, pad_string: $prefix === '-' ? "\xff" : "\x00" )))[1], };
pad_string: $prefix === '-' ? "\xFF" : "\x00",
),
)
))[1], // the returned array of unpack() will starts index from 1
Expand Down
5 changes: 4 additions & 1 deletion be/infection.json5
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
"excludes": ["vendor", "tests", ".phpstorm.meta.php", "/_ide_helper.*.php/", "bootstrap/cache/*"]
},
"mutators": {
"@default": true
"@default": true,
"MethodCallRemoval": {
"ignoreSourceCodeByRegex": ['\\$this->debugbar.*']
}
}
}
45 changes: 39 additions & 6 deletions be/tests/Feature/App/Http/PostsQuery/BaseQueryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,18 @@ protected function setUp(): void
{
parent::setUp();
$this->sut = $this->getMockBuilder(BaseQuery::class)
->setConstructorArgs([app(LaravelDebugbar::class)])
->setConstructorArgs([$this->createMock(LaravelDebugbar::class)])
->getMockForAbstractClass();
(new \ReflectionProperty(BaseQuery::class, 'orderByField'))
->setValue($this->sut, 'postedAt');
}

public function testPerPageItemsDefaultValue(): void
{
$prop = new \ReflectionProperty(BaseQuery::class, 'perPageItems');
self::assertEquals(50, $prop->getValue($this->sut));
}

#[Test]
#[DataProvider('reOrderNestedPostsDataProvider')]
/** @backupStaticAttributes enabled */
Expand All @@ -41,7 +47,11 @@ public function reOrderNestedPosts(
$input = collect($input)->recursive();
(new \ReflectionProperty(BaseQuery::class, 'orderByDesc'))
->setValue($this->sut, $orderByDesc);
self::assertEquals($expected, $this->sut->reOrderNestedPosts($input, $shouldRemoveSortingKey));
if ($shouldRemoveSortingKey) { // make https://infection.github.io/guide/mutators.html#TrueValue happy
self::assertEquals($expected, $this->sut->reOrderNestedPosts($input));
} else {

Check failure on line 52 in be/tests/Feature/App/Http/PostsQuery/BaseQueryTest.php

View workflow job for this annotation

GitHub Actions / runs-on (windows-latest) / phpmd

BaseQueryTest.php: The method reOrderNestedPosts uses an else expression. Else clauses are basically not necessary and you can simplify the code by not using them. (ElseExpression, Clean Code Rules)
self::assertEquals($expected, $this->sut->reOrderNestedPosts($input, false));
}
}

public static function reOrderNestedPostsDataProvider(): array

Check warning on line 57 in be/tests/Feature/App/Http/PostsQuery/BaseQueryTest.php

View workflow job for this annotation

GitHub Actions / runs-on (windows-latest) / phpmd

BaseQueryTest.php: The method reOrderNestedPostsDataProvider() has 168 lines of code. Current threshold is set to 100. Avoid really long methods. (ExcessiveMethodLength, Code Size Rules)
Expand All @@ -64,7 +74,11 @@ public static function reOrderNestedPostsDataProvider(): array
[
'postedAt' => 4,
'isMatchQuery' => false,
'subReplies' => [['postedAt' => 5], ['postedAt' => 60]],
'subReplies' => [
['postedAt' => 5],
['postedAt' => 33, 'isMatchQuery' => false],
['postedAt' => 60],
],
],
],
],
Expand Down Expand Up @@ -96,7 +110,11 @@ public static function reOrderNestedPostsDataProvider(): array
[
'postedAt' => 4,
'isMatchQuery' => false,
'subReplies' => [['postedAt' => 5], ['postedAt' => 60]],
'subReplies' => [
['postedAt' => 5],
['postedAt' => 33, 'isMatchQuery' => false],
['postedAt' => 60],
],
'sortingKey' => 5,
],
],
Expand Down Expand Up @@ -134,7 +152,11 @@ public static function reOrderNestedPostsDataProvider(): array
[
'postedAt' => 4,
'isMatchQuery' => false,
'subReplies' => [['postedAt' => 5], ['postedAt' => 60]],
'subReplies' => [
['postedAt' => 5],
['postedAt' => 33, 'isMatchQuery' => false],
['postedAt' => 60],
],
],
],
],
Expand All @@ -158,7 +180,11 @@ public static function reOrderNestedPostsDataProvider(): array
[
'postedAt' => 4,
'isMatchQuery' => false,
'subReplies' => [['postedAt' => 60], ['postedAt' => 5]],
'subReplies' => [
['postedAt' => 60],
['postedAt' => 33, 'isMatchQuery' => false],
['postedAt' => 5],
],
'sortingKey' => 60,
],
[
Expand Down Expand Up @@ -219,6 +245,13 @@ public function decodeCursor(): void
'subReply' => new Cursor(['spid' => 3, 'postedAt' => 'test']),
]);
self::assertEquals($expected, $this->sut->decodeCursor('AQ,0,Ag,-:____fw,Aw,S:test'));

$expected = collect([
'thread' => new Cursor(['tid' => 0, 'postedAt' => 0]),
'reply' => new Cursor(['pid' => 0, 'postedAt' => 0]),
'subReply' => new Cursor(['spid' => 0, 'postedAt' => 0]),
]);
self::assertEquals($expected, $this->sut->decodeCursor(',,,,0,0'));
}

#[Test]
Expand Down

0 comments on commit 19520b9

Please sign in to comment.