-
Notifications
You must be signed in to change notification settings - Fork 275
/
IterablesMatcher.php
79 lines (67 loc) · 2.14 KB
/
IterablesMatcher.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
<?php
namespace PhpSpec\Matcher\Iterate;
final class IterablesMatcher
{
/**
* @param array|\Traversable $subject
* @param array|\Traversable $expected
*
* @throws \InvalidArgumentException
* @throws SubjectElementDoesNotMatchException
* @throws SubjectHasLessElementsException
* @throws SubjectHasMoreElementsException
*/
public function match($subject, $expected)
{
if (!$this->isIterable($subject)) {
throw new \InvalidArgumentException('Subject value should be an array or implement \Traversable.');
}
if (!$this->isIterable($expected)) {
throw new \InvalidArgumentException('Expected value should be an array or implement \Traversable.');
}
$expectedIterator = $this->createIteratorFromIterable($expected);
$count = 0;
foreach ($subject as $subjectKey => $subjectValue) {
if (!$expectedIterator->valid()) {
throw new SubjectHasMoreElementsException();
}
if ($subjectKey !== $expectedIterator->key() || $subjectValue !== $expectedIterator->current()) {
throw new SubjectElementDoesNotMatchException(
$count,
$subjectKey,
$subjectValue,
$expectedIterator->key(),
$expectedIterator->current()
);
}
$expectedIterator->next();
++$count;
}
if ($expectedIterator->valid()) {
throw new SubjectHasLessElementsException();
}
}
/**
* @param mixed $variable
*
* @return bool
*/
private function isIterable($variable)
{
return is_array($variable) || $variable instanceof \Traversable;
}
/**
* @param array|\Traversable $expected
*
* @return \Iterator
*/
private function createIteratorFromIterable($expected)
{
if (is_array($expected)) {
return new \ArrayIterator($expected);
}
$iterator = new \IteratorIterator($expected);
$iterator->rewind();
return $iterator;
}
}