Passed
Branch version-4 (8b03a3)
by Sebastian
02:18
created

Functions   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 66
Duplicated Lines 0 %

Test Coverage

Coverage 67.57%

Importance

Changes 2
Bugs 0 Features 1
Metric Value
eloc 31
c 2
b 0
f 1
dl 0
loc 66
ccs 25
cts 37
cp 0.6757
rs 10
wmc 17

6 Methods

Rating   Name   Duplication   Size   Complexity  
A assertScalar() 0 4 2
B assertValidCallable() 0 23 7
A isStrigableObject() 0 3 2
A throwNotApplicableCallableException() 0 8 1
A assertStringable() 0 5 3
A assertType() 0 4 2
1
<?php
2
declare(strict_types=1);
3
4
namespace Seboettg\Collection\Assert;
5
6
use ReflectionException;
7
use ReflectionFunction;
8
use Seboettg\Collection\Assert\Exception\NotApplicableCallableException;
9
use Seboettg\Collection\Assert\Exception\NotConvertibleToStringException;
10
use Seboettg\Collection\Assert\Exception\TypeIsNotAScalarException;
11
use Seboettg\Collection\Assert\Exception\WrongTypeException;
12
use function is_scalar;
13
use function is_object;
14
use function method_exists;
15
16
final class Functions
17
{
18 22
    public static final function assertScalar($value, string $message): void
0 ignored issues
show
Coding Style introduced by
As per PSR2, final should precede the visibility keyword.
Loading history...
19
    {
20 22
        if (!is_scalar($value)) {
21 3
            throw new TypeIsNotAScalarException($message);
22
        }
23 22
    }
24
25 1
    public static final function assertType($value, string $fqcn, string $message)
0 ignored issues
show
Coding Style introduced by
As per PSR2, final should precede the visibility keyword.
Loading history...
26
    {
27 1
        if (!$value instanceof $fqcn) {
28
            throw new WrongTypeException($message);
29
        }
30 1
    }
31
32 4
    public static final function assertStringable($value, string $message)
0 ignored issues
show
Coding Style introduced by
As per PSR2, final should precede the visibility keyword.
Loading history...
33
    {
34 4
        if (!is_scalar($value)) {
35 2
            if (!self::isStrigableObject($value)) {
36 1
                throw new NotConvertibleToStringException($message);
37
            }
38
        }
39 3
    }
40
41 2
    private static function isStrigableObject($value): bool
42
    {
43 2
        return is_object($value) && method_exists($value, "__toString");
44
    }
45
46 2
    public static function assertValidCallable(callable $callable, array $parameters)
47
    {
48 2
        $reflected = new ReflectionFunction($callable);
49 2
        if (count($reflected->getParameters()) !== count($parameters)) {
50
            throw new NotApplicableCallableException(
51
                "The number of parameters of the given callable does not match the expected number."
52
            );
53
        }
54 2
        for ($i = 0; $i < count($reflected->getParameters()); ++$i) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
55 2
            $reflectedParamType = $reflected->getParameters()[$i]->getType()->getName();
0 ignored issues
show
Bug introduced by
The method getName() does not exist on ReflectionType. It seems like you code against a sub-type of ReflectionType such as ReflectionNamedType. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

55
            $reflectedParamType = $reflected->getParameters()[$i]->getType()->/** @scrutinizer ignore-call */ getName();
Loading history...
56 2
            $expectedParam = $parameters[$i];
57 2
            switch ($expectedParam) {
58 2
                case "scalar":
59
                    if (!in_array($reflectedParamType, ["int", "string", "bool", "float"])) {
60
                        self::throwNotApplicableCallableException($i, "scalar", $reflectedParamType);
61
                    }
62
                    break;
63 2
                case "mixed":
64
                    //ignore, since every type is allowed
65
                    break;
66
                default:
67 2
                    if ($reflectedParamType !== $expectedParam) {
68
                        self::throwNotApplicableCallableException($i, $expectedParam, $reflectedParamType);
69
                    }
70
            }
71
        }
72 2
    }
73
74
    private static function throwNotApplicableCallableException($paramNumber, $expectedType, $actualType)
75
    {
76
        throw new NotApplicableCallableException(
77
            sprintf(
78
                "Parameter %d of type %s does not match the expected type of %s",
79
                $paramNumber,
80
                $actualType,
81
                $expectedType
82
            )
83
        );
84
    }
85
}
86
87
/**
88
 * @param $value
89
 * @param string $message description that will be included in the failure message if the assertion fails.
90
 * @return void
91
 */
92
function assertScalar($value, string $message): void
93
{
94 22
    Functions::assertScalar($value, $message);
95 22
}
96
97
/**
98
 * @param $value
99
 * @param string $fqcn full qualified class name
100
 * @param string $message description that will be included in the failure message if the assertion fails.
101
 * @return void
102
 */
103
function assertType($value, string $fqcn, string $message): void
104
{
105 1
    Functions::assertType($value, $fqcn, $message);
106 1
}
107
108
/**
109
 * @param $value
110
 * @param string $message description that will be included in the failure message if the assertion fails.
111
 * @return void
112
 */
113
function assertStringable($value, string $message): void
114
{
115 4
    Functions::assertStringable($value, $message);
116 3
}
117
118
119
function assertValidCallable(callable $callable, array $parameters)
120
{
121
    Functions::assertValidCallable($callable, $parameters);
122
}