Skip to content

Commit 0dd758c

Browse files
committed
Add support for Faker modifiers
1 parent ee8e117 commit 0dd758c

File tree

1 file changed

+76
-1
lines changed

1 file changed

+76
-1
lines changed

system/Test/Fabricator.php

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
namespace CodeIgniter\Test;
1515

16+
use Closure;
1617
use CodeIgniter\Exceptions\FrameworkException;
1718
use CodeIgniter\I18n\Time;
1819
use CodeIgniter\Model;
@@ -88,6 +89,17 @@ class Fabricator
8889
*/
8990
protected $tempOverrides;
9091

92+
/**
93+
* Fields to be modified before applying any formatter.
94+
*
95+
* @var array{
96+
* unique: array<non-empty-string, array{reset: bool, maxRetries: int}>,
97+
* optional: array<non-empty-string, array{weight: float, default: mixed}>,
98+
* valid: array<non-empty-string, array{validator: Closure(mixed): bool|null, maxRetries: int}>
99+
* }
100+
*/
101+
private array $modifiedFields = ['unique' => [], 'optional' => [], 'valid' => []];
102+
91103
/**
92104
* Default formatter to use when nothing is detected
93105
*
@@ -251,6 +263,46 @@ public function setOverrides(array $overrides = [], $persist = true): self
251263
return $this;
252264
}
253265

266+
/**
267+
* Set a field to be unique.
268+
*
269+
* @param bool $reset If set to true, resets the list of existing values
270+
* @param int $maxRetries Maximum number of retries to find a unique value,
271+
* After which an OverflowException is thrown.
272+
*/
273+
public function setUnique(string $field, bool $reset = false, int $maxRetries = 10000): static
274+
{
275+
$this->modifiedFields['unique'][$field] = compact('reset', 'maxRetries');
276+
277+
return $this;
278+
}
279+
280+
/**
281+
* Set a field to be optional.
282+
*
283+
* @param float $weight A probability between 0 and 1, 0 means that we always get the default value.
284+
*/
285+
public function setOptional(string $field, float $weight = 0.5, mixed $default = null): static
286+
{
287+
$this->modifiedFields['optional'][$field] = compact('weight', 'default');
288+
289+
return $this;
290+
}
291+
292+
/**
293+
* Set a field to be valid using a callback.
294+
*
295+
* @param Closure(mixed): bool|null $validator A function returning true for valid values
296+
* @param int $maxRetries Maximum number of retries to find a valid value,
297+
* After which an OverflowException is thrown.
298+
*/
299+
public function setValid(string $field, ?Closure $validator = null, int $maxRetries = 10000): static
300+
{
301+
$this->modifiedFields['valid'][$field] = compact('validator', 'maxRetries');
302+
303+
return $this;
304+
}
305+
254306
/**
255307
* Returns the current formatters
256308
*/
@@ -380,7 +432,30 @@ public function makeArray()
380432
$result = [];
381433

382434
foreach ($this->formatters as $field => $formatter) {
383-
$result[$field] = $this->faker->{$formatter}();
435+
$faker = $this->faker;
436+
437+
if (isset($this->modifiedFields['unique'][$field])) {
438+
$faker = $faker->unique(
439+
$this->modifiedFields['unique'][$field]['reset'],
440+
$this->modifiedFields['unique'][$field]['maxRetries']
441+
);
442+
}
443+
444+
if (isset($this->modifiedFields['optional'][$field])) {
445+
$faker = $faker->optional(
446+
$this->modifiedFields['optional'][$field]['weight'],
447+
$this->modifiedFields['optional'][$field]['default']
448+
);
449+
}
450+
451+
if (isset($this->modifiedFields['valid'][$field])) {
452+
$faker = $faker->valid(
453+
$this->modifiedFields['valid'][$field]['validator'],
454+
$this->modifiedFields['valid'][$field]['maxRetries']
455+
);
456+
}
457+
458+
$result[$field] = $faker->format($formatter);
384459
}
385460
}
386461
// If no formatters were defined then look for a model fake() method

0 commit comments

Comments
 (0)