12
12
namespace Cross \TestUtils \TestCase ;
13
13
14
14
use Cross \TestUtils \Exception \InvalidUsageException ;
15
+ use Cross \TestUtils \Utils \Instance ;
15
16
use Cross \TestUtils \Utils \Target ;
16
17
17
18
/**
36
37
*
37
38
* Available keys in the <spec> array:
38
39
*
40
+ * * 'target': Allows to specify a SUT for this particular test only.
41
+ * The value must be either an object a string representing a FQCN
42
+ * or an array [FQCN, arg, ...]
43
+ *
44
+ * * target_callback': Get the SUT via a callback.
45
+ * If a string is given, it is assumed that a method
46
+ * in the TestCase is meant.
47
+ * The callbakc must return an object.
48
+ *
39
49
* * 'value': The value to test the setter and getter with.
40
50
* First the setter will be called with the value as argument.
41
51
* Then the assertion will gets called, passing in the value and
88
98
* @property array $setterAndGetter
89
99
*
90
100
* @author Mathias Gelhausen <[email protected] >
101
+ *
102
+ * @since @#next#@ Allow SUT per individual test.
91
103
*/
92
104
trait TestSetterAndGetterTrait
93
105
{
@@ -123,16 +135,9 @@ public function testSetterAndGetter($name, $spec = null): void
123
135
return ;
124
136
}
125
137
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 ' ];
138
+ $ target = $ this ->setterAndGetterGetTarget ($ spec );
139
+ $ spec = $ this ->setterAndGetterNormalizeSpec ($ spec , $ name , $ target );
140
+ $ value = $ spec ['value ' ];
136
141
137
142
if ($ spec ['exception ' ]) {
138
143
if (is_array ($ spec ['exception ' ])) {
@@ -171,9 +176,53 @@ public function testSetterAndGetter($name, $spec = null): void
171
176
}
172
177
}
173
178
179
+ /**
180
+ * @param string|array $spec
181
+ * @internal
182
+ */
183
+ private function setterAndGetterGetTarget ($ spec ): object
184
+ {
185
+ if (isset ($ spec ['target ' ])) {
186
+ return
187
+ is_object ($ spec ['target ' ])
188
+ ? $ spec ['target ' ]
189
+ : Instance::withMappedArguments ($ spec ['target ' ], $ this )
190
+ ;
191
+ }
192
+
193
+ if (isset ($ spec ['target_callback ' ])) {
194
+ $ cb = $ spec ['target_callback ' ];
195
+
196
+ if (is_string ($ cb ) && !is_callable ($ cb )) {
197
+ $ cb = [$ this , $ cb ];
198
+ }
199
+
200
+ if (!is_callable ($ cb )) {
201
+ throw InvalidUsageException::fromTrait (__TRAIT__ , __CLASS__ , 'Invalid target callback. ' );
202
+ }
203
+
204
+ $ target = $ cb ();
205
+
206
+ if (!is_object ($ target )) {
207
+ throw InvalidUsageException::fromTrait (__TRAIT__ , __CLASS__ , 'Target callback must return an object. ' );
208
+ }
209
+
210
+ return $ target ;
211
+ }
212
+
213
+ return Target::get (
214
+ $ this ,
215
+ ['getSetterAndGetterTarget ' , 'getTarget ' ],
216
+ ['setterAndGetterTarget ' , 'target ' ],
217
+ 'setterAndGetter ' ,
218
+ true
219
+ );
220
+ }
221
+
174
222
/**
175
223
* Normalize the test specification.
176
224
*
225
+ * @internal
177
226
* @param array|string $spec
178
227
* @param string $name
179
228
* @param object $target
@@ -198,10 +247,8 @@ private function setterAndGetterNormalizeSpec($spec, string $name, object $targe
198
247
return $ normalized ;
199
248
}
200
249
201
- $ err = __TRAIT__ . ': ' . get_class ($ this ) . ': ' ;
202
-
203
250
if (!is_array ($ spec )) {
204
- throw new \ PHPUnit \ Framework \ Exception ( $ err . 'Invalid specification. Must be array. ' );
251
+ throw InvalidUsageException:: fromTrait ( __TRAIT__ , __CLASS__ , 'Invalid specification. Must be array. ' );
205
252
}
206
253
207
254
foreach ($ spec as $ key => $ value ) {
@@ -253,12 +300,16 @@ private function setterAndGetterNormalizeSpec($spec, string $name, object $targe
253
300
case 'value_callback ' :
254
301
case 'setter_value_callback ' :
255
302
case 'expect_callback ' :
256
- if (is_string ($ value )) {
303
+ if (is_string ($ value ) && ! is_callable ( $ value ) ) {
257
304
$ value = [$ this , $ value ];
258
305
}
259
306
260
307
if (!is_callable ($ value )) {
261
- throw new \PHPUnit \Framework \Exception ($ err . 'Invalid callback for " ' . $ key . '". ' );
308
+ throw InvalidUsageException::fromTrait (
309
+ __TRAIT__ ,
310
+ __CLASS__ ,
311
+ 'Invalid callback for " ' . $ key . '". '
312
+ );
262
313
}
263
314
264
315
$ key = substr ($ key , 0 , -9 );
@@ -277,7 +328,11 @@ private function setterAndGetterNormalizeSpec($spec, string $name, object $targe
277
328
}
278
329
279
330
if (!is_callable ($ value )) {
280
- throw new \PHPUnit \Framework \Exception ($ err . 'Invalid callback for " ' . $ key . '". ' );
331
+ throw InvalidUsageException::fromTrait (
332
+ __TRAIT__ ,
333
+ __CLASS__ ,
334
+ 'Invalid callback for " ' . $ key . '". '
335
+ );
281
336
}
282
337
283
338
break ;
0 commit comments