PageRenderTime 59ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/tests/Doctrine/Tests/ORM/Tools/EntityGeneratorTest.php

http://github.com/doctrine/doctrine2
PHP | 1331 lines | 1186 code | 103 blank | 42 comment | 11 complexity | 6bd2ade243e1df100dc49b0b7716dce6 MD5 | raw file
Possible License(s): Unlicense

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. declare(strict_types=1);
  3. namespace Doctrine\Tests\ORM\Tools;
  4. use DateTime;
  5. use Doctrine\Common\Annotations\AnnotationReader;
  6. use Doctrine\Common\Collections\ArrayCollection;
  7. use Doctrine\ORM\Mapping\ClassMetadataFactory;
  8. use Doctrine\ORM\Mapping\ClassMetadataInfo;
  9. use Doctrine\ORM\Mapping\Column;
  10. use Doctrine\ORM\Mapping\Driver\AnnotationDriver;
  11. use Doctrine\ORM\Tools\EntityGenerator;
  12. use Doctrine\Persistence\Mapping\RuntimeReflectionService;
  13. use Doctrine\Tests\Models\DDC2372\DDC2372Admin;
  14. use Doctrine\Tests\Models\DDC2372\DDC2372User;
  15. use Doctrine\Tests\OrmTestCase;
  16. use InvalidArgumentException;
  17. use RecursiveDirectoryIterator;
  18. use RecursiveIteratorIterator;
  19. use ReflectionClass;
  20. use ReflectionMethod;
  21. use ReflectionObject;
  22. use ReflectionProperty;
  23. use SplFileInfo;
  24. use stdClass;
  25. use function array_keys;
  26. use function assert;
  27. use function basename;
  28. use function class_exists;
  29. use function file_get_contents;
  30. use function file_put_contents;
  31. use function get_class;
  32. use function method_exists;
  33. use function mkdir;
  34. use function preg_match;
  35. use function preg_replace;
  36. use function rmdir;
  37. use function sprintf;
  38. use function str_replace;
  39. use function sys_get_temp_dir;
  40. use function ucfirst;
  41. use function uniqid;
  42. use function unlink;
  43. use const DIRECTORY_SEPARATOR;
  44. class EntityGeneratorTest extends OrmTestCase
  45. {
  46. /** @var EntityGenerator */
  47. private $generator;
  48. /** @var string */
  49. private $tmpDir;
  50. /** @var string */
  51. private $namespace;
  52. protected function setUp(): void
  53. {
  54. $this->namespace = uniqid('doctrine_');
  55. $this->tmpDir = sys_get_temp_dir();
  56. mkdir($this->tmpDir . DIRECTORY_SEPARATOR . $this->namespace);
  57. $this->generator = new EntityGenerator();
  58. $this->generator->setGenerateAnnotations(true);
  59. $this->generator->setGenerateStubMethods(true);
  60. $this->generator->setRegenerateEntityIfExists(false);
  61. $this->generator->setUpdateEntityIfExists(true);
  62. $this->generator->setFieldVisibility(EntityGenerator::FIELD_VISIBLE_PROTECTED);
  63. }
  64. public function tearDown(): void
  65. {
  66. $ri = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->tmpDir . '/' . $this->namespace));
  67. foreach ($ri as $file) {
  68. assert($file instanceof SplFileInfo);
  69. if ($file->isFile()) {
  70. unlink($file->getPathname());
  71. }
  72. }
  73. rmdir($this->tmpDir . '/' . $this->namespace);
  74. }
  75. /**
  76. * @param ClassMetadataInfo[] $embeddedClasses
  77. */
  78. public function generateBookEntityFixture(array $embeddedClasses = []): ClassMetadataInfo
  79. {
  80. $metadata = new ClassMetadataInfo($this->namespace . '\EntityGeneratorBook');
  81. $metadata->namespace = $this->namespace;
  82. $metadata->customRepositoryClassName = $this->namespace . '\EntityGeneratorBookRepository';
  83. $metadata->table['name'] = 'book';
  84. $metadata->table['uniqueConstraints']['name_uniq'] = ['columns' => ['name']];
  85. $metadata->table['indexes']['status_idx'] = ['columns' => ['status']];
  86. $metadata->mapField(['fieldName' => 'name', 'type' => 'string']);
  87. $metadata->mapField(['fieldName' => 'status', 'type' => 'string', 'options' => ['default' => 'published']]);
  88. $metadata->mapField(['fieldName' => 'id', 'type' => 'integer', 'id' => true]);
  89. $metadata->mapOneToOne(
  90. ['fieldName' => 'author', 'targetEntity' => EntityGeneratorAuthor::class, 'mappedBy' => 'book']
  91. );
  92. $joinColumns = [
  93. ['name' => 'author_id', 'referencedColumnName' => 'id'],
  94. ];
  95. $metadata->mapManyToMany(
  96. [
  97. 'fieldName' => 'comments',
  98. 'targetEntity' => EntityGeneratorComment::class,
  99. 'fetch' => ClassMetadataInfo::FETCH_EXTRA_LAZY,
  100. 'joinTable' => [
  101. 'name' => 'book_comment',
  102. 'joinColumns' => [['name' => 'book_id', 'referencedColumnName' => 'id']],
  103. 'inverseJoinColumns' => [['name' => 'comment_id', 'referencedColumnName' => 'id']],
  104. ],
  105. ]
  106. );
  107. $metadata->addLifecycleCallback('loading', 'postLoad');
  108. $metadata->addLifecycleCallback('willBeRemoved', 'preRemove');
  109. $metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_AUTO);
  110. foreach ($embeddedClasses as $fieldName => $embeddedClass) {
  111. $this->mapNestedEmbedded($fieldName, $metadata, $embeddedClass);
  112. $this->mapEmbedded($fieldName, $metadata, $embeddedClass);
  113. }
  114. $this->generator->writeEntityClass($metadata, $this->tmpDir);
  115. return $metadata;
  116. }
  117. private function generateEntityTypeFixture(array $field): ClassMetadataInfo
  118. {
  119. $metadata = new ClassMetadataInfo($this->namespace . '\EntityType');
  120. $metadata->namespace = $this->namespace;
  121. $metadata->table['name'] = 'entity_type';
  122. $metadata->mapField(['fieldName' => 'id', 'type' => 'integer', 'id' => true]);
  123. $metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_AUTO);
  124. $name = $field['fieldName'];
  125. $type = $field['dbType'];
  126. $metadata->mapField(['fieldName' => $name, 'type' => $type]);
  127. $this->generator->writeEntityClass($metadata, $this->tmpDir);
  128. return $metadata;
  129. }
  130. private function generateIsbnEmbeddableFixture(array $embeddedClasses = [], $columnPrefix = null): ClassMetadataInfo
  131. {
  132. $metadata = new ClassMetadataInfo($this->namespace . '\EntityGeneratorIsbn');
  133. $metadata->namespace = $this->namespace;
  134. $metadata->isEmbeddedClass = true;
  135. $metadata->mapField(['fieldName' => 'prefix', 'type' => 'integer']);
  136. $metadata->mapField(['fieldName' => 'groupNumber', 'type' => 'integer']);
  137. $metadata->mapField(['fieldName' => 'publisherNumber', 'type' => 'integer']);
  138. $metadata->mapField(['fieldName' => 'titleNumber', 'type' => 'integer']);
  139. $metadata->mapField(['fieldName' => 'checkDigit', 'type' => 'integer']);
  140. foreach ($embeddedClasses as $fieldName => $embeddedClass) {
  141. $this->mapEmbedded($fieldName, $metadata, $embeddedClass, $columnPrefix);
  142. }
  143. $this->generator->writeEntityClass($metadata, $this->tmpDir);
  144. return $metadata;
  145. }
  146. private function generateTestEmbeddableFixture(): ClassMetadataInfo
  147. {
  148. $metadata = new ClassMetadataInfo($this->namespace . '\EntityGeneratorTestEmbeddable');
  149. $metadata->namespace = $this->namespace;
  150. $metadata->isEmbeddedClass = true;
  151. $metadata->mapField(['fieldName' => 'field1', 'type' => 'integer']);
  152. $metadata->mapField(['fieldName' => 'field2', 'type' => 'integer', 'nullable' => true]);
  153. $metadata->mapField(['fieldName' => 'field3', 'type' => 'datetime']);
  154. $metadata->mapField(['fieldName' => 'field4', 'type' => 'datetime', 'nullable' => true]);
  155. $this->generator->writeEntityClass($metadata, $this->tmpDir);
  156. return $metadata;
  157. }
  158. /**
  159. * @param string|bool $columnPrefix
  160. */
  161. private function mapEmbedded(
  162. string $fieldName,
  163. ClassMetadataInfo $classMetadata,
  164. ClassMetadataInfo $embeddableMetadata,
  165. $columnPrefix = false
  166. ): void {
  167. $classMetadata->mapEmbedded(
  168. ['fieldName' => $fieldName, 'class' => $embeddableMetadata->name, 'columnPrefix' => $columnPrefix]
  169. );
  170. }
  171. private function mapNestedEmbedded(
  172. string $fieldName,
  173. ClassMetadataInfo $classMetadata,
  174. ClassMetadataInfo $embeddableMetadata
  175. ): void {
  176. foreach ($embeddableMetadata->embeddedClasses as $property => $embeddableClass) {
  177. $classMetadata->mapEmbedded(
  178. [
  179. 'fieldName' => $fieldName . '.' . $property,
  180. 'class' => $embeddableClass['class'],
  181. 'columnPrefix' => $embeddableClass['columnPrefix'],
  182. 'declaredField' => $embeddableClass['declaredField']
  183. ? $fieldName . '.' . $embeddableClass['declaredField']
  184. : $fieldName,
  185. 'originalField' => $embeddableClass['originalField'] ?: $property,
  186. ]
  187. );
  188. }
  189. }
  190. private function loadEntityClass(ClassMetadataInfo $metadata): void
  191. {
  192. $className = basename(str_replace('\\', '/', $metadata->name));
  193. $path = $this->tmpDir . '/' . $this->namespace . '/' . $className . '.php';
  194. self::assertFileExists($path);
  195. require_once $path;
  196. }
  197. /**
  198. * @return mixed An instance of the given metadata's class.
  199. */
  200. public function newInstance(ClassMetadataInfo $metadata)
  201. {
  202. $this->loadEntityClass($metadata);
  203. return new $metadata->name();
  204. }
  205. /**
  206. * @group GH-6314
  207. */
  208. public function testEmbeddedEntityWithNamedColumnPrefix(): void
  209. {
  210. $columnPrefix = 'GH6314Prefix_';
  211. $testMetadata = $this->generateTestEmbeddableFixture();
  212. $isbnMetadata = $this->generateIsbnEmbeddableFixture(['testEmbedded' => $testMetadata], $columnPrefix);
  213. $isbnEntity = $this->newInstance($isbnMetadata);
  214. $refClass = new ReflectionClass($isbnEntity);
  215. self::assertTrue($refClass->hasProperty('testEmbedded'));
  216. $docComment = $refClass->getProperty('testEmbedded')->getDocComment();
  217. $needle = sprintf('@ORM\Embedded(class="%s", columnPrefix="%s")', $testMetadata->name, $columnPrefix);
  218. self::assertStringContainsString($needle, $docComment);
  219. }
  220. /**
  221. * @group GH-6314
  222. */
  223. public function testEmbeddedEntityWithoutColumnPrefix(): void
  224. {
  225. $testMetadata = $this->generateTestEmbeddableFixture();
  226. $isbnMetadata = $this->generateIsbnEmbeddableFixture(['testEmbedded' => $testMetadata], false);
  227. $isbnEntity = $this->newInstance($isbnMetadata);
  228. $refClass = new ReflectionClass($isbnEntity);
  229. self::assertTrue($refClass->hasProperty('testEmbedded'));
  230. $docComment = $refClass->getProperty('testEmbedded')->getDocComment();
  231. $needle = sprintf('@ORM\Embedded(class="%s", columnPrefix=false)', $testMetadata->name);
  232. self::assertStringContainsString($needle, $docComment);
  233. }
  234. public function testGeneratedEntityClass(): void
  235. {
  236. $testMetadata = $this->generateTestEmbeddableFixture();
  237. $isbnMetadata = $this->generateIsbnEmbeddableFixture(['test' => $testMetadata]);
  238. $metadata = $this->generateBookEntityFixture(['isbn' => $isbnMetadata]);
  239. $book = $this->newInstance($metadata);
  240. self::assertTrue(class_exists($metadata->name), 'Class does not exist.');
  241. self::assertTrue(method_exists($metadata->namespace . '\EntityGeneratorBook', '__construct'), 'EntityGeneratorBook::__construct() missing.');
  242. self::assertTrue(method_exists($metadata->namespace . '\EntityGeneratorBook', 'getId'), 'EntityGeneratorBook::getId() missing.');
  243. self::assertTrue(method_exists($metadata->namespace . '\EntityGeneratorBook', 'setName'), 'EntityGeneratorBook::setName() missing.');
  244. self::assertTrue(method_exists($metadata->namespace . '\EntityGeneratorBook', 'getName'), 'EntityGeneratorBook::getName() missing.');
  245. self::assertTrue(method_exists($metadata->namespace . '\EntityGeneratorBook', 'setStatus'), 'EntityGeneratorBook::setStatus() missing.');
  246. self::assertTrue(method_exists($metadata->namespace . '\EntityGeneratorBook', 'getStatus'), 'EntityGeneratorBook::getStatus() missing.');
  247. self::assertTrue(method_exists($metadata->namespace . '\EntityGeneratorBook', 'setAuthor'), 'EntityGeneratorBook::setAuthor() missing.');
  248. self::assertTrue(method_exists($metadata->namespace . '\EntityGeneratorBook', 'getAuthor'), 'EntityGeneratorBook::getAuthor() missing.');
  249. self::assertTrue(method_exists($metadata->namespace . '\EntityGeneratorBook', 'getComments'), 'EntityGeneratorBook::getComments() missing.');
  250. self::assertTrue(method_exists($metadata->namespace . '\EntityGeneratorBook', 'addComment'), 'EntityGeneratorBook::addComment() missing.');
  251. self::assertTrue(method_exists($metadata->namespace . '\EntityGeneratorBook', 'removeComment'), 'EntityGeneratorBook::removeComment() missing.');
  252. self::assertTrue(method_exists($metadata->namespace . '\EntityGeneratorBook', 'setIsbn'), 'EntityGeneratorBook::setIsbn() missing.');
  253. self::assertTrue(method_exists($metadata->namespace . '\EntityGeneratorBook', 'getIsbn'), 'EntityGeneratorBook::getIsbn() missing.');
  254. $reflClass = new ReflectionClass($metadata->name);
  255. self::assertCount(6, $reflClass->getProperties());
  256. self::assertCount(15, $reflClass->getMethods());
  257. self::assertEquals('published', $book->getStatus());
  258. $book->setName('Jonathan H. Wage');
  259. self::assertEquals('Jonathan H. Wage', $book->getName());
  260. $reflMethod = new ReflectionMethod($metadata->name, 'addComment');
  261. $addCommentParameters = $reflMethod->getParameters();
  262. self::assertEquals('comment', $addCommentParameters[0]->getName());
  263. $reflMethod = new ReflectionMethod($metadata->name, 'removeComment');
  264. $removeCommentParameters = $reflMethod->getParameters();
  265. self::assertEquals('comment', $removeCommentParameters[0]->getName());
  266. $author = new EntityGeneratorAuthor();
  267. $book->setAuthor($author);
  268. self::assertEquals($author, $book->getAuthor());
  269. $comment = new EntityGeneratorComment();
  270. self::assertInstanceOf($metadata->name, $book->addComment($comment));
  271. self::assertInstanceOf(ArrayCollection::class, $book->getComments());
  272. self::assertEquals(new ArrayCollection([$comment]), $book->getComments());
  273. self::assertIsBool($book->removeComment($comment));
  274. self::assertEquals(new ArrayCollection([]), $book->getComments());
  275. $this->newInstance($isbnMetadata);
  276. $isbn = new $isbnMetadata->name();
  277. $book->setIsbn($isbn);
  278. self::assertSame($isbn, $book->getIsbn());
  279. $reflMethod = new ReflectionMethod($metadata->name, 'setIsbn');
  280. $reflParameters = $reflMethod->getParameters();
  281. self::assertEquals($isbnMetadata->name, $reflParameters[0]->getType()->getName());
  282. }
  283. public function testBooleanDefaultValue(): void
  284. {
  285. $metadata = $this->generateBookEntityFixture(['isbn' => $this->generateIsbnEmbeddableFixture()]);
  286. $metadata->mapField(['fieldName' => 'foo', 'type' => 'boolean', 'options' => ['default' => '1']]);
  287. $testEmbeddableMetadata = $this->generateTestEmbeddableFixture();
  288. $this->mapEmbedded('testEmbedded', $metadata, $testEmbeddableMetadata);
  289. $this->generator->writeEntityClass($metadata, $this->tmpDir);
  290. self::assertFileExists($this->tmpDir . '/' . $this->namespace . '/EntityGeneratorBook.php~');
  291. $book = $this->newInstance($metadata);
  292. $reflClass = new ReflectionClass($metadata->name);
  293. self::assertTrue($book->getfoo());
  294. }
  295. public function testEntityUpdatingWorks(): void
  296. {
  297. $metadata = $this->generateBookEntityFixture(['isbn' => $this->generateIsbnEmbeddableFixture()]);
  298. $metadata->mapField(['fieldName' => 'test', 'type' => 'string']);
  299. $testEmbeddableMetadata = $this->generateTestEmbeddableFixture();
  300. $this->mapEmbedded('testEmbedded', $metadata, $testEmbeddableMetadata);
  301. $this->generator->writeEntityClass($metadata, $this->tmpDir);
  302. self::assertFileExists($this->tmpDir . '/' . $this->namespace . '/EntityGeneratorBook.php~');
  303. $book = $this->newInstance($metadata);
  304. $reflClass = new ReflectionClass($metadata->name);
  305. self::assertTrue($reflClass->hasProperty('name'), "Regenerating keeps property 'name'.");
  306. self::assertTrue($reflClass->hasProperty('status'), "Regenerating keeps property 'status'.");
  307. self::assertTrue($reflClass->hasProperty('id'), "Regenerating keeps property 'id'.");
  308. self::assertTrue($reflClass->hasProperty('isbn'), "Regenerating keeps property 'isbn'.");
  309. self::assertTrue($reflClass->hasProperty('test'), 'Check for property test failed.');
  310. self::assertTrue($reflClass->getProperty('test')->isProtected(), 'Check for protected property test failed.');
  311. self::assertTrue($reflClass->hasProperty('testEmbedded'), 'Check for property testEmbedded failed.');
  312. self::assertTrue($reflClass->getProperty('testEmbedded')->isProtected(), 'Check for protected property testEmbedded failed.');
  313. self::assertTrue($reflClass->hasMethod('getTest'), "Check for method 'getTest' failed.");
  314. self::assertTrue($reflClass->getMethod('getTest')->isPublic(), "Check for public visibility of method 'getTest' failed.");
  315. self::assertTrue($reflClass->hasMethod('setTest'), "Check for method 'setTest' failed.");
  316. self::assertTrue($reflClass->getMethod('setTest')->isPublic(), "Check for public visibility of method 'setTest' failed.");
  317. self::assertTrue($reflClass->hasMethod('getTestEmbedded'), "Check for method 'getTestEmbedded' failed.");
  318. self::assertTrue(
  319. $reflClass->getMethod('getTestEmbedded')->isPublic(),
  320. "Check for public visibility of method 'getTestEmbedded' failed."
  321. );
  322. self::assertTrue($reflClass->hasMethod('setTestEmbedded'), "Check for method 'setTestEmbedded' failed.");
  323. self::assertTrue(
  324. $reflClass->getMethod('setTestEmbedded')->isPublic(),
  325. "Check for public visibility of method 'setTestEmbedded' failed."
  326. );
  327. }
  328. /**
  329. * @group DDC-3152
  330. */
  331. public function testDoesNotRegenerateExistingMethodsWithDifferentCase(): void
  332. {
  333. $metadata = $this->generateBookEntityFixture(['isbn' => $this->generateIsbnEmbeddableFixture()]);
  334. // Workaround to change existing fields case (just to simulate the use case)
  335. $metadata->fieldMappings['status']['fieldName'] = 'STATUS';
  336. $metadata->embeddedClasses['ISBN'] = $metadata->embeddedClasses['isbn'];
  337. unset($metadata->embeddedClasses['isbn']);
  338. // Should not throw a PHP fatal error
  339. $this->generator->writeEntityClass($metadata, $this->tmpDir);
  340. self::assertFileExists($this->tmpDir . '/' . $this->namespace . '/EntityGeneratorBook.php~');
  341. $this->newInstance($metadata);
  342. $reflClass = new ReflectionClass($metadata->name);
  343. self::assertTrue($reflClass->hasProperty('status'));
  344. self::assertTrue($reflClass->hasProperty('STATUS'));
  345. self::assertTrue($reflClass->hasProperty('isbn'));
  346. self::assertTrue($reflClass->hasProperty('ISBN'));
  347. self::assertTrue($reflClass->hasMethod('getStatus'));
  348. self::assertTrue($reflClass->hasMethod('setStatus'));
  349. self::assertTrue($reflClass->hasMethod('getIsbn'));
  350. self::assertTrue($reflClass->hasMethod('setIsbn'));
  351. }
  352. /**
  353. * @group DDC-2121
  354. */
  355. public function testMethodDocBlockShouldStartWithBackSlash(): void
  356. {
  357. $embeddedMetadata = $this->generateIsbnEmbeddableFixture();
  358. $metadata = $this->generateBookEntityFixture(['isbn' => $embeddedMetadata]);
  359. $book = $this->newInstance($metadata);
  360. $this->assertPhpDocVarType('\Doctrine\Common\Collections\Collection', new ReflectionProperty($book, 'comments'));
  361. $this->assertPhpDocReturnType('\Doctrine\Common\Collections\Collection', new ReflectionMethod($book, 'getComments'));
  362. $this->assertPhpDocParamType('\Doctrine\Tests\ORM\Tools\EntityGeneratorComment', new ReflectionMethod($book, 'addComment'));
  363. $this->assertPhpDocReturnType('EntityGeneratorBook', new ReflectionMethod($book, 'addComment'));
  364. $this->assertPhpDocParamType('\Doctrine\Tests\ORM\Tools\EntityGeneratorComment', new ReflectionMethod($book, 'removeComment'));
  365. $this->assertPhpDocReturnType('boolean', new ReflectionMethod($book, 'removeComment'));
  366. $this->assertPhpDocVarType('\Doctrine\Tests\ORM\Tools\EntityGeneratorAuthor', new ReflectionProperty($book, 'author'));
  367. $this->assertPhpDocReturnType('\Doctrine\Tests\ORM\Tools\EntityGeneratorAuthor|null', new ReflectionMethod($book, 'getAuthor'));
  368. $this->assertPhpDocParamType('\Doctrine\Tests\ORM\Tools\EntityGeneratorAuthor|null', new ReflectionMethod($book, 'setAuthor'));
  369. $expectedClassName = '\\' . $embeddedMetadata->name;
  370. $this->assertPhpDocVarType($expectedClassName, new ReflectionProperty($book, 'isbn'));
  371. $this->assertPhpDocReturnType($expectedClassName, new ReflectionMethod($book, 'getIsbn'));
  372. $this->assertPhpDocParamType($expectedClassName, new ReflectionMethod($book, 'setIsbn'));
  373. }
  374. public function testEntityExtendsStdClass(): void
  375. {
  376. $this->generator->setClassToExtend('stdClass');
  377. $metadata = $this->generateBookEntityFixture();
  378. $book = $this->newInstance($metadata);
  379. self::assertInstanceOf('stdClass', $book);
  380. $metadata = $this->generateIsbnEmbeddableFixture();
  381. $isbn = $this->newInstance($metadata);
  382. self::assertInstanceOf('stdClass', $isbn);
  383. }
  384. public function testLifecycleCallbacks(): void
  385. {
  386. $metadata = $this->generateBookEntityFixture();
  387. $book = $this->newInstance($metadata);
  388. $reflClass = new ReflectionClass($metadata->name);
  389. self::assertTrue($reflClass->hasMethod('loading'), 'Check for postLoad lifecycle callback.');
  390. self::assertTrue($reflClass->hasMethod('willBeRemoved'), 'Check for preRemove lifecycle callback.');
  391. }
  392. public function testLoadMetadata(): void
  393. {
  394. $embeddedMetadata = $this->generateIsbnEmbeddableFixture();
  395. $metadata = $this->generateBookEntityFixture(['isbn' => $embeddedMetadata]);
  396. $book = $this->newInstance($metadata);
  397. $reflectionService = new RuntimeReflectionService();
  398. $cm = new ClassMetadataInfo($metadata->name);
  399. $cm->initializeReflection($reflectionService);
  400. $driver = $this->createAnnotationDriver();
  401. $driver->loadMetadataForClass($cm->name, $cm);
  402. self::assertEquals($cm->columnNames, $metadata->columnNames);
  403. self::assertEquals($cm->getTableName(), $metadata->getTableName());
  404. self::assertEquals($cm->lifecycleCallbacks, $metadata->lifecycleCallbacks);
  405. self::assertEquals($cm->identifier, $metadata->identifier);
  406. self::assertEquals($cm->idGenerator, $metadata->idGenerator);
  407. self::assertEquals($cm->customRepositoryClassName, $metadata->customRepositoryClassName);
  408. self::assertEquals($cm->embeddedClasses, $metadata->embeddedClasses);
  409. self::assertEquals($cm->isEmbeddedClass, $metadata->isEmbeddedClass);
  410. self::assertEquals(ClassMetadataInfo::FETCH_EXTRA_LAZY, $cm->associationMappings['comments']['fetch']);
  411. $isbn = $this->newInstance($embeddedMetadata);
  412. $cm = new ClassMetadataInfo($embeddedMetadata->name);
  413. $cm->initializeReflection($reflectionService);
  414. $driver->loadMetadataForClass($cm->name, $cm);
  415. self::assertEquals($cm->columnNames, $embeddedMetadata->columnNames);
  416. self::assertEquals($cm->embeddedClasses, $embeddedMetadata->embeddedClasses);
  417. self::assertEquals($cm->isEmbeddedClass, $embeddedMetadata->isEmbeddedClass);
  418. }
  419. public function testLoadPrefixedMetadata(): void
  420. {
  421. $this->generator->setAnnotationPrefix('ORM\\');
  422. $embeddedMetadata = $this->generateIsbnEmbeddableFixture();
  423. $metadata = $this->generateBookEntityFixture(['isbn' => $embeddedMetadata]);
  424. $reader = new AnnotationReader();
  425. $driver = new AnnotationDriver($reader, []);
  426. $book = $this->newInstance($metadata);
  427. $reflectionService = new RuntimeReflectionService();
  428. $cm = new ClassMetadataInfo($metadata->name);
  429. $cm->initializeReflection($reflectionService);
  430. $driver->loadMetadataForClass($cm->name, $cm);
  431. self::assertEquals($cm->columnNames, $metadata->columnNames);
  432. self::assertEquals($cm->getTableName(), $metadata->getTableName());
  433. self::assertEquals($cm->lifecycleCallbacks, $metadata->lifecycleCallbacks);
  434. self::assertEquals($cm->identifier, $metadata->identifier);
  435. self::assertEquals($cm->idGenerator, $metadata->idGenerator);
  436. self::assertEquals($cm->customRepositoryClassName, $metadata->customRepositoryClassName);
  437. $isbn = $this->newInstance($embeddedMetadata);
  438. $cm = new ClassMetadataInfo($embeddedMetadata->name);
  439. $cm->initializeReflection($reflectionService);
  440. $driver->loadMetadataForClass($cm->name, $cm);
  441. self::assertEquals($cm->columnNames, $embeddedMetadata->columnNames);
  442. self::assertEquals($cm->embeddedClasses, $embeddedMetadata->embeddedClasses);
  443. self::assertEquals($cm->isEmbeddedClass, $embeddedMetadata->isEmbeddedClass);
  444. }
  445. /**
  446. * @group DDC-3272
  447. */
  448. public function testMappedSuperclassAnnotationGeneration(): void
  449. {
  450. $metadata = new ClassMetadataInfo($this->namespace . '\EntityGeneratorBook');
  451. $metadata->namespace = $this->namespace;
  452. $metadata->isMappedSuperclass = true;
  453. $this->generator->setAnnotationPrefix('ORM\\');
  454. $this->generator->writeEntityClass($metadata, $this->tmpDir);
  455. $this->newInstance($metadata); // force instantiation (causes autoloading to kick in)
  456. $driver = new AnnotationDriver(new AnnotationReader(), []);
  457. $cm = new ClassMetadataInfo($metadata->name);
  458. $cm->initializeReflection(new RuntimeReflectionService());
  459. $driver->loadMetadataForClass($cm->name, $cm);
  460. self::assertTrue($cm->isMappedSuperclass);
  461. }
  462. /**
  463. * @dataProvider getParseTokensInEntityFileData
  464. */
  465. public function testParseTokensInEntityFile($php, $classes): void
  466. {
  467. $r = new ReflectionObject($this->generator);
  468. $m = $r->getMethod('parseTokensInEntityFile');
  469. $m->setAccessible(true);
  470. $p = $r->getProperty('staticReflection');
  471. $p->setAccessible(true);
  472. $ret = $m->invoke($this->generator, $php);
  473. self::assertEquals($classes, array_keys($p->getValue($this->generator)));
  474. }
  475. /**
  476. * @group DDC-1784
  477. */
  478. public function testGenerateEntityWithSequenceGenerator(): void
  479. {
  480. $metadata = new ClassMetadataInfo($this->namespace . '\DDC1784Entity');
  481. $metadata->namespace = $this->namespace;
  482. $metadata->mapField(['fieldName' => 'id', 'type' => 'integer', 'id' => true]);
  483. $metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_SEQUENCE);
  484. $metadata->setSequenceGeneratorDefinition(
  485. [
  486. 'sequenceName' => 'DDC1784_ID_SEQ',
  487. 'allocationSize' => 1,
  488. 'initialValue' => 2,
  489. ]
  490. );
  491. $this->generator->writeEntityClass($metadata, $this->tmpDir);
  492. $filename = $this->tmpDir . DIRECTORY_SEPARATOR
  493. . $this->namespace . DIRECTORY_SEPARATOR . 'DDC1784Entity.php';
  494. self::assertFileExists($filename);
  495. require_once $filename;
  496. $reflection = new ReflectionProperty($metadata->name, 'id');
  497. $docComment = $reflection->getDocComment();
  498. self::assertStringContainsString('@ORM\Id', $docComment);
  499. self::assertStringContainsString('@ORM\Column(name="id", type="integer")', $docComment);
  500. self::assertStringContainsString('@ORM\GeneratedValue(strategy="SEQUENCE")', $docComment);
  501. self::assertStringContainsString(
  502. '@ORM\SequenceGenerator(sequenceName="DDC1784_ID_SEQ", allocationSize=1, initialValue=2)',
  503. $docComment
  504. );
  505. }
  506. /**
  507. * @group DDC-2079
  508. */
  509. public function testGenerateEntityWithMultipleInverseJoinColumns(): void
  510. {
  511. $metadata = new ClassMetadataInfo($this->namespace . '\DDC2079Entity');
  512. $metadata->namespace = $this->namespace;
  513. $metadata->mapField(['fieldName' => 'id', 'type' => 'integer', 'id' => true]);
  514. $metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_SEQUENCE);
  515. $metadata->mapManyToMany(
  516. [
  517. 'fieldName' => 'centroCustos',
  518. 'targetEntity' => 'DDC2079CentroCusto',
  519. 'joinTable' => [
  520. 'name' => 'unidade_centro_custo',
  521. 'joinColumns' => [
  522. ['name' => 'idorcamento', 'referencedColumnName' => 'idorcamento'],
  523. ['name' => 'idunidade', 'referencedColumnName' => 'idunidade'],
  524. ],
  525. 'inverseJoinColumns' => [
  526. ['name' => 'idcentrocusto', 'referencedColumnName' => 'idcentrocusto'],
  527. ['name' => 'idpais', 'referencedColumnName' => 'idpais'],
  528. ],
  529. ],
  530. ]
  531. );
  532. $this->generator->writeEntityClass($metadata, $this->tmpDir);
  533. $filename = $this->tmpDir . DIRECTORY_SEPARATOR
  534. . $this->namespace . DIRECTORY_SEPARATOR . 'DDC2079Entity.php';
  535. self::assertFileExists($filename);
  536. require_once $filename;
  537. $property = new ReflectionProperty($metadata->name, 'centroCustos');
  538. $docComment = $property->getDocComment();
  539. //joinColumns
  540. self::assertStringContainsString(
  541. '@ORM\JoinColumn(name="idorcamento", referencedColumnName="idorcamento"),',
  542. $docComment
  543. );
  544. self::assertStringContainsString(
  545. '@ORM\JoinColumn(name="idunidade", referencedColumnName="idunidade")',
  546. $docComment
  547. );
  548. //inverseJoinColumns
  549. self::assertStringContainsString(
  550. '@ORM\JoinColumn(name="idcentrocusto", referencedColumnName="idcentrocusto"),',
  551. $docComment
  552. );
  553. self::assertStringContainsString(
  554. '@ORM\JoinColumn(name="idpais", referencedColumnName="idpais")',
  555. $docComment
  556. );
  557. }
  558. /**
  559. * @group DDC-2172
  560. */
  561. public function testGetInheritanceTypeString(): void
  562. {
  563. $reflection = new ReflectionClass('\Doctrine\ORM\Mapping\ClassMetadataInfo');
  564. $method = new ReflectionMethod($this->generator, 'getInheritanceTypeString');
  565. $constants = $reflection->getConstants();
  566. $pattern = '/^INHERITANCE_TYPE_/';
  567. $method->setAccessible(true);
  568. foreach ($constants as $name => $value) {
  569. if (! preg_match($pattern, $name)) {
  570. continue;
  571. }
  572. $expected = preg_replace($pattern, '', $name);
  573. $actual = $method->invoke($this->generator, $value);
  574. self::assertEquals($expected, $actual);
  575. }
  576. $this->expectException(InvalidArgumentException::class);
  577. $this->expectExceptionMessage('Invalid provided InheritanceType: INVALID');
  578. $method->invoke($this->generator, 'INVALID');
  579. }
  580. /**
  581. * @group DDC-2172
  582. */
  583. public function testGetChangeTrackingPolicyString(): void
  584. {
  585. $reflection = new ReflectionClass('\Doctrine\ORM\Mapping\ClassMetadata');
  586. $method = new ReflectionMethod($this->generator, 'getChangeTrackingPolicyString');
  587. $constants = $reflection->getConstants();
  588. $pattern = '/^CHANGETRACKING_/';
  589. $method->setAccessible(true);
  590. foreach ($constants as $name => $value) {
  591. if (! preg_match($pattern, $name)) {
  592. continue;
  593. }
  594. $expected = preg_replace($pattern, '', $name);
  595. $actual = $method->invoke($this->generator, $value);
  596. self::assertEquals($expected, $actual);
  597. }
  598. $this->expectException(InvalidArgumentException::class);
  599. $this->expectExceptionMessage('Invalid provided ChangeTrackingPolicy: INVALID');
  600. $method->invoke($this->generator, 'INVALID');
  601. }
  602. /**
  603. * @group DDC-2172
  604. */
  605. public function testGetIdGeneratorTypeString(): void
  606. {
  607. $reflection = new ReflectionClass('\Doctrine\ORM\Mapping\ClassMetadataInfo');
  608. $method = new ReflectionMethod($this->generator, 'getIdGeneratorTypeString');
  609. $constants = $reflection->getConstants();
  610. $pattern = '/^GENERATOR_TYPE_/';
  611. $method->setAccessible(true);
  612. foreach ($constants as $name => $value) {
  613. if (! preg_match($pattern, $name)) {
  614. continue;
  615. }
  616. if ($name === 'GENERATOR_TYPE_TABLE') {
  617. continue;
  618. }
  619. $expected = preg_replace($pattern, '', $name);
  620. $actual = $method->invoke($this->generator, $value);
  621. self::assertEquals($expected, $actual);
  622. }
  623. $this->expectException(InvalidArgumentException::class);
  624. $this->expectExceptionMessage('Invalid provided IdGeneratorType: INVALID');
  625. $method->invoke($this->generator, 'INVALID');
  626. }
  627. /**
  628. * @dataProvider getEntityTypeAliasDataProvider
  629. * @group DDC-1694
  630. */
  631. public function testEntityTypeAlias(array $field): void
  632. {
  633. $metadata = $this->generateEntityTypeFixture($field);
  634. $path = $this->tmpDir . '/' . $this->namespace . '/EntityType.php';
  635. self::assertFileExists($path);
  636. require_once $path;
  637. $entity = new $metadata->name();
  638. $reflClass = new ReflectionClass($metadata->name);
  639. $type = $field['phpType'];
  640. $name = $field['fieldName'];
  641. $value = $field['value'];
  642. $getter = 'get' . ucfirst($name);
  643. $setter = 'set' . ucfirst($name);
  644. $this->assertPhpDocVarType($type, $reflClass->getProperty($name));
  645. $this->assertPhpDocParamType($type, $reflClass->getMethod($setter));
  646. $this->assertPhpDocReturnType($type, $reflClass->getMethod($getter));
  647. self::assertSame($entity, $entity->{$setter}($value));
  648. self::assertEquals($value, $entity->{$getter}());
  649. }
  650. /**
  651. * @group DDC-2372
  652. */
  653. public function testTraitPropertiesAndMethodsAreNotDuplicated(): void
  654. {
  655. $cmf = new ClassMetadataFactory();
  656. $em = $this->getTestEntityManager();
  657. $cmf->setEntityManager($em);
  658. $user = new DDC2372User();
  659. $metadata = $cmf->getMetadataFor(get_class($user));
  660. $metadata->name = $this->namespace . '\DDC2372User';
  661. $metadata->namespace = $this->namespace;
  662. $this->generator->writeEntityClass($metadata, $this->tmpDir);
  663. self::assertFileExists($this->tmpDir . '/' . $this->namespace . '/DDC2372User.php');
  664. require $this->tmpDir . '/' . $this->namespace . '/DDC2372User.php';
  665. $reflClass = new ReflectionClass($metadata->name);
  666. self::assertFalse($reflClass->hasProperty('address'));
  667. self::assertFalse($reflClass->hasMethod('setAddress'));
  668. self::assertFalse($reflClass->hasMethod('getAddress'));
  669. }
  670. /**
  671. * @group DDC-2372
  672. */
  673. public function testTraitPropertiesAndMethodsAreNotDuplicatedInChildClasses(): void
  674. {
  675. $cmf = new ClassMetadataFactory();
  676. $em = $this->getTestEntityManager();
  677. $cmf->setEntityManager($em);
  678. $user = new DDC2372Admin();
  679. $metadata = $cmf->getMetadataFor(get_class($user));
  680. $metadata->name = $this->namespace . '\DDC2372Admin';
  681. $metadata->namespace = $this->namespace;
  682. $this->generator->writeEntityClass($metadata, $this->tmpDir);
  683. self::assertFileExists($this->tmpDir . '/' . $this->namespace . '/DDC2372Admin.php');
  684. require $this->tmpDir . '/' . $this->namespace . '/DDC2372Admin.php';
  685. $reflClass = new ReflectionClass($metadata->name);
  686. self::assertFalse($reflClass->hasProperty('address'));
  687. self::assertFalse($reflClass->hasMethod('setAddress'));
  688. self::assertFalse($reflClass->hasMethod('getAddress'));
  689. }
  690. /**
  691. * @group DDC-1590
  692. */
  693. public function testMethodsAndPropertiesAreNotDuplicatedInChildClasses(): void
  694. {
  695. $cmf = new ClassMetadataFactory();
  696. $em = $this->getTestEntityManager();
  697. $cmf->setEntityManager($em);
  698. $ns = $this->namespace;
  699. $nsdir = $this->tmpDir . '/' . $ns;
  700. $content = str_replace(
  701. 'namespace Doctrine\Tests\Models\DDC1590',
  702. 'namespace ' . $ns,
  703. file_get_contents(__DIR__ . '/../../Models/DDC1590/DDC1590User.php')
  704. );
  705. $fname = $nsdir . '/DDC1590User.php';
  706. file_put_contents($fname, $content);
  707. require $fname;
  708. $metadata = $cmf->getMetadataFor($ns . '\DDC1590User');
  709. $this->generator->writeEntityClass($metadata, $this->tmpDir);
  710. // class DDC1590User extends DDC1590Entity { ... }
  711. $source = file_get_contents($fname);
  712. // class _DDC1590User extends DDC1590Entity { ... }
  713. $source2 = str_replace('class DDC1590User', 'class _DDC1590User', $source);
  714. $fname2 = $nsdir . '/_DDC1590User.php';
  715. file_put_contents($fname2, $source2);
  716. require $fname2;
  717. // class __DDC1590User { ... }
  718. $source3 = str_replace('class DDC1590User extends DDC1590Entity', 'class __DDC1590User', $source);
  719. $fname3 = $nsdir . '/__DDC1590User.php';
  720. file_put_contents($fname3, $source3);
  721. require $fname3;
  722. // class _DDC1590User extends DDC1590Entity { ... }
  723. $rc2 = new ReflectionClass($ns . '\_DDC1590User');
  724. self::assertTrue($rc2->hasProperty('name'));
  725. self::assertTrue($rc2->hasProperty('id'));
  726. self::assertTrue($rc2->hasProperty('createdAt'));
  727. self::assertTrue($rc2->hasMethod('getName'));
  728. self::assertTrue($rc2->hasMethod('setName'));
  729. self::assertTrue($rc2->hasMethod('getId'));
  730. self::assertFalse($rc2->hasMethod('setId'));
  731. self::assertTrue($rc2->hasMethod('getCreatedAt'));
  732. self::assertTrue($rc2->hasMethod('setCreatedAt'));
  733. // class __DDC1590User { ... }
  734. $rc3 = new ReflectionClass($ns . '\__DDC1590User');
  735. self::assertTrue($rc3->hasProperty('name'));
  736. self::assertFalse($rc3->hasProperty('id'));
  737. self::assertFalse($rc3->hasProperty('createdAt'));
  738. self::assertTrue($rc3->hasMethod('getName'));
  739. self::assertTrue($rc3->hasMethod('setName'));
  740. self::assertFalse($rc3->hasMethod('getId'));
  741. self::assertFalse($rc3->hasMethod('setId'));
  742. self::assertFalse($rc3->hasMethod('getCreatedAt'));
  743. self::assertFalse($rc3->hasMethod('setCreatedAt'));
  744. }
  745. /**
  746. * @group DDC-3304
  747. */
  748. public function testGeneratedMutableEmbeddablesClass(): void
  749. {
  750. $embeddedMetadata = $this->generateTestEmbeddableFixture();
  751. $metadata = $this->generateIsbnEmbeddableFixture(['test' => $embeddedMetadata]);
  752. $isbn = $this->newInstance($metadata);
  753. self::assertTrue(class_exists($metadata->name), 'Class does not exist.');
  754. self::assertFalse(method_exists($metadata->name, '__construct'), 'EntityGeneratorIsbn::__construct present.');
  755. self::assertTrue(method_exists($metadata->name, 'getPrefix'), 'EntityGeneratorIsbn::getPrefix() missing.');
  756. self::assertTrue(method_exists($metadata->name, 'setPrefix'), 'EntityGeneratorIsbn::setPrefix() missing.');
  757. self::assertTrue(method_exists($metadata->name, 'getGroupNumber'), 'EntityGeneratorIsbn::getGroupNumber() missing.');
  758. self::assertTrue(method_exists($metadata->name, 'setGroupNumber'), 'EntityGeneratorIsbn::setGroupNumber() missing.');
  759. self::assertTrue(method_exists($metadata->name, 'getPublisherNumber'), 'EntityGeneratorIsbn::getPublisherNumber() missing.');
  760. self::assertTrue(method_exists($metadata->name, 'setPublisherNumber'), 'EntityGeneratorIsbn::setPublisherNumber() missing.');
  761. self::assertTrue(method_exists($metadata->name, 'getTitleNumber'), 'EntityGeneratorIsbn::getTitleNumber() missing.');
  762. self::assertTrue(method_exists($metadata->name, 'setTitleNumber'), 'EntityGeneratorIsbn::setTitleNumber() missing.');
  763. self::assertTrue(method_exists($metadata->name, 'getCheckDigit'), 'EntityGeneratorIsbn::getCheckDigit() missing.');
  764. self::assertTrue(method_exists($metadata->name, 'setCheckDigit'), 'EntityGeneratorIsbn::setCheckDigit() missing.');
  765. self::assertTrue(method_exists($metadata->name, 'getTest'), 'EntityGeneratorIsbn::getTest() missing.');
  766. self::assertTrue(method_exists($metadata->name, 'setTest'), 'EntityGeneratorIsbn::setTest() missing.');
  767. $isbn->setPrefix(978);
  768. self::assertSame(978, $isbn->getPrefix());
  769. $this->newInstance($embeddedMetadata);
  770. $test = new $embeddedMetadata->name();
  771. $isbn->setTest($test);
  772. self::assertSame($test, $isbn->getTest());
  773. $reflMethod = new ReflectionMethod($metadata->name, 'setTest');
  774. $reflParameters = $reflMethod->getParameters();
  775. self::assertEquals($embeddedMetadata->name, $reflParameters[0]->getType()->getName());
  776. }
  777. /**
  778. * @group DDC-3304
  779. */
  780. public function testGeneratedImmutableEmbeddablesClass(): void
  781. {
  782. $this->generator->setEmbeddablesImmutable(true);
  783. $embeddedMetadata = $this->generateTestEmbeddableFixture();
  784. $metadata = $this->generateIsbnEmbeddableFixture(['test' => $embeddedMetadata]);
  785. $this->loadEntityClass($embeddedMetadata);
  786. $this->loadEntityClass($metadata);
  787. self::assertTrue(class_exists($metadata->name), 'Class does not exist.');
  788. self::assertTrue(method_exists($metadata->name, '__construct'), 'EntityGeneratorIsbn::__construct missing.');
  789. self::assertTrue(method_exists($metadata->name, 'getPrefix'), 'EntityGeneratorIsbn::getPrefix() missing.');
  790. self::assertFalse(method_exists($metadata->name, 'setPrefix'), 'EntityGeneratorIsbn::setPrefix() present.');
  791. self::assertTrue(method_exists($metadata->name, 'getGroupNumber'), 'EntityGeneratorIsbn::getGroupNumber() missing.');
  792. self::assertFalse(method_exists($metadata->name, 'setGroupNumber'), 'EntityGeneratorIsbn::setGroupNumber() present.');
  793. self::assertTrue(method_exists($metadata->name, 'getPublisherNumber'), 'EntityGeneratorIsbn::getPublisherNumber() missing.');
  794. self::assertFalse(method_exists($metadata->name, 'setPublisherNumber'), 'EntityGeneratorIsbn::setPublisherNumber() present.');
  795. self::assertTrue(method_exists($metadata->name, 'getTitleNumber'), 'EntityGeneratorIsbn::getTitleNumber() missing.');
  796. self::assertFalse(method_exists($metadata->name, 'setTitleNumber'), 'EntityGeneratorIsbn::setTitleNumber() present.');
  797. self::assertTrue(method_exists($metadata->name, 'getCheckDigit'), 'EntityGeneratorIsbn::getCheckDigit() missing.');
  798. self::assertFalse(method_exists($metadata->name, 'setCheckDigit'), 'EntityGeneratorIsbn::setCheckDigit() present.');
  799. self::assertTrue(method_exists($metadata->name, 'getTest'), 'EntityGeneratorIsbn::getTest() missing.');
  800. self::assertFalse(method_exists($metadata->name, 'setTest'), 'EntityGeneratorIsbn::setTest() present.');
  801. $test = new $embeddedMetadata->name(1, new DateTime());
  802. $isbn = new $metadata->name($test, 978, 3, 12, 732320, 83);
  803. $reflMethod = new ReflectionMethod($isbn, '__construct');
  804. $reflParameters = $reflMethod->getParameters();
  805. self::assertCount(6, $reflParameters);
  806. self::assertSame($embeddedMetadata->name, $reflParameters[0]->getType()->getName());
  807. self::assertSame('test', $reflParameters[0]->getName());
  808. self::assertFalse($reflParameters[0]->isOptional());
  809. self::assertSame('prefix', $reflParameters[1]->getName());
  810. self::assertFalse($reflParameters[1]->isOptional());
  811. self::assertSame('groupNumber', $reflParameters[2]->getName());
  812. self::assertFalse($reflParameters[2]->isOptional());
  813. self::assertSame('publisherNumber', $reflParameters[3]->getName());
  814. self::assertFalse($reflParameters[3]->isOptional());
  815. self::assertSame('titleNumber', $reflParameters[4]->getName());
  816. self::assertFalse($reflParameters[4]->isOptional());
  817. self::assertSame('checkDigit', $reflParameters[5]->getName());
  818. self::assertFalse($reflParameters[5]->isOptional());
  819. $reflMethod = new ReflectionMethod($test, '__construct');
  820. $reflParameters = $reflMethod->getParameters();
  821. self::assertCount(4, $reflParameters);
  822. self::assertSame('field1', $reflParameters[0]->getName());
  823. self::assertFalse($reflParameters[0]->isOptional());
  824. self::assertSame('DateTime', $reflParameters[1]->getType()->getName());
  825. self::assertSame('field3', $reflParameters[1]->getName());
  826. self::assertFalse($reflParameters[1]->isOptional());
  827. self::assertSame('field2', $reflParameters[2]->getName());
  828. self::assertTrue($reflParameters[2]->isOptional());
  829. self::assertSame('DateTime', $reflParameters[3]->getType()->getName());
  830. self::assertSame('field4', $reflParameters[3]->getName());
  831. self::assertTrue($reflParameters[3]->isOptional());
  832. }
  833. public function testRegenerateEntityClass(): void
  834. {
  835. $metadata = $this->generateBookEntityFixture();
  836. $this->loadEntityClass($metadata);
  837. $className = basename(str_replace('\\', '/', $metadata->name));
  838. $path = $this->tmpDir . '/' . $this->namespace . '/' . $className . '.php';
  839. $classTest = file_get_contents($path);
  840. $this->generator->setRegenerateEntityIfExists(true);
  841. $this->generator->setBackupExisting(false);
  842. $this->generator->writeEntityClass($metadata, $this->tmpDir);
  843. $classNew = file_get_contents($path);
  844. self::assertSame($classTest, $classNew);
  845. }
  846. /**
  847. * @return mixed[]
  848. * @psalm-return list<array{
  849. * fieldName: string,
  850. * phpType: string,
  851. * dbType: string,
  852. * value: mixed
  853. * }>
  854. */
  855. public function getEntityTypeAliasDataProvider(): array
  856. {
  857. return [
  858. [
  859. [
  860. 'fieldName' => 'datetimetz',
  861. 'phpType' => '\\DateTime',
  862. 'dbType' => 'datetimetz',
  863. 'value' => new DateTime(),
  864. ],
  865. ],
  866. [
  867. [
  868. 'fieldName' => 'datetime',
  869. 'phpType' => '\\DateTime',
  870. 'dbType' => 'datetime',
  871. 'value' => new DateTime(),
  872. ],
  873. ],
  874. [
  875. [
  876. 'fieldName' => 'date',
  877. 'phpType' => '\\DateTime',
  878. 'dbType' => 'date',
  879. 'value' => new DateTime(),
  880. ],
  881. ],
  882. [
  883. [
  884. 'fieldName' => 'time',
  885. 'phpType' => '\DateTime',
  886. 'dbType' => 'time',
  887. 'value' => new DateTime(),
  888. ],
  889. ],
  890. [
  891. [
  892. 'fieldName' => 'object',
  893. 'phpType' => '\stdClass',
  894. 'dbType' => 'object',
  895. 'value' => new stdClass(),
  896. ],
  897. ],
  898. [
  899. [
  900. 'fieldName' => 'bigint',
  901. 'phpType' => 'int',
  902. 'dbType' => 'bigint',
  903. 'value' => 11,
  904. ],
  905. ],
  906. [
  907. [
  908. 'fieldName' => 'smallint',
  909. 'phpType' => 'int',
  910. 'dbType' => 'smallint',
  911. 'value' => 22,
  912. ],
  913. ],
  914. [
  915. [
  916. 'fieldName' => 'text',
  917. 'phpType' => 'string',
  918. 'dbType' => 'text',
  919. 'value' => 'text',
  920. ],
  921. ],
  922. [
  923. [
  924. 'fieldName' => 'blob',
  925. 'phpType' => 'string',
  926. 'dbType' => 'blob',
  927. 'value' => 'blob',
  928. ],
  929. ],
  930. [
  931. [
  932. 'fieldName' => 'guid',
  933. 'phpType' => 'string',
  934. 'dbType' => 'guid',
  935. 'value' => '00000000-0000-0000-0000-000000000001',
  936. ],
  937. ],
  938. [
  939. [
  940. 'fieldName' => 'decimal',
  941. 'phpType' => 'string',
  942. 'dbType' => 'decimal',
  943. 'value' => '12.34',
  944. ],
  945. ],
  946. ];
  947. }
  948. /**
  949. * @psalm-return list<array{string, array{string}}>
  950. */
  951. public function getParseTokensInEntityFileData(): array
  952. {
  953. return [
  954. [
  955. '<?php namespace Foo\Bar; class Baz {}',
  956. ['Foo\Bar\Baz'],
  957. ],
  958. [
  959. '<?php namespace Foo\Bar; use Foo; class Baz {}',
  960. ['Foo\Bar\Baz'],
  961. ],
  962. [
  963. '<?php namespace /*Comment…

Large files files are truncated, but you can click here to view the full file