From 7e930cfe7040c2eaed4a5a29924e393d2a9a0f37 Mon Sep 17 00:00:00 2001 From: Alain Date: Tue, 23 Jul 2019 23:17:39 +0200 Subject: [PATCH 1/6] auto-document : first raw version of this feature Now with good config and new method addFIxtureEntity can look into the object and extract wanted properties for the doc --- composer.json | 3 +- composer.lock | 129 +++++++++++++++++- src/DependencyInjection/Configuration.php | 12 +- .../FixturesDocumentationExtension.php | 5 + src/Model/Documentation.php | 29 +++- src/Resources/config/services.yml | 1 + src/Service/FixturesDocumentationManager.php | 9 +- 7 files changed, 178 insertions(+), 10 deletions(-) diff --git a/composer.json b/composer.json index 7d3a26e..edf798d 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,8 @@ "doctrine/orm": "^2.5", "doctrine/doctrine-bundle": "^1.8", "doctrine/doctrine-fixtures-bundle": "^2.4|^3.0", - "ext-json": "*" + "ext-json": "*", + "symfony/property-access": "^4.3" }, "require-dev": { "phpunit/phpunit": "^7.0", diff --git a/composer.lock b/composer.lock index 4b0d11c..46d44a1 100644 --- a/composer.lock +++ b/composer.lock @@ -1,10 +1,10 @@ { "_readme": [ "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "e9a8ff3c1dfbc5f007661d6f531c23cf", + "content-hash": "e82c558a188eaf45db100ec63a4fb8a4", "packages": [ { "name": "doctrine/annotations", @@ -2420,6 +2420,64 @@ "homepage": "https://symfony.com", "time": "2019-06-26T14:26:16+00:00" }, + { + "name": "symfony/inflector", + "version": "v4.3.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/inflector.git", + "reference": "889dc28cb6350ddb302fe9b8c796e4e6eb836856" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/inflector/zipball/889dc28cb6350ddb302fe9b8c796e4e6eb836856", + "reference": "889dc28cb6350ddb302fe9b8c796e4e6eb836856", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/polyfill-ctype": "~1.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.3-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Inflector\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Inflector Component", + "homepage": "https://symfony.com", + "keywords": [ + "inflection", + "pluralize", + "singularize", + "string", + "symfony", + "words" + ], + "time": "2019-05-30T09:28:08+00:00" + }, { "name": "symfony/mime", "version": "v4.3.2", @@ -2820,6 +2878,73 @@ "homepage": "https://symfony.com", "time": "2019-05-30T16:10:05+00:00" }, + { + "name": "symfony/property-access", + "version": "v4.3.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/property-access.git", + "reference": "18ea48862a39e364927e71b9e4942af3c1a1cb8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/property-access/zipball/18ea48862a39e364927e71b9e4942af3c1a1cb8c", + "reference": "18ea48862a39e364927e71b9e4942af3c1a1cb8c", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/inflector": "~3.4|~4.0" + }, + "require-dev": { + "symfony/cache": "~3.4|~4.0" + }, + "suggest": { + "psr/cache-implementation": "To cache access methods." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.3-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\PropertyAccess\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony PropertyAccess Component", + "homepage": "https://symfony.com", + "keywords": [ + "access", + "array", + "extraction", + "index", + "injection", + "object", + "property", + "property path", + "reflection" + ], + "time": "2019-06-06T10:05:02+00:00" + }, { "name": "symfony/routing", "version": "v4.3.2", diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index 842d60e..82b1505 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -21,11 +21,17 @@ public function getConfigTreeBuilder(): TreeBuilder $rootNode ->children() ->scalarNode('title') - ->defaultValue('Fixtures documentation')->end() + ->defaultValue('Fixtures documentation') + ->end() ->arrayNode('reloadCommands') ->scalarPrototype()->end() - ->end() - ->end(); + ->end() + ->arrayNode('configEntities') + ->arrayPrototype() + ->scalarPrototype()->end() + ->end() + ->end() + ->end(); return $treeBuilder; } diff --git a/src/DependencyInjection/FixturesDocumentationExtension.php b/src/DependencyInjection/FixturesDocumentationExtension.php index ddd8afa..06062e9 100644 --- a/src/DependencyInjection/FixturesDocumentationExtension.php +++ b/src/DependencyInjection/FixturesDocumentationExtension.php @@ -33,6 +33,11 @@ public function load(array $configs, ContainerBuilder $container): void $config['reloadCommands'] ); + $container->setParameter( + 'adlarge_fixtures_documentation.configEntities', + $config['configEntities'] + ); + $loader = new Loader\YamlFileLoader( $container, new FileLocator(__DIR__ . '/../Resources/config') diff --git a/src/Model/Documentation.php b/src/Model/Documentation.php index ae37e19..4f3ef03 100644 --- a/src/Model/Documentation.php +++ b/src/Model/Documentation.php @@ -5,7 +5,10 @@ namespace Adlarge\FixturesDocumentationBundle\Model; use Adlarge\FixturesDocumentationBundle\Exception\DuplicateFixtureException; +use Symfony\Component\PropertyAccess\PropertyAccess; use TypeError; +use function array_key_exists; + class Documentation { @@ -15,15 +18,19 @@ class Documentation * @var Section[] */ private $sections = []; - + /** + * @var array + */ + private $configEntities; /** * Documentation constructor. * * @param string $jsonString * @throws DuplicateFixtureException */ - public function __construct(string $jsonString = null) + public function __construct(array $configEntities, string $jsonString = null) { + $this->configEntities = $configEntities; if ($jsonString) { $this->init($jsonString); } @@ -74,6 +81,24 @@ public function addFixture(string $sectionTitle, array $fixture): self return $this; } + public function addFixtureEntity(object $entity): self + { + $className = (new \ReflectionClass($entity))->getShortName(); + if (array_key_exists($className, $this->configEntities)) { + $propertyAccessor = PropertyAccess::createPropertyAccessor(); + /** @var array $properties */ + $properties = $this->configEntities[$className]; + $fixture = []; + foreach ($properties as $property) { + $value = $propertyAccessor->getValue($entity, $property); + $fixture[$property] = $value; + } + + $this->addFixture($className . 's', $fixture); + } + return $this; + } + /** * Reset the documentation by removing all sections. * diff --git a/src/Resources/config/services.yml b/src/Resources/config/services.yml index 8262f1a..266ad0a 100644 --- a/src/Resources/config/services.yml +++ b/src/Resources/config/services.yml @@ -14,6 +14,7 @@ services: arguments: $projectDir: '%kernel.project_dir%' $reloadCommands: '%adlarge_fixtures_documentation.reloadCommands%' + $configEntities: '%adlarge_fixtures_documentation.configEntities%' # Listeners Adlarge\FixturesDocumentationBundle\EventListener\FixturesDocumentationListener: diff --git a/src/Service/FixturesDocumentationManager.php b/src/Service/FixturesDocumentationManager.php index b0b5246..cfb6201 100644 --- a/src/Service/FixturesDocumentationManager.php +++ b/src/Service/FixturesDocumentationManager.php @@ -24,6 +24,10 @@ class FixturesDocumentationManager * @var array */ private $reloadCommands; + /** + * @var array + */ + private $configEntities; /** * @var Documentation */ @@ -37,11 +41,12 @@ class FixturesDocumentationManager * * @throws DuplicateFixtureException */ - public function __construct(string $projectDir, array $reloadCommands) + public function __construct(string $projectDir, array $reloadCommands, array $configEntities) { $this->projectDir = $projectDir; $this->jsonFilePath = $this->projectDir . '/var/' . self::FILE_NAME; $this->reloadCommands = $reloadCommands; + $this->configEntities = $configEntities; $this->initDocumentation(); } @@ -55,7 +60,7 @@ protected function initDocumentation(): void if ($this->jsonFilePath && is_file($this->jsonFilePath)) { $jsonString = file_get_contents($this->jsonFilePath); } - $this->documentation = new Documentation($jsonString); + $this->documentation = new Documentation($this->configEntities, $jsonString); } /** * Get current Documentation. From b178e3d9e19f87efe0146a27292ca3f581366f3d Mon Sep 17 00:00:00 2001 From: Alain Date: Wed, 24 Jul 2019 23:07:01 +0200 Subject: [PATCH 2/6] tests: fix failing tests and add new ones for this new method --- .gitignore | 2 + src/Model/Documentation.php | 17 ++- tests/Model/DocumentationTest.php | 115 ++++++++++++++++-- .../FixturesDocumentationManagerTest.php | 18 ++- tests/helpers/Model/Category.php | 8 ++ tests/helpers/Model/Product.php | 46 +++++++ tests/helpers/Model/ProductComplex.php | 60 +++++++++ tests/helpers/Model/ProductPublic.php | 12 ++ 8 files changed, 260 insertions(+), 18 deletions(-) create mode 100644 tests/helpers/Model/Category.php create mode 100644 tests/helpers/Model/Product.php create mode 100644 tests/helpers/Model/ProductComplex.php create mode 100644 tests/helpers/Model/ProductPublic.php diff --git a/.gitignore b/.gitignore index 7a72d69..492afb8 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,5 @@ tests/_output/ tests/.phpunit.result.cache tests/clover.xml + +tests/coverage\.xml diff --git a/src/Model/Documentation.php b/src/Model/Documentation.php index 4f3ef03..4008012 100644 --- a/src/Model/Documentation.php +++ b/src/Model/Documentation.php @@ -81,6 +81,17 @@ public function addFixture(string $sectionTitle, array $fixture): self return $this; } + /** + * Add a fixture to the documentation when passing directly the entity. + * Use configEntites and their property to create the array of value + * to pass to addFixture method + * + * @param object $entity + * + * @return Documentation + * + * @throws DuplicateFixtureException + */ public function addFixtureEntity(object $entity): self { $className = (new \ReflectionClass($entity))->getShortName(); @@ -91,10 +102,12 @@ public function addFixtureEntity(object $entity): self $fixture = []; foreach ($properties as $property) { $value = $propertyAccessor->getValue($entity, $property); - $fixture[$property] = $value; + if (is_scalar($value)) { + $fixture[$property] = $value; + } } - $this->addFixture($className . 's', $fixture); + $this->addFixture($className, $fixture); } return $this; } diff --git a/tests/Model/DocumentationTest.php b/tests/Model/DocumentationTest.php index 5a94b42..641d17a 100644 --- a/tests/Model/DocumentationTest.php +++ b/tests/Model/DocumentationTest.php @@ -5,9 +5,14 @@ use org\bovigo\vfs\vfsStreamDirectory; use PHPUnit\Framework\TestCase; use Adlarge\FixturesDocumentationBundle\Model\Documentation; -use \Adlarge\FixturesDocumentationBundle\Exception\DuplicateFixtureException; +use Adlarge\FixturesDocumentationBundle\Exception\DuplicateFixtureException; use TypeError; use org\bovigo\vfs\vfsStream; +use Mockery; +use Adlarge\FixturesDocumentationBundle\helpers\Model\Product; +use Adlarge\FixturesDocumentationBundle\helpers\Model\ProductPublic; +use Adlarge\FixturesDocumentationBundle\helpers\Model\ProductComplex; +use Adlarge\FixturesDocumentationBundle\helpers\Model\Category; class DocumentationTest extends TestCase { @@ -21,7 +26,7 @@ public function setUp(): void public function tearDown(): void { - $documentation = new Documentation(); + $documentation = new Documentation([]); $documentation->reset(); } @@ -30,7 +35,7 @@ public function tearDown(): void */ public function testAddFixture(): void { - $documentation = new Documentation(); + $documentation = new Documentation([]); $documentation->addFixture('fixtures', ['id' => 1, 'name' => 'fixture1']); @@ -43,7 +48,7 @@ public function testAddFixture(): void */ public function testAddFixtureWithSameSection(): void { - $documentation = new Documentation(); + $documentation = new Documentation([]); $documentation->addFixture('fixtures', ['id' => 1, 'name' => 'fixture1']); $documentation->addFixture('fixtures', ['id' => 2, 'name' => 'fixture2']); @@ -56,7 +61,7 @@ public function testAddFixtureWithSameSection(): void */ public function testAddFixtureWithDifferentSection(): void { - $documentation = new Documentation(); + $documentation = new Documentation([]); $documentation->addFixture('fixtures', ['id' => 1, 'name' => 'fixture1']); $documentation->addFixture('other', ['id' => 1, 'name' => 'fixture1']); @@ -71,17 +76,107 @@ public function testAddFixtureWithMultidimensionalArray(): void { $this->expectException(TypeError::class); - $documentation = new Documentation(); + $documentation = new Documentation([]); $documentation->addFixture('fixtures', ['id' => 1, 'array' => ['name' => 'fixture1', 'color' => 'red']]); } + /** + * @throws DuplicateFixtureException + */ + public function testAddFixtureEntity(): void + { + $mockDocumentation = Mockery::mock( + Documentation::class, + [ + ['Product' => ['name', 'category']] + ] + ) + ->makePartial(); + + $mockDocumentation->shouldReceive('addFixture') + ->once() + ->with('Product', [ + 'name' => 'product 1', + 'category' => 'category 1' + ]) + ->andReturn($mockDocumentation); + + $product = (new Product()) + ->setId(1) + ->setName('product 1') + ->setCategory('category 1'); + + $mockDocumentation->addFixtureEntity($product); + $this->assertCount(0, $mockDocumentation->getSections()); + } + + /** + * @throws DuplicateFixtureException + */ + public function testAddFixtureEntityWithPublicProperties(): void + { + $mockDocumentation = Mockery::mock( + Documentation::class, + [ + ['ProductPublic' => ['name', 'category']] + ] + ) + ->makePartial(); + + $mockDocumentation->shouldReceive('addFixture') + ->once() + ->with('ProductPublic', [ + 'name' => 'product 1', + 'category' => 'category 1' + ]) + ->andReturn($mockDocumentation); + + $product = new ProductPublic(); + $product->id = 1; + $product->name = 'product 1'; + $product->category = 'category 1'; + + $mockDocumentation->addFixtureEntity($product); + $this->assertCount(0, $mockDocumentation->getSections()); + } + + /** + * @throws DuplicateFixtureException + */ + public function testAddFixtureEntityWithComplexProperties(): void + { + $mockDocumentation = Mockery::mock( + Documentation::class, + [ + ['ProductComplex' => ['name', 'category', 'tags']] + ] + ) + ->makePartial(); + + $mockDocumentation->shouldReceive('addFixture') + ->once() + ->with('ProductComplex', [ + 'name' => 'product 1' + ]) + ->andReturn($mockDocumentation); + + $product = (new ProductComplex()) + ->setId(1) + ->setName('product 1') + ->setCategory(new Category()) + ->setTags(['tag1', 'tag2', 'tag3']); + + $mockDocumentation->addFixtureEntity($product); + $this->assertCount(0, $mockDocumentation->getSections()); + } + /** * @throws DuplicateFixtureException */ public function testReset(): void { - $documentation = new Documentation(); + $documentation = new Documentation([]); $documentation->addFixture('fixtures', ['id' => 1, 'name' => 'fixture1']); $this->assertCount(1, $documentation->getSections()); @@ -95,7 +190,7 @@ public function testReset(): void */ public function testToJson(): void { - $documentation = new Documentation(); + $documentation = new Documentation([]); $documentation->addFixture('some', ['id' => 1, 'name' => 'fixture1']); $documentation->addFixture('some', ['id' => 2, 'name' => 'fixture2']); @@ -113,7 +208,7 @@ public function testInit(): void { $jsonString = '{"some":{"fixtures":[{"id":1,"name":"fixture1"},{"id":2,"name":"fixture2"}]},"others":{"fixtures":[{"id":1,"pseudo":"autre2"}]}}'; - $documentation = new Documentation($jsonString); + $documentation = new Documentation([], $jsonString); $this->assertCount(2, $documentation->getSections()); } @@ -124,7 +219,7 @@ public function testInitEmpty(): void { $jsonString = null; - $documentation = new Documentation($jsonString); + $documentation = new Documentation([], $jsonString); $this->assertCount(0, $documentation->getSections()); } } diff --git a/tests/Service/FixturesDocumentationManagerTest.php b/tests/Service/FixturesDocumentationManagerTest.php index 50f87ff..95c3e91 100644 --- a/tests/Service/FixturesDocumentationManagerTest.php +++ b/tests/Service/FixturesDocumentationManagerTest.php @@ -39,7 +39,8 @@ public function testGetDocumentation(): void vfsStream::newDirectory('var')->at($this->root); $documentationManager = new FixturesDocumentationManager( $this->root->url(), - ['dummyCommand'] + ['dummyCommand'], + [] ); $this->assertInstanceOf(Documentation::class, $documentationManager->getDocumentation()); @@ -53,7 +54,8 @@ public function testReset(): void vfsStream::newDirectory('var')->at($this->root); $documentationManager = new FixturesDocumentationManager( $this->root->url(), - ['dummyCommand'] + ['dummyCommand'], + [] ); file_put_contents( @@ -73,7 +75,8 @@ public function testSave(): void vfsStream::newDirectory('var')->at($this->root); $documentationManager = new FixturesDocumentationManager( $this->root->url(), - ['dummyCommand'] + ['dummyCommand'], + [] ); $documentationManager->save(); @@ -93,7 +96,8 @@ public function testInitDocumentation(): void ); $documentationManager = new FixturesDocumentationManager( $this->root->url(), - ['dummyCommand'] + ['dummyCommand'], + [] ); $this->assertInstanceOf(Documentation::class, $documentationManager->getDocumentation()); @@ -108,7 +112,8 @@ public function testReloadWithUnknownCommand(): void $documentationManager = new FixturesDocumentationManager( $this->root->url(), - ['unknowCommand'] + ['unknowCommand'], + [] ); $documentationManager->reload(); @@ -131,7 +136,8 @@ public function testReload(): void $documentationManager = new FixturesDocumentationManager( $this->root->url(), - ['workingCommand'] + ['workingCommand'], + [] ); $this->assertSame(1, $documentationManager->reload()); diff --git a/tests/helpers/Model/Category.php b/tests/helpers/Model/Category.php new file mode 100644 index 0000000..0735d69 --- /dev/null +++ b/tests/helpers/Model/Category.php @@ -0,0 +1,8 @@ +name = $name; + return $this; + } + + public function setId(int $id): self + { + $this->id = $id; + return $this; + } + + public function setCategory(string $category): self + { + $this->category = $category; + return $this; + } + + public function getId(): int + { + return $this->id; + } + + public function getName(): string + { + return $this->name; + } + + public function getCategory(): string + { + return $this->category; + } + +} \ No newline at end of file diff --git a/tests/helpers/Model/ProductComplex.php b/tests/helpers/Model/ProductComplex.php new file mode 100644 index 0000000..271d751 --- /dev/null +++ b/tests/helpers/Model/ProductComplex.php @@ -0,0 +1,60 @@ +name = $name; + return $this; + } + + public function setId(int $id): self + { + $this->id = $id; + return $this; + } + + public function setCategory(Category $category): self + { + $this->category = $category; + return $this; + } + + public function getId(): int + { + return $this->id; + } + + public function getName(): string + { + return $this->name; + } + + public function getCategory(): Category + { + return $this->category; + } + + public function setTags(array $tags): self + { + $this->tags = $tags; + return $this; + } + + public function getTags(): array + { + return $this->tags; + } +} \ No newline at end of file diff --git a/tests/helpers/Model/ProductPublic.php b/tests/helpers/Model/ProductPublic.php new file mode 100644 index 0000000..88c06cf --- /dev/null +++ b/tests/helpers/Model/ProductPublic.php @@ -0,0 +1,12 @@ + Date: Wed, 24 Jul 2019 23:20:06 +0200 Subject: [PATCH 3/6] Update documentation for new method --- README.md | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/README.md b/README.md index 7f37529..a5014aa 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,14 @@ You can define vars by creating the file `config/packages/dev/adlarge_fixtures_d reloadCommands: - php bin/console doctrine:fixtures:load - .... + entities: + Product: + - id + - name + - category + Customer: + - firstname + - lastname Then you can install assets : @@ -51,6 +59,8 @@ Then you can install assets : To add fixtures to your documentation you have to get the manager in your fixtures file : +### Adding fixtures manually + ```php class AppFixtures extends Fixture { @@ -98,6 +108,83 @@ class AppFixtures extends Fixture } ``` +### Adding fixtures with configuration and entity + +If you provided the good entity name and properties in configuration `entities` you can +use the method `addFIxtureEntity`. +It only parse scalar properties and can check public properties as well as private ones with a getter (property, getProperty(), hasProperty(), isProperty()). +It will ignore non scalar properties as well as non existing ones. + +With the following configuration : + +```yaml + adlarge_fixtures_documentation: + title: 'Your title' + reloadCommands: + - php bin/console doctrine:fixtures:load + entities: + Product: + - name + - category + Customer: + - firstname + - lastname + - email +``` + +You can use + +```php +class AppFixtures extends Fixture + { + /** + * @var FixturesDocumentationManager + */ + private $documentationManager; + + /** + * AppFixtures constructor. + * + * @param FixturesDocumentationManager $documentationManager + */ + public function __construct(FixturesDocumentationManager $documentationManager) + { + $this->documentationManager = $documentationManager; + } + + /** + * @param ObjectManager $manager + * + * @throws DuplicateFixtureException + */ + public function load(ObjectManager $manager) + { + $doc = $this->documentationManager->getDocumentation(); + + $product = (new Product()) + ->setName("Product 1") + ->setCategory("Category 1"); + + $doc->addFixtureEntity($product); + + $product = (new Product()) + ->setName("Product 2") + ->setCategory("Category 2"); + + $doc->addFixtureEntity($product); + + $customer = (new Customer()) + ->setFirstname('John') + ->setLastname('Doe') + ->setEmail('john.doe@test.fr'); + + $doc->addFixtureEntity($customer); + + $manager->flush(); + } + } +``` + Then to generate the doc you only have to run : php bin/console doctrine:fixtures:load From f55bbfeac177bec68ba5512cbf6d6dfe07d551ca Mon Sep 17 00:00:00 2001 From: Alain Date: Wed, 24 Jul 2019 23:23:44 +0200 Subject: [PATCH 4/6] addFixtureEntity: add the case with non existing property --- src/Model/Documentation.php | 13 +++++++++---- tests/Model/DocumentationTest.php | 29 +++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/src/Model/Documentation.php b/src/Model/Documentation.php index 4008012..ce81c52 100644 --- a/src/Model/Documentation.php +++ b/src/Model/Documentation.php @@ -6,6 +6,7 @@ use Adlarge\FixturesDocumentationBundle\Exception\DuplicateFixtureException; use Symfony\Component\PropertyAccess\PropertyAccess; +use Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException; use TypeError; use function array_key_exists; @@ -101,10 +102,14 @@ public function addFixtureEntity(object $entity): self $properties = $this->configEntities[$className]; $fixture = []; foreach ($properties as $property) { - $value = $propertyAccessor->getValue($entity, $property); - if (is_scalar($value)) { - $fixture[$property] = $value; - } + try { + $value = $propertyAccessor->getValue($entity, $property); + if (is_scalar($value)) { + $fixture[$property] = $value; + } + } catch (NoSuchPropertyException $exception) { + // ignore this exception silently + } } $this->addFixture($className, $fixture); diff --git a/tests/Model/DocumentationTest.php b/tests/Model/DocumentationTest.php index 641d17a..c3e5b95 100644 --- a/tests/Model/DocumentationTest.php +++ b/tests/Model/DocumentationTest.php @@ -171,6 +171,35 @@ public function testAddFixtureEntityWithComplexProperties(): void $this->assertCount(0, $mockDocumentation->getSections()); } + /** + * @throws DuplicateFixtureException + */ + public function testAddFixtureEntityWithNonExistingProperty(): void + { + $mockDocumentation = Mockery::mock( + Documentation::class, + [ + ['Product' => ['names', 'category']] + ] + ) + ->makePartial(); + + $mockDocumentation->shouldReceive('addFixture') + ->once() + ->with('Product', [ + 'category' => 'category 1' + ]) + ->andReturn($mockDocumentation); + + $product = (new Product()) + ->setId(1) + ->setName('product 1') + ->setCategory('category 1'); + + $mockDocumentation->addFixtureEntity($product); + $this->assertCount(0, $mockDocumentation->getSections()); + } + /** * @throws DuplicateFixtureException */ From 72386f8fc7af8b8b662844ca640e366e6f8b4cf9 Mon Sep 17 00:00:00 2001 From: Alain Date: Thu, 25 Jul 2019 20:41:13 +0200 Subject: [PATCH 5/6] tests: add a way to quickly test with php7.1 --- Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile b/Makefile index b349496..553031e 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,8 @@ test: vendor/bin/phpunit tests +test7.1: + /usr/bin/php7.1 vendor/bin/phpunit tests + coverage: vendor/bin/phpunit --configuration tests/php-unit.xml --coverage-html tests/_output tests \ No newline at end of file From 2cbb09a3733eedd8a71b9ce4563dccee3973cdfa Mon Sep 17 00:00:00 2001 From: Alain Date: Thu, 25 Jul 2019 20:41:35 +0200 Subject: [PATCH 6/6] some fix and fix tests on php7.1 --- README.md | 2 +- src/Model/Documentation.php | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index a5014aa..551ce59 100644 --- a/README.md +++ b/README.md @@ -111,7 +111,7 @@ class AppFixtures extends Fixture ### Adding fixtures with configuration and entity If you provided the good entity name and properties in configuration `entities` you can -use the method `addFIxtureEntity`. +use the method `addFixtureEntity`. It only parse scalar properties and can check public properties as well as private ones with a getter (property, getProperty(), hasProperty(), isProperty()). It will ignore non scalar properties as well as non existing ones. diff --git a/src/Model/Documentation.php b/src/Model/Documentation.php index ce81c52..97430d0 100644 --- a/src/Model/Documentation.php +++ b/src/Model/Documentation.php @@ -8,9 +8,10 @@ use Symfony\Component\PropertyAccess\PropertyAccess; use Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException; use TypeError; +use ReflectionClass; +use ReflectionException; use function array_key_exists; - class Documentation { /** @@ -26,7 +27,9 @@ class Documentation /** * Documentation constructor. * + * @param array $configEntities * @param string $jsonString + * * @throws DuplicateFixtureException */ public function __construct(array $configEntities, string $jsonString = null) @@ -87,15 +90,16 @@ public function addFixture(string $sectionTitle, array $fixture): self * Use configEntites and their property to create the array of value * to pass to addFixture method * - * @param object $entity + * @param mixed $entity * * @return Documentation * * @throws DuplicateFixtureException + * @throws ReflectionException */ - public function addFixtureEntity(object $entity): self + public function addFixtureEntity($entity): self { - $className = (new \ReflectionClass($entity))->getShortName(); + $className = (new ReflectionClass($entity))->getShortName(); if (array_key_exists($className, $this->configEntities)) { $propertyAccessor = PropertyAccess::createPropertyAccessor(); /** @var array $properties */