|
1 | | -<?php |
| 1 | +<?php declare(strict_types=1); |
2 | 2 | /** |
3 | 3 | * CROSS PHPUnit Utils |
4 | 4 | * |
|
7 | 7 | * @copyright 2019 Cross Solution <http://cross-solution.de> |
8 | 8 | */ |
9 | 9 |
|
10 | | -declare(strict_types=1); |
11 | | - |
12 | 10 | namespace Cross\TestUtils\TestCase; |
13 | 11 |
|
14 | 12 | use Cross\TestUtils\Exception\InvalidUsageException; |
| 13 | +use Cross\TestUtils\Utils\Instance; |
15 | 14 | use Cross\TestUtils\Utils\Target; |
16 | 15 |
|
17 | 16 | /** |
|
36 | 35 | * |
37 | 36 | * Available keys in the <spec> array: |
38 | 37 | * |
| 38 | + * * 'target': Allows to specify a SUT for this particular test only. |
| 39 | + * The value must be either an object a string representing a FQCN |
| 40 | + * or an array [FQCN, arg, ...] |
| 41 | + * |
| 42 | + * * target_callback': Get the SUT via a callback. |
| 43 | + * If a string is given, it is assumed that a method |
| 44 | + * in the TestCase is meant. |
| 45 | + * The callbakc must return an object. |
| 46 | + * |
39 | 47 | * * 'value': The value to test the setter and getter with. |
40 | 48 | * First the setter will be called with the value as argument. |
41 | 49 | * Then the assertion will gets called, passing in the value and |
|
88 | 96 | * @property array $setterAndGetter |
89 | 97 | * |
90 | 98 | * @author Mathias Gelhausen <gelhausen@cross-solution.de> |
| 99 | + * |
| 100 | + * @since @#next#@ Allow SUT per individual test. |
91 | 101 | */ |
92 | 102 | trait TestSetterAndGetterTrait |
93 | 103 | { |
@@ -123,16 +133,9 @@ public function testSetterAndGetter($name, $spec = null): void |
123 | 133 | return; |
124 | 134 | } |
125 | 135 |
|
126 | | - $target = Target::get( |
127 | | - $this, |
128 | | - ['getSetterAndGetterTarget', 'getTarget'], |
129 | | - ['setterAndGetterTarget', 'target'], |
130 | | - 'setterAndGetter', |
131 | | - true |
132 | | - ); |
133 | | - |
134 | | - $spec = $this->setterAndGetterNormalizeSpec($spec, $name, $target); |
135 | | - $value = $spec['value']; |
| 136 | + $target = $this->setterAndGetterGetTarget($spec); |
| 137 | + $spec = $this->setterAndGetterNormalizeSpec($spec, $name, $target); |
| 138 | + $value = $spec['value']; |
136 | 139 |
|
137 | 140 | if ($spec['exception']) { |
138 | 141 | if (is_array($spec['exception'])) { |
@@ -171,9 +174,52 @@ public function testSetterAndGetter($name, $spec = null): void |
171 | 174 | } |
172 | 175 | } |
173 | 176 |
|
| 177 | + /** |
| 178 | + * @param string|array $spec |
| 179 | + * @internal |
| 180 | + */ |
| 181 | + private function setterAndGetterGetTarget($spec): object |
| 182 | + { |
| 183 | + if (isset($spec['target'])) { |
| 184 | + return |
| 185 | + is_object($spec['target']) |
| 186 | + ? $spec['target'] |
| 187 | + : Instance::withMappedArguments($spec['target'], $this) |
| 188 | + ; |
| 189 | + } |
| 190 | + |
| 191 | + if (isset($spec['target_callback'])) { |
| 192 | + $cb = $spec['target_callback']; |
| 193 | + if (is_string($cb)) { |
| 194 | + $cb = [$this, $cb]; |
| 195 | + } |
| 196 | + |
| 197 | + if (!is_callable($cb)) { |
| 198 | + throw InvalidUsageException::fromTrait(__TRAIT__, __CLASS__, 'Invalid target callback.'); |
| 199 | + } |
| 200 | + |
| 201 | + $target = $cb(); |
| 202 | + |
| 203 | + if (!is_object($target)) { |
| 204 | + throw InvalidUsageException::fromTrait(__TRAIT__, __CLASS__, 'Target callback must return an object.'); |
| 205 | + } |
| 206 | + |
| 207 | + return $target; |
| 208 | + } |
| 209 | + |
| 210 | + return Target::get( |
| 211 | + $this, |
| 212 | + ['getSetterAndGetterTarget', 'getTarget'], |
| 213 | + ['setterAndGetterTarget', 'target'], |
| 214 | + 'setterAndGetter', |
| 215 | + true |
| 216 | + ); |
| 217 | + } |
| 218 | + |
174 | 219 | /** |
175 | 220 | * Normalize the test specification. |
176 | 221 | * |
| 222 | + * @internal |
177 | 223 | * @param array|string $spec |
178 | 224 | * @param string $name |
179 | 225 | * @param object $target |
|
0 commit comments