Skip to content

Commit f0a4417

Browse files
committed
Implemented xpath like key array.
1 parent 6f655f5 commit f0a4417

File tree

3 files changed

+199
-0
lines changed

3 files changed

+199
-0
lines changed

src/InvalidOffsetTypeException.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
namespace Sevavietl\Arrays;
4+
5+
class InvalidOffsetTypeException extends \InvalidArgumentException
6+
{
7+
8+
}

src/XPathKeyArray.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
namespace Sevavietl\Arrays;
4+
5+
class XPathKeyArray extends CompositeKeyArray
6+
{
7+
protected function setOffsets($offsets)
8+
{
9+
if ($this->notIntegerOrString($offsets)) {
10+
throw new InvalidOffsetTypeException("Invalid offset type: " . gettype($offsets) . ".");
11+
}
12+
13+
parent::setOffsets(array_map(function ($offset) {
14+
return $offset === '[]' ? [] : $offset;
15+
}, explode('/', $offsets)));
16+
}
17+
18+
protected function notIntegerOrString($value)
19+
{
20+
return !$this->integerOrString($value);
21+
}
22+
23+
protected function integerOrString($value)
24+
{
25+
return is_integer($value) || is_string($value);
26+
}
27+
}

tests/unit/XPathKeyArrayTest.php

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
<?php
2+
3+
namespace Sevavietl\Arrays\Tests\Unit;
4+
5+
use Sevavietl\Arrays\XPathKeyArray;
6+
use Sevavietl\Arrays\UndefinedOffsetException;
7+
use Sevavietl\Arrays\InvalidOffsetTypeException;
8+
9+
class XPathKeyArrayTest extends \TestCase
10+
{
11+
/**
12+
* @dataProvider arrayDataProviderForIssetTesting
13+
*/
14+
public function testOffsetExists($array, $offset, $exists)
15+
{
16+
$array = new XPathKeyArray($array);
17+
18+
$this->assertEquals(
19+
$exists,
20+
isset($array[$offset])
21+
);
22+
}
23+
24+
public function arrayDataProviderForIssetTesting()
25+
{
26+
return [
27+
[[1], 0, true],
28+
[[1], 1, false],
29+
[[1], '', false],
30+
31+
[['foo' => 'bar'], 'foo', true],
32+
[['foo' => 'bar'], 'bar', false],
33+
34+
[['foo' => ['bar' => 'baz']], 'foo/bar', true],
35+
[['foo' => ['bar' => 'baz']], 'foo/baz', false],
36+
];
37+
}
38+
39+
/**
40+
* @dataProvider arrayDataProviderForGetTesting
41+
*/
42+
public function testOffsetGet($array, $offset, $value)
43+
{
44+
$array = new XPathKeyArray($array);
45+
46+
$this->assertEquals(
47+
$value,
48+
$array[$offset]
49+
);
50+
}
51+
52+
public function arrayDataProviderForGetTesting()
53+
{
54+
return [
55+
[[1], 0, 1],
56+
[[1 => [2 => 3]], '1/2', 3],
57+
58+
[['foo' => 'bar'], 'foo', 'bar'],
59+
[['foo' => ['bar' => 'baz']], 'foo/bar', 'baz'],
60+
];
61+
}
62+
63+
/**
64+
* @expectedException Sevavietl\Arrays\UndefinedOffsetException
65+
*/
66+
public function testOffsetGetThrowsUndefinedOffsetException()
67+
{
68+
$array = new XPathKeyArray();
69+
70+
$value = $array['foo/bar'];
71+
}
72+
73+
/**
74+
* @expectedException Sevavietl\Arrays\InvalidOffsetTypeException
75+
*/
76+
public function testOffsetGetThrowsInvalidOffsetTypeException()
77+
{
78+
$array = new XPathKeyArray();
79+
80+
$value = $array[['foo', 'bar']];
81+
}
82+
83+
/**
84+
* @dataProvider arrayDataProviderForSetTesting
85+
*/
86+
public function testOffsetSet($array, $offset, $value)
87+
{
88+
$array = new XPathKeyArray($array);
89+
90+
$array[$offset] = $value;
91+
92+
$this->assertEquals(
93+
$value,
94+
$array[$offset]
95+
);
96+
}
97+
98+
public function arrayDataProviderForSetTesting()
99+
{
100+
return [
101+
[[], 0, 1],
102+
[[], '0/1', 2],
103+
];
104+
}
105+
106+
public function testOffsetSetEdgeCases()
107+
{
108+
$array = new XPathKeyArray();
109+
110+
$array['[]'] = 'foo';
111+
112+
$this->assertEquals(
113+
'foo',
114+
$array[0]
115+
);
116+
117+
$array = new XPathKeyArray();
118+
119+
$array['1/[]/2'] = 3;
120+
121+
$this->assertEquals(
122+
3,
123+
$array['1/0/2']
124+
);
125+
126+
$array = new XPathKeyArray();
127+
128+
$array['1/[]/[]/[]/2'] = 3;
129+
130+
$this->assertEquals(
131+
3,
132+
$array['1/0/0/0/2']
133+
);
134+
}
135+
136+
/**
137+
* @dataProvider arrayDataProviderForUnsetTesting
138+
*/
139+
public function testOffsetUnset($array, $offset, $arrayAfterUnset)
140+
{
141+
$array = new XPathKeyArray($array);
142+
143+
unset($array[$offset]);
144+
145+
$this->assertEquals(
146+
$arrayAfterUnset,
147+
$array->toArray()
148+
);
149+
}
150+
151+
public function arrayDataProviderForUnsetTesting()
152+
{
153+
return [
154+
[[1], 0, []],
155+
[[1, 2], 0, [1 => 2]],
156+
157+
[['foo' => 'bar'], 'foo', []],
158+
[['foo' => 'bar', 'baz' => 'quux'], 'foo', ['baz' => 'quux']],
159+
160+
[['foo' => ['bar' => 'baz']], 'foo/bar', ['foo' => []]],
161+
[['foo' => ['bar' => ['baz']]], 'foo/bar/0', ['foo' => ['bar' => []]]],
162+
];
163+
}
164+
}

0 commit comments

Comments
 (0)