Skip to content

Commit

Permalink
fix: make sort operation's direction match PHP usort function's d…
Browse files Browse the repository at this point in the history
…irection

This partially revert 99323e6

Related to: #331
  • Loading branch information
drupol committed Jan 22, 2024
1 parent 3ba53a9 commit 3b0f875
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 5 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
],
"require": {
"php": ">= 8.1",
"loophp/iterators": "^3.1"
"loophp/iterators": "^3.1.1"
},
"require-dev": {
"ext-pcov": "*",
Expand Down
2 changes: 1 addition & 1 deletion docs/pages/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2136,7 +2136,7 @@ sort
~~~~

Sort a collection using a callback. If no callback is provided, it will sort
using natural order, ascending.
using natural order. The direction by default match the PHP `usort` function.

By default, it will sort by values and using the default callback. If you want
to sort by keys, you can pass a parameter to change the behaviour.
Expand Down
2 changes: 1 addition & 1 deletion src/Operation/Matching.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ static function (Criteria $criteria): Closure {
$next = null;

foreach (array_reverse($orderings) as $field => $ordering) {
$next = ClosureExpressionVisitor::sortByField($field, Criteria::ASC === $ordering ? -1 : 1, $next);
$next = ClosureExpressionVisitor::sortByField($field, Criteria::DESC === $ordering ? -1 : 1, $next);
}

$pipes[] = (new Sort())()(Sortable::BY_VALUES)($next);
Expand Down
2 changes: 1 addition & 1 deletion src/Operation/Sort.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ static function (null|callable|Closure $callback = null) use ($type): Closure {
* @param TKey $leftKey
* @param TKey $rightKey
*/
static fn (mixed $left, mixed $right, mixed $leftKey, mixed $rightKey): int => $right <=> $left;
static fn (mixed $left, mixed $right, mixed $leftKey, mixed $rightKey): int => $left <=> $right;

if (!($callback instanceof Closure)) {
trigger_deprecation(
Expand Down
47 changes: 47 additions & 0 deletions tests/unit/IssuesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,51 @@ public function __construct(

self::assertEquals([1, 2, 3], $input->all());
}

private static function createValueObject(int $id, int $weight): object
{
return new class($id, $weight) {
public function __construct(
public int $id,
public int $weight,
) {
}
};
}

public function testPhpSorting(): void
{
$input = [
self::createValueObject(id: 1, weight: 2),
self::createValueObject(id: 160, weight: 1),
self::createValueObject(id: 1600, weight: 3),
self::createValueObject(id: 2, weight: 2),
self::createValueObject(id: 150, weight: 1),
self::createValueObject(id: 1500, weight: 3),
self::createValueObject(id: 3, weight: 2),
];

usort($input, static fn (object $a, object $b): int => $a->weight <=> $b->weight);

$collection = Collection::fromIterable($input)->map(static fn (object $item): int => $item->id);

self::assertEquals([160, 150, 1, 2, 3, 1600, 1500], $collection->all());
}

public function testCollectionSorting(): void
{
$input = Collection::fromIterable([
self::createValueObject(id: 1, weight: 2),
self::createValueObject(id: 160, weight: 1),
self::createValueObject(id: 1600, weight: 3),
self::createValueObject(id: 2, weight: 2),
self::createValueObject(id: 150, weight: 1),
self::createValueObject(id: 1500, weight: 3),
self::createValueObject(id: 3, weight: 2),
])
->sort(callback: static fn (object $a, object $b): int => $a->weight <=> $b->weight)
->map(static fn (object $item): int => $item->id);

self::assertEquals([160, 150, 1, 2, 3, 1600, 1500], $input->all());
}
}
2 changes: 1 addition & 1 deletion tests/unit/Traits/GenericCollectionProviders.php
Original file line number Diff line number Diff line change
Expand Up @@ -4071,7 +4071,7 @@ public static function sortOperationProvider()
static fn (string $left, string $right): int => $left <=> $right,
],
$input,
array_combine(range('A', 'E'), range('E', 'A')),
array_combine(range('E', 'A'), range('A', 'E')),
];

$inputGen = static function () {
Expand Down

0 comments on commit 3b0f875

Please sign in to comment.