Total Complexity | 73 |
Total Lines | 1364 |
Duplicated Lines | 0 % |
Changes | 0 |
Complex classes like DocParserTest often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use DocParserTest, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
15 | class DocParserTest extends TestCase |
||
16 | { |
||
17 | public function testNestedArraysWithNestedAnnotation() |
||
18 | { |
||
19 | $parser = $this->createTestParser(); |
||
20 | |||
21 | // Nested arrays with nested annotations |
||
22 | $result = $parser->parse('@Name(foo={1,2, {"key"=@Name}})'); |
||
23 | $annot = $result[0]; |
||
24 | |||
25 | self::assertInstanceOf(Name::class, $annot); |
||
26 | self::assertNull($annot->value); |
||
27 | self::assertCount(3, $annot->foo); |
||
28 | self::assertEquals(1, $annot->foo[0]); |
||
29 | self::assertEquals(2, $annot->foo[1]); |
||
30 | self::assertInternalType('array', $annot->foo[2]); |
||
31 | |||
32 | $nestedArray = $annot->foo[2]; |
||
33 | self::assertTrue(isset($nestedArray['key'])); |
||
34 | self::assertInstanceOf(Name::class, $nestedArray['key']); |
||
35 | } |
||
36 | |||
37 | public function testBasicAnnotations() |
||
38 | { |
||
39 | $parser = $this->createTestParser(); |
||
40 | |||
41 | // Marker annotation |
||
42 | $result = $parser->parse('@Name'); |
||
43 | $annot = $result[0]; |
||
44 | self::assertInstanceOf(Name::class, $annot); |
||
45 | self::assertNull($annot->value); |
||
46 | self::assertNull($annot->foo); |
||
47 | |||
48 | // Associative arrays |
||
49 | $result = $parser->parse('@Name(foo={"key1" = "value1"})'); |
||
50 | $annot = $result[0]; |
||
51 | self::assertNull($annot->value); |
||
52 | self::assertInternalType('array', $annot->foo); |
||
53 | self::assertTrue(isset($annot->foo['key1'])); |
||
54 | |||
55 | // Numerical arrays |
||
56 | $result = $parser->parse('@Name({2="foo", 4="bar"})'); |
||
57 | $annot = $result[0]; |
||
58 | self::assertInternalType('array', $annot->value); |
||
59 | self::assertEquals('foo', $annot->value[2]); |
||
60 | self::assertEquals('bar', $annot->value[4]); |
||
61 | self::assertFalse(isset($annot->value[0])); |
||
62 | self::assertFalse(isset($annot->value[1])); |
||
63 | self::assertFalse(isset($annot->value[3])); |
||
64 | |||
65 | // Multiple values |
||
66 | $result = $parser->parse('@Name(@Name, @Name)'); |
||
67 | $annot = $result[0]; |
||
68 | |||
69 | self::assertInstanceOf(Name::class, $annot); |
||
70 | self::assertInternalType('array', $annot->value); |
||
71 | self::assertInstanceOf(Name::class, $annot->value[0]); |
||
72 | self::assertInstanceOf(Name::class, $annot->value[1]); |
||
73 | |||
74 | // Multiple types as values |
||
75 | $result = $parser->parse('@Name(foo="Bar", @Name, {"key1"="value1", "key2"="value2"})'); |
||
76 | $annot = $result[0]; |
||
77 | |||
78 | self::assertInstanceOf(Name::class, $annot); |
||
79 | self::assertInternalType('array', $annot->value); |
||
80 | self::assertInstanceOf(Name::class, $annot->value[0]); |
||
81 | self::assertInternalType('array', $annot->value[1]); |
||
82 | self::assertEquals('value1', $annot->value[1]['key1']); |
||
83 | self::assertEquals('value2', $annot->value[1]['key2']); |
||
84 | |||
85 | // Complete docblock |
||
86 | $docblock = <<<DOCBLOCK |
||
87 | /** |
||
88 | * Some nifty class. |
||
89 | * |
||
90 | * @author Mr.X |
||
91 | * @Name(foo="bar") |
||
92 | */ |
||
93 | DOCBLOCK; |
||
94 | |||
95 | $result = $parser->parse($docblock); |
||
96 | self::assertCount(1, $result); |
||
97 | $annot = $result[0]; |
||
98 | self::assertInstanceOf(Name::class, $annot); |
||
99 | self::assertEquals('bar', $annot->foo); |
||
100 | self::assertNull($annot->value); |
||
101 | } |
||
102 | |||
103 | public function testDefaultValueAnnotations() |
||
104 | { |
||
105 | $parser = $this->createTestParser(); |
||
106 | |||
107 | // Array as first value |
||
108 | $result = $parser->parse('@Name({"key1"="value1"})'); |
||
109 | $annot = $result[0]; |
||
110 | |||
111 | self::assertInstanceOf(Name::class, $annot); |
||
112 | self::assertInternalType('array', $annot->value); |
||
113 | self::assertEquals('value1', $annot->value['key1']); |
||
114 | |||
115 | // Array as first value and additional values |
||
116 | $result = $parser->parse('@Name({"key1"="value1"}, foo="bar")'); |
||
117 | $annot = $result[0]; |
||
118 | |||
119 | self::assertInstanceOf(Name::class, $annot); |
||
120 | self::assertInternalType('array', $annot->value); |
||
121 | self::assertEquals('value1', $annot->value['key1']); |
||
122 | self::assertEquals('bar', $annot->foo); |
||
123 | } |
||
124 | |||
125 | public function testNamespacedAnnotations() |
||
126 | { |
||
127 | $parser = new DocParser; |
||
128 | $parser->setIgnoreNotImportedAnnotations(true); |
||
129 | |||
130 | $docblock = <<<DOCBLOCK |
||
131 | /** |
||
132 | * Some nifty class. |
||
133 | * |
||
134 | * @package foo |
||
135 | * @subpackage bar |
||
136 | * @author Mr.X <[email protected]> |
||
137 | * @Doctrine\Tests\Annotations\Name(foo="bar") |
||
138 | * @ignore |
||
139 | */ |
||
140 | DOCBLOCK; |
||
141 | |||
142 | $result = $parser->parse($docblock); |
||
143 | self::assertCount(1, $result); |
||
144 | $annot = $result[0]; |
||
145 | self::assertInstanceOf(Name::class, $annot); |
||
146 | self::assertEquals('bar', $annot->foo); |
||
147 | } |
||
148 | |||
149 | /** |
||
150 | * @group debug |
||
151 | */ |
||
152 | public function testTypicalMethodDocBlock() |
||
153 | { |
||
154 | $parser = $this->createTestParser(); |
||
155 | |||
156 | $docblock = <<<DOCBLOCK |
||
157 | /** |
||
158 | * Some nifty method. |
||
159 | * |
||
160 | * @since 2.0 |
||
161 | * @Doctrine\Tests\Annotations\Name(foo="bar") |
||
162 | * @param string \$foo This is foo. |
||
163 | * @param mixed \$bar This is bar. |
||
164 | * @return string Foo and bar. |
||
165 | * @This is irrelevant |
||
166 | * @Marker |
||
167 | */ |
||
168 | DOCBLOCK; |
||
169 | |||
170 | $result = $parser->parse($docblock); |
||
171 | self::assertCount(2, $result); |
||
172 | self::assertTrue(isset($result[0])); |
||
173 | self::assertTrue(isset($result[1])); |
||
174 | $annot = $result[0]; |
||
175 | self::assertInstanceOf(Name::class, $annot); |
||
176 | self::assertEquals('bar', $annot->foo); |
||
177 | $marker = $result[1]; |
||
178 | self::assertInstanceOf(Marker::class, $marker); |
||
179 | } |
||
180 | |||
181 | |||
182 | public function testAnnotationWithoutConstructor() |
||
183 | { |
||
184 | $parser = $this->createTestParser(); |
||
185 | |||
186 | |||
187 | $docblock = <<<DOCBLOCK |
||
188 | /** |
||
189 | * @SomeAnnotationClassNameWithoutConstructor("Some data") |
||
190 | */ |
||
191 | DOCBLOCK; |
||
192 | |||
193 | $result = $parser->parse($docblock); |
||
194 | self::assertCount(1, $result); |
||
195 | $annot = $result[0]; |
||
196 | |||
197 | self::assertInstanceOf(SomeAnnotationClassNameWithoutConstructor::class, $annot); |
||
198 | |||
199 | self::assertNull($annot->name); |
||
200 | self::assertNotNull($annot->data); |
||
201 | self::assertEquals($annot->data, 'Some data'); |
||
202 | |||
203 | |||
204 | |||
205 | |||
206 | $docblock = <<<DOCBLOCK |
||
207 | /** |
||
208 | * @SomeAnnotationClassNameWithoutConstructor(name="Some Name", data = "Some data") |
||
209 | */ |
||
210 | DOCBLOCK; |
||
211 | |||
212 | |||
213 | $result = $parser->parse($docblock); |
||
214 | self::assertCount(1, $result); |
||
215 | $annot = $result[0]; |
||
216 | |||
217 | self::assertNotNull($annot); |
||
218 | self::assertInstanceOf(SomeAnnotationClassNameWithoutConstructor::class, $annot); |
||
219 | |||
220 | self::assertEquals($annot->name, 'Some Name'); |
||
221 | self::assertEquals($annot->data, 'Some data'); |
||
222 | |||
223 | |||
224 | |||
225 | |||
226 | $docblock = <<<DOCBLOCK |
||
227 | /** |
||
228 | * @SomeAnnotationClassNameWithoutConstructor(data = "Some data") |
||
229 | */ |
||
230 | DOCBLOCK; |
||
231 | |||
232 | $result = $parser->parse($docblock); |
||
233 | self::assertCount(1, $result); |
||
234 | $annot = $result[0]; |
||
235 | |||
236 | self::assertEquals($annot->data, 'Some data'); |
||
237 | self::assertNull($annot->name); |
||
238 | |||
239 | |||
240 | $docblock = <<<DOCBLOCK |
||
241 | /** |
||
242 | * @SomeAnnotationClassNameWithoutConstructor(name = "Some name") |
||
243 | */ |
||
244 | DOCBLOCK; |
||
245 | |||
246 | $result = $parser->parse($docblock); |
||
247 | self::assertCount(1, $result); |
||
248 | $annot = $result[0]; |
||
249 | |||
250 | self::assertEquals($annot->name, 'Some name'); |
||
251 | self::assertNull($annot->data); |
||
252 | |||
253 | $docblock = <<<DOCBLOCK |
||
254 | /** |
||
255 | * @SomeAnnotationClassNameWithoutConstructor("Some data") |
||
256 | */ |
||
257 | DOCBLOCK; |
||
258 | |||
259 | $result = $parser->parse($docblock); |
||
260 | self::assertCount(1, $result); |
||
261 | $annot = $result[0]; |
||
262 | |||
263 | self::assertEquals($annot->data, 'Some data'); |
||
264 | self::assertNull($annot->name); |
||
265 | |||
266 | |||
267 | |||
268 | $docblock = <<<DOCBLOCK |
||
269 | /** |
||
270 | * @SomeAnnotationClassNameWithoutConstructor("Some data",name = "Some name") |
||
271 | */ |
||
272 | DOCBLOCK; |
||
273 | |||
274 | $result = $parser->parse($docblock); |
||
275 | self::assertCount(1, $result); |
||
276 | $annot = $result[0]; |
||
277 | |||
278 | self::assertEquals($annot->name, 'Some name'); |
||
279 | self::assertEquals($annot->data, 'Some data'); |
||
280 | |||
281 | |||
282 | $docblock = <<<DOCBLOCK |
||
283 | /** |
||
284 | * @SomeAnnotationWithConstructorWithoutParams(name = "Some name") |
||
285 | */ |
||
286 | DOCBLOCK; |
||
287 | |||
288 | $result = $parser->parse($docblock); |
||
289 | self::assertCount(1, $result); |
||
290 | $annot = $result[0]; |
||
291 | |||
292 | self::assertEquals($annot->name, 'Some name'); |
||
293 | self::assertEquals($annot->data, 'Some data'); |
||
294 | |||
295 | $docblock = <<<DOCBLOCK |
||
296 | /** |
||
297 | * @SomeAnnotationClassNameWithoutConstructorAndProperties() |
||
298 | */ |
||
299 | DOCBLOCK; |
||
300 | |||
301 | $result = $parser->parse($docblock); |
||
302 | self::assertCount(1, $result); |
||
303 | self::assertInstanceOf(SomeAnnotationClassNameWithoutConstructorAndProperties::class, $result[0]); |
||
304 | } |
||
305 | |||
306 | public function testAnnotationTarget() |
||
307 | { |
||
308 | |||
309 | $parser = new DocParser; |
||
310 | $parser->setImports([ |
||
311 | '__NAMESPACE__' => 'Doctrine\Tests\Annotations\Fixtures', |
||
312 | ]); |
||
313 | $class = new \ReflectionClass(Fixtures\ClassWithValidAnnotationTarget::class); |
||
314 | |||
315 | |||
316 | $context = 'class ' . $class->getName(); |
||
317 | $docComment = $class->getDocComment(); |
||
318 | |||
319 | $parser->setTarget(Target::TARGET_CLASS); |
||
320 | self::assertNotNull($parser->parse($docComment,$context)); |
||
321 | |||
322 | |||
323 | $property = $class->getProperty('foo'); |
||
324 | $docComment = $property->getDocComment(); |
||
325 | $context = 'property ' . $class->getName() . "::\$" . $property->getName(); |
||
326 | |||
327 | $parser->setTarget(Target::TARGET_PROPERTY); |
||
328 | self::assertNotNull($parser->parse($docComment,$context)); |
||
329 | |||
330 | |||
331 | |||
332 | $method = $class->getMethod('someFunction'); |
||
333 | $docComment = $property->getDocComment(); |
||
334 | $context = 'method ' . $class->getName() . '::' . $method->getName() . '()'; |
||
335 | |||
336 | $parser->setTarget(Target::TARGET_METHOD); |
||
337 | self::assertNotNull($parser->parse($docComment,$context)); |
||
338 | |||
339 | |||
340 | try { |
||
341 | $class = new \ReflectionClass(Fixtures\ClassWithInvalidAnnotationTargetAtClass::class); |
||
342 | $context = 'class ' . $class->getName(); |
||
343 | $docComment = $class->getDocComment(); |
||
344 | |||
345 | $parser->setTarget(Target::TARGET_CLASS); |
||
346 | $parser->parse($docComment, $context); |
||
347 | |||
348 | $this->fail(); |
||
349 | } catch (AnnotationException $exc) { |
||
350 | self::assertNotNull($exc->getMessage()); |
||
351 | } |
||
352 | |||
353 | |||
354 | try { |
||
355 | |||
356 | $class = new \ReflectionClass(Fixtures\ClassWithInvalidAnnotationTargetAtMethod::class); |
||
357 | $method = $class->getMethod('functionName'); |
||
358 | $docComment = $method->getDocComment(); |
||
359 | $context = 'method ' . $class->getName() . '::' . $method->getName() . '()'; |
||
360 | |||
361 | $parser->setTarget(Target::TARGET_METHOD); |
||
362 | $parser->parse($docComment, $context); |
||
363 | |||
364 | $this->fail(); |
||
365 | } catch (AnnotationException $exc) { |
||
366 | self::assertNotNull($exc->getMessage()); |
||
367 | } |
||
368 | |||
369 | |||
370 | try { |
||
371 | $class = new \ReflectionClass(Fixtures\ClassWithInvalidAnnotationTargetAtProperty::class); |
||
372 | $property = $class->getProperty('foo'); |
||
373 | $docComment = $property->getDocComment(); |
||
374 | $context = 'property ' . $class->getName() . "::\$" . $property->getName(); |
||
375 | |||
376 | $parser->setTarget(Target::TARGET_PROPERTY); |
||
377 | $parser->parse($docComment, $context); |
||
378 | |||
379 | $this->fail(); |
||
380 | } catch (AnnotationException $exc) { |
||
381 | self::assertNotNull($exc->getMessage()); |
||
382 | } |
||
383 | |||
384 | } |
||
385 | |||
386 | public function getAnnotationVarTypeProviderValid() |
||
387 | { |
||
388 | //({attribute name}, {attribute value}) |
||
389 | return [ |
||
390 | // mixed type |
||
391 | ['mixed', '"String Value"'], |
||
392 | ['mixed', 'true'], |
||
393 | ['mixed', 'false'], |
||
394 | ['mixed', '1'], |
||
395 | ['mixed', '1.2'], |
||
396 | ['mixed', '@Doctrine\Tests\Annotations\Fixtures\AnnotationTargetAll'], |
||
397 | |||
398 | // boolean type |
||
399 | ['boolean', 'true'], |
||
400 | ['boolean', 'false'], |
||
401 | |||
402 | // alias for internal type boolean |
||
403 | ['bool', 'true'], |
||
404 | ['bool', 'false'], |
||
405 | |||
406 | // integer type |
||
407 | ['integer', '0'], |
||
408 | ['integer', '1'], |
||
409 | ['integer', '123456789'], |
||
410 | ['integer', '9223372036854775807'], |
||
411 | |||
412 | // alias for internal type double |
||
413 | ['float', '0.1'], |
||
414 | ['float', '1.2'], |
||
415 | ['float', '123.456'], |
||
416 | |||
417 | // string type |
||
418 | ['string', '"String Value"'], |
||
419 | ['string', '"true"'], |
||
420 | ['string', '"123"'], |
||
421 | |||
422 | // array type |
||
423 | ['array', '{@AnnotationExtendsAnnotationTargetAll}'], |
||
424 | ['array', '{@AnnotationExtendsAnnotationTargetAll,@AnnotationExtendsAnnotationTargetAll}'], |
||
425 | |||
426 | ['arrayOfIntegers', '1'], |
||
427 | ['arrayOfIntegers', '{1}'], |
||
428 | ['arrayOfIntegers', '{1,2,3,4}'], |
||
429 | ['arrayOfAnnotations', '@AnnotationExtendsAnnotationTargetAll'], |
||
430 | ['arrayOfAnnotations', '{@Doctrine\Tests\Annotations\Fixtures\AnnotationTargetAll}'], |
||
431 | ['arrayOfAnnotations', '{@AnnotationExtendsAnnotationTargetAll, @Doctrine\Tests\Annotations\Fixtures\AnnotationTargetAll}'], |
||
432 | |||
433 | // annotation instance |
||
434 | ['annotation', '@Doctrine\Tests\Annotations\Fixtures\AnnotationTargetAll'], |
||
435 | ['annotation', '@AnnotationExtendsAnnotationTargetAll'], |
||
436 | ]; |
||
437 | } |
||
438 | |||
439 | public function getAnnotationVarTypeProviderInvalid() |
||
440 | { |
||
441 | //({attribute name}, {type declared type}, {attribute value} , {given type or class}) |
||
442 | return [ |
||
443 | // boolean type |
||
444 | ['boolean','boolean','1','integer'], |
||
445 | ['boolean','boolean','1.2','double'], |
||
446 | ['boolean','boolean','"str"','string'], |
||
447 | ['boolean','boolean','{1,2,3}','array'], |
||
448 | ['boolean','boolean','@Name', 'an instance of Doctrine\Tests\Annotations\Name'], |
||
449 | |||
450 | // alias for internal type boolean |
||
451 | ['bool','bool', '1','integer'], |
||
452 | ['bool','bool', '1.2','double'], |
||
453 | ['bool','bool', '"str"','string'], |
||
454 | ['bool','bool', '{"str"}','array'], |
||
455 | |||
456 | // integer type |
||
457 | ['integer','integer', 'true','boolean'], |
||
458 | ['integer','integer', 'false','boolean'], |
||
459 | ['integer','integer', '1.2','double'], |
||
460 | ['integer','integer', '"str"','string'], |
||
461 | ['integer','integer', '{"str"}','array'], |
||
462 | ['integer','integer', '{1,2,3,4}','array'], |
||
463 | |||
464 | // alias for internal type double |
||
465 | ['float','float', 'true','boolean'], |
||
466 | ['float','float', 'false','boolean'], |
||
467 | ['float','float', '123','integer'], |
||
468 | ['float','float', '"str"','string'], |
||
469 | ['float','float', '{"str"}','array'], |
||
470 | ['float','float', '{12.34}','array'], |
||
471 | ['float','float', '{1,2,3}','array'], |
||
472 | |||
473 | // string type |
||
474 | ['string','string', 'true','boolean'], |
||
475 | ['string','string', 'false','boolean'], |
||
476 | ['string','string', '12','integer'], |
||
477 | ['string','string', '1.2','double'], |
||
478 | ['string','string', '{"str"}','array'], |
||
479 | ['string','string', '{1,2,3,4}','array'], |
||
480 | |||
481 | // annotation instance |
||
482 | ['annotation', AnnotationTargetAll::class, 'true','boolean'], |
||
483 | ['annotation', AnnotationTargetAll::class, 'false','boolean'], |
||
484 | ['annotation', AnnotationTargetAll::class, '12','integer'], |
||
485 | ['annotation', AnnotationTargetAll::class, '1.2','double'], |
||
486 | ['annotation', AnnotationTargetAll::class, '{"str"}','array'], |
||
487 | ['annotation', AnnotationTargetAll::class, '{1,2,3,4}','array'], |
||
488 | ['annotation', AnnotationTargetAll::class, '@Name','an instance of Doctrine\Tests\Annotations\Name'], |
||
489 | ]; |
||
490 | } |
||
491 | |||
492 | public function getAnnotationVarTypeArrayProviderInvalid() |
||
493 | { |
||
494 | //({attribute name}, {type declared type}, {attribute value} , {given type or class}) |
||
495 | return [ |
||
496 | ['arrayOfIntegers', 'integer', 'true', 'boolean'], |
||
497 | ['arrayOfIntegers', 'integer', 'false', 'boolean'], |
||
498 | ['arrayOfIntegers', 'integer', '{true,true}', 'boolean'], |
||
499 | ['arrayOfIntegers', 'integer', '{1,true}', 'boolean'], |
||
500 | ['arrayOfIntegers', 'integer', '{1,2,1.2}', 'double'], |
||
501 | ['arrayOfIntegers', 'integer', '{1,2,"str"}', 'string'], |
||
502 | |||
503 | ['arrayOfStrings', 'string', 'true', 'boolean'], |
||
504 | ['arrayOfStrings', 'string', 'false', 'boolean'], |
||
505 | ['arrayOfStrings', 'string', '{true,true}', 'boolean'], |
||
506 | ['arrayOfStrings', 'string', '{"foo",true}', 'boolean'], |
||
507 | ['arrayOfStrings', 'string', '{"foo","bar",1.2}', 'double'], |
||
508 | ['arrayOfStrings', 'string', '1', 'integer'], |
||
509 | |||
510 | ['arrayOfAnnotations', AnnotationTargetAll::class, 'true', 'boolean'], |
||
511 | ['arrayOfAnnotations', AnnotationTargetAll::class, 'false', 'boolean'], |
||
512 | ['arrayOfAnnotations', AnnotationTargetAll::class, '{@Doctrine\Tests\Annotations\Fixtures\AnnotationTargetAll,true}', 'boolean'], |
||
513 | ['arrayOfAnnotations', AnnotationTargetAll::class, '{@Doctrine\Tests\Annotations\Fixtures\AnnotationTargetAll,true}', 'boolean'], |
||
514 | ['arrayOfAnnotations', AnnotationTargetAll::class, '{@Doctrine\Tests\Annotations\Fixtures\AnnotationTargetAll,1.2}', 'double'], |
||
515 | ['arrayOfAnnotations', AnnotationTargetAll::class, '{@Doctrine\Tests\Annotations\Fixtures\AnnotationTargetAll,@AnnotationExtendsAnnotationTargetAll,"str"}', 'string'], |
||
516 | ]; |
||
517 | } |
||
518 | |||
519 | /** |
||
520 | * @dataProvider getAnnotationVarTypeProviderValid |
||
521 | */ |
||
522 | public function testAnnotationWithVarType($attribute, $value) |
||
523 | { |
||
524 | $parser = $this->createTestParser(); |
||
525 | $context = 'property SomeClassName::$invalidProperty.'; |
||
526 | $docblock = sprintf('@Doctrine\Tests\Annotations\Fixtures\AnnotationWithVarType(%s = %s)',$attribute, $value); |
||
527 | $parser->setTarget(Target::TARGET_PROPERTY); |
||
528 | |||
529 | $result = $parser->parse($docblock, $context); |
||
530 | |||
531 | self::assertCount(1, $result); |
||
532 | self::assertInstanceOf(Fixtures\AnnotationWithVarType::class, $result[0]); |
||
533 | self::assertNotNull($result[0]->$attribute); |
||
534 | } |
||
535 | |||
536 | /** |
||
537 | * @dataProvider getAnnotationVarTypeProviderInvalid |
||
538 | */ |
||
539 | public function testAnnotationWithVarTypeError($attribute,$type,$value,$given) |
||
540 | { |
||
541 | $parser = $this->createTestParser(); |
||
542 | $context = 'property SomeClassName::invalidProperty.'; |
||
543 | $docblock = sprintf('@Doctrine\Tests\Annotations\Fixtures\AnnotationWithVarType(%s = %s)',$attribute, $value); |
||
544 | $parser->setTarget(Target::TARGET_PROPERTY); |
||
545 | |||
546 | try { |
||
547 | $parser->parse($docblock, $context); |
||
548 | $this->fail(); |
||
549 | } catch (AnnotationException $exc) { |
||
550 | self::assertStringMatchesFormat( |
||
551 | '[Type Error] Attribute "' . $attribute . '" of @Doctrine\Tests\Annotations\Fixtures\AnnotationWithVarType declared on property SomeClassName::invalidProperty. expects a(n) %A' . $type . ', but got ' . $given . '.', |
||
552 | $exc->getMessage() |
||
553 | ); |
||
554 | } |
||
555 | } |
||
556 | |||
557 | |||
558 | /** |
||
559 | * @dataProvider getAnnotationVarTypeArrayProviderInvalid |
||
560 | */ |
||
561 | public function testAnnotationWithVarTypeArrayError($attribute,$type,$value,$given) |
||
562 | { |
||
563 | $parser = $this->createTestParser(); |
||
564 | $context = 'property SomeClassName::invalidProperty.'; |
||
565 | $docblock = sprintf('@Doctrine\Tests\Annotations\Fixtures\AnnotationWithVarType(%s = %s)',$attribute, $value); |
||
566 | $parser->setTarget(Target::TARGET_PROPERTY); |
||
567 | |||
568 | try { |
||
569 | $parser->parse($docblock, $context); |
||
570 | $this->fail(); |
||
571 | } catch (AnnotationException $exc) { |
||
572 | self::assertStringMatchesFormat( |
||
573 | '[Type Error] Attribute "' . $attribute . '" of @Doctrine\Tests\Annotations\Fixtures\AnnotationWithVarType declared on property SomeClassName::invalidProperty. expects either a(n) %A' . $type . ', or an array of %A' . $type . 's, but got ' . $given . '.', |
||
574 | $exc->getMessage() |
||
575 | ); |
||
576 | } |
||
577 | } |
||
578 | |||
579 | /** |
||
580 | * @dataProvider getAnnotationVarTypeProviderValid |
||
581 | */ |
||
582 | public function testAnnotationWithAttributes($attribute, $value) |
||
583 | { |
||
584 | $parser = $this->createTestParser(); |
||
585 | $context = 'property SomeClassName::$invalidProperty.'; |
||
586 | $docblock = sprintf('@Doctrine\Tests\Annotations\Fixtures\AnnotationWithAttributes(%s = %s)',$attribute, $value); |
||
587 | $parser->setTarget(Target::TARGET_PROPERTY); |
||
588 | |||
589 | $result = $parser->parse($docblock, $context); |
||
590 | |||
591 | self::assertCount(1, $result); |
||
592 | self::assertInstanceOf(Fixtures\AnnotationWithAttributes::class, $result[0]); |
||
593 | $getter = 'get' .ucfirst($attribute); |
||
594 | self::assertNotNull($result[0]->$getter()); |
||
595 | } |
||
596 | |||
597 | /** |
||
598 | * @dataProvider getAnnotationVarTypeProviderInvalid |
||
599 | */ |
||
600 | public function testAnnotationWithAttributesError($attribute,$type,$value,$given) |
||
601 | { |
||
602 | $parser = $this->createTestParser(); |
||
603 | $context = 'property SomeClassName::invalidProperty.'; |
||
604 | $docblock = sprintf('@Doctrine\Tests\Annotations\Fixtures\AnnotationWithAttributes(%s = %s)',$attribute, $value); |
||
605 | $parser->setTarget(Target::TARGET_PROPERTY); |
||
606 | |||
607 | try { |
||
608 | $parser->parse($docblock, $context); |
||
609 | $this->fail(); |
||
610 | } catch (AnnotationException $exc) { |
||
611 | self::assertContains("[Type Error] Attribute \"$attribute\" of @Doctrine\Tests\Annotations\Fixtures\AnnotationWithAttributes declared on property SomeClassName::invalidProperty. expects a(n) $type, but got $given.", $exc->getMessage()); |
||
612 | } |
||
613 | } |
||
614 | |||
615 | |||
616 | /** |
||
617 | * @dataProvider getAnnotationVarTypeArrayProviderInvalid |
||
618 | */ |
||
619 | public function testAnnotationWithAttributesWithVarTypeArrayError($attribute,$type,$value,$given) |
||
620 | { |
||
621 | $parser = $this->createTestParser(); |
||
622 | $context = 'property SomeClassName::invalidProperty.'; |
||
623 | $docblock = sprintf('@Doctrine\Tests\Annotations\Fixtures\AnnotationWithAttributes(%s = %s)',$attribute, $value); |
||
624 | $parser->setTarget(Target::TARGET_PROPERTY); |
||
625 | |||
626 | try { |
||
627 | $parser->parse($docblock, $context); |
||
628 | $this->fail(); |
||
629 | } catch (AnnotationException $exc) { |
||
630 | self::assertContains("[Type Error] Attribute \"$attribute\" of @Doctrine\Tests\Annotations\Fixtures\AnnotationWithAttributes declared on property SomeClassName::invalidProperty. expects either a(n) $type, or an array of {$type}s, but got $given.", $exc->getMessage()); |
||
631 | } |
||
632 | } |
||
633 | |||
634 | public function testAnnotationWithRequiredAttributes() |
||
635 | { |
||
636 | $parser = $this->createTestParser(); |
||
637 | $context = 'property SomeClassName::invalidProperty.'; |
||
638 | $parser->setTarget(Target::TARGET_PROPERTY); |
||
639 | |||
640 | |||
641 | $docblock = '@Doctrine\Tests\Annotations\Fixtures\AnnotationWithRequiredAttributes("Some Value", annot = @Doctrine\Tests\Annotations\Fixtures\AnnotationTargetAnnotation)'; |
||
642 | $result = $parser->parse($docblock); |
||
643 | |||
644 | self::assertCount(1, $result); |
||
645 | |||
646 | /* @var $annotation Fixtures\AnnotationWithRequiredAttributes */ |
||
647 | $annotation = $result[0]; |
||
648 | |||
649 | self::assertInstanceOf(Fixtures\AnnotationWithRequiredAttributes::class, $annotation); |
||
650 | self::assertEquals('Some Value', $annotation->getValue()); |
||
651 | self::assertInstanceOf(Fixtures\AnnotationTargetAnnotation::class, $annotation->getAnnot()); |
||
652 | |||
653 | |||
654 | $docblock = '@Doctrine\Tests\Annotations\Fixtures\AnnotationWithRequiredAttributes("Some Value")'; |
||
655 | try { |
||
656 | $parser->parse($docblock, $context); |
||
657 | $this->fail(); |
||
658 | } catch (AnnotationException $exc) { |
||
659 | self::assertContains('Attribute "annot" of @Doctrine\Tests\Annotations\Fixtures\AnnotationWithRequiredAttributes declared on property SomeClassName::invalidProperty. expects a(n) Doctrine\Tests\Annotations\Fixtures\AnnotationTargetAnnotation. This value should not be null.', $exc->getMessage()); |
||
660 | } |
||
661 | |||
662 | $docblock = '@Doctrine\Tests\Annotations\Fixtures\AnnotationWithRequiredAttributes(annot = @Doctrine\Tests\Annotations\Fixtures\AnnotationTargetAnnotation)'; |
||
663 | try { |
||
664 | $parser->parse($docblock, $context); |
||
665 | $this->fail(); |
||
666 | } catch (AnnotationException $exc) { |
||
667 | self::assertContains('Attribute "value" of @Doctrine\Tests\Annotations\Fixtures\AnnotationWithRequiredAttributes declared on property SomeClassName::invalidProperty. expects a(n) string. This value should not be null.', $exc->getMessage()); |
||
668 | } |
||
669 | |||
670 | } |
||
671 | |||
672 | public function testAnnotationWithRequiredAttributesWithoutConstructor() |
||
673 | { |
||
674 | $parser = $this->createTestParser(); |
||
675 | $context = 'property SomeClassName::invalidProperty.'; |
||
676 | $parser->setTarget(Target::TARGET_PROPERTY); |
||
677 | |||
678 | |||
679 | $docblock = '@Doctrine\Tests\Annotations\Fixtures\AnnotationWithRequiredAttributesWithoutConstructor("Some Value", annot = @Doctrine\Tests\Annotations\Fixtures\AnnotationTargetAnnotation)'; |
||
680 | $result = $parser->parse($docblock); |
||
681 | |||
682 | self::assertCount(1, $result); |
||
683 | self::assertInstanceOf(Fixtures\AnnotationWithRequiredAttributesWithoutConstructor::class, $result[0]); |
||
684 | self::assertEquals('Some Value', $result[0]->value); |
||
685 | self::assertInstanceOf(Fixtures\AnnotationTargetAnnotation::class, $result[0]->annot); |
||
686 | |||
687 | |||
688 | $docblock = '@Doctrine\Tests\Annotations\Fixtures\AnnotationWithRequiredAttributesWithoutConstructor("Some Value")'; |
||
689 | try { |
||
690 | $parser->parse($docblock, $context); |
||
691 | $this->fail(); |
||
692 | } catch (AnnotationException $exc) { |
||
693 | self::assertContains('Attribute "annot" of @Doctrine\Tests\Annotations\Fixtures\AnnotationWithRequiredAttributesWithoutConstructor declared on property SomeClassName::invalidProperty. expects a(n) \Doctrine\Tests\Annotations\Fixtures\AnnotationTargetAnnotation. This value should not be null.', $exc->getMessage()); |
||
694 | } |
||
695 | |||
696 | $docblock = '@Doctrine\Tests\Annotations\Fixtures\AnnotationWithRequiredAttributesWithoutConstructor(annot = @Doctrine\Tests\Annotations\Fixtures\AnnotationTargetAnnotation)'; |
||
697 | try { |
||
698 | $parser->parse($docblock, $context); |
||
699 | $this->fail(); |
||
700 | } catch (AnnotationException $exc) { |
||
701 | self::assertContains('Attribute "value" of @Doctrine\Tests\Annotations\Fixtures\AnnotationWithRequiredAttributesWithoutConstructor declared on property SomeClassName::invalidProperty. expects a(n) string. This value should not be null.', $exc->getMessage()); |
||
702 | } |
||
703 | |||
704 | } |
||
705 | |||
706 | /** |
||
707 | * @expectedException \Doctrine\Annotations\AnnotationException |
||
708 | * @expectedExceptionMessage Attribute "value" of @Doctrine\Tests\Annotations\Fixtures\AnnotationEnum declared on property SomeClassName::invalidProperty. accept only [ONE, TWO, THREE], but got FOUR. |
||
709 | */ |
||
710 | public function testAnnotationEnumeratorException() |
||
711 | { |
||
712 | $parser = $this->createTestParser(); |
||
713 | $context = 'property SomeClassName::invalidProperty.'; |
||
714 | $docblock = '@Doctrine\Tests\Annotations\Fixtures\AnnotationEnum("FOUR")'; |
||
715 | |||
716 | $parser->setIgnoreNotImportedAnnotations(false); |
||
717 | $parser->setTarget(Target::TARGET_PROPERTY); |
||
718 | $parser->parse($docblock, $context); |
||
719 | } |
||
720 | |||
721 | /** |
||
722 | * @expectedException \Doctrine\Annotations\AnnotationException |
||
723 | * @expectedExceptionMessage Attribute "value" of @Doctrine\Tests\Annotations\Fixtures\AnnotationEnumLiteral declared on property SomeClassName::invalidProperty. accept only [AnnotationEnumLiteral::ONE, AnnotationEnumLiteral::TWO, AnnotationEnumLiteral::THREE], but got 4. |
||
724 | */ |
||
725 | public function testAnnotationEnumeratorLiteralException() |
||
726 | { |
||
727 | $parser = $this->createTestParser(); |
||
728 | $context = 'property SomeClassName::invalidProperty.'; |
||
729 | $docblock = '@Doctrine\Tests\Annotations\Fixtures\AnnotationEnumLiteral(4)'; |
||
730 | |||
731 | $parser->setIgnoreNotImportedAnnotations(false); |
||
732 | $parser->setTarget(Target::TARGET_PROPERTY); |
||
733 | $parser->parse($docblock, $context); |
||
734 | } |
||
735 | |||
736 | /** |
||
737 | * @expectedException \InvalidArgumentException |
||
738 | * @expectedExceptionMessage @Enum supports only scalar values "array" given. |
||
739 | */ |
||
740 | public function testAnnotationEnumInvalidTypeDeclarationException() |
||
741 | { |
||
742 | $parser = $this->createTestParser(); |
||
743 | $docblock = '@Doctrine\Tests\Annotations\Fixtures\AnnotationEnumInvalid("foo")'; |
||
744 | |||
745 | $parser->setIgnoreNotImportedAnnotations(false); |
||
746 | $parser->parse($docblock); |
||
747 | } |
||
748 | |||
749 | /** |
||
750 | * @expectedException \InvalidArgumentException |
||
751 | * @expectedExceptionMessage Undefined enumerator value "3" for literal "AnnotationEnumLiteral::THREE". |
||
752 | */ |
||
753 | public function testAnnotationEnumInvalidLiteralDeclarationException() |
||
754 | { |
||
755 | $parser = $this->createTestParser(); |
||
756 | $docblock = '@Doctrine\Tests\Annotations\Fixtures\AnnotationEnumLiteralInvalid("foo")'; |
||
757 | |||
758 | $parser->setIgnoreNotImportedAnnotations(false); |
||
759 | $parser->parse($docblock); |
||
760 | } |
||
761 | |||
762 | public function getConstantsProvider() |
||
763 | { |
||
764 | $provider[] = [ |
||
|
|||
765 | '@AnnotationWithConstants(PHP_EOL)', |
||
766 | PHP_EOL |
||
767 | ]; |
||
768 | $provider[] = [ |
||
769 | '@AnnotationWithConstants(AnnotationWithConstants::INTEGER)', |
||
770 | AnnotationWithConstants::INTEGER |
||
771 | ]; |
||
772 | $provider[] = [ |
||
773 | '@Doctrine\Tests\Annotations\Fixtures\AnnotationWithConstants(AnnotationWithConstants::STRING)', |
||
774 | AnnotationWithConstants::STRING |
||
775 | ]; |
||
776 | $provider[] = [ |
||
777 | '@AnnotationWithConstants(Doctrine\Tests\Annotations\Fixtures\AnnotationWithConstants::FLOAT)', |
||
778 | AnnotationWithConstants::FLOAT |
||
779 | ]; |
||
780 | $provider[] = [ |
||
781 | '@AnnotationWithConstants(ClassWithConstants::SOME_VALUE)', |
||
782 | ClassWithConstants::SOME_VALUE |
||
783 | ]; |
||
784 | $provider[] = [ |
||
785 | '@AnnotationWithConstants(ClassWithConstants::OTHER_KEY_)', |
||
786 | ClassWithConstants::OTHER_KEY_ |
||
787 | ]; |
||
788 | $provider[] = [ |
||
789 | '@AnnotationWithConstants(ClassWithConstants::OTHER_KEY_2)', |
||
790 | ClassWithConstants::OTHER_KEY_2 |
||
791 | ]; |
||
792 | $provider[] = [ |
||
793 | '@AnnotationWithConstants(Doctrine\Tests\Annotations\Fixtures\ClassWithConstants::SOME_VALUE)', |
||
794 | ClassWithConstants::SOME_VALUE |
||
795 | ]; |
||
796 | $provider[] = [ |
||
797 | '@AnnotationWithConstants(InterfaceWithConstants::SOME_VALUE)', |
||
798 | InterfaceWithConstants::SOME_VALUE |
||
799 | ]; |
||
800 | $provider[] = [ |
||
801 | '@AnnotationWithConstants(\Doctrine\Tests\Annotations\Fixtures\InterfaceWithConstants::SOME_VALUE)', |
||
802 | InterfaceWithConstants::SOME_VALUE |
||
803 | ]; |
||
804 | $provider[] = [ |
||
805 | '@AnnotationWithConstants({AnnotationWithConstants::STRING, AnnotationWithConstants::INTEGER, AnnotationWithConstants::FLOAT})', |
||
806 | [AnnotationWithConstants::STRING, AnnotationWithConstants::INTEGER, AnnotationWithConstants::FLOAT] |
||
807 | ]; |
||
808 | $provider[] = [ |
||
809 | '@AnnotationWithConstants({ |
||
810 | AnnotationWithConstants::STRING = AnnotationWithConstants::INTEGER |
||
811 | })', |
||
812 | [AnnotationWithConstants::STRING => AnnotationWithConstants::INTEGER] |
||
813 | ]; |
||
814 | $provider[] = [ |
||
815 | '@AnnotationWithConstants({ |
||
816 | Doctrine\Tests\Annotations\Fixtures\InterfaceWithConstants::SOME_KEY = AnnotationWithConstants::INTEGER |
||
817 | })', |
||
818 | [InterfaceWithConstants::SOME_KEY => AnnotationWithConstants::INTEGER] |
||
819 | ]; |
||
820 | $provider[] = [ |
||
821 | '@AnnotationWithConstants({ |
||
822 | \Doctrine\Tests\Annotations\Fixtures\InterfaceWithConstants::SOME_KEY = AnnotationWithConstants::INTEGER |
||
823 | })', |
||
824 | [InterfaceWithConstants::SOME_KEY => AnnotationWithConstants::INTEGER] |
||
825 | ]; |
||
826 | $provider[] = [ |
||
827 | '@AnnotationWithConstants({ |
||
828 | AnnotationWithConstants::STRING = AnnotationWithConstants::INTEGER, |
||
829 | ClassWithConstants::SOME_KEY = ClassWithConstants::SOME_VALUE, |
||
830 | Doctrine\Tests\Annotations\Fixtures\ClassWithConstants::SOME_KEY = InterfaceWithConstants::SOME_VALUE |
||
831 | })', |
||
832 | [ |
||
833 | AnnotationWithConstants::STRING => AnnotationWithConstants::INTEGER, |
||
834 | ClassWithConstants::SOME_KEY => ClassWithConstants::SOME_VALUE, |
||
835 | ClassWithConstants::SOME_KEY => InterfaceWithConstants::SOME_VALUE |
||
836 | ] |
||
837 | ]; |
||
838 | $provider[] = [ |
||
839 | '@AnnotationWithConstants(AnnotationWithConstants::class)', |
||
840 | AnnotationWithConstants::class |
||
841 | ]; |
||
842 | $provider[] = [ |
||
843 | '@AnnotationWithConstants({AnnotationWithConstants::class = AnnotationWithConstants::class})', |
||
844 | [AnnotationWithConstants::class => AnnotationWithConstants::class] |
||
845 | ]; |
||
846 | $provider[] = [ |
||
847 | '@AnnotationWithConstants(Doctrine\Tests\Annotations\Fixtures\AnnotationWithConstants::class)', |
||
848 | AnnotationWithConstants::class |
||
849 | ]; |
||
850 | $provider[] = [ |
||
851 | '@Doctrine\Tests\Annotations\Fixtures\AnnotationWithConstants(Doctrine\Tests\Annotations\Fixtures\AnnotationWithConstants::class)', |
||
852 | AnnotationWithConstants::class |
||
853 | ]; |
||
854 | return $provider; |
||
855 | } |
||
856 | |||
857 | /** |
||
858 | * @dataProvider getConstantsProvider |
||
859 | */ |
||
860 | public function testSupportClassConstants($docblock, $expected) |
||
861 | { |
||
862 | $parser = $this->createTestParser(); |
||
863 | $parser->setImports([ |
||
864 | 'classwithconstants' => ClassWithConstants::class, |
||
865 | 'interfacewithconstants' => InterfaceWithConstants::class, |
||
866 | 'annotationwithconstants' => AnnotationWithConstants::class |
||
867 | ]); |
||
868 | |||
869 | $result = $parser->parse($docblock); |
||
870 | self::assertInstanceOf(AnnotationWithConstants::class, $annotation = $result[0]); |
||
871 | self::assertEquals($expected, $annotation->value); |
||
872 | } |
||
873 | |||
874 | /** |
||
875 | * @expectedException \Doctrine\Annotations\AnnotationException |
||
876 | * @expectedExceptionMessage The annotation @SomeAnnotationClassNameWithoutConstructorAndProperties declared on does not accept any values, but got {"value":"Foo"}. |
||
877 | */ |
||
878 | public function testWithoutConstructorWhenIsNotDefaultValue() |
||
879 | { |
||
880 | $parser = $this->createTestParser(); |
||
881 | $docblock = <<<DOCBLOCK |
||
882 | /** |
||
883 | * @SomeAnnotationClassNameWithoutConstructorAndProperties("Foo") |
||
884 | */ |
||
885 | DOCBLOCK; |
||
886 | |||
887 | |||
888 | $parser->setTarget(Target::TARGET_CLASS); |
||
889 | $parser->parse($docblock); |
||
890 | } |
||
891 | |||
892 | /** |
||
893 | * @expectedException \Doctrine\Annotations\AnnotationException |
||
894 | * @expectedExceptionMessage The annotation @SomeAnnotationClassNameWithoutConstructorAndProperties declared on does not accept any values, but got {"value":"Foo"}. |
||
895 | */ |
||
896 | public function testWithoutConstructorWhenHasNoProperties() |
||
897 | { |
||
898 | $parser = $this->createTestParser(); |
||
899 | $docblock = <<<DOCBLOCK |
||
900 | /** |
||
901 | * @SomeAnnotationClassNameWithoutConstructorAndProperties(value = "Foo") |
||
902 | */ |
||
903 | DOCBLOCK; |
||
904 | |||
905 | $parser->setTarget(Target::TARGET_CLASS); |
||
906 | $parser->parse($docblock); |
||
907 | } |
||
908 | |||
909 | /** |
||
910 | * @expectedException \Doctrine\Annotations\AnnotationException |
||
911 | * @expectedExceptionMessage Expected namespace separator or identifier, got ')' at position 24 in class @Doctrine\Tests\Annotations\Fixtures\AnnotationWithTargetSyntaxError. |
||
912 | */ |
||
913 | public function testAnnotationTargetSyntaxError() |
||
914 | { |
||
915 | $parser = $this->createTestParser(); |
||
916 | $context = 'class ' . 'SomeClassName'; |
||
917 | $docblock = <<<DOCBLOCK |
||
918 | /** |
||
919 | * @Doctrine\Tests\Annotations\Fixtures\AnnotationWithTargetSyntaxError() |
||
920 | */ |
||
921 | DOCBLOCK; |
||
922 | |||
923 | $parser->setTarget(Target::TARGET_CLASS); |
||
924 | $parser->parse($docblock, $context); |
||
925 | } |
||
926 | |||
927 | /** |
||
928 | * @expectedException \InvalidArgumentException |
||
929 | * @expectedExceptionMessage Invalid Target "Foo". Available targets: [ALL, CLASS, METHOD, PROPERTY, ANNOTATION] |
||
930 | */ |
||
931 | public function testAnnotationWithInvalidTargetDeclarationError() |
||
932 | { |
||
933 | $parser = $this->createTestParser(); |
||
934 | $context = 'class ' . 'SomeClassName'; |
||
935 | $docblock = <<<DOCBLOCK |
||
936 | /** |
||
937 | * @AnnotationWithInvalidTargetDeclaration() |
||
938 | */ |
||
939 | DOCBLOCK; |
||
940 | |||
941 | $parser->setTarget(Target::TARGET_CLASS); |
||
942 | $parser->parse($docblock, $context); |
||
943 | } |
||
944 | |||
945 | /** |
||
946 | * @expectedException \InvalidArgumentException |
||
947 | * @expectedExceptionMessage @Target expects either a string value, or an array of strings, "NULL" given. |
||
948 | */ |
||
949 | public function testAnnotationWithTargetEmptyError() |
||
950 | { |
||
951 | $parser = $this->createTestParser(); |
||
952 | $context = 'class ' . 'SomeClassName'; |
||
953 | $docblock = <<<DOCBLOCK |
||
954 | /** |
||
955 | * @AnnotationWithTargetEmpty() |
||
956 | */ |
||
957 | DOCBLOCK; |
||
958 | |||
959 | $parser->setTarget(Target::TARGET_CLASS); |
||
960 | $parser->parse($docblock, $context); |
||
961 | } |
||
962 | |||
963 | /** |
||
964 | * @group DDC-575 |
||
965 | */ |
||
966 | public function testRegressionDDC575() |
||
967 | { |
||
968 | $parser = $this->createTestParser(); |
||
969 | |||
970 | $docblock = <<<DOCBLOCK |
||
971 | /** |
||
972 | * @Name |
||
973 | * |
||
974 | * Will trigger error. |
||
975 | */ |
||
976 | DOCBLOCK; |
||
977 | |||
978 | $result = $parser->parse($docblock); |
||
979 | |||
980 | self::assertInstanceOf(Name::class, $result[0]); |
||
981 | |||
982 | $docblock = <<<DOCBLOCK |
||
983 | /** |
||
984 | * @Name |
||
985 | * @Marker |
||
986 | * |
||
987 | * Will trigger error. |
||
988 | */ |
||
989 | DOCBLOCK; |
||
990 | |||
991 | $result = $parser->parse($docblock); |
||
992 | |||
993 | self::assertInstanceOf(Name::class, $result[0]); |
||
994 | } |
||
995 | |||
996 | /** |
||
997 | * @group DDC-77 |
||
998 | */ |
||
999 | public function testAnnotationWithoutClassIsIgnoredWithoutWarning() |
||
1000 | { |
||
1001 | $parser = new DocParser(); |
||
1002 | $parser->setIgnoreNotImportedAnnotations(true); |
||
1003 | $result = $parser->parse('@param'); |
||
1004 | |||
1005 | self::assertEmpty($result); |
||
1006 | } |
||
1007 | |||
1008 | /** |
||
1009 | * Tests if it's possible to ignore whole namespaces |
||
1010 | * |
||
1011 | * @param string $ignoreAnnotationName annotation/namespace to ignore |
||
1012 | * @param string $input annotation/namespace from the docblock |
||
1013 | * |
||
1014 | * @return void |
||
1015 | * |
||
1016 | * @dataProvider provideTestIgnoreWholeNamespaces |
||
1017 | * @group 45 |
||
1018 | */ |
||
1019 | public function testIgnoreWholeNamespaces($ignoreAnnotationName, $input) |
||
1020 | { |
||
1021 | $parser = new DocParser(); |
||
1022 | $parser->setIgnoredAnnotationNamespaces([$ignoreAnnotationName => true]); |
||
1023 | $result = $parser->parse($input); |
||
1024 | |||
1025 | self::assertEmpty($result); |
||
1026 | } |
||
1027 | |||
1028 | public function provideTestIgnoreWholeNamespaces() |
||
1048 | ]; |
||
1049 | } |
||
1050 | |||
1051 | /** |
||
1052 | * @group DCOM-168 |
||
1053 | */ |
||
1054 | public function testNotAnAnnotationClassIsIgnoredWithoutWarning() |
||
1055 | { |
||
1056 | $parser = new DocParser(); |
||
1057 | $parser->setIgnoreNotImportedAnnotations(true); |
||
1058 | $parser->setIgnoredAnnotationNames([\PHPUnit\Framework\TestCase::class => true]); |
||
1059 | $result = $parser->parse('@\PHPUnit\Framework\TestCase'); |
||
1060 | |||
1061 | self::assertEmpty($result); |
||
1062 | } |
||
1063 | |||
1064 | public function testNotAnAnnotationClassIsIgnoredWithoutWarningWithoutCheating() |
||
1065 | { |
||
1066 | $parser = new DocParser(); |
||
1067 | $parser->setIgnoreNotImportedAnnotations(true); |
||
1068 | $result = $parser->parse('@\PHPUnit\Framework\TestCase'); |
||
1069 | |||
1070 | self::assertEmpty($result); |
||
1071 | } |
||
1072 | |||
1073 | /** |
||
1074 | * @expectedException \Doctrine\Annotations\AnnotationException |
||
1075 | * @expectedExceptionMessage Expected PlainValue, got ''' at position 10. |
||
1076 | */ |
||
1077 | public function testAnnotationDontAcceptSingleQuotes() |
||
1081 | } |
||
1082 | |||
1083 | /** |
||
1084 | * @group DCOM-41 |
||
1085 | */ |
||
1086 | public function testAnnotationDoesntThrowExceptionWhenAtSignIsNotFollowedByIdentifier() |
||
1087 | { |
||
1088 | $parser = new DocParser(); |
||
1089 | $result = $parser->parse("'@'"); |
||
1090 | |||
1091 | self::assertEmpty($result); |
||
1092 | } |
||
1093 | |||
1094 | /** |
||
1095 | * @group DCOM-41 |
||
1096 | * @expectedException \Doctrine\Annotations\AnnotationException |
||
1097 | */ |
||
1098 | public function testAnnotationThrowsExceptionWhenAtSignIsNotFollowedByIdentifierInNestedAnnotation() |
||
1099 | { |
||
1100 | $parser = new DocParser(); |
||
1101 | $parser->parse("@Doctrine\Tests\Annotations\Name(@')"); |
||
1102 | } |
||
1103 | |||
1104 | /** |
||
1105 | * @group DCOM-56 |
||
1106 | */ |
||
1107 | public function testAutoloadAnnotation() |
||
1108 | { |
||
1109 | self::assertFalse(class_exists('Doctrine\Tests\Annotations\Fixture\Annotation\Autoload', false), 'Pre-condition: Doctrine\Tests\Annotations\Fixture\Annotation\Autoload not allowed to be loaded.'); |
||
1110 | |||
1111 | $parser = new DocParser(); |
||
1112 | |||
1113 | $parser->setImports([ |
||
1114 | 'autoload' => Fixtures\Annotation\Autoload::class, |
||
1115 | ]); |
||
1116 | $annotations = $parser->parse('@Autoload'); |
||
1117 | |||
1118 | self::assertCount(1, $annotations); |
||
1119 | self::assertInstanceOf(Fixtures\Annotation\Autoload::class, $annotations[0]); |
||
1120 | } |
||
1121 | |||
1122 | public function createTestParser() |
||
1123 | { |
||
1124 | $parser = new DocParser(); |
||
1125 | $parser->setIgnoreNotImportedAnnotations(true); |
||
1126 | $parser->setImports([ |
||
1127 | 'name' => Name::class, |
||
1128 | '__NAMESPACE__' => 'Doctrine\Tests\Annotations', |
||
1129 | ]); |
||
1130 | |||
1131 | return $parser; |
||
1132 | } |
||
1133 | |||
1134 | /** |
||
1135 | * @group DDC-78 |
||
1136 | * @expectedException \Doctrine\Annotations\AnnotationException |
||
1137 | * @expectedExceptionMessage Expected PlainValue, got ''' at position 10 in class \Doctrine\Tests\Annotations\Name |
||
1138 | */ |
||
1139 | public function testSyntaxErrorWithContextDescription() |
||
1140 | { |
||
1141 | $parser = $this->createTestParser(); |
||
1142 | $parser->parse("@Name(foo='bar')", "class \Doctrine\Tests\Annotations\Name"); |
||
1143 | } |
||
1144 | |||
1145 | /** |
||
1146 | * @group DDC-183 |
||
1147 | */ |
||
1148 | public function testSyntaxErrorWithUnknownCharacters() |
||
1149 | { |
||
1150 | $docblock = <<<DOCBLOCK |
||
1151 | /** |
||
1152 | * @test at. |
||
1153 | */ |
||
1154 | class A { |
||
1155 | } |
||
1156 | DOCBLOCK; |
||
1157 | |||
1158 | //$lexer = new \Doctrine\Annotations\Lexer(); |
||
1159 | //$lexer->setInput(trim($docblock, '/ *')); |
||
1160 | //var_dump($lexer); |
||
1161 | |||
1162 | try { |
||
1163 | $parser = $this->createTestParser(); |
||
1164 | self::assertEmpty($parser->parse($docblock)); |
||
1165 | } catch (AnnotationException $e) { |
||
1166 | $this->fail($e->getMessage()); |
||
1167 | } |
||
1168 | } |
||
1169 | |||
1170 | /** |
||
1171 | * @group DCOM-14 |
||
1172 | */ |
||
1173 | public function testIgnorePHPDocThrowTag() |
||
1174 | { |
||
1175 | $docblock = <<<DOCBLOCK |
||
1176 | /** |
||
1177 | * @throws \RuntimeException |
||
1178 | */ |
||
1179 | class A { |
||
1180 | } |
||
1181 | DOCBLOCK; |
||
1182 | |||
1183 | try { |
||
1184 | $parser = $this->createTestParser(); |
||
1185 | self::assertEmpty($parser->parse($docblock)); |
||
1186 | } catch (AnnotationException $e) { |
||
1187 | $this->fail($e->getMessage()); |
||
1188 | } |
||
1189 | } |
||
1190 | |||
1191 | /** |
||
1192 | * @group DCOM-38 |
||
1193 | */ |
||
1194 | public function testCastInt() |
||
1195 | { |
||
1196 | $parser = $this->createTestParser(); |
||
1197 | |||
1198 | $result = $parser->parse('@Name(foo=1234)'); |
||
1199 | $annot = $result[0]; |
||
1200 | self::assertInternalType('int', $annot->foo); |
||
1201 | } |
||
1202 | |||
1203 | /** |
||
1204 | * @group DCOM-38 |
||
1205 | */ |
||
1206 | public function testCastNegativeInt() |
||
1207 | { |
||
1208 | $parser = $this->createTestParser(); |
||
1209 | |||
1210 | $result = $parser->parse('@Name(foo=-1234)'); |
||
1211 | $annot = $result[0]; |
||
1212 | self::assertInternalType('int', $annot->foo); |
||
1213 | } |
||
1214 | |||
1215 | /** |
||
1216 | * @group DCOM-38 |
||
1217 | */ |
||
1218 | public function testCastFloat() |
||
1219 | { |
||
1220 | $parser = $this->createTestParser(); |
||
1221 | |||
1222 | $result = $parser->parse('@Name(foo=1234.345)'); |
||
1223 | $annot = $result[0]; |
||
1224 | self::assertInternalType('float', $annot->foo); |
||
1225 | } |
||
1226 | |||
1227 | /** |
||
1228 | * @group DCOM-38 |
||
1229 | */ |
||
1230 | public function testCastNegativeFloat() |
||
1241 | } |
||
1242 | |||
1243 | /** |
||
1244 | * @expectedException \Doctrine\Annotations\AnnotationException |
||
1245 | * @expectedExceptionMessage [Creation Error] The annotation @SomeAnnotationClassNameWithoutConstructor declared on some class does not have a property named "invalidaProperty". Available properties: data, name |
||
1246 | */ |
||
1247 | public function testSetValuesExeption() |
||
1248 | { |
||
1249 | $docblock = <<<DOCBLOCK |
||
1250 | /** |
||
1251 | * @SomeAnnotationClassNameWithoutConstructor(invalidaProperty = "Some val") |
||
1252 | */ |
||
1253 | DOCBLOCK; |
||
1254 | |||
1255 | $this->createTestParser()->parse($docblock, 'some class'); |
||
1256 | } |
||
1257 | |||
1258 | /** |
||
1259 | * @expectedException \Doctrine\Annotations\AnnotationException |
||
1260 | * @expectedExceptionMessage [Syntax Error] Expected Doctrine\Annotations\DocLexer::T_IDENTIFIER or Doctrine\Annotations\DocLexer::T_TRUE or Doctrine\Annotations\DocLexer::T_FALSE or Doctrine\Annotations\DocLexer::T_NULL, got '3.42' at position 5. |
||
1261 | */ |
||
1262 | public function testInvalidIdentifierInAnnotation() |
||
1263 | { |
||
1264 | $parser = $this->createTestParser(); |
||
1265 | $parser->parse('@Foo\3.42'); |
||
1266 | } |
||
1267 | |||
1268 | public function testTrailingCommaIsAllowed() |
||
1269 | { |
||
1270 | $parser = $this->createTestParser(); |
||
1271 | |||
1272 | $annots = $parser->parse('@Name({ |
||
1273 | "Foo", |
||
1274 | "Bar", |
||
1275 | })'); |
||
1276 | self::assertCount(1, $annots); |
||
1277 | self::assertEquals(['Foo', 'Bar'], $annots[0]->value); |
||
1278 | } |
||
1279 | |||
1280 | public function testTabPrefixIsAllowed() |
||
1281 | { |
||
1282 | $docblock = <<<DOCBLOCK |
||
1283 | /** |
||
1284 | * @Name |
||
1285 | */ |
||
1286 | DOCBLOCK; |
||
1287 | |||
1288 | $parser = $this->createTestParser(); |
||
1289 | $result = $parser->parse($docblock); |
||
1290 | self::assertCount(1, $result); |
||
1291 | self::assertInstanceOf(Name::class, $result[0]); |
||
1292 | } |
||
1293 | |||
1294 | public function testDefaultAnnotationValueIsNotOverwritten() |
||
1295 | { |
||
1296 | $parser = $this->createTestParser(); |
||
1297 | |||
1298 | $annots = $parser->parse('@Doctrine\Tests\Annotations\Fixtures\Annotation\AnnotWithDefaultValue'); |
||
1299 | self::assertCount(1, $annots); |
||
1300 | self::assertEquals('bar', $annots[0]->foo); |
||
1301 | } |
||
1302 | |||
1303 | public function testArrayWithColon() |
||
1304 | { |
||
1305 | $parser = $this->createTestParser(); |
||
1306 | |||
1307 | $annots = $parser->parse('@Name({"foo": "bar"})'); |
||
1308 | self::assertCount(1, $annots); |
||
1309 | self::assertEquals(['foo' => 'bar'], $annots[0]->value); |
||
1310 | } |
||
1311 | |||
1312 | /** |
||
1313 | * @expectedException \Doctrine\Annotations\AnnotationException |
||
1314 | * @expectedExceptionMessage [Semantical Error] Couldn't find constant foo. |
||
1315 | */ |
||
1316 | public function testInvalidContantName() |
||
1317 | { |
||
1318 | $parser = $this->createTestParser(); |
||
1319 | $parser->parse('@Name(foo: "bar")'); |
||
1320 | } |
||
1321 | |||
1322 | /** |
||
1323 | * Tests parsing empty arrays. |
||
1324 | */ |
||
1325 | public function testEmptyArray() |
||
1332 | } |
||
1333 | |||
1334 | public function testKeyHasNumber() |
||
1335 | { |
||
1336 | $parser = $this->createTestParser(); |
||
1337 | $annots = $parser->parse('@SettingsAnnotation(foo="test", bar2="test")'); |
||
1338 | |||
1339 | self::assertCount(1, $annots); |
||
1340 | self::assertEquals(['foo' => 'test', 'bar2' => 'test'], $annots[0]->settings); |
||
1341 | } |
||
1342 | |||
1343 | /** |
||
1344 | * @group 44 |
||
1345 | */ |
||
1346 | public function testSupportsEscapedQuotedValues() |
||
1347 | { |
||
1348 | $result = $this->createTestParser()->parse('@Doctrine\Tests\Annotations\Name(foo="""bar""")'); |
||
1349 | |||
1350 | self::assertCount(1, $result); |
||
1351 | |||
1352 | self::assertInstanceOf(Name::class, $result[0]); |
||
1353 | self::assertEquals('"bar"', $result[0]->foo); |
||
1354 | } |
||
1355 | |||
1356 | /** |
||
1357 | * @see http://php.net/manual/en/mbstring.configuration.php |
||
1358 | * mbstring.func_overload can be changed only in php.ini |
||
1359 | * so for testing this case instead of skipping it you need to manually configure your php installation |
||
1360 | */ |
||
1361 | public function testMultiByteAnnotation() |
||
1362 | { |
||
1363 | $overloadStringFunctions = 2; |
||
1364 | if (!extension_loaded('mbstring') || (ini_get('mbstring.func_overload') & $overloadStringFunctions) == 0) { |
||
1365 | $this->markTestSkipped('This test requires mbstring function overloading is turned on'); |
||
1366 | } |
||
1367 | |||
1368 | $docblock = <<<DOCBLOCK |
||
1369 | /** |
||
1370 | * Мультибайтовый текст ломал парсер при оверлоадинге строковых функций |
||
1371 | * @Doctrine\Tests\Annotations\Name |
||
1372 | */ |
||
1373 | DOCBLOCK; |
||
1374 | |||
1375 | $docParser = $this->createTestParser(); |
||
1376 | $result = $docParser->parse($docblock); |
||
1377 | |||
1379 | |||
1380 | } |
||
1381 | } |
||
1449 |