Failed Conditions
Pull Request — new-parser-ast-metadata (#5)
by
unknown
02:27
created

testGetInvalidPropertyAnnotations()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 7
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\Tests\Annotations;
6
7
use Doctrine\Annotations\Annotation\IgnoreAnnotation;
8
use Doctrine\Annotations\Assembler\Constant\ReflectionConstantResolver;
9
use Doctrine\Annotations\Assembler\Validator\Exception\InvalidTarget;
10
use Doctrine\Annotations\Assembler\Validator\Exception\InvalidValue;
11
use Doctrine\Annotations\Metadata\MetadataCollection;
12
use Doctrine\Annotations\Metadata\Reflection\DefaultReflectionProvider;
13
use Doctrine\Annotations\NewAnnotationReader;
14
use Doctrine\Tests\Annotations\Fixtures;
15
use Hoa\Compiler\Exception\UnrecognizedToken;
16
use PHPUnit\Framework\TestCase;
17
use TopLevelAnnotation;
18
19
class NewAnnotationReaderTest extends TestCase
20
{
21
    /** @var MetadataCollection */
22
    private $collection;
23
24
    /** @var NewAnnotationReader */
25
    private $reader;
26
27
    public function setUp() : void
28
    {
29
        $this->collection = new MetadataCollection();
30
        $this->reader     = new NewAnnotationReader(
31
            $this->collection,
32
            new DefaultReflectionProvider(),
33
            new ReflectionConstantResolver(new DefaultReflectionProvider())
34
        );
35
    }
36
37
    /**
38
     * @dataProvider classAnnotationExamples
39
     */
40
    public function testGetClassAnnotations(string $className, callable $expectedFactory) : void
41
    {
42
        $class = new \ReflectionClass($className);
43
44
        $annotations = $this->reader->getClassAnnotations($class);
45
46
        $this->assertEquals($expectedFactory(), $annotations);
47
    }
48
49
    /**
50
     * @return mixed[]
51
     */
52
    public function classAnnotationExamples() : iterable
53
    {
54
        yield 'ClassWithAnnotationTargetAll' => [
0 ignored issues
show
Bug Best Practice introduced by
The expression yield 'ClassWithAnnotati...ion(...) { /* ... */ }) returns the type Generator which is incompatible with the documented return type array<mixed,mixed>.
Loading history...
55
            Fixtures\ClassWithAnnotationTargetAll::class,
56
            static function () : array {
57
                $annotation = new Fixtures\AnnotationTargetAll();
58
                $annotation->name = '123';
59
60
                return [$annotation];
61
            },
62
        ];
63
64
        yield 'ClassWithValidAnnotationTarget' => [
65
            Fixtures\ClassWithValidAnnotationTarget::class,
66
            static function () : array {
67
                $annotation = new Fixtures\AnnotationTargetClass();
68
                $annotation->data = 'Some data';
69
70
                return [$annotation];
71
            },
72
        ];
73
74
        yield 'DummyClassWithDanglingComma' => [
75
            DummyClassWithDanglingComma::class,
76
            static function () : array {
77
                $annotation = new DummyAnnotation([
78
                    'dummyValue' => 'bar'
79
                ]);
80
81
                return [$annotation];
82
            },
83
        ];
84
85
        yield 'ClassWithRequire' => [
86
            Fixtures\ClassWithRequire::class,
87
            static function () : array {
88
                $annotation = new DummyAnnotationWithIgnoredAnnotation([
89
                    'dummyValue' => 'hello'
90
                ]);
91
92
                return [$annotation];
93
            },
94
        ];
95
96
        yield 'TestIgnoresNonAnnotationsClass' => [
97
            TestIgnoresNonAnnotationsClass::class,
98
            static function () : array {
99
                return [new Name([])];
100
            },
101
        ];
102
103
        yield 'InvalidAnnotationUsageButIgnoredClass' => [
104
            Fixtures\InvalidAnnotationUsageButIgnoredClass::class,
105
            static function () : array {
106
                $routeAnnotation = new Fixtures\Annotation\Route();
107
                $routeAnnotation->name = 'foo';
108
109
                return [
110
                    new IgnoreAnnotation(["NoAnnotation"]),
111
                    $routeAnnotation
112
                ];
113
            },
114
        ];
115
116
        yield 'InvalidAnnotationButIgnored - DDC-1660' => [
117
            Fixtures\ClassDDC1660::class,
118
            static function () : array {
119
                return [];
120
            },
121
        ];
122
123
        yield 'ignore case insensitivity - DCOM-106' => [
124
            DCOM106::class,
125
            static function () : array {
126
                return [];
127
            },
128
        ];
129
    }
130
131
    /**
132
     * @dataProvider invalidClassAnnotationExamples
133
     */
134
    public function testGetInvalidClassAnnotations(string $className, string $expectedException) : void
135
    {
136
        $class = new \ReflectionClass($className);
137
138
        $this->expectException($expectedException);
139
140
        $this->reader->getClassAnnotations($class);
141
    }
142
143
    /**
144
     * @return mixed[]
145
     */
146
    public function invalidClassAnnotationExamples() : iterable
147
    {
148
        yield 'ClassWithAnnotationTargetAll' => [
0 ignored issues
show
Bug Best Practice introduced by
The expression yield 'ClassWithAnnotati...n\InvalidTarget::class) returns the type Generator which is incompatible with the documented return type array<mixed,mixed>.
Loading history...
149
            Fixtures\ClassWithInvalidAnnotationTargetAtClass::class,
150
            InvalidTarget::class
151
        ];
152
153
        yield 'ClassWithAnnotationWithTargetSyntaxError' => [
154
            Fixtures\ClassWithAnnotationWithTargetSyntaxError::class,
155
            UnrecognizedToken::class
156
        ];
157
158
        yield 'DummyClassSyntaxError' => [
159
            DummyClassSyntaxError::class,
160
            UnrecognizedToken::class
161
        ];
162
163
        yield 'InvalidAnnotationUsageClass' => [
164
            Fixtures\InvalidAnnotationUsageClass::class,
165
            UnrecognizedToken::class
166
        ];
167
    }
168
169
    /**
170
     * @dataProvider methodAnnotationExamples
171
     */
172
    public function testGetMethodAnnotations(string $className, string $methodName, callable $expectedFactory) : void
173
    {
174
        $method = new \ReflectionMethod($className, $methodName);
175
176
        $annotations = $this->reader->getMethodAnnotations($method);
177
178
        $this->assertEquals($expectedFactory(), $annotations);
179
    }
180
181
    /**
182
     * @return mixed[]
183
     */
184
    public function methodAnnotationExamples() : iterable
185
    {
186
        yield 'ClassWithAnnotationWithVarType - bar' => [
0 ignored issues
show
Bug Best Practice introduced by
The expression yield 'ClassWithAnnotati...ion(...) { /* ... */ }) returns the type Generator which is incompatible with the documented return type array<mixed,mixed>.
Loading history...
187
            Fixtures\ClassWithAnnotationWithVarType::class,
188
            'bar',
189
            static function () : array {
190
                $annotation = new Fixtures\AnnotationWithVarType();
191
                $annotation->annotation = new Fixtures\AnnotationTargetAll();
192
193
                return [$annotation];
194
            },
195
        ];
196
197
        yield 'InvalidAnnotationButIgnored - DDC-1660 - bar' => [
198
            Fixtures\ClassDDC1660::class,
199
            'bar',
200
            static function () : array {
201
                return [];
202
            },
203
        ];
204
    }
205
206
    /**
207
     * @dataProvider invalidMethodAnnotationExamples
208
     */
209
    public function testGetInvalidMethodAnnotations(string $className, string $methodName, string $expectedException) : void
210
    {
211
        $method = new \ReflectionMethod($className, $methodName);
212
213
        $this->expectException($expectedException);
214
215
        $this->reader->getMethodAnnotations($method);
216
    }
217
218
    /**
219
     * @return mixed[]
220
     */
221
    public function invalidMethodAnnotationExamples() : iterable
222
    {
223
        yield 'ClassWithInvalidAnnotationTargetAtMethod - functionName' => [
0 ignored issues
show
Bug Best Practice introduced by
The expression yield 'ClassWithInvalidA...n\InvalidTarget::class) returns the type Generator which is incompatible with the documented return type array<mixed,mixed>.
Loading history...
224
            Fixtures\ClassWithInvalidAnnotationTargetAtMethod::class,
225
            'functionName',
226
            InvalidTarget::class
227
        ];
228
229
        yield 'ClassWithAnnotationWithTargetSyntaxError - bar' => [
230
            Fixtures\ClassWithAnnotationWithTargetSyntaxError::class,
231
            'bar',
232
            UnrecognizedToken::class
233
        ];
234
235
        yield 'ClassWithAnnotationWithVarType - invalidMethod' => [
236
            Fixtures\ClassWithAnnotationWithVarType::class,
237
            'invalidMethod',
238
            InvalidValue::class
239
        ];
240
241
        yield 'DummyClassMethodSyntaxError - foo' => [
242
            DummyClassMethodSyntaxError::class,
243
            'foo',
244
            UnrecognizedToken::class
245
        ];
246
247
        yield 'ClassWithAnnotationEnum - invalid value - bar' => [
248
            Fixtures\ClassWithAnnotationEnum::class,
249
            'bar',
250
            InvalidValue::class
251
        ];
252
    }
253
254
    /**
255
     * @dataProvider propertyAnnotationExamples
256
     */
257
    public function testGetPropertyAnnotations(string $className, string $propertyName, callable $expectedFactory) : void
258
    {
259
        $property = new \ReflectionProperty($className, $propertyName);
260
261
        $annotations = $this->reader->getPropertyAnnotations($property);
262
263
        $this->assertEquals($expectedFactory(), $annotations);
264
    }
265
266
    /**
267
     * @return mixed[]
268
     */
269
    public function propertyAnnotationExamples() : iterable
270
    {
271
        yield 'ClassWithValidAnnotationTarget - foo' => [
0 ignored issues
show
Bug Best Practice introduced by
The expression yield 'ClassWithValidAnn...ion(...) { /* ... */ }) returns the type Generator which is incompatible with the documented return type array<mixed,mixed>.
Loading history...
272
            Fixtures\ClassWithValidAnnotationTarget::class,
273
            'foo',
274
            static function () : array {
275
                $annotation = new Fixtures\AnnotationTargetPropertyMethod();
276
                $annotation->data = 'Some data';
277
278
                return [$annotation];
279
            },
280
        ];
281
282
        yield 'ClassWithValidAnnotationTarget - name' => [
283
            Fixtures\ClassWithValidAnnotationTarget::class,
284
            'name',
285
            static function () : array {
286
                $annotation = new Fixtures\AnnotationTargetAll();
287
                $annotation->data = 'Some data';
288
                $annotation->name = 'Some name';
289
290
                return [$annotation];
291
            },
292
        ];
293
294
        yield 'ClassWithAnnotationWithVarType - bar' => [
295
            Fixtures\ClassWithAnnotationWithVarType::class,
296
            'foo',
297
            static function () : array {
298
                $annotation = new Fixtures\AnnotationWithVarType();
299
                $annotation->string = 'String Value';
300
301
                return [$annotation];
302
            },
303
        ];
304
305
        yield 'ClassWithAtInDescriptionAndAnnotation - foo' => [
306
            Fixtures\ClassWithAtInDescriptionAndAnnotation::class,
307
            'foo',
308
            static function () : array {
309
                $annotation = new Fixtures\AnnotationTargetPropertyMethod();
310
                $annotation->data = 'Bar';
311
312
                return [$annotation];
313
            },
314
        ];
315
316
        yield 'ClassWithAtInDescriptionAndAnnotation - bar' => [
317
            Fixtures\ClassWithAtInDescriptionAndAnnotation::class,
318
            'bar',
319
            static function () : array {
320
                $annotation = new Fixtures\AnnotationTargetPropertyMethod();
321
                $annotation->data = 'Bar';
322
323
                return [$annotation];
324
            },
325
        ];
326
327
        yield 'DummyClass2 - id - multiple annotations on the same line' => [
328
            DummyClass2::class,
329
            'id',
330
            static function () : array {
331
                return [
332
                    new DummyId([]),
333
                    new DummyColumn(['type' => 'integer']),
334
                    new DummyGeneratedValue([])
335
                ];
336
            },
337
        ];
338
339
        yield 'DummyClassNonAnnotationProblem - foo' => [
340
            DummyClassNonAnnotationProblem::class,
341
            'foo',
342
            static function () : array {
343
                return [
344
                    new DummyAnnotation([])
345
                ];
346
            },
347
        ];
348
349
        yield 'TestParentClass - child' => [
350
            TestParentClass::class,
351
            'child',
352
            static function () : array {
353
                return [
354
                    new Foo\Name([
355
                        'name' => 'foo'
356
                    ])
357
                ];
358
            },
359
        ];
360
361
        yield 'TestParentClass - parent' => [
362
            TestParentClass::class,
363
            'parent',
364
            static function () : array {
365
                return [
366
                    new Bar\Name([
367
                        'name' => 'bar'
368
                    ])
369
                ];
370
            },
371
        ];
372
373
        yield 'TestTopLevelAnnotationClass - field' => [
374
            TestTopLevelAnnotationClass::class,
375
            'field',
376
            static function () : array {
377
                return [
378
                    new TopLevelAnnotation([])
379
                ];
380
            },
381
        ];
382
383
        yield 'InvalidAnnotationButIgnored - DDC-1660 - foo' => [
384
            Fixtures\ClassDDC1660::class,
385
            'foo',
386
            static function () : array {
387
                return [];
388
            },
389
        ];
390
    }
391
392
    /**
393
     * @dataProvider invalidPropertyAnnotationExamples
394
     */
395
    public function testGetInvalidPropertyAnnotations(string $className, string $methodName, string $expectedException) : void
396
    {
397
        $property = new \ReflectionProperty($className, $methodName);
398
399
        $this->expectException($expectedException);
400
401
        $this->reader->getPropertyAnnotations($property);
402
    }
403
404
    /**
405
     * @return mixed[]
406
     */
407
    public function invalidPropertyAnnotationExamples() : iterable
408
    {
409
        yield 'ClassWithInvalidAnnotationTargetAtProperty - foo' => [
0 ignored issues
show
Bug Best Practice introduced by
The expression yield 'ClassWithInvalidA...n\InvalidTarget::class) returns the type Generator which is incompatible with the documented return type array<mixed,mixed>.
Loading history...
410
            Fixtures\ClassWithInvalidAnnotationTargetAtProperty::class,
411
            'foo',
412
            InvalidTarget::class
413
        ];
414
415
        yield 'ClassWithInvalidAnnotationTargetAtProperty - bar' => [
416
            Fixtures\ClassWithInvalidAnnotationTargetAtProperty::class,
417
            'bar',
418
            InvalidTarget::class
419
        ];
420
421
        yield 'ClassWithAnnotationWithTargetSyntaxError - foo' => [
422
            Fixtures\ClassWithAnnotationWithTargetSyntaxError::class,
423
            'foo',
424
            UnrecognizedToken::class
425
        ];
426
427
        yield 'ClassWithAnnotationWithVarType - invalidProperty' => [
428
            Fixtures\ClassWithAnnotationWithVarType::class,
429
            'invalidProperty',
430
            InvalidValue::class
431
        ];
432
433
        yield 'DummyClassPropertySyntaxError - foo' => [
434
            DummyClassPropertySyntaxError::class,
435
            'foo',
436
            UnrecognizedToken::class
437
        ];
438
439
        yield 'TestAnnotationNotImportedClass - field' => [
440
            TestAnnotationNotImportedClass::class,
441
            'field',
442
            \ReflectionException::class
443
        ];
444
445
        yield 'TestNonExistentAnnotationClass - field' => [
446
            TestNonExistentAnnotationClass::class,
447
            'field',
448
            \ReflectionException::class
449
        ];
450
451
        yield 'ClassWithAnnotationEnum - invalid value - foo' => [
452
            Fixtures\ClassWithAnnotationEnum::class,
453
            'foo',
454
            InvalidValue::class
455
        ];
456
    }
457
}
458