Skip to content

Commit d1f17b1

Browse files
authored
Merge pull request #42 from mulertech/introduce_assert_collection_equal_canonicalizing
Introduce assertCollectionEqualsCanonicalizing method
2 parents a66af48 + eb94102 commit d1f17b1

File tree

3 files changed

+187
-0
lines changed

3 files changed

+187
-0
lines changed

README.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,51 @@ public function theUsersAreOrdered(): void
8686
}
8787
```
8888

89+
#### assertCollectionEqualsCanonicalizing
90+
91+
Matches if the collections are canonically equals.
92+
93+
```php
94+
$collection1 = new Collection(['1', '2', '3']);
95+
$collection2 = new Collection(['3', '2', '1']);
96+
$this->assertCollectionEqualsCanonicalizing($collection1, $collection2);
97+
```
98+
99+
2 Collections are considered equal if they contain the same elements, indexed by the same keys.
100+
101+
```php
102+
$this->assertCollectionEqualsCanonicalizing(new Collection([1, 2]), new Collection([1, 2, 3])); // fail
103+
$this->assertCollectionEqualsCanonicalizing(new Collection([1, 2, 3]), new Collection([1, 2])); // fail
104+
$this->assertCollectionEqualsCanonicalizing(new Collection([1, 2, 3]), new Collection([1, 2, "3"])); // fail
105+
$this->assertCollectionEqualsCanonicalizing(new Collection(['a' => 1, 'b' => 2, 'c' => 3]), new Collection(['a' => 1, 'b' => 2])); // fail
106+
$this->assertCollectionEqualsCanonicalizing(new Collection(['a' => 1, 'b' => 2, 'c' => 3]), new Collection(['a' => 1, 'b' => 2, 'c' => 4])); // fail
107+
$this->assertCollectionEqualsCanonicalizing(new Collection(['a' => 1, 'b' => 2, 'c' => 3]), new Collection(['a' => 1, 'b' => 2, 3])); // fail
108+
```
109+
110+
If the Collections contain Models, `assertCollectionEqualsCanonicalizing` will use Model comparison of `assertIsModel`.
111+
112+
```php
113+
$user1 = User::factory()->createOne();
114+
$user2 = User::find($user1->id);
115+
$this->assertCollectionEqualsCanonicalizing(collect([$user1]), collect([$user2])); // Success
116+
```
117+
118+
You can give an array in the `$expected` parameter of `assertCollectionEqualsCanonicalizing` :
119+
120+
```php
121+
/** @test */
122+
public function theUsersAreOrdered(): void
123+
{
124+
$user1 = User::factory()->createOne();
125+
$user2 = User::factory()->createOne();
126+
127+
$this->assertCollectionEqualsCanonicalizing(
128+
[$user1, $user2],
129+
User::query()->get()
130+
);
131+
}
132+
```
133+
89134
### TestResponse assertions
90135

91136
All these methods are available in `Illuminate\Testing\TestResponse`:

src/Concerns/LaravelAssertions.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Soyhuce\Testing\Concerns;
44

55
use Illuminate\Database\Eloquent\Model;
6+
use Illuminate\Support\Arr;
67
use Illuminate\Support\Collection;
78
use PHPUnit\Framework\Assert;
89
use Soyhuce\Testing\Constraints\CollectionEquals;
@@ -38,6 +39,30 @@ public static function assertCollectionEquals(Collection|array $expected, mixed
3839
Assert::assertThat($actual, $constraint, $message);
3940
}
4041

42+
/**
43+
* @static
44+
* @param array<array-key, mixed>|\Illuminate\Support\Collection<array-key, mixed> $expected
45+
*/
46+
public static function assertCollectionEqualsCanonicalizing(
47+
Collection|array $expected,
48+
mixed $actual,
49+
string $message = ''
50+
): void {
51+
if (is_array($expected)) {
52+
$expected = new Collection($expected);
53+
}
54+
55+
$expected = Arr::isList($expected->all()) ? $expected->sort()->values() : $expected->sort();
56+
57+
if ($actual instanceof Collection) {
58+
$actual = Arr::isList($actual->all()) ? $actual->sort()->values() : $actual->sort();
59+
}
60+
61+
$constraint = new CollectionEquals($expected);
62+
63+
Assert::assertThat($actual, $constraint, $message);
64+
}
65+
4166
public static function assertDataEquals(Data $expected, mixed $actual, string $message = ''): void
4267
{
4368
$constraint = new DataEquals($expected);

tests/Unit/CollectionEqualsTest.php

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Illuminate\Support\Collection;
99
use PHPUnit\Framework\ExpectationFailedException;
1010
use Soyhuce\Testing\Concerns\LaravelAssertions;
11+
use Soyhuce\Testing\Tests\Fixtures\SimpleData;
1112
use Soyhuce\Testing\Tests\TestCase;
1213

1314
/**
@@ -42,6 +43,56 @@ public static function sameCollection(): array
4243
];
4344
}
4445

46+
public static function sameUnorderedCollection(): array
47+
{
48+
Model::unguard();
49+
50+
return [
51+
[new Collection([1, 2, 3]), new Collection([2, 1, 3])],
52+
[[1, 2, 3], new Collection([1, 3, 2])],
53+
[new Collection([1 => 1, 0 => 2, 3 => 3]), new Collection([0 => 2, 1 => 1, 3 => 3])],
54+
[[1 => 1, 0 => 2, 3 => 3], new Collection([1 => 1, 3 => 3, 0 => 2])],
55+
[new Collection(['a' => 1, 'b' => 2, 'c' => 3]), new Collection(['a' => 1, 'c' => 3, 'b' => 2])],
56+
[['c' => 3, 'a' => 1, 'b' => 2], new Collection(['a' => 1, 'b' => 2, 'c' => 3])],
57+
[
58+
new Collection([new User(['id' => 1, 'name' => 'John']), new User(['id' => 2, 'name' => 'Jack'])]),
59+
new Collection([new User(['id' => 2, 'name' => 'Jack']), new User(['id' => 1, 'name' => 'Peter'])]),
60+
],
61+
[
62+
new Collection([
63+
'John' => new User(['id' => 1, 'name' => 'John']),
64+
'Jack' => new User(['id' => 2, 'name' => 'Jack']),
65+
]),
66+
new Collection([
67+
'Jack' => new User(['id' => 2, 'name' => 'Jack']),
68+
'John' => new User(['id' => 1, 'name' => 'John']),
69+
]),
70+
],
71+
[
72+
new Collection([
73+
CarbonImmutable::create(2022, 2, 11),
74+
CarbonImmutable::create(2022, 5, 11),
75+
]),
76+
new Collection([
77+
CarbonImmutable::createFromFormat('!Y-m-d', '2022-05-11'),
78+
CarbonImmutable::createFromFormat('!Y-m-d', '2022-02-11'),
79+
]),
80+
],
81+
[
82+
new Collection([new Collection([1, 2, 3]), new Collection([2, 3, 1])]),
83+
new Collection([new Collection([2, 3, 1]), new Collection([1, 2, 3])]),
84+
],
85+
[
86+
new Collection([[1, 2, 3], [2, 1, 3]]),
87+
new Collection([[2, 1, 3], [1, 2, 3]]),
88+
],
89+
[
90+
[new SimpleData('John', 25), new SimpleData('Jack', 30)],
91+
new Collection([new SimpleData('Jack', 30), new SimpleData('John', 25)]),
92+
],
93+
];
94+
}
95+
4596
/**
4697
* @test
4798
* @dataProvider sameCollection
@@ -51,6 +102,15 @@ public function collectionsAreEqual(mixed $first, mixed $second): void
51102
$this->assertCollectionEquals($first, $second);
52103
}
53104

105+
/**
106+
* @test
107+
* @dataProvider sameUnorderedCollection
108+
*/
109+
public function collectionsAreEqualCanonicalizing(mixed $first, mixed $second): void
110+
{
111+
$this->assertCollectionEqualsCanonicalizing($first, $second);
112+
}
113+
54114
public static function differentCollections(): array
55115
{
56116
Model::unguard();
@@ -78,6 +138,52 @@ public static function differentCollections(): array
78138
];
79139
}
80140

141+
public static function differentUnorderedCollections(): array
142+
{
143+
Model::unguard();
144+
145+
return [
146+
[new Collection([1, 2]), new Collection([1, 2, 3])],
147+
[new Collection([1, 2, 3]), new Collection([1, 2])],
148+
[new Collection([1, 2, 3]), new Collection([3, 1, 4])],
149+
[new Collection([1, 2, 3]), new Collection([3, 1, 5])],
150+
[new Collection([1, 2, 3]), new Collection([1, 2, '3'])],
151+
[new Collection([1 => 1, 0 => 2, 3 => 3]), new Collection([0 => 2, 1 => 1, 3 => 6])],
152+
[[1 => 1, 0 => 2, 3 => 3], new Collection([1 => 1, 4 => 3, 0 => 2])],
153+
[new Collection(['a' => 1, 'b' => 2, 'c' => 3]), new Collection(['a' => 1, 'b' => 2])],
154+
[new Collection(['a' => 1, 'b' => 2, 'c' => 3]), new Collection(['a' => 1, 'b' => 2, 'c' => 4])],
155+
[new Collection(['a' => 1, 'b' => 2, 'c' => 3]), new Collection(['a' => 1, 'b' => 2, 'd' => 3])],
156+
[new Collection(['a' => 1, 'b' => 2, 'c' => 3]), new Collection(['a' => 1, 'c' => 6, 'b' => 2])],
157+
[new Collection(['a' => 1, 'b' => 2, 'c' => 3]), new Collection(['a' => 1, 'b' => 2, 3])],
158+
[
159+
new Collection([new User(['id' => 1, 'name' => 'John']), new User(['id' => 2, 'name' => 'Jack'])]),
160+
new Collection([new User(['id' => 2, 'name' => 'Jack']), new User(['id' => 5, 'name' => 'Peter'])]),
161+
],
162+
[
163+
new Collection([
164+
'id1' => new User(['id' => 1, 'name' => 'John']),
165+
'id2' => new User(['id' => 2, 'name' => 'Jack']),
166+
]),
167+
new Collection([
168+
'id2' => new User(['id' => 4, 'name' => 'Jack']),
169+
'id1' => new User(['id' => 1, 'name' => 'John']),
170+
]),
171+
],
172+
[
173+
new Collection([new Collection([1, 2, 3])]),
174+
new Collection([new Collection([1, '2', 3])]),
175+
],
176+
[
177+
new Collection([[1, 2, 3]]),
178+
new Collection([[1, '2', 3]]),
179+
],
180+
[
181+
[new SimpleData('John', 25), new SimpleData('Jack', 30)],
182+
new Collection([new SimpleData('Jack', 30), new SimpleData('Jim', 35)]),
183+
]
184+
];
185+
}
186+
81187
/**
82188
* @test
83189
* @dataProvider differentCollections
@@ -88,4 +194,15 @@ public function collectionsAreDifferent(mixed $first, mixed $second): void
88194

89195
$this->assertCollectionEquals($first, $second);
90196
}
197+
198+
/**
199+
* @test
200+
* @dataProvider differentUnorderedCollections
201+
*/
202+
public function collectionsAreDifferentCanonicalizing(mixed $first, mixed $second): void
203+
{
204+
$this->expectException(ExpectationFailedException::class);
205+
206+
$this->assertCollectionEqualsCanonicalizing($first, $second);
207+
}
91208
}

0 commit comments

Comments
 (0)