96% of 1707OPs |
98% of 270Lines |
84% of 238Branches |
38% of 137Paths |
# | |
---|---|
1 |
<?php |
2 | |
3 |
namespace mageekguy\atoum\asserters; |
4 | |
5 |
use |
6 |
mageekguy\atoum\asserters, |
7 |
mageekguy\atoum\exceptions |
8 |
; |
9 | |
10 |
class phpArray extends asserters\variable implements \arrayAccess |
11 |
{ |
12 |
private $key = null; |
13 |
private $innerAsserter = null; |
14 |
private $innerAsserterUsed = false; |
15 |
private $innerValue = null; |
16 |
private $innerValueIsSet = false; |
17 | |
18 |
public function __get($asserter)100% |
19 |
{ |
20 |
switch (strtolower($asserter)) |
21 |
{ |
22 |
case 'keys': |
23 |
return $this->getKeysAsserter(); |
24 | |
25 |
case 'size': |
26 |
return $this->getSizeAsserter(); |
27 | |
28 |
case 'isempty': |
29 |
return $this->isEmpty(); |
30 | |
31 |
default: |
32 |
$asserter = parent::__get($asserter); |
33 | |
34 |
if ($asserter instanceof asserters\variable === false) |
35 |
{ |
36 |
$this->resetInnerAsserter(); |
37 | |
38 |
return $asserter; |
39 |
} |
40 |
else |
41 |
{ |
42 |
if ($this->innerAsserter === null || $this->innerAsserterUsed === true) |
43 |
{ |
44 |
$this->innerValue = $this->value; |
45 |
$this->innerAsserterUsed = false; |
46 |
} |
47 | |
48 |
$this->innerAsserter = $asserter; |
49 | |
50 |
return $this; |
51 |
} |
52 |
} |
53 |
} |
54 | |
55 |
public function __call($method, $arguments)100% |
56 |
{ |
57 |
if ($this->innerAsserterCanUse($method) === false) |
58 |
{ |
59 |
return parent::__call($method, $arguments); |
60 |
} |
61 |
else |
62 |
{ |
63 |
return $this->callInnerAsserterMethod($method, $arguments); |
64 |
} |
65 |
} |
66 | |
67 |
public function getKey()100% |
68 |
{ |
69 |
return $this->key; |
70 |
} |
71 | |
72 |
public function getInnerAsserter()100% |
73 |
{ |
74 |
return $this->innerAsserter; |
75 |
} |
76 | |
77 |
public function getInnerValue()100% |
78 |
{ |
79 |
return $this->innerValue; |
80 |
} |
81 | |
82 |
public function reset()100% |
83 |
{ |
84 |
$this->key = null; |
85 | |
86 |
return parent::reset()->resetInnerAsserter(); |
87 |
} |
88 | |
89 |
public function offsetGet($key)93% |
90 |
{ |
91 |
if ($this->innerAsserter === null) |
92 |
{ |
93 |
if ($this->analyzer->isArray($this->hasKey($key)->value[$key]) === true) |
94 |
{ |
95 |
parent::setWith($this->value[$key]); |
96 |
} |
97 |
else |
98 |
{ |
99 |
$this->fail($this->_('Value %s at key %s is not an array', $this->getTypeOf($this->value[$key]), $key)); |
100 |
} |
101 |
} |
102 |
else |
103 |
{ |
104 |
if (array_key_exists($key, $this->innerValue) === false) |
105 |
{ |
106 |
$this->fail($this->_('%s has no key %s', $this->getTypeOf($this->innerValue), $this->getTypeOf($key))); |
107 |
} |
108 |
else |
109 |
{ |
110 |
$this->innerValue = $this->innerValue[$key]; |
111 |
$this->innerValueIsSet = true; |
112 |
} |
113 |
} |
114 | |
115 |
return $this; |
116 |
} |
117 | |
118 |
public function offsetSet($key, $value)100% |
119 |
{ |
120 |
throw new exceptions\logic('Tested array is read only'); |
121 |
} |
122 | |
123 |
public function offsetUnset($key)100% |
124 |
{ |
125 |
throw new exceptions\logic('Array is read only'); |
126 |
} |
127 | |
128 |
public function offsetExists($key)100% |
129 |
{ |
130 |
$value = ($this->innerAsserter === null ? $this->value : $this->innerValue); |
131 | |
132 |
return ($value !== null && array_key_exists($key, $value) === true); |
133 |
} |
134 | |
135 |
public function setWith($value)100% |
136 |
{ |
137 |
$innerAsserter = $this->innerAsserter; |
138 | |
139 |
if ($innerAsserter !== null) |
140 |
{ |
141 |
$this->reset(); |
142 | |
143 |
return $innerAsserter->setWith($value); |
144 |
} |
145 |
else |
146 |
{ |
147 |
parent::setWith($value); |
148 | |
149 |
if ($this->analyzer->isArray($this->value) === true) |
150 |
{ |
151 |
$this->pass(); |
152 |
} |
153 |
else |
154 |
{ |
155 |
$this->fail($this->_('%s is not an array', $this)); |
156 |
} |
157 | |
158 |
return $this; |
159 |
} |
160 |
} |
161 | |
162 |
public function setByReferenceWith(& $value)80% |
163 |
{ |
164 |
if ($this->innerAsserter !== null) |
165 |
{ |
166 |
return $this->innerAsserter->setByReferenceWith($value); |
167 |
} |
168 |
else |
169 |
{ |
170 |
parent::setByReferenceWith($value); |
171 | |
172 |
if ($this->analyzer->isArray($this->value) === true) |
173 |
{ |
174 |
$this->pass(); |
175 |
} |
176 |
else |
177 |
{ |
178 |
$this->fail($this->_('%s is not an array', $this)); |
179 |
} |
180 | |
181 |
return $this; |
182 |
} |
183 |
} |
184 | |
185 |
public function hasSize($size, $failMessage = null)100% |
186 |
{ |
187 |
if (sizeof($this->valueIsSet()->value) == $size) |
188 |
{ |
189 |
$this->pass(); |
190 |
} |
191 |
else |
192 |
{ |
193 |
$this->fail($failMessage ?: $this->_('%s has size %d, expected size %d', $this, sizeof($this->valueIsSet()->value), $size)); |
194 |
} |
195 | |
196 |
return $this; |
197 |
} |
198 | |
199 |
public function isEmpty($failMessage = null)100% |
200 |
{ |
201 |
if (sizeof($this->valueIsSet()->value) == 0) |
202 |
{ |
203 |
$this->pass(); |
204 |
} |
205 |
else |
206 |
{ |
207 |
$this->fail($failMessage ?: $this->_('%s is not empty', $this)); |
208 |
} |
209 | |
210 |
return $this; |
211 |
} |
212 | |
213 |
public function isNotEmpty($failMessage = null)100% |
214 |
{ |
215 |
if (sizeof($this->valueIsSet()->value) > 0) |
216 |
{ |
217 |
$this->pass(); |
218 |
} |
219 |
else |
220 |
{ |
221 |
$this->fail($failMessage ?: $this->_('%s is empty', $this)); |
222 |
} |
223 | |
224 |
return $this; |
225 |
} |
226 | |
227 |
public function strictlyContains($value, $failMessage = null)100% |
228 |
{ |
229 |
return $this->containsValue($value, $failMessage, true); |
230 |
} |
231 | |
232 |
public function contains($value, $failMessage = null)100% |
233 |
{ |
234 |
return $this->containsValue($value, $failMessage, false); |
235 |
} |
236 | |
237 |
public function strictlyNotContains($value, $failMessage = null)100% |
238 |
{ |
239 |
return $this->notContainsValue($value, $failMessage, true); |
240 |
} |
241 | |
242 |
public function notContains($value, $failMessage = null)100% |
243 |
{ |
244 |
return $this->notContainsValue($value, $failMessage, false); |
245 |
} |
246 | |
247 |
public function atKey($key, $failMessage = null)100% |
248 |
{ |
249 |
$this->hasKey($key, $failMessage)->key = $key; |
250 | |
251 |
return $this; |
252 |
} |
253 | |
254 |
public function hasKeys(array $keys, $failMessage = null)100% |
255 |
{ |
256 |
if (sizeof($undefinedKeys = array_diff($keys, array_keys($this->valueIsSet()->value))) <= 0) |
257 |
{ |
258 |
$this->pass(); |
259 |
} |
260 |
else |
261 |
{ |
262 |
$this->fail($failMessage ?: $this->_('%s has no keys %s', $this, $this->getTypeOf($undefinedKeys))); |
263 |
} |
264 | |
265 |
return $this; |
266 |
} |
267 | |
268 |
public function notHasKeys(array $keys, $failMessage = null)100% |
269 |
{ |
270 |
$this->valueIsSet(); |
271 | |
272 |
if (sizeof($definedKeys = array_intersect($keys, array_keys($this->value))) <= 0) |
273 |
{ |
274 |
$this->pass(); |
275 |
} |
276 |
else |
277 |
{ |
278 |
$this->fail($failMessage ?: $this->_('%s has keys %s', $this, $this->getTypeOf($definedKeys))); |
279 |
} |
280 | |
281 |
return $this; |
282 |
} |
283 | |
284 |
public function hasKey($key, $failMessage = null)100% |
285 |
{ |
286 |
if (array_key_exists($key, $this->valueIsSet()->value)) |
287 |
{ |
288 |
$this->pass(); |
289 |
} |
290 |
else |
291 |
{ |
292 |
$this->fail($failMessage ?: $this->_('%s has no key %s', $this, $this->getTypeOf($key))); |
293 |
} |
294 | |
295 |
return $this; |
296 |
} |
297 | |
298 |
public function notHasKey($key, $failMessage = null)100% |
299 |
{ |
300 |
if (array_key_exists($key, $this->valueIsSet()->value) === false) |
301 |
{ |
302 |
$this->pass(); |
303 |
} |
304 |
else |
305 |
{ |
306 |
$this->fail($failMessage ?: $this->_('%s has key %s', $this, $this->getTypeOf($key))); |
307 |
} |
308 | |
309 |
return $this; |
310 |
} |
311 | |
312 |
public function containsValues(array $values, $failMessage = null)100% |
313 |
{ |
314 |
return $this->intersect($values, $failMessage, false); |
315 |
} |
316 | |
317 |
public function strictlyContainsValues(array $values, $failMessage = null)100% |
318 |
{ |
319 |
return $this->intersect($values, $failMessage, true); |
320 |
} |
321 | |
322 |
public function notContainsValues(array $values, $failMessage = null)100% |
323 |
{ |
324 |
return $this->notIntersect($values, $failMessage, false); |
325 |
} |
326 | |
327 |
public function strictlyNotContainsValues(array $values, $failMessage = null)100% |
328 |
{ |
329 |
return $this->notIntersect($values, $failMessage, true); |
330 |
} |
331 | |
332 |
public function isEqualTo($value, $failMessage = null)100% |
333 |
{ |
334 |
return $this->callAssertion(__FUNCTION__, array($value, $failMessage)); |
335 |
} |
336 | |
337 |
public function isNotEqualTo($value, $failMessage = null)100% |
338 |
{ |
339 |
return $this->callAssertion(__FUNCTION__, array($value, $failMessage)); |
340 |
} |
341 | |
342 |
public function isIdenticalTo($value, $failMessage = null)100% |
343 |
{ |
344 |
return $this->callAssertion(__FUNCTION__, array($value, $failMessage)); |
345 |
} |
346 | |
347 |
public function isNotIdenticalTo($value, $failMessage = null)100% |
348 |
{ |
349 |
return $this->callAssertion(__FUNCTION__, array($value, $failMessage)); |
350 |
} |
351 | |
352 |
public function isReferenceTo(& $reference, $failMessage = null)0% |
353 |
{ |
354 |
return $this->callAssertion(__FUNCTION__, array(& $reference, $failMessage)); |
355 |
} |
356 | |
357 |
protected function containsValue($value, $failMessage, $strict)100% |
358 |
{ |
359 |
if (in_array($value, $this->valueIsSet()->value, $strict) === true) |
360 |
{ |
361 |
if ($this->key === null) |
362 |
{ |
363 |
$this->pass(); |
364 |
} |
365 |
else |
366 |
{ |
367 |
if ($strict === false) |
368 |
{ |
369 |
$pass = ($this->value[$this->key] == $value); |
370 |
} |
371 |
else |
372 |
{ |
373 |
$pass = ($this->value[$this->key] === $value); |
374 |
} |
375 | |
376 |
if ($pass === false) |
377 |
{ |
378 |
$key = $this->key; |
379 |
} |
380 | |
381 |
$this->key = null; |
382 | |
383 |
if ($pass === true) |
384 |
{ |
385 |
$this->pass(); |
386 |
} |
387 |
else |
388 |
{ |
389 |
if ($failMessage === null) |
390 |
{ |
391 |
if ($strict === false) |
392 |
{ |
393 |
$failMessage = $this->_('%s does not contain %s at key %s', $this, $this->getTypeOf($value), $this->getTypeOf($key)); |
394 |
} |
395 |
else |
396 |
{ |
397 |
$failMessage = $this->_('%s does not strictly contain %s at key %s', $this, $this->getTypeOf($value), $this->getTypeOf($key)); |
398 |
} |
399 |
} |
400 | |
401 |
$this->fail($failMessage); |
402 |
} |
403 |
} |
404 |
} |
405 |
else |
406 |
{ |
407 |
if ($failMessage === null) |
408 |
{ |
409 |
if ($strict === false) |
410 |
{ |
411 |
$failMessage = $this->_('%s does not contain %s', $this, $this->getTypeOf($value)); |
412 |
} |
413 |
else |
414 |
{ |
415 |
$failMessage = $this->_('%s does not strictly contain %s', $this, $this->getTypeOf($value)); |
416 |
} |
417 |
} |
418 | |
419 |
$this->fail($failMessage); |
420 |
} |
421 | |
422 |
return $this; |
423 |
} |
424 | |
425 |
protected function notContainsValue($value, $failMessage, $strict)98% |
426 |
{ |
427 |
if (in_array($value, $this->valueIsSet()->value, $strict) === false) |
428 |
{ |
429 |
$this->pass(); |
430 |
} |
431 |
else |
432 |
{ |
433 |
if ($this->key === null) |
434 |
{ |
435 |
if ($failMessage === null) |
436 |
{ |
437 |
if ($strict === false) |
438 |
{ |
439 |
$failMessage = $this->_('%s contains %s', $this, $this->getTypeOf($value)); |
440 |
} |
441 |
else |
442 |
{ |
443 |
$failMessage = $this->_('%s strictly contains %s', $this, $this->getTypeOf($value)); |
444 |
} |
445 |
} |
446 | |
447 |
$this->fail($failMessage); |
448 |
} |
449 |
else |
450 |
{ |
451 |
if ($strict === false) |
452 |
{ |
453 |
$pass = ($this->value[$this->key] != $value); |
454 |
} |
455 |
else |
456 |
{ |
457 |
$pass = ($this->value[$this->key] !== $value); |
458 |
} |
459 | |
460 |
if ($pass === false) |
461 |
{ |
462 |
$key = $this->key; |
463 |
} |
464 | |
465 |
$this->key = null; |
466 | |
467 |
if ($pass === true) |
468 |
{ |
469 |
$this->pass(); |
470 |
} |
471 |
else |
472 |
{ |
473 |
if ($failMessage === null) |
474 |
{ |
475 |
if ($strict === false) |
476 |
{ |
477 |
$failMessage = $this->_('%s contains %s at key %s', $this, $this->getTypeOf($value), $this->getTypeOf($key)); |
478 |
} |
479 |
else |
480 |
{ |
481 |
$failMessage = $this->_('%s strictly contains %s at key %s', $this, $this->getTypeOf($value), $this->getTypeOf($key)); |
482 |
} |
483 |
} |
484 | |
485 |
$this->fail($failMessage); |
486 |
} |
487 |
} |
488 |
} |
489 | |
490 |
return $this; |
491 |
} |
492 | |
493 |
protected function intersect(array $values, $failMessage, $strict)100% |
494 |
{ |
495 |
$this->valueIsSet(); |
496 | |
497 |
$unknownValues = array(); |
498 | |
499 |
foreach ($values as $value) if (in_array($value, $this->value, $strict) === false) |
500 |
{ |
501 |
$unknownValues[] = $value; |
502 |
} |
503 | |
504 |
if (sizeof($unknownValues) <= 0) |
505 |
{ |
506 |
$this->pass(); |
507 |
} |
508 |
else |
509 |
{ |
510 |
if ($failMessage === null) |
511 |
{ |
512 |
if ($strict === false) |
513 |
{ |
514 |
$failMessage = $this->_('%s does not contain values %s', $this, $this->getTypeOf($unknownValues)); |
515 |
} |
516 |
else |
517 |
{ |
518 |
$failMessage = $this->_('%s does not contain strictly values %s', $this, $this->getTypeOf($unknownValues)); |
519 |
} |
520 |
} |
521 | |
522 |
$this->fail($failMessage); |
523 |
} |
524 | |
525 |
return $this; |
526 |
} |
527 | |
528 |
protected function notIntersect(array $values, $failMessage, $strict)100% |
529 |
{ |
530 |
$this->valueIsSet(); |
531 | |
532 |
$knownValues = array(); |
533 | |
534 |
foreach ($values as $value) if (in_array($value, $this->value, $strict) === true) |
535 |
{ |
536 |
$knownValues[] = $value; |
537 |
} |
538 | |
539 |
if (sizeof($knownValues) <= 0) |
540 |
{ |
541 |
$this->pass(); |
542 |
} |
543 |
else |
544 |
{ |
545 |
if ($failMessage === null) |
546 |
{ |
547 |
if ($strict === false) |
548 |
{ |
549 |
$failMessage = $this->_('%s contains values %s', $this, $this->getTypeOf($knownValues)); |
550 |
} |
551 |
else |
552 |
{ |
553 |
$failMessage = $this->_('%s contains strictly values %s', $this, $this->getTypeOf($knownValues)); |
554 |
} |
555 |
} |
556 | |
557 |
$this->fail($failMessage); |
558 |
} |
559 | |
560 |
return $this; |
561 |
} |
562 | |
563 |
protected function valueIsSet($message = 'Array is undefined')100% |
564 |
{ |
565 |
return parent::valueIsSet($message); |
566 |
} |
567 | |
568 |
protected function getKeysAsserter()100% |
569 |
{ |
570 |
return $this->generator->__call('phpArray', array(array_keys($this->valueIsSet()->value))); |
571 |
} |
572 | |
573 |
protected function getSizeAsserter()100% |
574 |
{ |
575 |
return $this->generator->__call('integer', array(sizeof($this->valueIsSet()->value))); |
576 |
} |
577 | |
578 |
protected function callAssertion($method, array $arguments)100% |
579 |
{ |
580 |
if ($this->innerAsserterCanUse($method) === false) |
581 |
{ |
582 |
call_user_func_array(array('parent', $method), $arguments); |
583 |
} |
584 |
else |
585 |
{ |
586 |
$this->callInnerAsserterMethod($method, $arguments); |
587 |
} |
588 | |
589 |
return $this; |
590 |
} |
591 | |
592 |
protected function innerAsserterCanUse($method)100% |
593 |
{ |
594 |
return ($this->innerAsserter !== null && $this->innerValueIsSet === true && method_exists($this->innerAsserter, $method) === true); |
595 |
} |
596 | |
597 |
protected function callInnerAsserterMethod($method, $arguments)100% |
598 |
{ |
599 |
call_user_func_array(array($this->innerAsserter->setWith($this->innerValue), $method), $arguments); |
600 | |
601 |
$this->innerAsserterUsed = true; |
602 | |
603 |
return $this; |
604 |
} |
605 | |
606 |
protected function resetInnerAsserter()100% |
607 |
{ |
608 |
$this->innerAsserter = null; |
609 |
$this->innerValue = null; |
610 |
$this->innerValueIsSet = false; |
611 | |
612 |
return $this; |
613 |
} |
614 |
} |