• 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

91.43
/Transcoder/CallableTranscoder.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\Transcoder;
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 transcoders.
25
 *
26
 * @final
27
 */
28
final class CallableTranscoder implements TranscoderInterface
29
{
30
    /**
31
     * @var callable(string, string, 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, string, string, null|array<string, mixed>): (string|null) $callable Transcoding 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)
7✔
47
    {
48
        $this->validateCallable($callable);
7✔
49

50
        $this->callable = $callable;
6✔
51
        $this->priority = $priority;
6✔
52
    }
53

54
    /**
55
     * @inheritDoc
56
     */
57
    public function transcode(string $data, string $to, string $from, ?array $options = null): ?string
3✔
58
    {
59
        /** @var string|null|mixed $result */
60
        $result = ($this->callable)($data, $to, $from, $options);
3✔
61

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

71
        return $result;
2✔
72
    }
73

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

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

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

102
            return 3 <= $reflection->getNumberOfParameters();
7✔
NEW
103
        } catch (ReflectionException $e) {
×
104
            // Because of PHP 7.4 we need to validate the callable
105
            // if ReflectionException occured.
106
            return true;
×
107
        }
108
    }
109

110
    /**
111
     * Validates callable signature.
112
     *
113
     * @param callable $callable Callable to validate
114
     *
115
     * @throws InvalidArgumentException If signature is invalid
116
     */
117
    private function validateCallable(callable $callable): void
7✔
118
    {
119
        if (!self::isValidCallable($callable)) {
7✔
120
            throw new InvalidArgumentException(
1✔
121
                'Callable transcoder must accept at least 4 parameters: (string, string, string, array)'
1✔
122
            );
1✔
123
        }
124
    }
125

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

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

145
        $closure = Closure::fromCallable($callable);
6✔
146

147
        return new ReflectionFunction($closure);
6✔
148
    }
149
}
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