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

Skip to content

Commit 56161cc

Browse files
elliotbruneelElliot Bruneel
andauthored
feat: add randomRangeOrCreate() method (#932)
* feat: add randomRangeOrCreate method * feat: add randomRangeOrCreate method --------- Co-authored-by: Elliot Bruneel <[email protected]>
1 parent 0af39f3 commit 56161cc

10 files changed

Lines changed: 126 additions & 0 deletions

docs/index.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ This command will generate a ``PostFactory`` class that looks like this:
237237
* @method static Post[]&Proxy[] createSequence(iterable|callable $sequence)
238238
* @method static Post[]|Proxy[] findBy(array $attributes)
239239
* @method static Post[]|Proxy[] randomRange(int $min, int $max, array $attributes = []))
240+
* @method static Post[]|Proxy[] randomRangeOrCreate(int $min, int $max, array $attributes = [])
240241
* @method static Post[]|Proxy[] randomSet(int $number, array $attributes = []))
241242
*
242243
* @phpstan-method Proxy<Post>&Post create(array|callable $attributes = [])
@@ -252,6 +253,7 @@ This command will generate a ``PostFactory`` class that looks like this:
252253
* @phpstan-method static list<Proxy<Post>&Post> createSequence(array|callable $sequence)
253254
* @phpstan-method static list<Proxy<Post>&Post> findBy(array $attributes)
254255
* @phpstan-method static list<Proxy<Post>&Post> randomRange(int $min, int $max, array $attributes = [])
256+
* @phpstan-method static list<Proxy<Post>&Post> randomRangeOrCreate(int $min, int $max, array $attributes = [])
255257
* @phpstan-method static list<Proxy<Post>&Post> randomSet(int $number, array $attributes = [])
256258
* @phpstan-method static RepositoryProxy<Post>&Post repository()
257259
*/
@@ -371,6 +373,10 @@ Using your Factory
371373
$posts = PostFactory::randomRange(0, 5); // array containing 0-5 "Post|Proxy" objects
372374
$posts = PostFactory::randomRange(0, 5, ['author' => 'kevin']); // filter by the passed attributes
373375

376+
// or automatically persist a new random range of objects if none exists
377+
$posts = PostFactory::randomRangeOrCreate(0, 5); // array containing 0-5 "Post|Proxy" objects
378+
$posts = PostFactory::randomRangeOrCreate(0, 5, ['author' => 'kevin']); // filter by or create with the passed attributes
379+
374380
Reusable Factory "States"
375381
~~~~~~~~~~~~~~~~~~~~~~~~~
376382

src/Maker/Factory/MakeFactoryPHPDocMethod.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ public static function createAll(MakeFactoryData $makeFactoryData): array
4545
$methods[] = new self($makeFactoryData->getObjectShortName(), 'all()', returnsCollection: true);
4646
$methods[] = new self($makeFactoryData->getObjectShortName(), 'findBy(array $attributes)', returnsCollection: true);
4747
$methods[] = new self($makeFactoryData->getObjectShortName(), 'randomRange(int $min, int $max, array $attributes = [])', returnsCollection: true);
48+
$methods[] = new self($makeFactoryData->getObjectShortName(), 'randomRangeOrCreate(int $min, int $max, array $attributes = [])', returnsCollection: true);
4849
$methods[] = new self($makeFactoryData->getObjectShortName(), 'randomSet(int $number, array $attributes = [])', returnsCollection: true);
4950

5051
if (null !== $makeFactoryData->getRepositoryReflectionClass()) {

src/Persistence/PersistentObjectFactory.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,32 @@ public static function randomRange(int $min, int $max, array $criteria = []): ar
116116
return static::repository()->randomRange($min, $max, $criteria);
117117
}
118118

119+
/**
120+
* @param int<0, max> $min
121+
* @param int<0, max> $max
122+
* @phpstan-param Parameters $criteria
123+
*
124+
* @return list<T>
125+
*/
126+
public static function randomRangeOrCreate(int $min, int $max, array $criteria = []): array
127+
{
128+
$targetCount = mt_rand($min, $max);
129+
130+
try {
131+
return static::repository()->randomRange($min, $targetCount, $criteria);
132+
} catch (NotEnoughObjects) {
133+
$foundObjects = static::repository()->findBy($criteria);
134+
} catch (PersistenceNotAvailable|PersistenceDisabled) {
135+
$foundObjects = [];
136+
}
137+
138+
$objectsToCreate = $targetCount - count($foundObjects);
139+
140+
$newObjects = static::createMany($objectsToCreate, $criteria);
141+
142+
return [...$foundObjects, ...$newObjects];
143+
}
144+
119145
/**
120146
* @phpstan-param Parameters $criteria
121147
*

src/Persistence/PersistentProxyObjectFactory.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,14 @@ final public static function randomRange(int $min, int $max, array $criteria = [
9393
return \array_map(proxy(...), parent::randomRange($min, $max, $criteria));
9494
}
9595

96+
/**
97+
* @return list<T&Proxy<T>>
98+
*/
99+
public static function randomRangeOrCreate(int $min, int $max, array $criteria = []): array
100+
{
101+
return \array_map(proxy(...), parent::randomRangeOrCreate($min, $max, $criteria));
102+
}
103+
96104
/**
97105
* @return list<T&Proxy<T>>
98106
*/

stubs/phpstan/PersistentProxyObjectFactory.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ protected function defaults(): array
5252
assertType("list<{$proxyType}>", UserProxyFactory::createRange(1, 2));
5353
assertType("list<{$proxyType}>", UserProxyFactory::createSequence([]));
5454
assertType("list<{$proxyType}>", UserProxyFactory::randomRange(1, 2));
55+
assertType("list<{$proxyType}>", UserProxyFactory::randomRangeOrCreate(1, 2));
5556
assertType("list<{$proxyType}>", UserProxyFactory::randomSet(2));
5657
assertType("list<{$proxyType}>", UserProxyFactory::findBy(['name' => 'foo']));
5758

@@ -117,6 +118,7 @@ protected function defaults(): array
117118
assertType("string", UserProxyFactory::createRange(1, 2)[0]->name);
118119
assertType("string", UserProxyFactory::createSequence([])[0]->name);
119120
assertType("string", UserProxyFactory::randomRange(1, 2)[0]->name);
121+
assertType("string", UserProxyFactory::randomRangeOrCreate(1,2)[0]->name);
120122
assertType("string", UserProxyFactory::randomSet(2)[0]->name);
121123
assertType("string", UserProxyFactory::findBy(['name' => 'foo'])[0]->name);
122124

stubs/psalm/PersistentProxyObjectFactory.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ protected function defaults(): array|callable
6464
/** @psalm-check-type-exact $var = list<UserForProxyFactory&Proxy<UserForProxyFactory>> */
6565
$var = UserProxyFactory::randomRange(1, 2);
6666
/** @psalm-check-type-exact $var = list<UserForProxyFactory&Proxy<UserForProxyFactory>> */
67+
$var = UserProxyFactory::randomRangeOrCreate(1, 2);
68+
/** @psalm-check-type-exact $var = list<UserForProxyFactory&Proxy<UserForProxyFactory>> */
6769
$var = UserProxyFactory::randomSet(2);
6870
/** @psalm-check-type-exact $var = list<UserForProxyFactory&Proxy<UserForProxyFactory>> */
6971
$var = UserProxyFactory::findBy(['name' => 'foo']);

tests/Fixture/Maker/expected/can_create_factory_for_entity_with_repository.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
* @method static GenericEntity[]|Proxy[] createSequence(iterable|callable $sequence)
3636
* @method static GenericEntity[]|Proxy[] findBy(array $attributes)
3737
* @method static GenericEntity[]|Proxy[] randomRange(int $min, int $max, array $attributes = [])
38+
* @method static GenericEntity[]|Proxy[] randomRangeOrCreate(int $min, int $max, array $attributes = [])
3839
* @method static GenericEntity[]|Proxy[] randomSet(int $number, array $attributes = [])
3940
*
4041
* @phpstan-method GenericEntity&Proxy<GenericEntity> create(array|callable $attributes = [])
@@ -51,6 +52,7 @@
5152
* @phpstan-method static list<GenericEntity&Proxy<GenericEntity>> createSequence(iterable|callable $sequence)
5253
* @phpstan-method static list<GenericEntity&Proxy<GenericEntity>> findBy(array $attributes)
5354
* @phpstan-method static list<GenericEntity&Proxy<GenericEntity>> randomRange(int $min, int $max, array $attributes = [])
55+
* @phpstan-method static list<GenericEntity&Proxy<GenericEntity>> randomRangeOrCreate(int $min, int $max, array $attributes = [])
5456
* @phpstan-method static list<GenericEntity&Proxy<GenericEntity>> randomSet(int $number, array $attributes = [])
5557
*/
5658
final class GenericEntityFactory extends PersistentProxyObjectFactory

tests/Fixture/Maker/expected/can_create_factory_with_static_analysis_annotations_with_data_set_phpstan.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
* @method static Category[]|Proxy[] createSequence(iterable|callable $sequence)
3535
* @method static Category[]|Proxy[] findBy(array $attributes)
3636
* @method static Category[]|Proxy[] randomRange(int $min, int $max, array $attributes = [])
37+
* @method static Category[]|Proxy[] randomRangeOrCreate(int $min, int $max, array $attributes = [])
3738
* @method static Category[]|Proxy[] randomSet(int $number, array $attributes = [])
3839
*
3940
* @phpstan-method Category&Proxy<Category> create(array|callable $attributes = [])
@@ -50,6 +51,7 @@
5051
* @phpstan-method static list<Category&Proxy<Category>> createSequence(iterable|callable $sequence)
5152
* @phpstan-method static list<Category&Proxy<Category>> findBy(array $attributes)
5253
* @phpstan-method static list<Category&Proxy<Category>> randomRange(int $min, int $max, array $attributes = [])
54+
* @phpstan-method static list<Category&Proxy<Category>> randomRangeOrCreate(int $min, int $max, array $attributes = [])
5355
* @phpstan-method static list<Category&Proxy<Category>> randomSet(int $number, array $attributes = [])
5456
*/
5557
final class CategoryFactory extends PersistentProxyObjectFactory

tests/Fixture/Maker/expected/can_create_factory_with_static_analysis_annotations_with_data_set_psalm.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
* @method static Category[]|Proxy[] createSequence(iterable|callable $sequence)
3535
* @method static Category[]|Proxy[] findBy(array $attributes)
3636
* @method static Category[]|Proxy[] randomRange(int $min, int $max, array $attributes = [])
37+
* @method static Category[]|Proxy[] randomRangeOrCreate(int $min, int $max, array $attributes = [])
3738
* @method static Category[]|Proxy[] randomSet(int $number, array $attributes = [])
3839
*
3940
* @psalm-method Category&Proxy<Category> create(array|callable $attributes = [])
@@ -50,6 +51,7 @@
5051
* @psalm-method static list<Category&Proxy<Category>> createSequence(iterable|callable $sequence)
5152
* @psalm-method static list<Category&Proxy<Category>> findBy(array $attributes)
5253
* @psalm-method static list<Category&Proxy<Category>> randomRange(int $min, int $max, array $attributes = [])
54+
* @psalm-method static list<Category&Proxy<Category>> randomRangeOrCreate(int $min, int $max, array $attributes = [])
5355
* @psalm-method static list<Category&Proxy<Category>> randomSet(int $number, array $attributes = [])
5456
*/
5557
final class CategoryFactory extends PersistentProxyObjectFactory

tests/Integration/Persistence/GenericFactoryTestCase.php

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,81 @@ public function random_or_create(): void
286286
static::factory()::repository()->assert()->count(2);
287287
}
288288

289+
/**
290+
* @test
291+
*/
292+
#[Test]
293+
public function random_range_or_create_enough_object(): void
294+
{
295+
static::factory()->create(['prop1' => 'a']);
296+
static::factory()->create(['prop1' => 'a']);
297+
static::factory()->create(['prop1' => 'a']);
298+
299+
$range = static::factory()::randomRangeOrCreate(2, 3);
300+
301+
$this->assertGreaterThanOrEqual(2, \count($range));
302+
$this->assertLessThanOrEqual(3, \count($range));
303+
304+
foreach ($range as $object) {
305+
$this->assertSame('a', $object->getProp1());
306+
}
307+
}
308+
309+
/**
310+
* @test
311+
*/
312+
#[Test]
313+
public function random_range_or_create_not_enough_object(): void
314+
{
315+
static::factory()->create(['prop1' => 'a']);
316+
317+
$range = static::factory()::randomRangeOrCreate(2, 3);
318+
319+
$this->assertGreaterThanOrEqual(2, \count($range));
320+
$this->assertLessThanOrEqual(3, \count($range));
321+
322+
static::factory()::assert()
323+
->exists(['prop1' => 'default1']);
324+
}
325+
326+
/**
327+
* @test
328+
*/
329+
#[Test]
330+
public function random_range_or_create_not_enough_object_with_criteria(): void
331+
{
332+
static::factory()->create(['prop1' => 'a']);
333+
static::factory()->create(['prop1' => 'b']);
334+
335+
$range = static::factory()::randomRangeOrCreate(2, 3, ['prop1' => 'b']);
336+
337+
$this->assertGreaterThanOrEqual(2, \count($range));
338+
$this->assertLessThanOrEqual(3, \count($range));
339+
340+
foreach ($range as $object) {
341+
$this->assertSame('b', $object->getProp1());
342+
}
343+
}
344+
345+
/**
346+
* @test
347+
*/
348+
#[Test]
349+
public function random_range_or_create_no_object_with_criteria(): void
350+
{
351+
static::factory()->create(['prop1' => 'a']);
352+
static::factory()->create(['prop1' => 'b']);
353+
354+
$range = static::factory()::randomRangeOrCreate(2, 3, ['prop1' => 'c']);
355+
356+
$this->assertGreaterThanOrEqual(2, \count($range));
357+
$this->assertLessThanOrEqual(3, \count($range));
358+
359+
foreach ($range as $object) {
360+
$this->assertSame('c', $object->getProp1());
361+
}
362+
}
363+
289364
/**
290365
* @test
291366
*/

0 commit comments

Comments
 (0)