1212namespace 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 */
1919final 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}
0 commit comments