ConsecutiveTrait::consecutive()   B
last analyzed

Complexity

Conditions 9
Paths 25

Size

Total Lines 50
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 25
nc 25
nop 1
dl 0
loc 50
rs 8.0555
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Jasny\PHPUnit;
6
7
use PHPUnit\Framework\Assert;
8
use PHPUnit\Framework\Constraint\Constraint;
9
use PHPUnit\Framework\Constraint\IsEqual;
10
use RuntimeException;
11
12
/**
13
 * Usage: ->with(...$this->consecutive(['a', 1], ['b', 2]))
14
 */
15
trait ConsecutiveTrait
16
{
17
    public static function consecutive(...$parameterGroups): array
18
    {
19
        $result = [];
20
        $parametersCount = null;
21
        $groups = [];
22
        $values = [];
23
24
        foreach ($parameterGroups as $index => $parameters) {
25
            // initial
26
            $parametersCount ??= count($parameters);
27
28
            // compare
29
            if ($parametersCount !== count($parameters)) {
30
                throw new RuntimeException('Parameters count max much in all groups');
31
            }
32
33
            // prepare parameters
34
            foreach ($parameters as $parameter) {
35
                if (!$parameter instanceof Constraint) {
36
                    $parameter = new IsEqual($parameter);
37
                }
38
39
                $groups[$index][] = $parameter;
40
            }
41
        }
42
43
        // collect values
44
        foreach ($groups as $parameters) {
45
            foreach ($parameters as $index => $parameter) {
46
                $values[$index][] = $parameter;
47
            }
48
        }
49
50
        // build callback
51
        for ($index = 0; $index < $parametersCount; ++$index) {
52
            $result[$index] = Assert::callback(static function ($value) use ($values, $index) {
53
                static $map = null;
54
                $map ??= $values[$index];
55
56
                $expectedArg = array_shift($map);
57
                if ($expectedArg === null) {
58
                    throw new RuntimeException('No more expected calls');
59
                }
60
                $expectedArg->evaluate($value);
61
62
                return true;
63
            });
64
        }
65
66
        return $result;
67
    }
68
}
69