Skip to content

Commit 61aaaf1

Browse files
committed
Merge pull request #16 from gaillard/master
Add ::ofScalars, ::ofArrays filter and fix a few test bugs, and use force covers
2 parents 5415c37 + 5afed80 commit 61aaaf1

File tree

7 files changed

+220
-14
lines changed

7 files changed

+220
-14
lines changed

phpunit.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<phpunit>
1+
<phpunit forceCoversAnnotation="true">
22
<filter>
33
<whitelist>
44
<directory>src</directory>

src/DominionEnterprises/Filter/Arrays.php

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*/
55

66
namespace DominionEnterprises\Filter;
7+
use DominionEnterprises\Filterer;
78

89
/**
910
* A collection of filters for arrays.
@@ -81,9 +82,66 @@ public static function in($value, array $haystack, $strict = true)
8182
}
8283

8384
if (!in_array($value, $haystack, $strict)) {
84-
throw new \Exception("Value '" . trim(var_export($value, true), "'") . "' is not in array " . var_export($haystack, true) . '"');
85+
throw new \Exception("Value '" . trim(var_export($value, true), "'") . "' is not in array " . var_export($haystack, true));
8586
}
8687

8788
return $value;
8889
}
90+
91+
/**
92+
* Filter an array by applying filters to each member
93+
*
94+
* @param array $values an array to be filtered. Use the Arrays::filter() before this method to ensure counts when you pass into Filterer
95+
* @param array $filters filters with each specified the same as in @see Filterer::filter. Eg [['string', false, 2], ['uint']]
96+
*
97+
* @return array the filtered $values
98+
*
99+
* @throws \Exception if any member of $values fails filtering
100+
*/
101+
public static function ofScalars(array $values, array $filters)
102+
{
103+
$wrappedFilters = array();
104+
foreach ($values as $key => $item) {
105+
$wrappedFilters[$key] = $filters;
106+
}
107+
108+
list($status, $result, $error) = Filterer::filter($wrappedFilters, $values);
109+
if (!$status) {
110+
throw new \Exception($error);
111+
}
112+
113+
return $result;
114+
}
115+
116+
/**
117+
* Filter an array by applying filters to each member
118+
*
119+
* @param array $values as array to be filtered. Use the Arrays::filter() before this method to ensure counts when you pass into Filterer
120+
* @param array $spec spec to apply to each $values member, specified the same as in @see Filterer::filter.
121+
* Eg ['key' => ['required' => true, ['string', false], ['unit']], 'key2' => ...]
122+
*
123+
* @return array the filtered $values
124+
*
125+
* @throws \Exception if any member of $values fails filtering
126+
*/
127+
public static function ofArrays(array $values, array $spec)
128+
{
129+
$results = array();
130+
$errors = array();
131+
foreach ($values as $key => $item) {
132+
list($status, $result, $error) = Filterer::filter($spec, $item);
133+
if (!$status) {
134+
$errors[] = $error;
135+
continue;
136+
}
137+
138+
$results[$key] = $result;
139+
}
140+
141+
if (!empty($errors)) {
142+
throw new \Exception(implode("\n", $errors));
143+
}
144+
145+
return $results;
146+
}
89147
}

src/DominionEnterprises/Filterer.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ final class Filterer
1818
'int' => '\DominionEnterprises\Filter\Int::filter',
1919
'uint' => '\DominionEnterprises\Filter\UnsignedInt::filter',
2020
'string' => '\DominionEnterprises\Filter\String::filter',
21+
'ofScalars' => '\DominionEnterprises\Filter\Arrays::ofScalars',
22+
'ofArrays' => '\DominionEnterprises\Filter\Arrays::ofArrays',
2123
);
2224

2325
/**

tests/DominionEnterprises/Filter/ArraysTest.php

Lines changed: 107 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -91,27 +91,29 @@ public function in_passStrict()
9191
/**
9292
* @test
9393
* @covers \DominionEnterprises\Filter\Arrays::in
94-
* @expectedException \Exception
95-
* @expectedExceptionMessage Value '0' is not in array array (
96-
* 0 => 0
97-
* )
9894
*/
9995
public function in_failStrict()
10096
{
101-
A::in('0', array(0));
97+
try {
98+
A::in('0', array(0));
99+
$this->fail();
100+
} catch (\Exception $e) {
101+
$this->assertSame("Value '0' is not in array array (\n 0 => 0,\n)", $e->getMessage());
102+
}
102103
}
103104

104105
/**
105106
* @test
106107
* @covers \DominionEnterprises\Filter\Arrays::in
107-
* @expectedException \Exception
108-
* @expectedExceptionMessage Value 'boo' is not in array array (
109-
* 0 => 'foo'
110-
* )
111108
*/
112109
public function in_failNotStrict()
113110
{
114-
A::in('boo', array('foo'), false);
111+
try {
112+
A::in('boo', array('foo'), false);
113+
$this->fail();
114+
} catch (\Exception $e) {
115+
$this->assertSame("Value 'boo' is not in array array (\n 0 => 'foo',\n)", $e->getMessage());
116+
}
115117
}
116118

117119
/**
@@ -133,4 +135,99 @@ public function in_strictNotBool()
133135
{
134136
A::in('boo', array(), 1);
135137
}
138+
139+
/**
140+
* @test
141+
* @covers \DominionEnterprises\Filter\Arrays::ofScalars
142+
*/
143+
public function ofScalars()
144+
{
145+
$this->assertSame(array(1, 2), A::ofScalars(array('1', '2'), array(array('uint'))));
146+
}
147+
148+
/**
149+
* @test
150+
* @covers \DominionEnterprises\Filter\Arrays::ofScalars
151+
*/
152+
public function ofScalars_chained()
153+
{
154+
$this->assertSame(array(3.3, 5.5), A::ofScalars(array('a3.3', 'a5.5'), array(array('trim', 'a'), array('floatval'))));
155+
}
156+
157+
/**
158+
* @test
159+
* @covers \DominionEnterprises\Filter\Arrays::ofScalars
160+
*/
161+
public function ofScalars_withMeaninglessKeys()
162+
{
163+
$this->assertSame(array('key1' => 1, 'key2' => 2), A::ofScalars(array('key1' => '1', 'key2' => '2'), array(array('uint'))));
164+
}
165+
166+
/**
167+
* @test
168+
* @covers \DominionEnterprises\Filter\Arrays::ofScalars
169+
*/
170+
public function ofScalars_fail()
171+
{
172+
try {
173+
A::ofScalars(array('1', 2, 3), array(array('string')));
174+
$this->fail();
175+
} catch (\Exception $e) {
176+
$expected = "Field '1' with value '2' failed filtering, message 'Value '2' is not a string'\n";
177+
$expected .= "Field '2' with value '3' failed filtering, message 'Value '3' is not a string'";
178+
$this->assertSame($expected, $e->getMessage());
179+
}
180+
}
181+
182+
/**
183+
* @test
184+
* @covers \DominionEnterprises\Filter\Arrays::ofArrays
185+
*/
186+
public function ofArrays()
187+
{
188+
$expected = array(array('key' => 1), array('key' => 2));
189+
$this->assertSame($expected, A::ofArrays(array(array('key' => '1'), array('key' => '2')), array('key' => array(array('uint')))));
190+
}
191+
192+
/**
193+
* @test
194+
* @covers \DominionEnterprises\Filter\Arrays::ofArrays
195+
*/
196+
public function ofArrays_chained()
197+
{
198+
$expected = array(array('key' => 3.3), array('key' => 5.5));
199+
$spec = array('key' => array(array('trim', 'a'), array('floatval')));
200+
$this->assertSame($expected, A::ofArrays(array(array('key' => 'a3.3'), array('key' => 'a5.5')), $spec));
201+
}
202+
203+
/**
204+
* @test
205+
* @covers \DominionEnterprises\Filter\Arrays::ofArrays
206+
*/
207+
public function ofArrays_requiredAndUnknown()
208+
{
209+
try {
210+
A::ofArrays(array(array('key' => '1'), array('key2' => '2')), array('key' => array('required' => true, array('uint'))));
211+
$this->fail();
212+
} catch (\Exception $e) {
213+
$expected = "Field 'key' was required and not present\nField 'key2' with value '2' is unknown";
214+
$this->assertSame($expected, $e->getMessage());
215+
}
216+
}
217+
218+
/**
219+
* @test
220+
* @covers \DominionEnterprises\Filter\Arrays::ofArrays
221+
*/
222+
public function ofArrays_fail()
223+
{
224+
try {
225+
A::ofArrays(array(array('key' => '1'), array('key' => 2), array('key' => 3)), array('key' => array(array('string'))));
226+
$this->fail();
227+
} catch (\Exception $e) {
228+
$expected = "Field 'key' with value '2' failed filtering, message 'Value '2' is not a string'\n";
229+
$expected .= "Field 'key' with value '3' failed filtering, message 'Value '3' is not a string'";
230+
$this->assertSame($expected, $e->getMessage());
231+
}
232+
}
136233
}

0 commit comments

Comments
 (0)