• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ducks-project / encoding-repair / 21231385783

22 Jan 2026 12:40AM UTC coverage: 79.793% (+3.8%) from 75.976%
21231385783

push

github

donaldinou
feat : coverage

3 of 5 new or added lines in 2 files covered. (60.0%)

18 existing lines in 2 files now uncovered.

308 of 386 relevant lines covered (79.79%)

7.36 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

88.57
/Detector/CallableDetector.php
1
<?php
2

3
/**
4
 * Part of EncodingRepair package.
5
 *
6
 * (c) Adrien Loyant <donald_duck@team-df.org>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11

12
declare(strict_types=1);
13

14
namespace Ducks\Component\EncodingRepair\Detector;
15

16
use Closure;
17
use InvalidArgumentException;
18
use ReflectionException;
19
use ReflectionFunctionAbstract;
20
use ReflectionFunction;
21
use ReflectionMethod;
22

23
/**
24
 * Adapter for legacy callable detectors.
25
 *
26
 * @final
27
 */
28
final class CallableDetector implements DetectorInterface
29
{
30
    /**
31
     * @var callable(string, null|array<string, mixed>): (string|null)
32
     */
33
    private $callable;
34

35
    /**
36
     * @var int
37
     */
38
    private $priority;
39

40
    /**
41
     * @param callable(string, null|array<string, mixed>): (string|null) $callable Detection function
42
     * @param int $priority Priority value
43
     *
44
     * @throws InvalidArgumentException If callable signature is invalid
45
     */
46
    public function __construct(callable $callable, int $priority)
6✔
47
    {
48
        $this->validateCallable($callable);
6✔
49
        $this->callable = $callable;
5✔
50
        $this->priority = $priority;
5✔
51
    }
52

53
    /**
54
     * @inheritDoc
55
     */
56
    public function detect(string $string, ?array $options = null): ?string
4✔
57
    {
58
        /** @var string|null|mixed $result */
59
        $result = ($this->callable)($string, $options);
4✔
60

61
        if (null !== $result && !\is_string($result)) {
4✔
62
            throw new InvalidArgumentException(
1✔
63
                \sprintf(
1✔
64
                    'Callable detector must return string|null, %s returned',
1✔
65
                    \gettype($result)
1✔
66
                )
1✔
67
            );
1✔
68
        }
69

70
        return $result;
3✔
71
    }
72

73
    /**
74
     * @inheritDoc
75
     */
76
    public function getPriority(): int
1✔
77
    {
78
        return $this->priority;
1✔
79
    }
80

81
    /**
82
     * @inheritDoc
83
     */
84
    public function isAvailable(): bool
2✔
85
    {
86
        return true;
2✔
87
    }
88

89
    /**
90
     * Return true if callable is a valid callable detector.
91
     *
92
     * @param callable $callable
93
     *
94
     * @return bool
95
     */
96
    public static function isValidCallable(callable $callable): bool
6✔
97
    {
98
        try {
99
            $reflection = self::getReflection($callable);
6✔
100

101
            return $reflection->getNumberOfParameters() >= 1;
6✔
NEW
102
        } catch (ReflectionException $e) {
×
103
            return true;
×
104
        }
105
    }
106

107
    /**
108
     * Validates callable signature.
109
     *
110
     * @param callable $callable Callable to validate
111
     *
112
     * @throws InvalidArgumentException If signature is invalid
113
     */
114
    private function validateCallable(callable $callable): void
6✔
115
    {
116
        if (!self::isValidCallable($callable)) {
6✔
117
            throw new InvalidArgumentException(
1✔
118
                'Callable detector must accept at least 1 parameter: (string)'
1✔
119
            );
1✔
120
        }
121
    }
122

123
    /**
124
     * Get reflection for callable.
125
     *
126
     * @param callable $callable Callable to reflect
127
     *
128
     * @return ReflectionFunctionAbstract
129
     *
130
     * @throws ReflectionException
131
     */
132
    private static function getReflection(callable $callable): ReflectionFunctionAbstract
6✔
133
    {
134
        if (\is_array($callable)) {
6✔
135
            return new ReflectionMethod($callable[0], $callable[1]);
×
136
        }
137

138
        if (\is_object($callable) && !$callable instanceof Closure) {
6✔
139
            return new ReflectionMethod($callable, '__invoke');
×
140
        }
141

142
        $closure = Closure::fromCallable($callable);
6✔
143

144
        return new ReflectionFunction($closure);
6✔
145
    }
146
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc