ValidStrategy   A
last analyzed

Complexity

Total Complexity 4

Size/Duplication

Total Lines 45
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 4
eloc 11
dl 0
loc 45
ccs 10
cts 10
cp 1
rs 10
c 0
b 0
f 0

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A generate() 0 15 3
1
<?php
2
3
declare(strict_types = 1);
4
5
namespace DummyGenerator\Strategy;
6
7
use Closure;
8
9
class ValidStrategy implements StrategyInterface
10
{
11
    private Closure $validator;
12
13
    /**
14
     * To make sure the value meet some criteria, pass a callable that verifies the
15
     * output. If the validator fails, the generator will try again.
16
     *
17
     * The value validity is determined by a function passed as first argument.
18
     *
19
     * <code>
20
     * $values = array();
21
     * $evenValidator = function (int $digit): bool {
22
     *   return $digit % 2 === 0;
23
     * };
24
     * for ($i=0; $i < 10; $i++) {
25
     *   $values []= $generator->withStrategy(new ValidStrategy($evenValidator))->randomDigit();
26
     * }
27
     * print_r($values); // [0, 4, 8, 4, 2, 6, 0, 8, 8, 6]
28
     * </code>a
29
     *
30
     * @param callable(?mixed $value):bool $validator  A function returning true for valid values
31
     * @param int $retries Maximum number of retries to find a valid value,
32
     *                              After which an OverflowException is thrown.
33
     */
34 2
    public function __construct(callable $validator, private readonly int $retries = 10000)
35
    {
36 2
        $this->validator = $validator(...);
37
    }
38
39 2
    public function generate(string $name, callable $callback): mixed
40
    {
41 2
        $tries = 0;
42
43
        do {
44 2
            $response = $callback();
45
46 2
            ++$tries;
47
48 2
            if ($tries > $this->retries) {
49 1
                throw new \OverflowException(sprintf('Maximum retries of %d reached without finding a valid value', $this->retries));
50
            }
51 2
        } while (!$this->validator->call($this, $response));
52
53 1
        return $response;
54
    }
55
}
56