GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

AbstractResourceTest   A
last analyzed

Complexity

Total Complexity 29

Size/Duplication

Total Lines 216
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 29
lcom 1
cbo 8
dl 0
loc 216
ccs 0
cts 159
cp 0
rs 10
c 0
b 0
f 0

12 Methods

Rating   Name   Duplication   Size   Complexity  
getSyncAsync() 0 1 ?
getClass() 0 1 ?
getNamespace() 0 1 ?
A provideProperties() 0 4 1
A providePropertiesIncompatible() 0 4 1
B providePropertiesGenerator() 0 44 9
A testProperties() 0 19 2
A testPropertiesIncompatible() 0 29 4
A testInterface() 0 9 1
A generateTypeValues() 0 33 5
A getDocBlock() 0 8 2
A getAnnotation() 0 32 4
1
<?php
2
declare(strict_types=1);
3
4
namespace ApiClients\Tools\ResourceTestUtilities;
5
6
use ApiClients\Foundation\Hydrator\Annotation\Rename;
7
use ApiClients\Foundation\Hydrator\AnnotationInterface;
8
use ApiClients\Foundation\Resource\ResourceInterface;
9
use Doctrine\Common\Annotations\AnnotationReader;
10
use Doctrine\Common\Inflector\Inflector;
11
use phpDocumentor\Reflection\DocBlock;
12
use phpDocumentor\Reflection\DocBlockFactory;
13
use ReflectionClass;
14
use ReflectionProperty;
15
use TypeError;
16
17
abstract class AbstractResourceTest extends TestCase
18
{
19
    abstract public function getSyncAsync(): string;
20
21
    abstract public function getClass(): string;
22
23
    abstract public function getNamespace(): string;
24
25
    public function provideProperties(): array
26
    {
27
        return [[$this->providePropertiesGenerator('compatible')]];
28
    }
29
30
    public function providePropertiesIncompatible(): array
31
    {
32
        return [[$this->providePropertiesGenerator('incompatible')]];
33
    }
34
35
    public function providePropertiesGenerator(string $typeMethod): array
36
    {
37
        $yield = [];
38
        $class = new ReflectionClass($this->getClass());
39
40
        $jsonTemplate = [];
41
        foreach ($class->getProperties() as $property) {
42
            $key = $property->getName();
43
            $renamed = self::GetAnnotation($property->getDeclaringClass()->getName(), Rename::class);
0 ignored issues
show
introduced by
Consider using $property->class. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
44
45
            if ($renamed instanceof Rename && $renamed->has($key)) {
46
                $key = $renamed->get($key);
47
            }
48
49
            $jsonTemplate[$key] = '';
50
        }
51
52
        foreach ($class->getProperties() as $property) {
53
            $method = Inflector::camelize($property->getName());
54
            $docBlock = $this->getDocBlock($property->getDocComment());
55
56
            $varTag = $docBlock->getTagsByName('var');
57
            if (count($varTag) !== 1) {
58
                continue;
59
            }
60
61
            $varTag = $varTag[0];
62
            $scalar = (string)$varTag->getType();
63
            if ($scalar === '') {
64
                continue;
65
            }
66
67
            if (!Types::has($scalar)) {
68
                continue;
69
            }
70
71
            $type = Types::get($scalar);
72
            foreach ($this->generateTypeValues($type, $property, $method, $typeMethod, $jsonTemplate) as $item) {
73
                $yield[] = $item;
74
            }
75
        }
76
77
        return $yield;
78
    }
79
80
    /**
81
     * @dataProvider provideProperties
82
     * @param mixed $args
83
     */
84
    public function testProperties($args)
85
    {
86
        foreach ($args as $arg) {
87
            list($property, $method, $type, $json, $value) = $arg;
0 ignored issues
show
Unused Code introduced by
The assignment to $property is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
88
            $class = $this->getClass();
89
            $resource = $this->hydrate(
90
                str_replace(
91
                    $this->getNamespace(),
92
                    $this->getNamespace() . '\\Async',
93
                    $class
94
                ),
95
                $json,
96
                $this->getNamespace(),
97
                'Async'
98
            );
99
            $this->assertSame($value, $resource->{$method}());
100
            $this->assertInternalType($type->scalar(), $resource->{$method}());
101
        }
102
    }
103
104
    /**
105
     * @dataProvider providePropertiesIncompatible
106
     * @param mixed $args
107
     */
108
    public function testPropertiesIncompatible($args)
109
    {
110
        foreach ($args as $arg) {
111
            list($property, $method, $type, $json, $value) = $arg;
0 ignored issues
show
Unused Code introduced by
The assignment to $property is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
Unused Code introduced by
The assignment to $type is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
112
113
            try {
114
                $class = $this->getClass();
115
                $resource = $this->hydrate(
116
                    str_replace(
117
                        $this->getNamespace(),
118
                        $this->getNamespace() . '\\Async',
119
                        $class
120
                    ),
121
                    $json,
122
                    $this->getNamespace(),
123
                    'Async'
124
                );
125
126
                if ($value !== $resource->{$method}()) {
127
                    throw new TypeError();
128
                }
129
            } catch (\Throwable $t) {
130
                $this->assertTrue(true);
131
                continue;
132
            }
133
134
            $this->fail('We should not reach this');
135
        }
136
    }
137
138
    public function testInterface()
139
    {
140
        $this->assertTrue(
141
            is_subclass_of(
0 ignored issues
show
Bug introduced by
Due to PHP Bug #53727, is_subclass_of might return inconsistent results on some PHP versions if \ApiClients\Foundation\R...esourceInterface::class can be an interface. If so, you could instead use ReflectionClass::implementsInterface.
Loading history...
142
                $this->getClass(),
143
                ResourceInterface::class
144
            )
145
        );
146
    }
147
148
    protected function generateTypeValues(
149
        Type $type,
150
        ReflectionProperty $property,
151
        string $method,
152
        string $typeMethod,
153
        array $jsonTemplate
154
    ): array {
155
        $yield = [];
156
        $json = $jsonTemplate;
157
        foreach ($type->$typeMethod() as $typeClass) {
158
            $methodType = Types::get(constant($typeClass . '::SCALAR'));
159
            foreach ($methodType->generate(3) as $value) {
160
                $key = $property->getName();
161
162
                $renamed = self::GetAnnotation($property->getDeclaringClass()->getName(), Rename::class);
0 ignored issues
show
introduced by
Consider using $property->class. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
163
                if ($renamed instanceof Rename && $renamed->has($key)) {
164
                    $key = $renamed->get($key);
165
                }
166
167
                $json[$key] = $value;
168
169
                $yield[] = [
170
                    $property->getName(), // Name of the property to assign data to
171
                    $method,              // Method to call verifying that data
172
                    $type,                // The different types of data associated with this field
173
                    $json,                // JSON to use during testing
174
                    $value,               // Value to check against
175
                ];
176
            }
177
        }
178
179
        return $yield;
180
    }
181
182
    /**
183
     * @param $docBlockContents
184
     * @return DocBlock
185
     */
186
    protected function getDocBlock(string $docBlockContents): DocBlock
187
    {
188
        if (class_exists('phpDocumentor\Reflection\DocBlockFactory')) {
189
            return DocBlockFactory::createInstance()->create($docBlockContents);
190
        }
191
192
        return new DocBlock($docBlockContents);
193
    }
194
195
    /**
196
     * @param  string                   $class
197
     * @param  string                   $annotationClass
198
     * @return null|AnnotationInterface
199
     */
200
    protected static function getAnnotation(string $class, string $annotationClass)
201
    {
202
        $annotationReader = new AnnotationReader();
203
204
        $annotation = $annotationReader
205
            ->getClassAnnotation(
206
                new ReflectionClass($class),
207
                $annotationClass
208
            )
209
        ;
210
211
        if ($annotation === null) {
212
            return null;
213
        }
214
215
        if (get_class($annotation) === $annotationClass) {
216
            return $annotation;
217
        }
218
219
        $class = get_parent_class($class);
220
221
        if ($class === false) {
222
            return null;
223
        }
224
225
        return $annotationReader
226
            ->getClassAnnotation(
227
                new ReflectionClass($class),
228
                $annotationClass
229
            )
230
            ;
231
    }
232
}
233