-
Notifications
You must be signed in to change notification settings - Fork 821
/
SSListContains.php
143 lines (120 loc) · 3.57 KB
/
SSListContains.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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
<?php
namespace SilverStripe\Dev\Constraint;
// use PHPUnit_Framework_Constraint;
use PHPUnit\Framework\Constraint\Constraint;
// use PHPUnit_Framework_ExpectationFailedException;
use PHPUnit\Framework\ExpectationFailedException;
use SilverStripe\Dev\SSListExporter;
use SilverStripe\Dev\TestOnly;
use SilverStripe\ORM\SS_List;
use SilverStripe\View\ViewableData;
if (!class_exists(Constraint::class)) {
return;
}
/**
* Constraint for checking if a SS_List contains items matching the given
* key-value pairs.
*/
class SSListContains extends Constraint implements TestOnly
{
/**
* @var array
*/
protected $matches = [];
/**
* Check if the list has left over items that don't match
*
* @var bool
*/
protected $hasLeftoverItems = false;
public function __construct(array $matches)
{
$this->exporter = new SSListExporter();
$this->matches = $matches;
}
/**
* Evaluates the constraint for parameter $other
*
* If $returnResult is set to false (the default), an exception is thrown
* in case of a failure. null is returned otherwise.
*
* If $returnResult is true, the result of the evaluation is returned as
* a boolean value instead: true in case of success, false in case of a
* failure.
*
* @param SS_List $other Value or object to evaluate.
* @param string $description Additional information about the test
* @param bool $returnResult Whether to return a result or throw an exception
*
* @return null|bool
*
* @throws ExpectationFailedException
*/
public function evaluate($other, $description = '', $returnResult = false): ?bool
{
$success = true;
foreach ($other as $item) {
$this->checkIfItemEvaluatesRemainingMatches($item);
}
//we have remaining matches?
if (count($this->matches) !== 0) {
$success = false;
$this->hasLeftoverItems = true;
}
if ($returnResult) {
return $success;
}
if (!$success) {
$this->fail($other, $description);
}
return null;
}
/**
* @param ViewableData $item
* @return bool
*/
protected function checkIfItemEvaluatesRemainingMatches(ViewableData $item): bool
{
$success = false;
foreach ($this->matches as $key => $match) {
$constraint = new ViewableDataContains($match);
if ($constraint->evaluate($item, '', true)) {
$success = true;
unset($this->matches[$key]);
break;
}
}
return $success;
}
/**
* Returns a string representation of the object.
*
* @return string
*/
public function toString(): string
{
$matchToString = function ($key, $value) {
return ' "' . $key . '" is "' . $value . '"';
};
$matchesToString = function ($matches) use ($matchToString) {
$matchesAsString = implode(' and ', array_map(
$matchToString,
array_keys($matches),
array_values($matches)
));
return '(' . $matchesAsString . ')';
};
$allMatchesAsString = implode(
"\n or ",
array_map($matchesToString, $this->matches)
);
return $this->getStubForToString() . $allMatchesAsString;
}
/**
* @return string
*/
protected function getStubForToString(): string
{
return ' contains an item matching ';
}
}