@@ -184,4 +184,265 @@ public function testSelectorsPipeNested()
184184 $ subview [': ' ] = [55 , 77 ];
185185 $ this ->assertSame ([1 , 2 , 3 , 4 , 55 , 6 , 77 , 8 , 9 , 10 ], $ originalArray );
186186 }
187+
188+ public function testMap ()
189+ {
190+ $ source = [1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ];
191+ $ subview = ArrayView::toView ($ source )->subview ('::2 ' );
192+
193+ $ actual = $ subview ->map (fn ($ x ) => $ x * 10 );
194+ $ this ->assertSame ([10 , 30 , 50 , 70 , 90 ], $ actual );
195+ }
196+
197+ public function testMapWith ()
198+ {
199+ $ source = [1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ];
200+ $ subview = ArrayView::toView ($ source )->subview ('::2 ' );
201+ $ this ->assertSame ([1 , 3 , 5 , 7 , 9 ], $ subview ->toArray ());
202+
203+ $ data = [9 , 27 , 45 , 63 , 81 ];
204+
205+ $ actual = $ subview ->mapWith ($ data , fn ($ lhs , $ rhs ) => $ lhs + $ rhs );
206+ $ this ->assertSame ([10 , 30 , 50 , 70 , 90 ], $ actual );
207+ }
208+
209+ public function testIs ()
210+ {
211+ $ source = [1 , 2 , 3 , 4 , 5 , 6 ];
212+ $ view = ArrayView::toView ($ source );
213+
214+ $ mask = $ view ->is (fn ($ x ) => $ x % 2 === 0 );
215+ $ this ->assertSame ([false , true , false , true , false , true ], $ mask ->getValue ());
216+
217+ $ this ->assertSame ([2 , 4 , 6 ], $ view ->subview ($ mask )->toArray ());
218+ $ this ->assertSame ([2 , 4 , 6 ], $ view [$ mask ]);
219+
220+ $ view [$ mask ] = [20 , 40 , 60 ];
221+ $ this ->assertSame ([1 , 20 , 3 , 40 , 5 , 60 ], $ source );
222+ }
223+
224+ public function testMatch ()
225+ {
226+ $ source = [1 , 2 , 3 , 4 , 5 , 6 ];
227+ $ view = ArrayView::toView ($ source );
228+
229+ $ mask = $ view ->match (fn ($ x ) => $ x % 2 === 0 );
230+ $ this ->assertSame ([false , true , false , true , false , true ], $ mask ->getValue ());
231+
232+ $ this ->assertSame ([2 , 4 , 6 ], $ view ->subview ($ mask )->toArray ());
233+ $ this ->assertSame ([2 , 4 , 6 ], $ view [$ mask ]);
234+
235+ $ view [$ mask ] = [20 , 40 , 60 ];
236+ $ this ->assertSame ([1 , 20 , 3 , 40 , 5 , 60 ], $ source );
237+ }
238+
239+ public function testMatchWith ()
240+ {
241+ $ source = [1 , 2 , 3 , 4 , 5 , 6 ];
242+ $ view = ArrayView::toView ($ source );
243+
244+ $ data = [6 , 5 , 4 , 3 , 2 , 1 ];
245+
246+ $ mask = $ view ->matchWith ($ data , fn ($ lhs , $ rhs ) => $ lhs > $ rhs );
247+ $ this ->assertSame ([false , false , false , true , true , true ], $ mask ->getValue ());
248+
249+ $ this ->assertSame ([4 , 5 , 6 ], $ view ->subview ($ mask )->toArray ());
250+ $ this ->assertSame ([4 , 5 , 6 ], $ view [$ mask ]);
251+
252+ $ view [$ mask ] = [40 , 50 , 60 ];
253+ $ this ->assertSame ([1 , 2 , 3 , 40 , 50 , 60 ], $ source );
254+ }
255+
256+ public function testApply ()
257+ {
258+ $ source = [1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ];
259+ $ subview = ArrayView::toView ($ source )->subview ('::2 ' );
260+
261+ $ this ->assertSame ([1 , 3 , 5 , 7 , 9 ], $ subview ->toArray ());
262+
263+ $ subview ->apply (fn ($ x ) => $ x * 10 );
264+
265+ $ this ->assertSame ([10 , 30 , 50 , 70 , 90 ], $ subview ->toArray ());
266+ $ this ->assertSame ([10 , 2 , 30 , 4 , 50 , 6 , 70 , 8 , 90 , 10 ], $ source );
267+ }
268+
269+ public function testApplyWith ()
270+ {
271+ $ source = [1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ];
272+ $ subview = ArrayView::toView ($ source )->subview ('::2 ' );
273+
274+ $ this ->assertSame ([1 , 3 , 5 , 7 , 9 ], $ subview ->toArray ());
275+
276+ $ data = [9 , 27 , 45 , 63 , 81 ];
277+
278+ $ subview ->applyWith ($ data , fn ($ lhs , $ rhs ) => $ lhs + $ rhs );
279+ $ this ->assertSame ([10 , 30 , 50 , 70 , 90 ], $ subview ->toArray ());
280+
281+ $ this ->assertSame ([10 , 2 , 30 , 4 , 50 , 6 , 70 , 8 , 90 , 10 ], $ source );
282+ }
283+
284+ public function testFilter ()
285+ {
286+ $ source = [1 , 2 , 3 , 4 , 5 , 6 ];
287+ $ view = ArrayView::toView ($ source );
288+
289+ $ filtered = $ view ->filter (fn ($ x ) => $ x % 2 === 0 );
290+ $ this ->assertSame ([2 , 4 , 6 ], $ filtered ->toArray ());
291+
292+ $ filtered [': ' ] = [20 , 40 , 60 ];
293+ $ this ->assertSame ([20 , 40 , 60 ], $ filtered ->toArray ());
294+
295+ $ this ->assertSame ([1 , 20 , 3 , 40 , 5 , 60 ], $ source );
296+ }
297+
298+ public function testCount ()
299+ {
300+ $ source = [1 , 2 , 3 , 4 , 5 ];
301+
302+ $ subview = ArrayView::toView ($ source )->subview ('::2 ' );
303+
304+ $ this ->assertSame ([1 , 3 , 5 ], $ subview ->toArray ());
305+ $ this ->assertCount (3 , $ subview );
306+ }
307+
308+ public function testIterator ()
309+ {
310+ $ source = [1 , 2 , 3 , 4 , 5 ];
311+ $ subview = ArrayView::toView ($ source )->subview ('::2 ' ); // [1, 3, 5]
312+
313+ $ actual = [];
314+ foreach ($ subview as $ item ) {
315+ $ actual [] = $ item ;
316+ // 1, 3, 5
317+ }
318+ $ this ->assertSame ([1 , 3 , 5 ], $ actual );
319+ $ this ->assertSame ([1 , 3 , 5 ], [...$ subview ]);
320+ }
321+
322+ public function testIsReadonly ()
323+ {
324+ $ source = [1 , 2 , 3 , 4 , 5 ];
325+
326+ $ readonlyView = ArrayView::toView ($ source , true );
327+ $ this ->assertTrue ($ readonlyView ->isReadonly ());
328+
329+ $ readonlySubview = ArrayView::toView ($ source )->subview ('::2 ' , true );
330+ $ this ->assertTrue ($ readonlySubview ->isReadonly ());
331+
332+ $ view = ArrayView::toView ($ source );
333+ $ this ->assertFalse ($ view ->isReadonly ());
334+
335+ $ subview = ArrayView::toView ($ source )->subview ('::2 ' );
336+ $ this ->assertFalse ($ subview ->isReadonly ());
337+ }
338+
339+ public function testOffsetExists ()
340+ {
341+ $ source = [1 , 2 , 3 , 4 , 5 ];
342+ $ view = ArrayView::toView ($ source );
343+
344+ $ this ->assertTrue (isset ($ view [0 ]));
345+ $ this ->assertTrue (isset ($ view [-1 ]));
346+ $ this ->assertFalse (isset ($ view [10 ]));
347+
348+ $ this ->assertTrue (isset ($ view [new SliceSelector ('::2 ' )]));
349+ $ this ->assertTrue (isset ($ view [new IndexListSelector ([0 , 2 , 4 ])]));
350+ $ this ->assertFalse (isset ($ view [new IndexListSelector ([0 , 2 , 10 ])]));
351+ $ this ->assertTrue (isset ($ view [new MaskSelector ([true , true , false , false , true ])]));
352+ $ this ->assertFalse (isset ($ view [new MaskSelector ([true , true , false , false , true , true ])]));
353+
354+ $ this ->assertTrue (isset ($ view ['::2 ' ]));
355+ $ this ->assertTrue (isset ($ view [[0 , 2 , 4 ]]));
356+ $ this ->assertFalse (isset ($ view [[0 , 2 , 10 ]]));
357+ $ this ->assertTrue (isset ($ view [[true , true , false , false , true ]]));
358+ $ this ->assertFalse (isset ($ view [[true , true , false , false , true , true ]]));
359+ }
360+
361+ public function testOffsetGet ()
362+ {
363+ $ source = [1 , 2 , 3 , 4 , 5 ];
364+ $ view = ArrayView::toView ($ source );
365+
366+ $ this ->assertSame (1 , $ view [0 ]);
367+ $ this ->assertSame (5 , $ view [-1 ]);
368+
369+ $ this ->assertSame ([1 , 3 , 5 ], $ view [new SliceSelector ('::2 ' )]);
370+ $ this ->assertSame ([1 , 3 , 5 ], $ view [new IndexListSelector ([0 , 2 , 4 ])]);
371+ $ this ->assertSame ([1 , 2 , 5 ], $ view [new MaskSelector ([true , true , false , false , true ])]);
372+
373+ $ this ->assertSame ([1 , 3 , 5 ], $ view ['::2 ' ]);
374+ $ this ->assertSame ([1 , 3 , 5 ], $ view [[0 , 2 , 4 ]]);
375+ $ this ->assertSame ([1 , 2 , 5 ], $ view [[true , true , false , false , true ]]);
376+ }
377+
378+ public function testOffsetSet ()
379+ {
380+ $ source = [1 , 2 , 3 , 4 , 5 ];
381+ $ view = ArrayView::toView ($ source );
382+
383+ $ view [0 ] = 11 ;
384+ $ view [-1 ] = 55 ;
385+
386+ $ this ->assertSame ([11 , 2 , 3 , 4 , 55 ], $ source );
387+
388+ $ source = [1 , 2 , 3 , 4 , 5 ];
389+ $ view = ArrayView::toView ($ source );
390+
391+ $ view [new SliceSelector ('::2 ' )] = [11 , 33 , 55 ];
392+ $ this ->assertSame ([11 , 2 , 33 , 4 , 55 ], $ source );
393+
394+ $ view [new IndexListSelector ([1 , 3 ])] = [22 , 44 ];
395+ $ this ->assertSame ([11 , 22 , 33 , 44 , 55 ], $ source );
396+
397+ $ view [new MaskSelector ([true , false , false , false , true ])] = [111 , 555 ];
398+ $ this ->assertSame ([111 , 22 , 33 , 44 , 555 ], $ source );
399+
400+ $ source = [1 , 2 , 3 , 4 , 5 ];
401+ $ view = ArrayView::toView ($ source );
402+
403+ $ view ['::2 ' ] = [11 , 33 , 55 ];
404+ $ this ->assertSame ([11 , 2 , 33 , 4 , 55 ], $ source );
405+
406+ $ view [[1 , 3 ]] = [22 , 44 ];
407+ $ this ->assertSame ([11 , 22 , 33 , 44 , 55 ], $ source );
408+
409+ $ view [[true , false , false , false , true ]] = [111 , 555 ];
410+ $ this ->assertSame ([111 , 22 , 33 , 44 , 555 ], $ source );
411+ }
412+
413+ public function testSet ()
414+ {
415+ $ source = [1 , 2 , 3 , 4 , 5 ];
416+ $ subview = ArrayView::toView ($ source )->subview ('::2 ' ); // [1, 3, 5]
417+
418+ $ subview ->set ([11 , 33 , 55 ]);
419+ $ this ->assertSame ([11 , 33 , 55 ], $ subview ->toArray ());
420+ $ this ->assertSame ([11 , 2 , 33 , 4 , 55 ], $ source );
421+ }
422+
423+ public function testToUnlinkedView ()
424+ {
425+ $ source = [1 , 2 , 3 , 4 , 5 ];
426+ $ view = ArrayView::toUnlinkedView ($ source );
427+
428+ $ this ->assertSame (1 , $ view [0 ]);
429+ $ this ->assertSame ([2 , 4 ], $ view ['1::2 ' ]);
430+ $ view ['1::2 ' ] = [22 , 44 ];
431+
432+ $ this ->assertSame ([1 , 22 , 3 , 44 , 5 ], $ view ->toArray ());
433+ $ this ->assertSame ([1 , 2 , 3 , 4 , 5 ], $ source );
434+ }
435+
436+ public function testToView ()
437+ {
438+ $ source = [1 , 2 , 3 , 4 , 5 ];
439+ $ view = ArrayView::toView ($ source );
440+
441+ $ this ->assertSame (1 , $ view [0 ]);
442+ $ this ->assertSame ([2 , 4 ], $ view ['1::2 ' ]);
443+ $ view ['1::2 ' ] = [22 , 44 ];
444+
445+ $ this ->assertSame ([1 , 22 , 3 , 44 , 5 ], $ view ->toArray ());
446+ $ this ->assertSame ([1 , 22 , 3 , 44 , 5 ], $ source );
447+ }
187448}
0 commit comments