Ambient::theProperty()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 7

Duplication

Lines 7
Ratio 100 %

Importance

Changes 0
Metric Value
dl 7
loc 7
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
1
<?php
2
/**
3
 * ShouldPHP
4
 *
5
 * @author  Gabriel Jacinto <[email protected]>
6
 * @status  dev
7
 * @link    https://github.com/GabrielJMJ/ShouldPHP
8
 * @license MIT
9
 */
10
 
11
namespace Gabrieljmj\Should\Ambient;
12
13
use Gabrieljmj\Should\Ambient\AmbientInterface;
14
use Gabrieljmj\Should\ShouldClass;
15
use Gabrieljmj\Should\ShouldMethod;
16
use Gabrieljmj\Should\ShouldProperty;
17
use Gabrieljmj\Should\ShouldParameter;
18
use Gabrieljmj\Should\TheClass;
19
use Gabrieljmj\Should\TheMethod;
20
use Gabrieljmj\Should\TheProperty;
21
use Gabrieljmj\Should\TheParameter;
22
use Gabrieljmj\Should\Report\Report;
23
use Gabrieljmj\Should\Report\AssertReport;
24
use Gabrieljmj\Should\Report\AssertType;
25
26
class Ambient implements AmbientInterface
27
{
28
    /**
29
     * @var array
30
     */
31
    private $classCollection = [];
32
    
33
    /**
34
     * @var array
35
     */
36
    private $methodCollection = [];
37
    
38
    /**
39
     * @var array
40
     */
41
    private $propertyCollection = [];
42
43
    /**
44
     * @var array
45
     */
46
    private $parameterCollection = [];
47
48
    /**
49
     * @var string
50
     */
51
    protected $name;
52
    
53
    /**
54
     * @var \Gabrieljmj\Should\Report\Report
55
     */
56
    private $report;
57
    
58
    /**
59
     * @param string $name
60
     */
61
    final public function __construct($name = null)
62
    {
63
        if ($name !== null) {
64
            $this->name = $name;
65
        }
66
    }
67
    
68
    /**
69
     * @param string|object $class
70
     * @param array         $args
71
     * @return \Gabrieljmj\Should\TheClass
72
     */
73
    public function theClass($class, array $args = [])
74
    {
75
        $className = $this->getClassAsString($class);
76
77
        if (!is_object($class)) {
78
            $ref = new \ReflectionClass($class);
79
            $class = $ref->newInstanceArgs($args);
80
        }
81
        
82
        return $this->create('class', [$class], $className);
83
    }
84
    
85
    /**
86
     * @param string|object $class
87
     * @param string        $method
88
     * @return \Gabrieljmj\Should\TheMethod
89
     */
90 View Code Duplication
    public function theMethod($class, $method)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
91
    {
92
        $className = $this->getClassAsString($class);
93
        $index = $className . ':' . $method;
94
95
        return $this->create('method', func_get_args(), $index);
96
    }
97
98
    /**
99
     * @param string|object  $class
100
     * @param string         $property
101
     * @return \Gabrieljmj\Should\TheProperty
102
     */
103 View Code Duplication
    public function theProperty($class, $property)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
104
    {
105
        $className = $this->getClassAsString($class);
106
        $index = $className . ':' . $property;
107
108
        return $this->create('property', func_get_args(), $index);
109
    }
110
111
    /**
112
     * @param string|object $class
113
     * @param string        $method
114
     * @param string        $parameter
115
     * @return \Gabrieljmj\Should\TheParameter
116
     */
117 View Code Duplication
    public function theParameter($class, $method, $parameter)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
118
    {
119
        $className = $this->getClassAsString($class);
120
        $index = $className . ':' . $method . ':' . $parameter;
121
122
        return $this->create('parameter', func_get_args(), $index);
123
    }
124
    
125
    /**
126
     * Runs the tests and create the report
127
     */
128
    public function run()
129
    {
130
        $classAssertList = $this->createAssertList($this->classCollection);
131
        $methodAssertList = $this->createAssertList($this->methodCollection);
132
        $propertyAssertList = $this->createAssertList($this->propertyCollection);
133
        $parameterAssertList = $this->createAssertList($this->parameterCollection);
134
        
135
        $this->createReport($classAssertList, $methodAssertList, $propertyAssertList, $parameterAssertList);
136
    }
137
    
138
    /**
139
     * Returns the ambient tests report
140
     *
141
     * @param \Gabrieljmj\Should\Report\Report
142
     */
143
    public function getReport()
144
    {
145
        return $this->report;
146
    }
147
    
148
    /**
149
     * Returns the ambient name
150
     *
151
     * @return string
152
     */
153
    public function getName()
154
    {
155
        return $this->name === null ? get_class($this) : $this->name;
156
    }
157
    
158
    /**
159
     * @param array $classAssertList
160
     * @param array $methodAssertList
161
     * @return \Gabrieljmj\Should\Report
162
     */
163
    private function createReport(array $classAssertList, array $methodAssertList, array $propertyAssertList, array $parameterAssertList)
164
    {
165
        if (!$this->report instanceof Report) {
166
            $this->report = new Report($this->getName());
167
        }
168
169
        $this->createReportOfSomeType(AssertType::CLASS_T, $classAssertList);
170
        $this->createReportOfSomeType(AssertType::METHOD_T, $methodAssertList);
171
        $this->createReportOfSomeType(AssertType::PROPERTY_T, $propertyAssertList);
172
        $this->createReportOfSomeType(AssertType::PARAMETER_T, $parameterAssertList);
173
    }
174
175
    /**
176
     * @param string $type
177
     * @param array  $assertList
178
     */
179
    private function createReportOfSomeType($type, array $assertList) {
180
        foreach ($assertList as $assert) {
181
            $assertReport = new AssertReport($type, $assert);
182
            $this->report->addAssert($assertReport);
183
        }
184
    }
185
186
    /**
187
     * @param string|object $class
188
     * @return string
189
     */
190
    private function getClassAsString($class)
191
    {
192
        return is_object($class) ? get_class($class) : $class;
193
    }
194
195
    private function createAssertList(array $collection)
196
    {
197
        $assertList = [];
198
199
        foreach ($collection as $item) {
200
            foreach ($item->should->getAssertList() as $assert) {
201
                $assertList[] = $assert;
202
            }
203
        }
204
205
        return $assertList;
206
    }
207
208
    private function create($param, array $shouldParams, $index)
209
    {
210
        $shouldClass = '\Gabrieljmj\Should\Should' . ucfirst($param);
211
        $typeClass = '\Gabrieljmj\Should\The' . ucfirst($param);
212
        $collectionVarName = strtolower($param) . 'Collection';
213
214
        if (!isset($this->{$collectionVarName}[$index])) {
215
            $shoudlRef = new \ReflectionClass($shouldClass);
216
            $should = $shoudlRef->newInstanceArgs($shouldParams);
217
            $typeRef = new \ReflectionClass($typeClass);
218
219
            $this->{$collectionVarName}[$index] = $typeRef->newInstance($should);
220
        }
221
222
        return $this->{$collectionVarName}[$index];
223
    }
224
}