MatcherPackage::getProvideMatchers()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 21
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 1 Features 1
Metric Value
c 3
b 1
f 1
dl 0
loc 21
rs 9.3142
cc 3
eloc 12
nc 3
nop 0
1
<?php
2
3
/**
4
 * This file is part of expect package.
5
 *
6
 * (c) Noritaka Horio <[email protected]>
7
 *
8
 * This source file is subject to the MIT license that is bundled
9
 * with this source code in the file LICENSE.
10
 */
11
namespace expect;
12
13
use ArrayIterator;
14
use expect\package\ComposerJsonNotFoundException;
15
use expect\package\MatcherClass;
16
use expect\package\ReflectionIterator;
17
use expect\matcher\ReportableMatcher;
18
use Noodlehaus\Config;
19
20
/**
21
 * Matcher package
22
 *
23
 * @author Noritaka Horio <[email protected]>
24
 * @copyright Noritaka Horio <[email protected]>
25
 */
26
final class MatcherPackage implements RegisterablePackage
27
{
28
29
    /**
30
     * @var string
31
     */
32
    private $namespace;
33
34
    /**
35
     * @var string
36
     */
37
    private $namespaceDirectory;
38
39
    /**
40
     * Create a new macther package
41
     *
42
     * @param string $namespace          namespace of package
43
     * @param string $namespaceDirectory directory of package
44
     */
45
    public function __construct($namespace, $namespaceDirectory)
46
    {
47
        $this->namespace = $this->normalizeNamespace($namespace);
48
        $this->namespaceDirectory = $namespaceDirectory;
49
    }
50
51
    /**
52
     * {@inheritdoc}
53
     */
54
    public function registerTo(MatcherRegistry $registry)
55
    {
56
        $provideMatchers = $this->getProvideMatchers();
57
58
        foreach ($provideMatchers as $provideMatcher) {
59
            $registry->register($provideMatcher);
60
        }
61
    }
62
63
    /**
64
     * @return ArrayIterator
65
     */
66
    private function getProvideMatchers()
67
    {
68
        $matchers = [];
69
        $reflectionIterator = new ReflectionIterator(
70
            $this->namespace,
71
            $this->namespaceDirectory
72
        );
73
74
        foreach ($reflectionIterator as $reflection) {
75
            if ($reflection->implementsInterface(ReportableMatcher::class) === false) {
76
                continue;
77
            }
78
79
            $matchers[] = new MatcherClass(
80
                $reflection->getNamespaceName(),
81
                $reflection->getShortName()
82
            );
83
        }
84
85
        return new ArrayIterator($matchers);
86
    }
87
88
    private function normalizeNamespace($namespace)
89
    {
90
        $normalizeNamespace = $namespace;
91
        $lastCharAt = strlen($namespace) - 1;
92
93
        if (substr($namespace, $lastCharAt) === '\\') {
94
            $normalizeNamespace = substr($namespace, 0, $lastCharAt);
95
        }
96
97
        return $normalizeNamespace;
98
    }
99
100
    /**
101
     * Create a new matcher package from composer.json
102
     *
103
     * @param string $composerJson composer.json path
104
     *
105
     * @throws \expect\package\ComposerJsonNotFoundException
106
     */
107
    public static function fromPackageFile($composerJson)
108
    {
109
        if (file_exists($composerJson) === false) {
110
            throw new ComposerJsonNotFoundException("File {$composerJson} not found.");
111
        }
112
113
        $config = Config::load($composerJson);
114
        $autoload = $config->get('autoload.psr-4');
115
116
        $composerJsonDirectory = dirname($composerJson);
117
118
        $keys = array_keys($autoload);
119
        $namespace = array_shift($keys);
120
121
        $values = array_values($autoload);
122
        $namespaceDirectory = array_shift($values);
123
        $namespaceDirectory = realpath($composerJsonDirectory . '/' . $namespaceDirectory);
124
125
        return new self($namespace, $namespaceDirectory);
126
    }
127
}
128