Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 67a7731

Browse files
authored
fix: misc fixes when creating objects in data provider (#972)
1 parent a0857c5 commit 67a7731

10 files changed

Lines changed: 216 additions & 159 deletions

.github/workflows/ci.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,8 +221,13 @@ jobs:
221221
runs-on: ubuntu-latest
222222
env:
223223
DATABASE_URL: 'mysql://root:root@localhost:3306/foundry?serverVersion=5.7.42'
224-
MONGO_URL: ''
224+
MONGO_URL: 'mongodb://127.0.0.1:27017/dbName?compressors=disabled&gssapiServiceName=mongodb'
225225
USE_DAMA_DOCTRINE_TEST_BUNDLE: 1
226+
services:
227+
mongo:
228+
image: 'mongo:4'
229+
ports:
230+
- 27017:27017
226231
steps:
227232
- name: Checkout code
228233
uses: actions/checkout@v3

src/Persistence/PersistentObjectFactory.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -510,8 +510,8 @@ private function throwIfCannotCreateObject(): void
510510
}
511511

512512
if (
513-
!$configuration->isPersistenceAvailable()
514-
|| $this instanceof PersistentProxyObjectFactory
513+
$this instanceof PersistentProxyObjectFactory
514+
|| !$this->isPersisting()
515515
) {
516516
return;
517517
}

src/Persistence/PersistentProxyObjectFactory.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ abstract public static function class(): string;
3434
final public function create(callable|array $attributes = []): object
3535
{
3636
$configuration = Configuration::instance();
37-
if ($configuration->inADataProvider()) {
37+
if ($configuration->inADataProvider() && $this->isPersisting()) {
3838
return ProxyGenerator::wrapFactory($this, $attributes);
3939
}
4040

src/Persistence/ProxyGenerator.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Symfony\Component\VarExporter\LazyObjectInterface;
1616
use Symfony\Component\VarExporter\LazyProxyTrait;
1717
use Symfony\Component\VarExporter\ProxyHelper;
18+
use Zenstruck\Foundry\Configuration;
1819
use Zenstruck\Foundry\Factory;
1920

2021
/**
@@ -56,7 +57,13 @@ public static function wrap(object $object): Proxy
5657
*/
5758
public static function wrapFactory(PersistentProxyObjectFactory $factory, callable|array $attributes): Proxy
5859
{
59-
return self::generateClassFor($factory)::createLazyProxy(static fn() => unproxy($factory->create($attributes))); // @phpstan-ignore-line
60+
return self::generateClassFor($factory)::createLazyProxy(static function () use ($factory, $attributes) { // @phpstan-ignore staticMethod.notFound
61+
if (Configuration::instance()->inADataProvider() && $factory->isPersisting()) {
62+
throw new \LogicException('Cannot access to a persisted object from a data provider.');
63+
}
64+
65+
return unproxy($factory->create($attributes));
66+
});
6067
}
6168

6269
/**

tests/Integration/DataProvider/DataProviderInUnitTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,21 @@ public static function createObjectWithPersistentObjectFactoryInDataProvider():
6767
yield 'proxy persistent factory' => [GenericProxyEntityFactory::createOne(), new GenericEntity('default1')];
6868
}
6969

70+
#[Test]
71+
#[DataProvider('useGetterOnObjectCreatedInDataProvider')]
72+
public function assert_it_can_use_getter_on_object_created_in_data_provider(string $providedData, mixed $expectedData): void
73+
{
74+
self::assertEquals($expectedData, unproxy($providedData));
75+
}
76+
77+
public static function useGetterOnObjectCreatedInDataProvider(): iterable
78+
{
79+
yield 'object factory' => [Object1Factory::createOne()->getProp1(), 'value1-constructor'];
80+
yield 'persistent factory' => [GenericEntityFactory::createOne()->getProp1(), 'default1'];
81+
yield 'proxy persistent factory' => [GenericProxyEntityFactory::createOne()->getProp1(), 'default1'];
82+
yield 'proxy persistent factory using many' => [GenericProxyEntityFactory::createMany(1)[0]->getProp1(), 'default1'];
83+
}
84+
7085
#[Test]
7186
#[DataProvider('createObjectUsingFakerInDataProvider')]
7287
public function assert_it_can_create_use_faker_in_data_provider(mixed $providedData, string $expected): void

tests/Integration/DataProvider/DataProviderWithNonProxyFactoryInKernelTestCaseTest.php

Lines changed: 0 additions & 54 deletions
This file was deleted.
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the zenstruck/foundry package.
7+
*
8+
* (c) Kevin Bond <[email protected]>
9+
*
10+
* For the full copyright and license information, please view the LICENSE
11+
* file that was distributed with this source code.
12+
*/
13+
14+
namespace Zenstruck\Foundry\Tests\Integration\DataProvider;
15+
16+
use PHPUnit\Framework\Attributes\DataProvider;
17+
use PHPUnit\Framework\Attributes\IgnoreDeprecations;
18+
use PHPUnit\Framework\Attributes\RequiresPhpunit;
19+
use PHPUnit\Framework\Attributes\RequiresPhpunitExtension;
20+
use PHPUnit\Framework\Attributes\Test;
21+
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
22+
use Zenstruck\Foundry\Persistence\PersistentObjectFactory;
23+
use Zenstruck\Foundry\Persistence\PersistentProxyObjectFactory;
24+
use Zenstruck\Foundry\Persistence\Proxy;
25+
use Zenstruck\Foundry\PHPUnit\FoundryExtension;
26+
use Zenstruck\Foundry\Test\Factories;
27+
use Zenstruck\Foundry\Test\ResetDatabase;
28+
use Zenstruck\Foundry\Tests\Fixture\Factories\Object1Factory;
29+
use Zenstruck\Foundry\Tests\Fixture\Model\GenericModel;
30+
31+
use function Zenstruck\Foundry\Persistence\unproxy;
32+
33+
/**
34+
* @author Nicolas PHILIPPE <[email protected]>
35+
* @requires PHPUnit >=11.4
36+
*/
37+
#[RequiresPhpunit('>=11.4')]
38+
#[RequiresPhpunitExtension(FoundryExtension::class)]
39+
#[IgnoreDeprecations]
40+
abstract class DataProviderWithPersistentFactoryInKernelTestCase extends KernelTestCase
41+
{
42+
use Factories;
43+
use ResetDatabase;
44+
45+
#[Test]
46+
#[DataProvider('createOneObjectInDataProvider')]
47+
public function assert_it_can_create_one_object_in_data_provider(?GenericModel $providedData): void
48+
{
49+
static::proxyFactory()::assert()->count(1);
50+
51+
self::assertInstanceOf(Proxy::class, $providedData);
52+
self::assertNotInstanceOf(Proxy::class, unproxy($providedData)); // asserts two proxies are not nested
53+
self::assertSame('value set in data provider', $providedData->getProp1());
54+
}
55+
56+
public static function createOneObjectInDataProvider(): iterable
57+
{
58+
yield 'createOne()' => [
59+
static::proxyFactory()::createOne(['prop1' => 'value set in data provider']),
60+
];
61+
62+
yield 'create()' => [
63+
static::proxyFactory()->create(['prop1' => 'value set in data provider']),
64+
];
65+
}
66+
67+
#[Test]
68+
#[DataProvider('createMultipleObjectsInDataProvider')]
69+
public function assert_it_can_create_multiple_objects_in_data_provider(?array $providedData): void
70+
{
71+
self::assertIsArray($providedData);
72+
static::proxyFactory()::assert()->count(2);
73+
self::assertSame('prop 1', $providedData[0]->getProp1());
74+
self::assertSame('prop 2', $providedData[1]->getProp1());
75+
}
76+
77+
public static function createMultipleObjectsInDataProvider(): iterable
78+
{
79+
yield 'createSequence()' => [
80+
static::proxyFactory()::createSequence([
81+
['prop1' => 'prop 1'],
82+
['prop1' => 'prop 2'],
83+
]),
84+
];
85+
86+
yield 'FactoryCollection::create()' => [
87+
static::proxyFactory()->sequence([
88+
['prop1' => 'prop 1'],
89+
['prop1' => 'prop 2'],
90+
])->create(),
91+
];
92+
}
93+
94+
#[Test]
95+
#[DataProvider('useGetterOnProxyObjectCreatedInDataProvider')]
96+
public function assert_using_getter_proxy_object_created_in_a_data_provider_throws(?\Throwable $e): void
97+
{
98+
self::assertInstanceOf(\LogicException::class, $e);
99+
self::assertStringStartsWith('Cannot access to a persisted object from a data provider.', $e->getMessage());
100+
}
101+
102+
public static function useGetterOnProxyObjectCreatedInDataProvider(): iterable
103+
{
104+
try {
105+
static::proxyFactory()::createOne()->getProp1();
106+
} catch (\Throwable $e) {
107+
}
108+
109+
yield [$e ?? null];
110+
}
111+
112+
#[Test]
113+
#[DataProvider('throwsExceptionWhenCreatingObjectInDataProvider')]
114+
public function it_throws_when_creating_persisted_object_with_non_proxy_factory_in_data_provider(?\Throwable $e
115+
): void {
116+
self::assertInstanceOf(\LogicException::class, $e);
117+
self::assertStringStartsWith(
118+
'Cannot create object in a data provider for non-proxy factories.',
119+
$e->getMessage()
120+
);
121+
}
122+
123+
public static function throwsExceptionWhenCreatingObjectInDataProvider(): iterable
124+
{
125+
try {
126+
static::factory()::createOne();
127+
} catch (\Throwable $e) {
128+
}
129+
130+
yield [$e ?? null];
131+
}
132+
133+
#[Test]
134+
#[DataProvider('useGetterOnObjectCreatedInDataProvider')]
135+
public function assert_it_can_use_getter_on_non_persisted_object_created_in_data_provider(
136+
string $providedData,
137+
mixed $expectedData
138+
): void {
139+
self::assertEquals($expectedData, unproxy($providedData));
140+
}
141+
142+
public static function useGetterOnObjectCreatedInDataProvider(): iterable
143+
{
144+
yield 'object factory' => [Object1Factory::createOne()->getProp1(), 'router-constructor'];
145+
yield 'persistent factory' => [static::factory()::new()->withoutPersisting()->create()->getProp1(), 'default1'];
146+
yield 'persistent factory using many' => [
147+
static::factory()::new()->withoutPersisting()->many(1)->create()[0]->getProp1(),
148+
'default1'
149+
];
150+
yield 'proxy factory' => [static::proxyFactory()::new()->withoutPersisting()->create()->getProp1(), 'default1'];
151+
yield 'proxy factory using many' => [
152+
static::proxyFactory()::new()->withoutPersisting()->many(1)->create()[0]->getProp1(),
153+
'default1'
154+
];
155+
}
156+
157+
/**
158+
* @return PersistentProxyObjectFactory<GenericModel>
159+
*/
160+
abstract protected static function proxyFactory(): PersistentProxyObjectFactory;
161+
162+
/**
163+
* @return PersistentObjectFactory<GenericModel>
164+
*/
165+
abstract protected static function factory(): PersistentObjectFactory;
166+
}

tests/Integration/DataProvider/DataProviderWithProxyFactoryInKernelTestCase.php

Lines changed: 0 additions & 96 deletions
This file was deleted.

0 commit comments

Comments
 (0)