Passed
Push — master ( 1ddfa9...ac520b )
by Jakub
01:32
created

Doubler::createDoubles()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 2
nc 2
nop 1
dl 0
loc 4
ccs 3
cts 3
cp 1
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
namespace Zalas\PHPUnit\Doubles\TestCase;
5
6
use Zalas\PHPUnit\Doubles\Extractor\Extractor;
7
use Zalas\PHPUnit\Doubles\Extractor\Property;
8
use Zalas\PHPUnit\Doubles\Injector\Injector;
9
10
/**
11
 * @internal
12
 */
13
class Doubler
14
{
15
    /**
16
     * @var Extractor
17
     */
18
    private $extractor;
19
20
    /**
21
     * @var Injector
22
     */
23
    private $injector;
24
25
    /**
26
     * @var array
27
     */
28
    private $doubleFactories;
29
30 19
    public function __construct(Extractor $extractor, Injector $injector, array $doubleFactories)
31
    {
32 19
        $this->extractor = $extractor;
33 19
        $this->injector = $injector;
34 19
        $this->doubleFactories = $doubleFactories;
35
    }
36
37 19
    public function createDoubles(/*object */$testCase)
38
    {
39 19
        foreach ($this->getTestDoubleProperties($testCase) as $property) {
40 19
            $this->injector->inject($testCase, $property->getName(), $this->createTestDouble($property));
41
        }
42
    }
43
44 19
    private function createTestDouble(Property $property)
45
    {
46 19
        $doubleType = $this->getDoubleType($property);
47 18
        $allDoubleTypes = \array_keys($this->doubleFactories);
48
49
        return $this->doubleFactories[$doubleType]($property->getTypesFiltered(function (string $type) use ($allDoubleTypes): bool {
50 18
            return !\in_array($type, $allDoubleTypes);
51 18
        }));
52
    }
53
54
    /**
55
     * @param object $testCase
56
     *
57
     * @return Property[]
58
     */
59 19
    private function getTestDoubleProperties(/*object */$testCase): array
60
    {
61 19
        $supportedDoubles = \array_keys($this->doubleFactories);
62
63
        return $this->extractor->extract($testCase, function (Property $property) use ($supportedDoubles): bool {
64
            $doubleTypes = $property->getTypesFiltered(function (string $type) use ($supportedDoubles): bool {
65 19
                return \in_array($type, $supportedDoubles);
66 19
            });
67
68 19
            return \count($doubleTypes) > 0;
69 19
        });
70
    }
71
72 19
    private function getDoubleType(Property $property): string
73
    {
74 19
        $supportedDoubles = \array_keys($this->doubleFactories);
75
        $doubleTypes = $property->getTypesFiltered(function (string $type) use ($supportedDoubles): bool {
76 19
            return \in_array($type, $supportedDoubles);
77 19
        });
78
79 19
        if (\count($doubleTypes) > 1) {
80 1
            throw new \LogicException(\sprintf('Ambiguous test double definition for "%s": "%s".', $property->getName(), \implode('|', $property->getTypes())));
81
        }
82
83 18
        return \array_shift($doubleTypes);
84
    }
85
}
86