Skip to content

Commit 7277f0d

Browse files
committed
Enhance util class 'Target'
* uses new Utils\Instance class * add documentation * allow returning already instantiated objects
1 parent 4de13c5 commit 7277f0d

2 files changed

Lines changed: 71 additions & 33 deletions

File tree

src/Utils/Target.php

Lines changed: 53 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,48 @@
1212
namespace Cross\TestUtils\Utils;
1313

1414
/**
15+
* Retrieves the SUT for a test from various sources of a context class.
1516
*
1617
* @author Mathias Gelhausen <gelhausen@cross-solution.de>
17-
* @todo write tests
1818
*/
1919
final class Target
2020
{
21-
21+
/**
22+
* Get the SUT from various sources of a context class.
23+
*
24+
* __$methods__:
25+
* An array of method names. If one of that methods exists in the
26+
* context class, it is called
27+
* The methods can return one of the following:
28+
*
29+
* * an object: is used as SUT
30+
* * an array: {@link Instance::withMappedArguments()} is called with
31+
* the array and the context class, its return value is
32+
* returned as SUT.
33+
* * a string: is returned to use as the FQCN od the SUT,
34+
* unless $forceObject is true - then it's treated like
35+
* above.
36+
*
37+
* __$properties__:
38+
* An array of property names. If one of that property exists in the
39+
* context class, its value is used the same way as the return value
40+
* above.
41+
*
42+
* __$classesProperty__:
43+
* If the context class defines a class list array, you can
44+
* specify its name here, and if the SUT is not found yet, it will
45+
* take the element with the key 'target' or the first element and treat
46+
* it like a property value described above.
47+
* The element will be unset after the SUT creation.
48+
*
49+
* @param object $testcase Context class
50+
* @param array $methods
51+
* @param array $properties
52+
* @param string|null $classesProperty
53+
* @param bool $forceObject If true, an object is returned at any case
54+
*
55+
* @return string|object
56+
*/
2257
public static function get(
2358
object $testcase,
2459
array $methods,
@@ -28,12 +63,24 @@ public static function get(
2863
) {
2964
$testcaseReflection = new \ReflectionClass($testcase);
3065

66+
$createTarget = function ($target) use ($testcase, $forceObject) {
67+
if (is_object($target)) {
68+
return $target;
69+
}
70+
71+
if (!$forceObject && is_string($target) && '!' != $target{0}) {
72+
return $target;
73+
}
74+
75+
return Instance::withMappedArguments($target, $testcase);
76+
};
77+
3178
foreach ($methods as $method) {
3279
if ($testcaseReflection->hasMethod($method)) {
3380
$testcaseMethod = $testcaseReflection->getMethod($method);
3481
$testcaseMethod->setAccessible(true);
3582

36-
return self::create($testcaseMethod->invoke($testcase), $forceObject);
83+
return $createTarget($testcaseMethod->invoke($testcase));
3784
}
3885
}
3986

@@ -42,7 +89,7 @@ public static function get(
4289
$testcaseProperty = $testcaseReflection->getProperty($property);
4390
$testcaseProperty->setAccessible(true);
4491

45-
return self::create($testcaseProperty->getValue($testcase), $forceObject);
92+
return $createTarget($testcaseProperty->getValue($testcase));
4693
}
4794
}
4895

@@ -56,10 +103,10 @@ public static function get(
56103

57104
if (is_array($propertyValue) && count($propertyValue)) {
58105
if (isset($propertyValue['target'])) {
59-
$target = self::create($propertyValue['target'], $forceObject);
106+
$target = $createTarget($propertyValue['target']);
60107
unset($propertyValue['target']);
61108
} else {
62-
$target = self::create(array_shift($propertyValue), $forceObject);
109+
$target = $createTarget(array_shift($propertyValue));
63110
}
64111

65112
$testcaseProperty->setValue($testcase, $propertyValue);
@@ -70,31 +117,4 @@ public static function get(
70117

71118
throw new \PHPUnit_Framework_Exception('Could not find or create a target instance.');
72119
}
73-
74-
/**
75-
* Creates an instance or returns FQCN
76-
*
77-
* @param string|array $spec
78-
* @param bool $forceObject
79-
* @return string|object
80-
*/
81-
private static function create($spec, bool $forceObject)
82-
{
83-
if (is_array($spec)) {
84-
$class = array_shift($spec);
85-
return new $class(...$spec);
86-
}
87-
88-
if (is_string($spec)) {
89-
if (0 === strpos($spec, '!')) {
90-
return new \ReflectionClass(substr($spec, 1));
91-
}
92-
93-
if ($forceObject) {
94-
return new $spec();
95-
}
96-
}
97-
98-
return $spec;
99-
}
100120
}

test/TestUtilsTest/Utils/TargetTest.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,24 @@ public function __construct($class) {
121121
static::assertInstanceOf($class, $actual);
122122
}
123123

124+
public function testGetTargetIfAlreadyObject()
125+
{
126+
$object = new \stdClass;
127+
$target = new class
128+
{
129+
public $object;
130+
public function getTarget()
131+
{
132+
return $this->object;
133+
}
134+
};
135+
$target->object = $object;
136+
137+
$actual = Target::get($target, ['getTarget'], []);
138+
139+
static::assertSame($object, $actual);
140+
}
141+
124142
public function testGetTargetInstanceForcedObject()
125143
{
126144
$target = new class

0 commit comments

Comments
 (0)