Skip to content

Commit 36db5cd

Browse files
committed
More tests, fixes.
1 parent b1b8026 commit 36db5cd

File tree

6 files changed

+459
-7
lines changed

6 files changed

+459
-7
lines changed

src/Interfaces/ArrayViewInterface.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,13 @@ interface ArrayViewInterface extends \ArrayAccess, \IteratorAggregate, \Countabl
1818
*/
1919
public static function toView(&$source, ?bool $readonly = null): ArrayViewInterface;
2020

21+
/**
22+
* @param array<T>|ArrayViewInterface<T> $source
23+
* @param bool|null $readonly
24+
* @return ArrayViewInterface<T>
25+
*/
26+
public static function toUnlinkedView($source, ?bool $readonly = null): ArrayViewInterface;
27+
2128
/**
2229
* @return array<T>
2330
*/

src/Selectors/IndexListSelector.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ final class IndexListSelector implements ArraySelectorInterface
1414
private array $value;
1515

1616
/**
17-
* @param array<int> $value
17+
* @param array<int>|ArrayViewInterface<int> $value
1818
*/
19-
public function __construct(array $value)
19+
public function __construct($value)
2020
{
21-
$this->value = $value;
21+
$this->value = \is_array($value) ? $value : $value->toArray();
2222
}
2323

2424
/**

src/Selectors/MaskSelector.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@ class MaskSelector implements ArraySelectorInterface
1111
/**
1212
* @var array<bool>
1313
*/
14-
private array $value;
14+
private $value;
1515

1616
/**
17-
* @param array<bool> $value
17+
* @param array<bool>|ArrayViewInterface<bool> $value
1818
*/
19-
public function __construct(array $value)
19+
public function __construct($value)
2020
{
21-
$this->value = $value;
21+
$this->value = \is_array($value) ? $value : $value->toArray();
2222
}
2323

2424
/**

src/Views/ArrayView.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,14 @@ public static function toView(&$source, ?bool $readonly = null): ArrayViewInterf
5353
return $source;
5454
}
5555

56+
/**
57+
* {@inheritDoc}
58+
*/
59+
public static function toUnlinkedView($source, ?bool $readonly = null): ArrayViewInterface
60+
{
61+
return static::toView($source, $readonly);
62+
}
63+
5664
/**
5765
* @param array<T>|ArrayViewInterface<T> $source
5866
* @param bool|null $readonly

tests/unit/ArrayView/ReadTest.php

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
<?php
2+
3+
namespace Smoren\ArrayView\Tests\Unit\ArrayView;
4+
5+
use Smoren\ArrayView\Selectors\IndexListSelector;
6+
use Smoren\ArrayView\Selectors\MaskSelector;
7+
use Smoren\ArrayView\Selectors\SliceSelector;
8+
use Smoren\ArrayView\Views\ArrayIndexListView;
9+
use Smoren\ArrayView\Views\ArrayMaskView;
10+
use Smoren\ArrayView\Views\ArraySliceView;
11+
use Smoren\ArrayView\Views\ArrayView;
12+
13+
class ReadTest extends \Codeception\Test\Unit
14+
{
15+
/**
16+
* @dataProvider dataProviderForArrayRead
17+
*/
18+
public function testRead(array $source)
19+
{
20+
$view = ArrayView::toView($source);
21+
22+
foreach ($source as $i => $value) {
23+
$actual = $view[$i];
24+
$actualByStringIndex = $view[strval($i)];
25+
$expected = $source[$i];
26+
27+
$this->assertSame($expected, $actual);
28+
$this->assertSame($expected, $actualByStringIndex);
29+
}
30+
31+
$this->assertSame($source, $view->toArray());
32+
$this->assertSame($source, [...$view]);
33+
}
34+
35+
/**
36+
* @dataProvider dataProviderForReadCombine
37+
*/
38+
public function testReadCombined(array $source, callable $viewGetter, array $expected)
39+
{
40+
$view = $viewGetter($source);
41+
42+
$this->assertSame($view->toArray(), $expected);
43+
}
44+
45+
public function dataProviderForArrayRead(): array
46+
{
47+
return [
48+
[[1]],
49+
[[1, 2]],
50+
[[1, 2, 3]],
51+
[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]],
52+
[[10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10]],
53+
];
54+
}
55+
56+
public function dataProviderForReadCombine(): array
57+
{
58+
return [
59+
[
60+
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
61+
fn (array &$source) => ArrayView::toView($source)
62+
->subview('::2'),
63+
[1, 3, 5, 7, 9],
64+
],
65+
[
66+
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
67+
fn (array &$source) => (new ArrayIndexListView($source, array_keys($source)))
68+
->subview('::2'),
69+
[1, 3, 5, 7, 9],
70+
],
71+
72+
[
73+
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
74+
fn (array &$source) => (new ArrayIndexListView($source, array_keys($source)))
75+
->subview('::2'),
76+
[1, 3, 5, 7, 9],
77+
],
78+
[
79+
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
80+
fn (array &$source) => (new ArrayMaskView(
81+
$source,
82+
[true, true, true, true, true, true, true, true, true, true]
83+
))->subview('::2'),
84+
[1, 3, 5, 7, 9],
85+
],
86+
[
87+
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
88+
fn (array &$source) => (new ArraySliceView($source, new SliceSelector("::1")))
89+
->subview('::2'),
90+
[1, 3, 5, 7, 9],
91+
],
92+
[
93+
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
94+
fn (array &$source) => ArrayView::toView($source)
95+
->subview('::2')
96+
->subview(new MaskSelector([true, false, true, false, true])),
97+
[1, 5, 9],
98+
],
99+
[
100+
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
101+
fn (array &$source) => ArrayView::toView($source)
102+
->subview('::2')
103+
->subview(new MaskSelector([true, false, true, false, true]))
104+
->subview(new IndexListSelector([0, 2])),
105+
[1, 9],
106+
],
107+
[
108+
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
109+
fn (array &$source) => ArrayView::toView($source)
110+
->subview('::2')
111+
->subview(new MaskSelector([true, false, true, false, true]))
112+
->subview(new IndexListSelector([0, 2])),
113+
[1, 9],
114+
],
115+
[
116+
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
117+
fn (array &$source) => ArrayView::toView($source)
118+
->subview('::2')
119+
->subview(new MaskSelector(ArrayView::toUnlinkedView([true, false, true, false, true])))
120+
->subview(new IndexListSelector(ArrayView::toUnlinkedView([0, 2]))),
121+
[1, 9],
122+
],
123+
[
124+
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
125+
fn (array &$source) => ArrayView::toView($source)
126+
->subview('::2')
127+
->subview(new MaskSelector([true, false, true, false, true]))
128+
->subview(new IndexListSelector([0, 2]))
129+
->subview('1:'),
130+
[9],
131+
],
132+
[
133+
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
134+
fn (array &$source) => ArrayView::toView($source)
135+
->subview(new MaskSelector([true, false, true, false, true, false, true, false, true, false]))
136+
->subview(new MaskSelector([true, false, true, false, true]))
137+
->subview(new MaskSelector([true, false, true]))
138+
->subview(new MaskSelector([false, true])),
139+
[9],
140+
],
141+
[
142+
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
143+
fn (array &$source) => ArrayView::toView($source)
144+
->subview(new MaskSelector([true, false, true, false, true, false, true, false, true, false]))
145+
->subview(new MaskSelector([true, false, true, false, true]))
146+
->subview(new MaskSelector([true, false, true])),
147+
[1, 9],
148+
],
149+
[
150+
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
151+
fn (array &$source) => ArrayView::toView($source)
152+
->subview(new IndexListSelector([0, 2, 4, 6, 8]))
153+
->subview(new IndexListSelector([0, 2, 4]))
154+
->subview(new IndexListSelector([0, 2]))
155+
->subview(new IndexListSelector([1])),
156+
[9],
157+
],
158+
[
159+
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
160+
fn (array &$source) => ArrayView::toView($source)
161+
->subview('::2')
162+
->subview('::2')
163+
->subview('::2'),
164+
[1, 9],
165+
],
166+
[
167+
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
168+
fn (array &$source) => ArrayView::toView($source)
169+
->subview('::2')
170+
->subview('::2')
171+
->subview('::2')
172+
->subview('1:'),
173+
[9],
174+
],
175+
];
176+
}
177+
}

0 commit comments

Comments
 (0)