@@ -17,6 +17,15 @@ class Foo
1717{
1818}
1919
20+ /**
21+ * Test fixture for Collection.
22+ *
23+ * @package GeekCell\Ddd\Tests\Domain
24+ */
25+ class Bar
26+ {
27+ }
28+
2029class CollectionTest extends TestCase
2130{
2231 public function testTypedConstructor (): void
@@ -53,6 +62,40 @@ public function testUntypedConstructor(): void
5362 $ this ->assertInstanceOf (Collection::class, $ collection );
5463 }
5564
65+ public function testArrayAccess (): void
66+ {
67+ // Given
68+ $ items = [new Foo (), new Foo (), new Foo ()];
69+
70+ // When
71+ $ collection = new Collection ($ items , Foo::class);
72+
73+ // Then
74+ $ this ->assertEquals ($ collection [0 ], $ items [0 ]);
75+ $ this ->assertEquals ($ collection [1 ], $ items [1 ]);
76+ $ this ->assertEquals ($ collection [2 ], $ items [2 ]);
77+ $ this ->assertFalse (isset ($ collection [3 ]));
78+ }
79+
80+ public function testArrayAccessWithInvalidOffset (): void
81+ {
82+ // Given
83+ $ items = [new Foo (), new Foo (), new Foo ()];
84+ $ collection = new Collection ($ items , Foo::class);
85+
86+ // When
87+ $ result1 = $ collection [10 ];
88+ $ result2 = $ collection [-1 ];
89+ $ result3 = $ collection [0.5 ];
90+ $ result4 = $ collection ['foo ' ];
91+
92+ // When
93+ $ this ->assertNull ($ result1 );
94+ $ this ->assertNull ($ result2 );
95+ $ this ->assertNull ($ result3 );
96+ $ this ->assertNull ($ result4 );
97+ }
98+
5699 public function testCount (): void
57100 {
58101 // Given
@@ -77,4 +120,169 @@ public function testIterater(): void
77120 $ this ->assertEquals ($ items , iterator_to_array ($ collection ));
78121 $ this ->assertCount (3 , iterator_to_array ($ collection ));
79122 }
123+
124+ public function testAdd (): void
125+ {
126+ // Given
127+ $ items = [new Foo (), new Foo (), new Foo ()];
128+ $ collection = new Collection ($ items , Foo::class);
129+
130+ // When
131+ $ newCollection = $ collection ->add (new Foo ());
132+
133+ // Then
134+ $ this ->assertCount (4 , $ newCollection );
135+ $ this ->assertCount (3 , $ collection );
136+ $ this ->assertNotSame ($ collection , $ newCollection );
137+ }
138+
139+ public function testAddMultiple (): void
140+ {
141+ // Given
142+ $ items = [new Foo (), new Foo (), new Foo ()];
143+ $ collection = new Collection ($ items , Foo::class);
144+
145+ // When
146+ $ newCollection = $ collection ->add ([new Foo (), new Foo ()]);
147+
148+ // Then
149+ $ this ->assertCount (5 , $ newCollection );
150+ $ this ->assertCount (3 , $ collection );
151+ $ this ->assertNotSame ($ collection , $ newCollection );
152+ }
153+
154+ public function testFilter (): void
155+ {
156+ // Given
157+ $ items = [1 , 2 , 3 ,4 , 5 , 6 , 7 , 8 , 9 , 10 ];
158+ $ collection = new Collection ($ items );
159+
160+ // When
161+ $ newCollection = $ collection ->filter (fn (int $ i ) => $ i % 2 === 0 );
162+
163+ // Then
164+ $ this ->assertCount (5 , $ newCollection );
165+ $ this ->assertCount (10 , $ collection );
166+ $ this ->assertNotSame ($ collection , $ newCollection );
167+ }
168+
169+ public function testMap (): void
170+ {
171+ // Given
172+ $ items = [new Foo (), new Foo (), new Foo ()];
173+ $ collection = new Collection ($ items , Foo::class);
174+
175+ // When
176+ $ newCollection = $ collection ->map (fn (Foo $ item ) => new Bar ());
177+
178+ // Then
179+ $ this ->assertCount (3 , $ newCollection );
180+ $ this ->assertCount (3 , $ collection );
181+ $ this ->assertNotSame ($ collection , $ newCollection );
182+ }
183+
184+ public function testMapWithStrictTypes (): void
185+ {
186+ // Given
187+ $ items = [new Foo (), new Foo (), new Foo ()];
188+ $ collection = new Collection ($ items , Foo::class);
189+
190+ // Then
191+ $ this ->expectException (Assert \InvalidArgumentException::class);
192+
193+ // When
194+ $ counter = 0 ;
195+ $ newCollection = $ collection ->map (
196+ function (Foo $ item ) use (&$ counter ) {
197+ if ($ counter ++ % 2 ) {
198+ return new Bar ();
199+ }
200+
201+ return $ item ;
202+ },
203+ true ,
204+ );
205+ }
206+
207+ public function testMapWithoutStrictTypes (): void
208+ {
209+ // Given
210+ $ items = [new Foo (), new Foo (), new Foo ()];
211+ $ collection = new Collection ($ items , Foo::class);
212+
213+ // When
214+ $ counter = 0 ;
215+ $ newCollection = $ collection ->map (
216+ function ($ item ) use (&$ counter ) {
217+ if ($ counter ++ % 2 ) {
218+ return new Bar ();
219+ }
220+
221+ return $ item ;
222+ },
223+ false ,
224+ );
225+
226+ // Then
227+ $ this ->assertCount (3 , $ newCollection );
228+ $ this ->assertCount (3 , $ collection );
229+ $ this ->assertNotSame ($ collection , $ newCollection );
230+ }
231+
232+ public function testMapWithStrictTypesAndScalars (): void
233+ {
234+ // Given
235+ $ items = [new Foo (), new Foo (), new Foo ()];
236+ $ collection = new Collection ($ items , Foo::class);
237+
238+ // When
239+ $ counter = 0 ;
240+ $ newCollection = $ collection ->map (
241+ function (Foo $ item ) use (&$ counter ) {
242+ if ($ counter % 2 ) {
243+ return $ counter ++;
244+ }
245+
246+ return 'foo ' ;
247+ },
248+ true ,
249+ );
250+
251+ // Then
252+ $ this ->assertCount (3 , $ newCollection );
253+ $ this ->assertCount (3 , $ collection );
254+ $ this ->assertNotSame ($ collection , $ newCollection );
255+ }
256+
257+ public function testReduce (): void
258+ {
259+ // Given
260+ $ items = [1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ];
261+ $ collection = new Collection ($ items );
262+
263+ // When
264+ $ result = $ collection ->reduce (
265+ fn (int $ carry , int $ item ) => $ carry + $ item ,
266+ 0 ,
267+ );
268+
269+ // Then
270+ $ this ->assertEquals (55 , $ result );
271+ }
272+
273+ public function testChaining (): void
274+ {
275+ // Given
276+ $ items = [1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ];
277+ $ collection = new Collection ($ items );
278+
279+ // When
280+ $ result = $ collection
281+ ->filter (fn (int $ i ) => $ i % 2 === 0 )
282+ ->map (fn (int $ i ) => $ i * 2 )
283+ ->reduce (fn (int $ carry , int $ item ) => $ carry + $ item , 0 );
284+
285+ // Then
286+ $ this ->assertEquals (60 , $ result );
287+ }
80288}
0 commit comments