edmondscommerce /
doctrine-static-meta
| 1 | <?php |
||
| 2 | |||
| 3 | declare(strict_types=1); |
||
| 4 | |||
| 5 | namespace EdmondsCommerce\DoctrineStaticMeta\Tests\Assets; |
||
| 6 | |||
| 7 | use Composer\Autoload\ClassLoader; |
||
| 8 | use EdmondsCommerce\DoctrineStaticMeta\Builder\Builder; |
||
| 9 | use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Creation\Src\Entity\Fields\Traits\FieldTraitCreator; |
||
| 10 | use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Generator\AbstractGenerator; |
||
| 11 | use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Generator\FindAndReplaceHelper; |
||
| 12 | use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Generator\RelationsGenerator; |
||
| 13 | use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\NamespaceHelper; |
||
| 14 | use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\PostProcessor\FileOverrider; |
||
| 15 | use EdmondsCommerce\DoctrineStaticMeta\Entity\Embeddable\Traits\Attribute\HasWeightEmbeddableTrait; |
||
| 16 | use EdmondsCommerce\DoctrineStaticMeta\Entity\Embeddable\Traits\Financial\HasMoneyEmbeddableTrait; |
||
| 17 | use EdmondsCommerce\DoctrineStaticMeta\Entity\Embeddable\Traits\Geo\HasAddressEmbeddableTrait; |
||
| 18 | use EdmondsCommerce\DoctrineStaticMeta\Entity\Embeddable\Traits\Identity\HasFullNameEmbeddableTrait; |
||
| 19 | use EdmondsCommerce\DoctrineStaticMeta\Entity\Fields\Traits\String\EmailAddressFieldTrait; |
||
| 20 | use EdmondsCommerce\DoctrineStaticMeta\Exception\DoctrineStaticMetaException; |
||
| 21 | use EdmondsCommerce\DoctrineStaticMeta\MappingHelper; |
||
| 22 | use ReflectionException; |
||
| 23 | use RuntimeException; |
||
| 24 | use Symfony\Component\Filesystem\Filesystem; |
||
| 25 | |||
| 26 | use function spl_autoload_functions; |
||
| 27 | use function spl_autoload_unregister; |
||
| 28 | |||
| 29 | /** |
||
| 30 | * @SuppressWarnings(PHPMD.CouplingBetweenObjects) |
||
| 31 | */ |
||
| 32 | class TestCodeGenerator |
||
| 33 | { |
||
| 34 | |||
| 35 | public const TEST_PROJECT_ROOT_NAMESPACE = 'Test\\Code\\Generator'; |
||
| 36 | public const TEST_ENTITY_NAMESPACE_BASE = '\\' . AbstractGenerator::ENTITIES_FOLDER_NAME; |
||
| 37 | private const TEST_FIELD_NAMESPACE_BASE = '\\Entity\\Fields'; |
||
| 38 | private const TEST_FIELD_FQN_BASE = self::TEST_FIELD_NAMESPACE_BASE . '\\Traits'; |
||
| 39 | |||
| 40 | public const TEST_ENTITY_PERSON = '\\Person'; |
||
| 41 | public const TEST_ENTITY_ATTRIBUTES_ADDRESS = '\\Attributes\\Address'; |
||
| 42 | public const TEST_ENTITY_EMAIL = '\\Attributes\\Email'; |
||
| 43 | public const TEST_ENTITY_COMPANY = '\\Company'; |
||
| 44 | public const TEST_ENTITY_DIRECTOR = '\\Company\\Director'; |
||
| 45 | public const TEST_ENTITY_ORDER = '\\Order'; |
||
| 46 | public const TEST_ENTITY_ORDER_ADDRESS = '\\Order\\Address'; |
||
| 47 | public const TEST_ENTITY_NAME_SPACING_SOME_CLIENT = '\\Some\\Client'; |
||
| 48 | public const TEST_ENTITY_NAME_SPACING_ANOTHER_CLIENT = '\\Another\\Deeply\\Nested\\Client'; |
||
| 49 | public const TEST_ENTITY_LARGE_DATA = '\\Large\\Data'; |
||
| 50 | public const TEST_ENTITY_LARGE_PROPERTIES = '\\Large\\Property'; |
||
| 51 | public const TEST_ENTITY_LARGE_RELATIONS = '\\Large\\Relation'; |
||
| 52 | public const TEST_ENTITY_ALL_ARCHETYPE_FIELDS = '\\All\\StandardLibraryFields\\TestEntity'; |
||
| 53 | public const TEST_ENTITY_ALL_EMBEDDABLES = '\\AllEmbeddable'; |
||
| 54 | public const TEST_ENTITY_SIMPLE = '\\Simple'; |
||
| 55 | public const TEST_ENTITY_CUSTOM_RELATION = '\\CustomRelation'; |
||
| 56 | |||
| 57 | public const TEST_ENTITIES = [ |
||
| 58 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_PERSON, |
||
| 59 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_ATTRIBUTES_ADDRESS, |
||
| 60 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_EMAIL, |
||
| 61 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_COMPANY, |
||
| 62 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_DIRECTOR, |
||
| 63 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_ORDER, |
||
| 64 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_ORDER_ADDRESS, |
||
| 65 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_NAME_SPACING_SOME_CLIENT, |
||
| 66 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_NAME_SPACING_ANOTHER_CLIENT, |
||
| 67 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_LARGE_DATA, |
||
| 68 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_LARGE_PROPERTIES, |
||
| 69 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_LARGE_RELATIONS, |
||
| 70 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_ALL_ARCHETYPE_FIELDS, |
||
| 71 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_ALL_EMBEDDABLES, |
||
| 72 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_SIMPLE, |
||
| 73 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_CUSTOM_RELATION, |
||
| 74 | ]; |
||
| 75 | |||
| 76 | |||
| 77 | private const TEST_RELATIONS = [ |
||
| 78 | [ |
||
| 79 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_PERSON, |
||
| 80 | RelationsGenerator::HAS_UNIDIRECTIONAL_MANY_TO_ONE, |
||
| 81 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_ATTRIBUTES_ADDRESS, |
||
| 82 | false, |
||
| 83 | ], |
||
| 84 | [ |
||
| 85 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_PERSON, |
||
| 86 | RelationsGenerator::HAS_ONE_TO_MANY, |
||
| 87 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_EMAIL, |
||
| 88 | false, |
||
| 89 | ], |
||
| 90 | [ |
||
| 91 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_COMPANY, |
||
| 92 | RelationsGenerator::HAS_REQUIRED_MANY_TO_MANY, |
||
| 93 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_DIRECTOR, |
||
| 94 | true, |
||
| 95 | ], |
||
| 96 | [ |
||
| 97 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_COMPANY, |
||
| 98 | RelationsGenerator::HAS_REQUIRED_ONE_TO_MANY, |
||
| 99 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_ATTRIBUTES_ADDRESS, |
||
| 100 | false, |
||
| 101 | ], |
||
| 102 | [ |
||
| 103 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_COMPANY, |
||
| 104 | RelationsGenerator::HAS_REQUIRED_UNIDIRECTIONAL_ONE_TO_MANY, |
||
| 105 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_EMAIL, |
||
| 106 | false, |
||
| 107 | ], |
||
| 108 | [ |
||
| 109 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_DIRECTOR, |
||
| 110 | RelationsGenerator::HAS_REQUIRED_ONE_TO_ONE, |
||
| 111 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_PERSON, |
||
| 112 | false, |
||
| 113 | ], |
||
| 114 | [ |
||
| 115 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_ORDER, |
||
| 116 | RelationsGenerator::HAS_REQUIRED_UNIDIRECTIONAL_MANY_TO_ONE, |
||
| 117 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_PERSON, |
||
| 118 | false, |
||
| 119 | ], |
||
| 120 | [ |
||
| 121 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_ORDER, |
||
| 122 | RelationsGenerator::HAS_REQUIRED_ONE_TO_MANY, |
||
| 123 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_ORDER_ADDRESS, |
||
| 124 | true, |
||
| 125 | ], |
||
| 126 | [ |
||
| 127 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_ORDER_ADDRESS, |
||
| 128 | RelationsGenerator::HAS_REQUIRED_UNIDIRECTIONAL_ONE_TO_ONE, |
||
| 129 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_ATTRIBUTES_ADDRESS, |
||
| 130 | false, |
||
| 131 | ], |
||
| 132 | [ |
||
| 133 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_COMPANY, |
||
| 134 | RelationsGenerator::HAS_ONE_TO_ONE, |
||
| 135 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_NAME_SPACING_SOME_CLIENT, |
||
| 136 | false, |
||
| 137 | ], |
||
| 138 | [ |
||
| 139 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_COMPANY, |
||
| 140 | RelationsGenerator::HAS_ONE_TO_ONE, |
||
| 141 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_NAME_SPACING_ANOTHER_CLIENT, |
||
| 142 | false, |
||
| 143 | ], |
||
| 144 | [ |
||
| 145 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_LARGE_RELATIONS, |
||
| 146 | RelationsGenerator::HAS_UNIDIRECTIONAL_MANY_TO_ONE, |
||
| 147 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_ATTRIBUTES_ADDRESS, |
||
| 148 | false, |
||
| 149 | ], |
||
| 150 | [ |
||
| 151 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_LARGE_RELATIONS, |
||
| 152 | RelationsGenerator::HAS_REQUIRED_ONE_TO_MANY, |
||
| 153 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_EMAIL, |
||
| 154 | false, |
||
| 155 | ], |
||
| 156 | [ |
||
| 157 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_LARGE_RELATIONS, |
||
| 158 | RelationsGenerator::HAS_MANY_TO_MANY, |
||
| 159 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_DIRECTOR, |
||
| 160 | false, |
||
| 161 | ], |
||
| 162 | [ |
||
| 163 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_LARGE_RELATIONS, |
||
| 164 | RelationsGenerator::HAS_REQUIRED_UNIDIRECTIONAL_ONE_TO_MANY, |
||
| 165 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_LARGE_DATA, |
||
| 166 | false, |
||
| 167 | ], |
||
| 168 | [ |
||
| 169 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_LARGE_RELATIONS, |
||
| 170 | RelationsGenerator::HAS_ONE_TO_ONE, |
||
| 171 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_PERSON, |
||
| 172 | false, |
||
| 173 | ], |
||
| 174 | [ |
||
| 175 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_LARGE_RELATIONS, |
||
| 176 | RelationsGenerator::HAS_REQUIRED_MANY_TO_ONE, |
||
| 177 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_LARGE_PROPERTIES, |
||
| 178 | true, |
||
| 179 | ], |
||
| 180 | [ |
||
| 181 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_LARGE_RELATIONS, |
||
| 182 | RelationsGenerator::HAS_ONE_TO_MANY, |
||
| 183 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_ORDER_ADDRESS, |
||
| 184 | false, |
||
| 185 | ], |
||
| 186 | [ |
||
| 187 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_LARGE_RELATIONS, |
||
| 188 | RelationsGenerator::HAS_REQUIRED_UNIDIRECTIONAL_ONE_TO_ONE, |
||
| 189 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_COMPANY, |
||
| 190 | false, |
||
| 191 | ], |
||
| 192 | [ |
||
| 193 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_CUSTOM_RELATION, |
||
| 194 | RelationsGenerator::HAS_REQUIRED_UNIDIRECTIONAL_ONE_TO_ONE, |
||
| 195 | self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_COMPANY, |
||
| 196 | false, |
||
| 197 | ], |
||
| 198 | ]; |
||
| 199 | |||
| 200 | private const LARGE_DATA_FIELDS = [ |
||
| 201 | self::TEST_FIELD_FQN_BASE . '\\Large\\Data\\LargeDataOne', |
||
| 202 | self::TEST_FIELD_FQN_BASE . '\\Large\\Data\\LargeDataTwo', |
||
| 203 | self::TEST_FIELD_FQN_BASE . '\\Large\\Data\\LargeDataThree', |
||
| 204 | self::TEST_FIELD_FQN_BASE . '\\Large\\Data\\LargeDataFour', |
||
| 205 | ]; |
||
| 206 | |||
| 207 | private const LARGE_PROPERTIES_FIELDS = [ |
||
| 208 | self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData001', |
||
| 209 | self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData002', |
||
| 210 | self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData003', |
||
| 211 | self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData004', |
||
| 212 | self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData005', |
||
| 213 | self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData006', |
||
| 214 | self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData007', |
||
| 215 | self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData008', |
||
| 216 | self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData009', |
||
| 217 | self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData010', |
||
| 218 | self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData011', |
||
| 219 | self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData012', |
||
| 220 | self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData013', |
||
| 221 | self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData014', |
||
| 222 | self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData015', |
||
| 223 | self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData016', |
||
| 224 | self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData017', |
||
| 225 | self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData018', |
||
| 226 | self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData019', |
||
| 227 | self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData020', |
||
| 228 | self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData021', |
||
| 229 | self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData022', |
||
| 230 | self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData023', |
||
| 231 | self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData024', |
||
| 232 | self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData025', |
||
| 233 | self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData026', |
||
| 234 | self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData027', |
||
| 235 | self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData028', |
||
| 236 | self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData029', |
||
| 237 | self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData030', |
||
| 238 | self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData031', |
||
| 239 | self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData032', |
||
| 240 | self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData033', |
||
| 241 | self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData034', |
||
| 242 | self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData035', |
||
| 243 | self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData036', |
||
| 244 | self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData037', |
||
| 245 | self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData038', |
||
| 246 | self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData039', |
||
| 247 | ]; |
||
| 248 | |||
| 249 | private const BUILD_DIR = AbstractTest::VAR_PATH . '/../testCode'; |
||
| 250 | private const BUILD_DIR_TMP_B1 = AbstractTest::VAR_PATH . '/../testCodeTmp1'; |
||
| 251 | private const BUILD_DIR_TMP_B2 = AbstractTest::VAR_PATH . '/../testCodeTmp2'; |
||
| 252 | private const TEST_PROJECT_ROOT_NAMESPACE_B1 = self::TEST_PROJECT_ROOT_NAMESPACE . '\\Tmp1'; |
||
| 253 | private const TEST_ENTITY_NAMESPACE_BASE_B1 = self::TEST_PROJECT_ROOT_NAMESPACE_B1 . |
||
| 254 | self::TEST_ENTITY_NAMESPACE_BASE; |
||
| 255 | private const TEST_PROJECT_ROOT_NAMESPACE_B2 = self::TEST_PROJECT_ROOT_NAMESPACE . '\\Tmp2'; |
||
| 256 | private const BUILD_HASH_FILE = self::BUILD_DIR . '/.buildHash'; |
||
| 257 | |||
| 258 | /** |
||
| 259 | * @var Builder |
||
| 260 | */ |
||
| 261 | protected $builder; |
||
| 262 | /** |
||
| 263 | * @var Filesystem |
||
| 264 | */ |
||
| 265 | protected $filesystem; |
||
| 266 | /** |
||
| 267 | * @var FindAndReplaceHelper |
||
| 268 | */ |
||
| 269 | protected $findAndReplaceHelper; |
||
| 270 | /** |
||
| 271 | * @var CodeCopier |
||
| 272 | */ |
||
| 273 | private $codeCopier; |
||
| 274 | /** |
||
| 275 | * @var NamespaceHelper |
||
| 276 | */ |
||
| 277 | private $namespaceHelper; |
||
| 278 | |||
| 279 | public function __construct( |
||
| 280 | Builder $builder, |
||
| 281 | Filesystem $filesystem, |
||
| 282 | FindAndReplaceHelper $findAndReplaceHelper, |
||
| 283 | NamespaceHelper $namespaceHelper |
||
| 284 | ) { |
||
| 285 | $this->builder = $builder; |
||
| 286 | $this->filesystem = $filesystem; |
||
| 287 | $this->codeCopier = new CodeCopier($this->filesystem, $findAndReplaceHelper); |
||
| 288 | $this->namespaceHelper = $namespaceHelper; |
||
| 289 | $this->initBuildDir(); |
||
| 290 | $this->buildOnce(); |
||
| 291 | } |
||
| 292 | |||
| 293 | private function initBuildDir(): void |
||
| 294 | { |
||
| 295 | |||
| 296 | if (!is_dir(self::BUILD_DIR)) { |
||
| 297 | $this->filesystem->mkdir(self::BUILD_DIR); |
||
| 298 | } |
||
| 299 | } |
||
| 300 | |||
| 301 | private function buildOnce(): void |
||
| 302 | { |
||
| 303 | if ($this->isBuilt()) { |
||
| 304 | return; |
||
| 305 | } |
||
| 306 | $this->firstBuild(); |
||
| 307 | $this->secondBuild(); |
||
| 308 | $this->thirdBuild(); |
||
| 309 | $this->filesystem->remove(self::BUILD_DIR_TMP_B1); |
||
| 310 | $this->filesystem->remove(self::BUILD_DIR_TMP_B2); |
||
| 311 | $this->setBuildHash(); |
||
| 312 | } |
||
| 313 | |||
| 314 | /** |
||
| 315 | * Check that a file exists in the build directory which contains the md5 hash of this class. |
||
| 316 | * |
||
| 317 | * This means that if we update this class, the hash changes and the built files are invalid and will be nuked |
||
| 318 | * |
||
| 319 | * @return bool |
||
| 320 | */ |
||
| 321 | private function isBuilt(): bool |
||
| 322 | { |
||
| 323 | return file_exists(self::BUILD_HASH_FILE) && $this->validateBuildHash(); |
||
| 324 | } |
||
| 325 | |||
| 326 | private function validateBuildHash(): bool |
||
| 327 | { |
||
| 328 | return md5(\ts\file_get_contents(__FILE__)) === \ts\file_get_contents(self::BUILD_HASH_FILE); |
||
| 329 | } |
||
| 330 | |||
| 331 | private function firstBuild(): void |
||
| 332 | { |
||
| 333 | $this->emptyDir(self::BUILD_DIR_TMP_B1); |
||
| 334 | $this->builder->setProjectRootNamespace(self::TEST_PROJECT_ROOT_NAMESPACE_B1) |
||
| 335 | ->setPathToProjectRoot(self::BUILD_DIR_TMP_B1); |
||
| 336 | $this->filesystem->remove(self::BUILD_DIR_TMP_B1); |
||
| 337 | $this->filesystem->mkdir(self::BUILD_DIR_TMP_B1); |
||
| 338 | $this->extendAutoloader(self::TEST_PROJECT_ROOT_NAMESPACE_B1, self::BUILD_DIR_TMP_B1); |
||
| 339 | $fields = $this->buildCommonTypeFields(); |
||
| 340 | $this->buildEntitiesAndAssignCommonFields($fields); |
||
| 341 | $this->updateLargeDataEntity(); |
||
| 342 | $this->updateLargePropertiesEntity(); |
||
| 343 | $this->addArchetypeFieldsToEntities(); |
||
| 344 | $this->updateEmailEntity(); |
||
| 345 | $this->updateAllEmbeddablesEntity(); |
||
| 346 | $this->setRelations(); |
||
| 347 | $this->resetAutoloader(); |
||
| 348 | } |
||
| 349 | |||
| 350 | private function emptyDir(string $path): void |
||
| 351 | { |
||
| 352 | $this->filesystem->remove($path); |
||
| 353 | $this->filesystem->mkdir($path); |
||
| 354 | } |
||
| 355 | |||
| 356 | private function extendAutoloader(string $namespace, string $buildDir): void |
||
| 357 | { |
||
| 358 | $testLoader = new class ($namespace) extends ClassLoader |
||
| 359 | { |
||
| 360 | /** |
||
| 361 | * @var string |
||
| 362 | */ |
||
| 363 | protected $namespace; |
||
| 364 | |||
| 365 | public function __construct(string $namespace) |
||
| 366 | { |
||
| 367 | $this->namespace = $namespace; |
||
| 368 | } |
||
| 369 | |||
| 370 | public function loadClass($class) |
||
| 371 | { |
||
| 372 | if (false === strpos($class, $this->namespace)) { |
||
| 373 | return false; |
||
| 374 | } |
||
| 375 | $found = parent::loadClass($class); |
||
| 376 | if (false === $found || null === $found) { |
||
|
0 ignored issues
–
show
introduced
by
Loading history...
|
|||
| 377 | //good point to set a breakpoint |
||
| 378 | return $found; |
||
| 379 | } |
||
| 380 | |||
| 381 | return $found; |
||
| 382 | } |
||
| 383 | }; |
||
| 384 | $testLoader->addPsr4($namespace . '\\', $buildDir . '/src', true); |
||
| 385 | $testLoader->addPsr4($namespace . '\\', $buildDir . '/tests', true); |
||
| 386 | $testLoader->register(); |
||
| 387 | } |
||
| 388 | |||
| 389 | /** |
||
| 390 | * Build the fields and return an array of Field Trait FQNs |
||
| 391 | * |
||
| 392 | * @return array|string[] |
||
| 393 | * @throws DoctrineStaticMetaException |
||
| 394 | * @throws ReflectionException |
||
| 395 | */ |
||
| 396 | private function buildCommonTypeFields(): array |
||
| 397 | { |
||
| 398 | $fields = []; |
||
| 399 | $fieldGenerator = $this->builder->getFieldGenerator(); |
||
| 400 | |||
| 401 | foreach (MappingHelper::COMMON_TYPES as $type) { |
||
| 402 | $fields[] = $fieldGenerator->generateField( |
||
| 403 | self::TEST_PROJECT_ROOT_NAMESPACE_B1 |
||
| 404 | . self::TEST_FIELD_FQN_BASE . '\\' . ucwords($type) . FieldTraitCreator::SUFFIX, |
||
| 405 | $type |
||
| 406 | ); |
||
| 407 | } |
||
| 408 | |||
| 409 | return $fields; |
||
| 410 | } |
||
| 411 | |||
| 412 | private function buildEntitiesAndAssignCommonFields(array $fields): void |
||
| 413 | { |
||
| 414 | |||
| 415 | $entityGenerator = $this->builder->getEntityGenerator(); |
||
| 416 | $fieldSetter = $this->builder->getFieldSetter(); |
||
| 417 | |||
| 418 | foreach (self::TEST_ENTITIES as $entityFqn) { |
||
| 419 | $entityGenerator->generateEntity(self::TEST_PROJECT_ROOT_NAMESPACE_B1 . $entityFqn); |
||
| 420 | foreach ($fields as $fieldFqn) { |
||
| 421 | $fieldSetter->setEntityHasField( |
||
| 422 | self::TEST_PROJECT_ROOT_NAMESPACE_B1 . $entityFqn, |
||
| 423 | $fieldFqn |
||
| 424 | ); |
||
| 425 | } |
||
| 426 | } |
||
| 427 | } |
||
| 428 | |||
| 429 | private function updateLargeDataEntity(): void |
||
| 430 | { |
||
| 431 | $fieldGenerator = $this->builder->getFieldGenerator(); |
||
| 432 | $fieldSetter = $this->builder->getFieldSetter(); |
||
| 433 | foreach (self::LARGE_DATA_FIELDS as $field) { |
||
| 434 | $fieldSetter->setEntityHasField( |
||
| 435 | self::TEST_ENTITY_NAMESPACE_BASE_B1 . self::TEST_ENTITY_LARGE_DATA, |
||
| 436 | $fieldGenerator->generateField( |
||
| 437 | self::TEST_PROJECT_ROOT_NAMESPACE_B1 . $field, |
||
| 438 | MappingHelper::TYPE_TEXT |
||
| 439 | ) |
||
| 440 | ); |
||
| 441 | } |
||
| 442 | } |
||
| 443 | |||
| 444 | private function updateLargePropertiesEntity(): void |
||
| 445 | { |
||
| 446 | $fieldGenerator = $this->builder->getFieldGenerator(); |
||
| 447 | $fieldSetter = $this->builder->getFieldSetter(); |
||
| 448 | foreach (self::LARGE_PROPERTIES_FIELDS as $field) { |
||
| 449 | $fieldSetter->setEntityHasField( |
||
| 450 | self::TEST_ENTITY_NAMESPACE_BASE_B1 . self::TEST_ENTITY_LARGE_DATA, |
||
| 451 | $fieldGenerator->generateField( |
||
| 452 | self::TEST_PROJECT_ROOT_NAMESPACE_B1 . $field, |
||
| 453 | MappingHelper::TYPE_BOOLEAN |
||
| 454 | ) |
||
| 455 | ); |
||
| 456 | } |
||
| 457 | } |
||
| 458 | |||
| 459 | private function addArchetypeFieldsToEntities(): void |
||
| 460 | { |
||
| 461 | $archetypeFqns = $this->namespaceHelper->getAllArchetypeFieldFqns(); |
||
| 462 | $fieldSetter = $this->builder->getFieldSetter(); |
||
| 463 | foreach ($archetypeFqns as $archetypeFieldFqn) { |
||
| 464 | $fieldSetter->setEntityHasField( |
||
| 465 | self::TEST_ENTITY_NAMESPACE_BASE_B1 . self::TEST_ENTITY_ALL_ARCHETYPE_FIELDS, |
||
| 466 | $archetypeFieldFqn |
||
| 467 | ); |
||
| 468 | } |
||
| 469 | } |
||
| 470 | |||
| 471 | private function updateEmailEntity(): void |
||
| 472 | { |
||
| 473 | $emailEntityFqn = self::TEST_ENTITY_NAMESPACE_BASE_B1 . self::TEST_ENTITY_EMAIL; |
||
| 474 | $this->builder->getFieldSetter()->setEntityHasField($emailEntityFqn, EmailAddressFieldTrait::class); |
||
| 475 | } |
||
| 476 | |||
| 477 | private function updateAllEmbeddablesEntity(): void |
||
| 478 | { |
||
| 479 | $this->builder->setEmbeddablesToEntity( |
||
| 480 | self::TEST_ENTITY_NAMESPACE_BASE_B1 . self::TEST_ENTITY_ALL_EMBEDDABLES, |
||
| 481 | [ |
||
| 482 | HasMoneyEmbeddableTrait::class, |
||
| 483 | HasAddressEmbeddableTrait::class, |
||
| 484 | HasFullNameEmbeddableTrait::class, |
||
| 485 | HasWeightEmbeddableTrait::class, |
||
| 486 | ] |
||
| 487 | ); |
||
| 488 | } |
||
| 489 | |||
| 490 | private function setRelations(): void |
||
| 491 | { |
||
| 492 | $relationsGenerator = $this->builder->getRelationsGenerator(); |
||
| 493 | foreach (self::TEST_RELATIONS as $relation) { |
||
| 494 | $relationsGenerator->setEntityHasRelationToEntity( |
||
| 495 | self::TEST_PROJECT_ROOT_NAMESPACE_B1 . $relation[0], |
||
| 496 | (string)$relation[1], |
||
| 497 | self::TEST_PROJECT_ROOT_NAMESPACE_B1 . $relation[2], |
||
| 498 | (bool)$relation[3] |
||
| 499 | ); |
||
| 500 | } |
||
| 501 | } |
||
| 502 | |||
| 503 | private function resetAutoloader(): void |
||
| 504 | { |
||
| 505 | $registered = spl_autoload_functions(); |
||
| 506 | $loader = array_pop($registered); |
||
| 507 | spl_autoload_unregister($loader); |
||
| 508 | } |
||
| 509 | |||
| 510 | private function secondBuild(): void |
||
| 511 | { |
||
| 512 | $this->emptyDir(self::BUILD_DIR_TMP_B2); |
||
| 513 | $this->codeCopier->copy( |
||
| 514 | self::BUILD_DIR_TMP_B1, |
||
| 515 | self::BUILD_DIR_TMP_B2, |
||
| 516 | self::TEST_PROJECT_ROOT_NAMESPACE_B1, |
||
| 517 | self::TEST_PROJECT_ROOT_NAMESPACE_B2 |
||
| 518 | ); |
||
| 519 | $this->createCustomDataFiller(); |
||
| 520 | $this->extendAutoloader(self::TEST_PROJECT_ROOT_NAMESPACE_B2, self::BUILD_DIR_TMP_B2); |
||
| 521 | $this->builder->setPathToProjectRoot(self::BUILD_DIR_TMP_B2) |
||
| 522 | ->setProjectRootNamespace(self::TEST_PROJECT_ROOT_NAMESPACE_B2) |
||
| 523 | ->finaliseBuild(); |
||
| 524 | $this->emptyDir(self::BUILD_DIR); |
||
| 525 | $this->codeCopier->copy( |
||
| 526 | self::BUILD_DIR_TMP_B2, |
||
| 527 | self::BUILD_DIR, |
||
| 528 | self::TEST_PROJECT_ROOT_NAMESPACE_B2, |
||
| 529 | self::TEST_PROJECT_ROOT_NAMESPACE |
||
| 530 | ); |
||
| 531 | } |
||
| 532 | |||
| 533 | private function createCustomDataFiller(): void |
||
| 534 | { |
||
| 535 | |||
| 536 | $dataFiller = <<<'PHP' |
||
| 537 | <?php declare(strict_types=1); |
||
| 538 | |||
| 539 | namespace Test\Code\Generator\Assets\Entity\FakerDataFillers; |
||
| 540 | |||
| 541 | use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\NamespaceHelper; |
||
| 542 | use EdmondsCommerce\DoctrineStaticMeta\DoctrineStaticMeta; |
||
| 543 | use EdmondsCommerce\DoctrineStaticMeta\Entity\Interfaces\DataTransferObjectInterface; |
||
| 544 | use EdmondsCommerce\DoctrineStaticMeta\Entity\Testing\EntityGenerator\FakerDataFiller; |
||
| 545 | use EdmondsCommerce\DoctrineStaticMeta\Entity\Testing\EntityGenerator\FakerDataFillerFactory; |
||
| 546 | use EdmondsCommerce\DoctrineStaticMeta\Entity\Testing\EntityGenerator\FakerDataFillerInterface; |
||
| 547 | use Test\Code\Generator\Entity\DataTransferObjects\SimpleDto; |
||
| 548 | |||
| 549 | class SimpleFakerDataFiller implements FakerDataFillerInterface |
||
| 550 | { |
||
| 551 | /** |
||
| 552 | * @var FakerDataFiller |
||
| 553 | */ |
||
| 554 | private $wrappedFiller; |
||
| 555 | |||
| 556 | public function __construct( |
||
| 557 | FakerDataFillerFactory $fakerDataFillerFactory, |
||
| 558 | DoctrineStaticMeta $testedEntityDsm, |
||
| 559 | NamespaceHelper $namespaceHelper, |
||
| 560 | array $fakerDataProviderClasses, |
||
| 561 | ?float $seed = null |
||
| 562 | ) { |
||
| 563 | $this->wrappedFiller = |
||
| 564 | new FakerDataFiller( |
||
| 565 | $fakerDataFillerFactory, |
||
| 566 | $testedEntityDsm, |
||
| 567 | $namespaceHelper, |
||
| 568 | $fakerDataProviderClasses, |
||
| 569 | $seed |
||
| 570 | ); |
||
| 571 | } |
||
| 572 | |||
| 573 | public function updateDtoWithFakeData(DataTransferObjectInterface $dto): void |
||
| 574 | { |
||
| 575 | $this->wrappedFiller->updateDtoWithFakeData($dto); |
||
| 576 | $this->updateDtoWithKnownData($dto); |
||
| 577 | } |
||
| 578 | |||
| 579 | public function update(DataTransferObjectInterface $dto, $isRootDto = false): void |
||
| 580 | { |
||
| 581 | $this->wrappedFiller->update($dto, $isRootDto); |
||
| 582 | $this->updateDtoWithKnownData($dto); |
||
| 583 | } |
||
| 584 | |||
| 585 | private function updateDtoWithKnownData(DataTransferObjectInterface $dto): void |
||
| 586 | { |
||
| 587 | if (!$dto instanceof SimpleDto) { |
||
| 588 | throw new \RuntimeException(sprintf('Expected %s got %s', SimpleDto::class, get_class($dto))); |
||
| 589 | } |
||
| 590 | $dto->setString('Set from a custom Faker Data Filler'); |
||
| 591 | } |
||
| 592 | } |
||
| 593 | PHP; |
||
| 594 | $dirPath = self::BUILD_DIR_TMP_B2 . '/tests/Assets/Entity/FakerDataFillers/'; |
||
| 595 | $filePath = $dirPath . 'SimpleFakerDataFiller.php'; |
||
| 596 | if (!is_dir($dirPath)) { |
||
| 597 | mkdir($dirPath); |
||
| 598 | } |
||
| 599 | \ts\file_put_contents($filePath, $dataFiller); |
||
| 600 | } |
||
| 601 | |||
| 602 | private function thirdBuild(): void |
||
| 603 | { |
||
| 604 | $this->applyOverrides(); |
||
| 605 | $this->extendAutoloader(self::TEST_PROJECT_ROOT_NAMESPACE, self::BUILD_DIR); |
||
| 606 | $this->builder->setPathToProjectRoot(self::BUILD_DIR) |
||
| 607 | ->setProjectRootNamespace(self::TEST_PROJECT_ROOT_NAMESPACE) |
||
| 608 | ->finaliseBuild(); |
||
| 609 | } |
||
| 610 | |||
| 611 | private function applyOverrides(): void |
||
| 612 | { |
||
| 613 | $this->filesystem->mirror( |
||
| 614 | __DIR__ . '/../Assets/overrides', |
||
| 615 | self::BUILD_DIR . '/' . FileOverrider::OVERRIDES_PATH |
||
| 616 | ); |
||
| 617 | $overrider = new FileOverrider( |
||
| 618 | self::BUILD_DIR |
||
| 619 | ); |
||
| 620 | $invalidOverrides = $overrider->getInvalidOverrides(); |
||
| 621 | if ($invalidOverrides !== []) { |
||
| 622 | throw new RuntimeException('Invaild Overrides: ' . \ts\print_r($invalidOverrides, true)); |
||
| 623 | } |
||
| 624 | $overrider->applyOverrides(); |
||
| 625 | } |
||
| 626 | |||
| 627 | private function setBuildHash(): void |
||
| 628 | { |
||
| 629 | \ts\file_put_contents(self::BUILD_HASH_FILE, md5(\ts\file_get_contents(__FILE__))); |
||
| 630 | } |
||
| 631 | |||
| 632 | public function copyTo( |
||
| 633 | string $destinationPath, |
||
| 634 | string $replaceNamespace = AbstractTest::TEST_PROJECT_ROOT_NAMESPACE |
||
| 635 | ): void { |
||
| 636 | $this->codeCopier->copy( |
||
| 637 | self::BUILD_DIR, |
||
| 638 | $destinationPath, |
||
| 639 | self::TEST_PROJECT_ROOT_NAMESPACE, |
||
| 640 | $replaceNamespace |
||
| 641 | ); |
||
| 642 | } |
||
| 643 | } |
||
| 644 |