@@ -19,57 +19,52 @@ class ObjectGraphGenerator
1919{
2020 private const DEFAULT_SEED = 1 ;
2121
22- /** @var Generator */
23- private $ fakerInstance ;
24-
25- /** @var PropertyInfoExtractor */
26- private $ propertyInfo ;
27-
28- /** @var array */
29- private $ registry ;
22+ private Generator $ fakerInstance ;
23+ private PropertyInfoExtractor $ propertyInfo ;
24+ /**
25+ * @var array<mixed>
26+ */
27+ private array $ registry ;
3028
31- /** @var array */
32- private $ temporaryRegistry = [];
29+ /**
30+ * @var array<mixed>
31+ */
32+ private array $ temporaryRegistry = [];
3333
34+ /**
35+ * @param array<mixed> $registry
36+ */
3437 public function __construct (array $ registry = [])
3538 {
3639 $ this ->fakerInstance = Factory::create ();
3740
38- $ phpDocExtractor = new PhpDocExtractor ();
41+ $ phpDocExtractor = new PhpDocExtractor ();
3942 $ reflectionExtractor = new ReflectionExtractor ();
40- $ typeExtractors = [$ phpDocExtractor , $ reflectionExtractor ];
41- $ this ->propertyInfo = new PropertyInfoExtractor ([], $ typeExtractors , [], [], []);
43+ $ typeExtractors = [$ phpDocExtractor , $ reflectionExtractor ];
44+ $ this ->propertyInfo = new PropertyInfoExtractor ([], $ typeExtractors , [], [], []);
4245 $ this ->fakerInstance ->seed (self ::DEFAULT_SEED );
4346 $ this ->registry = $ registry ;
4447 }
4548
49+ /**
50+ * @param class-string $className
51+ */
4652 public function generate (string $ className ): object
4753 {
4854 return $ this ->generateObject ($ className );
4955 }
5056
51- public function generateWithTemporaryConfig (string $ className , array $ config ): object
52- {
53- $ this ->temporaryRegistry = $ config ;
54- $ object = $ this ->generateObject ($ className );
55- $ this ->temporaryRegistry = [];
56-
57- return $ object ;
58- }
59-
6057 /**
61- * @param string $className
62- *
63- * @return mixed|object
58+ * @param class-string $className
6459 * @throws ReflectionException
6560 */
66- private function generateObject (string $ className )
61+ private function generateObject (string $ className ): object
6762 {
6863 if ($ this ->isInRegistry ($ className )) {
6964 return $ this ->getFromRegistry ($ className );
7065 }
7166
72- $ class = new ReflectionClass ($ className );
67+ $ class = new ReflectionClass ($ className );
7368 $ factoryMethod = $ this ->findFactoryMethod ($ class );
7469
7570 if ($ factoryMethod === null ) {
@@ -78,6 +73,7 @@ private function generateObject(string $className)
7873
7974 $ arguments = array_map (
8075 function (ReflectionParameter $ parameter ) use ($ className ) {
76+ /** @var array<mixed> $type */
8177 $ type = $ this ->propertyInfo ->getTypes ($ className , $ parameter ->getName ());
8278
8379 return $ this ->generateArgument ($ type [0 ], $ className , $ parameter ->getName ());
@@ -90,13 +86,34 @@ function (ReflectionParameter $parameter) use ($className) {
9086 : $ factoryMethod ->invokeArgs (null , $ arguments );
9187 }
9288
89+ private function isInRegistry (string $ key ): bool
90+ {
91+ return array_key_exists ($ key , $ this ->temporaryRegistry ) || array_key_exists ($ key , $ this ->registry );
92+ }
93+
94+ /**
95+ * @return mixed
96+ */
97+ private function getFromRegistry (string $ key )
98+ {
99+ if (isset ($ this ->temporaryRegistry [$ key ])) {
100+ return $ this ->temporaryRegistry [$ key ]($ this , $ this ->fakerInstance );
101+ }
102+
103+ return $ this ->registry [$ key ]($ this , $ this ->fakerInstance );
104+ }
105+
106+ /**
107+ * @param ReflectionClass<object> $class
108+ */
93109 private function findFactoryMethod (ReflectionClass $ class ): ?ReflectionMethod
94110 {
95111 try {
96112 return $ class ->getMethod ('createNew ' );
97113 } catch (ReflectionException $ e ) {
98114 // Do nothing here
99115 }
116+
100117 try {
101118 return $ class ->getMethod ('create ' );
102119 } catch (ReflectionException $ e ) {
@@ -105,60 +122,70 @@ private function findFactoryMethod(ReflectionClass $class): ?ReflectionMethod
105122 }
106123
107124 /**
108- * @param Type $type
109- *
110- * @param string $className
111- * @param string $argumentName
112- *
113125 * @return mixed
114126 * @throws ReflectionException
115127 */
116128 private function generateArgument (Type $ type , string $ className , string $ argumentName )
117129 {
118130 $ faker = $ type ->isNullable () ? $ this ->fakerInstance ->optional () : $ this ->fakerInstance ;
119131 $ key = sprintf ('%s:%s ' , $ className , $ argumentName );
132+
120133 if ($ this ->isInRegistry ($ key )) {
121134 return $ this ->getFromRegistry ($ key );
122135 }
123136
124137 switch ($ type ->getBuiltinType ()) {
125138 case Type::BUILTIN_TYPE_INT :
126139 return $ faker ->randomNumber (5 );
140+
127141 case Type::BUILTIN_TYPE_FLOAT :
128142 return $ faker ->randomFloat ();
143+
129144 case Type::BUILTIN_TYPE_STRING :
130145 return $ faker ->text (100 );
146+
131147 case Type::BUILTIN_TYPE_BOOL :
132148 return $ faker ->boolean ();
149+
133150 case Type::BUILTIN_TYPE_ARRAY :
134151 $ collection = [];
152+
135153 if ($ type ->isCollection ()) {
136154 $ collection = array_map (
137155 function () use ($ argumentName , $ className , $ type ) {
138- return $ this ->generateArgument ($ type ->getCollectionValueType (), $ className , $ argumentName );
156+ /** @var Type $collectionValueType */
157+ $ collectionValueType = $ type ->getCollectionValueType ();
158+
159+ return $ this ->generateArgument ($ collectionValueType , $ className , $ argumentName );
139160 },
140161 range (0 , $ faker ->numberBetween (0 , 10 ))
141162 );
142163 }
164+
143165 return $ faker ->passthrough ($ collection );
166+
144167 case Type::BUILTIN_TYPE_OBJECT :
145- if ($ type ->getClassName () === 'DateTime ' ) {
168+ /** @var class-string $className */
169+ $ className = $ type ->getClassName ();
170+
171+ if ($ className === 'DateTime ' ) {
146172 return $ faker ->dateTime ();
147173 }
148- return $ faker ->passthrough ($ this ->generateObject ($ type ->getClassName ()));
174+
175+ return $ faker ->passthrough ($ this ->generateObject ($ className ));
149176 }
150177 }
151178
152- private function isInRegistry (string $ key ): bool
179+ /**
180+ * @param class-string $className
181+ * @param array<mixed> $config
182+ */
183+ public function generateWithTemporaryConfig (string $ className , array $ config ): object
153184 {
154- return array_key_exists ($ key , $ this ->temporaryRegistry ) || array_key_exists ($ key , $ this ->registry );
155- }
185+ $ this ->temporaryRegistry = $ config ;
186+ $ object = $ this ->generateObject ($ className );
187+ $ this ->temporaryRegistry = [];
156188
157- private function getFromRegistry (string $ key )
158- {
159- if (isset ($ this ->temporaryRegistry [$ key ])) {
160- return $ this ->temporaryRegistry [$ key ]($ this , $ this ->fakerInstance );
161- }
162- return $ this ->registry [$ key ]($ this , $ this ->fakerInstance );
189+ return $ object ;
163190 }
164191}
0 commit comments