Passed
Push — develop ( 4c7678...74dbd7 )
by Paul
02:25
created

ConstructorAnnotation   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 93
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 93
rs 10
c 0
b 0
f 0
wmc 11

5 Methods

Rating   Name   Duplication   Size   Complexity  
B validate() 0 21 5
A compile() 0 22 3
A getClass() 0 3 1
A getParameters() 0 3 1
A getType() 0 3 1
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\Util\Json;
9
use Respect\Validation\Validator;
10
11
/**
12
 * Class ConstructorAnnotation.
13
 *
14
 * @author     Paul Thébaud <[email protected]>.
15
 * @copyright  2017-2018 Paul Thébaud <[email protected]>.
16
 * @license    https://opensource.org/licenses/MIT The MIT license.
17
 * @link       https://github.com/paul-thebaud/phpunit-generator
18
 * @since      Class available since Release 2.0.0.
19
 */
20
class ConstructorAnnotation extends AbstractAnnotation
21
{
22
    /**
23
     * @var string|null $class The class name to use to construct the instance, null if none.
24
     */
25
    private $class;
26
27
    /**
28
     * @var string[] $parameters The constructor parameters.
29
     */
30
    private $parameters;
31
32
    /**
33
     * {@inheritdoc}
34
     */
35
    public function getType(): int
36
    {
37
        return AnnotationInterface::TYPE_CONSTRUCTOR;
38
    }
39
40
    /**
41
     * {@inheritdoc}
42
     */
43
    public function compile(): void
44
    {
45
        // Decode JSON content
46
        try {
47
            $decoded = Json::decode('[' . $this->getStringContent() . ']');
48
        } catch (JsonException $exception) {
49
            throw new AnnotationParseException('"construct" annotation content is invalid (invalid JSON content)');
50
        }
51
        $this->validate($decoded);
52
53
        $index = 0;
54
        // If there is a custom constructor class
55
        if (Validator::stringType()->validate($decoded[$index])) {
56
            // Get the last name part
57
            $nameArray = explode('\\', $decoded[$index]);
58
            $lastPart  = end($nameArray);
59
            // Add use to PhpFile
60
            $this->getParentNode()->getParentNode()->addConcreteUse($decoded[$index], $lastPart);
0 ignored issues
show
Bug introduced by
The method addConcreteUse() does not exist on PhpUnitGen\Model\PropertyInterface\NodeInterface. It seems like you code against a sub-type of PhpUnitGen\Model\PropertyInterface\NodeInterface such as PhpUnitGen\Model\ModelIn...e\PhpFileModelInterface or PhpUnitGen\Model\ModelIn...e\PhpFileModelInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

60
            $this->getParentNode()->getParentNode()->/** @scrutinizer ignore-call */ addConcreteUse($decoded[$index], $lastPart);
Loading history...
61
            $this->class = $lastPart;
62
            $index++;
63
        }
64
        $this->parameters = $decoded[$index];
65
    }
66
67
    /**
68
     * Validate the content of annotation.
69
     *
70
     * @param mixed $decoded The annotation content.
71
     *
72
     * @throws AnnotationParseException If the content is invalid.
73
     */
74
    private function validate($decoded): void
75
    {
76
        // Validate it is an array
77
        if (! Validator::arrayType()->length(1, 2)->validate($decoded)) {
78
            throw new AnnotationParseException(
79
                '"construct" annotation content is invalid (must contains parameters array, and maybe a class)'
80
            );
81
        }
82
83
        $size = count($decoded);
84
85
        // Validate that if size is 2, first value is a string
86
        if ($size === 2 && ! Validator::stringType()->validate($decoded[0])) {
87
            throw new AnnotationParseException(
88
                '"construct" annotation content is invalid (constructor class must be a string)'
89
            );
90
        }
91
        // Validate that last value is an array
92
        if (! Validator::arrayVal()->each(Validator::stringType(), Validator::intType())->validate($decoded[$size-1])) {
93
            throw new AnnotationParseException(
94
                '"construct" annotation content is invalid (constructor parameters must be a array of string)'
95
            );
96
        }
97
    }
98
99
    /**
100
     * @return string|null The class name, null if none.
101
     */
102
    public function getClass(): ?string
103
    {
104
        return $this->class;
105
    }
106
107
    /**
108
     * @return array The constructor parameters.
109
     */
110
    public function getParameters(): array
111
    {
112
        return $this->parameters;
113
    }
114
}
115