Passed
Push — develop ( fc48fc...bcf054 )
by Paul
02:25
created

MockAnnotation::compile()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 24
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 14
nc 4
nop 0
dl 0
loc 24
rs 8.6845
c 0
b 0
f 0
1
<?php
2
3
namespace PhpUnitGen\Annotation;
4
5
use PhpUnitGen\Annotation\AnnotationInterface\AnnotationInterface;
6
use PhpUnitGen\Exception\AnnotationParseException;
7
use PhpUnitGen\Exception\JsonException;
8
use PhpUnitGen\Model\ModelInterface\FunctionModelInterface;
9
use PhpUnitGen\Parser\NodeParserUtil\RootRetrieverHelper;
10
use PhpUnitGen\Util\Json;
11
use Respect\Validation\Validator;
12
13
/**
14
 * Class MockAnnotation.
15
 *
16
 * @author     Paul Thébaud <[email protected]>.
17
 * @copyright  2017-2018 Paul Thébaud <[email protected]>.
18
 * @license    https://opensource.org/licenses/MIT The MIT license.
19
 * @link       https://github.com/paul-thebaud/phpunit-generator
20
 * @since      Class available since Release 2.0.0.
21
 */
22
class MockAnnotation extends AbstractAnnotation
23
{
24
    /**
25
     * @var string $property The name of the property which will contains the mock.
26
     */
27
    private $property;
28
29
    /**
30
     * @var string $class The class to the mock.
31
     */
32
    private $class;
33
34
    /**
35
     * {@inheritdoc}
36
     */
37
    public function getType(): int
38
    {
39
        return AnnotationInterface::TYPE_MOCK;
40
    }
41
42
    /**
43
     * {@inheritdoc}
44
     */
45
    public function compile(): void
46
    {
47
        // Decode JSON content
48
        try {
49
            $decoded = Json::decode('[' . $this->getStringContent() . ']');
50
        } catch (JsonException $exception) {
51
            throw new AnnotationParseException('"mock" annotation content is invalid (invalid JSON content)');
52
        }
53
        $this->validate($decoded);
54
55
        $phpFile = RootRetrieverHelper::getRoot($this);
56
        // If class to use is not from global namespace
57
        if (! Validator::regex('/^\\\\/')->validate($decoded[0])) {
58
            // Add the current namespace to it
59
            $namespace = $phpFile->getNamespaceString();
60
            $decoded[0] = ($namespace !== null ? ($namespace . '\\') : '') . $decoded[0];
61
        }
62
        // Get the last name part
63
        $nameArray = explode('\\', $decoded[0]);
64
        $lastPart  = end($nameArray);
65
        // Add use to PhpFile
66
        $phpFile->addConcreteUse($decoded[0], $lastPart);
67
        $this->class = $lastPart;
68
        $this->property = $decoded[1];
69
    }
70
71
    /**
72
     * Validate the content of annotation.
73
     *
74
     * @param mixed $decoded The annotation content.
75
     *
76
     * @throws AnnotationParseException If the content is invalid.
77
     */
78
    private function validate($decoded): void
79
    {
80
        // Validate it is an array
81
        if (! Validator::arrayType()->length(2, 2)->validate($decoded)) {
82
            throw new AnnotationParseException(
83
                '"mock" annotation content is invalid (must contains the class to mock and the property name)'
84
            );
85
        }
86
        // Validate that each value is a string
87
        if (! Validator::arrayVal()->each(Validator::stringType(), Validator::intType())->validate($decoded)) {
88
            throw new AnnotationParseException(
89
                '"mock" annotation content is invalid (class and property name must be string)'
90
            );
91
        }
92
    }
93
94
    /**
95
     * @return string The name of the property which will contains the mock.
96
     */
97
    public function getProperty(): string
98
    {
99
        return $this->property;
100
    }
101
102
    /**
103
     * @return string The class to the mock.
104
     */
105
    public function getClass(): string
106
    {
107
        return $this->class;
108
    }
109
}
110