3 namespace Doctrine\Tests\Common\Annotations;
5 use Doctrine\Common\Annotations\Annotation\IgnorePhpDoc;
6 use Doctrine\Common\Annotations\Annotation\IgnoreAnnotation;
7 use Doctrine\Common\Annotations\DocParser;
8 use Doctrine\Common\Annotations\AnnotationRegistry;
9 use Doctrine\Common\Annotations\Annotation\Target;
10 use Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithConstants;
11 use Doctrine\Tests\Common\Annotations\Fixtures\ClassWithConstants;
12 use Doctrine\Tests\Common\Annotations\Fixtures\IntefaceWithConstants;
14 class DocParserTest extends \PHPUnit_Framework_TestCase
16 public function testNestedArraysWithNestedAnnotation()
18 $parser = $this->createTestParser();
20 // Nested arrays with nested annotations
21 $result = $parser->parse('@Name(foo={1,2, {"key"=@Name}})');
24 $this->assertTrue($annot instanceof Name);
25 $this->assertNull($annot->value);
26 $this->assertEquals(3, count($annot->foo));
27 $this->assertEquals(1, $annot->foo[0]);
28 $this->assertEquals(2, $annot->foo[1]);
29 $this->assertTrue(is_array($annot->foo[2]));
31 $nestedArray = $annot->foo[2];
32 $this->assertTrue(isset($nestedArray['key']));
33 $this->assertTrue($nestedArray['key'] instanceof Name);
36 public function testBasicAnnotations()
38 $parser = $this->createTestParser();
41 $result = $parser->parse("@Name");
43 $this->assertTrue($annot instanceof Name);
44 $this->assertNull($annot->value);
45 $this->assertNull($annot->foo);
48 $result = $parser->parse('@Name(foo={"key1" = "value1"})');
50 $this->assertNull($annot->value);
51 $this->assertTrue(is_array($annot->foo));
52 $this->assertTrue(isset($annot->foo['key1']));
55 $result = $parser->parse('@Name({2="foo", 4="bar"})');
57 $this->assertTrue(is_array($annot->value));
58 $this->assertEquals('foo', $annot->value[2]);
59 $this->assertEquals('bar', $annot->value[4]);
60 $this->assertFalse(isset($annot->value[0]));
61 $this->assertFalse(isset($annot->value[1]));
62 $this->assertFalse(isset($annot->value[3]));
65 $result = $parser->parse('@Name(@Name, @Name)');
68 $this->assertTrue($annot instanceof Name);
69 $this->assertTrue(is_array($annot->value));
70 $this->assertTrue($annot->value[0] instanceof Name);
71 $this->assertTrue($annot->value[1] instanceof Name);
73 // Multiple types as values
74 $result = $parser->parse('@Name(foo="Bar", @Name, {"key1"="value1", "key2"="value2"})');
77 $this->assertTrue($annot instanceof Name);
78 $this->assertTrue(is_array($annot->value));
79 $this->assertTrue($annot->value[0] instanceof Name);
80 $this->assertTrue(is_array($annot->value[1]));
81 $this->assertEquals('value1', $annot->value[1]['key1']);
82 $this->assertEquals('value2', $annot->value[1]['key2']);
85 $docblock = <<<DOCBLOCK
94 $result = $parser->parse($docblock);
95 $this->assertEquals(1, count($result));
97 $this->assertTrue($annot instanceof Name);
98 $this->assertEquals("bar", $annot->foo);
99 $this->assertNull($annot->value);
102 public function testNamespacedAnnotations()
104 $parser = new DocParser;
105 $parser->setIgnoreNotImportedAnnotations(true);
107 $docblock = <<<DOCBLOCK
113 * @author Mr.X <mr@x.com>
114 * @Doctrine\Tests\Common\Annotations\Name(foo="bar")
119 $result = $parser->parse($docblock);
120 $this->assertEquals(1, count($result));
122 $this->assertTrue($annot instanceof Name);
123 $this->assertEquals("bar", $annot->foo);
129 public function testTypicalMethodDocBlock()
131 $parser = $this->createTestParser();
133 $docblock = <<<DOCBLOCK
138 * @Doctrine\Tests\Common\Annotations\Name(foo="bar")
139 * @param string \$foo This is foo.
140 * @param mixed \$bar This is bar.
141 * @return string Foo and bar.
142 * @This is irrelevant
147 $result = $parser->parse($docblock);
148 $this->assertEquals(2, count($result));
149 $this->assertTrue(isset($result[0]));
150 $this->assertTrue(isset($result[1]));
152 $this->assertTrue($annot instanceof Name);
153 $this->assertEquals("bar", $annot->foo);
154 $marker = $result[1];
155 $this->assertTrue($marker instanceof Marker);
159 public function testAnnotationWithoutConstructor()
161 $parser = $this->createTestParser();
164 $docblock = <<<DOCBLOCK
166 * @SomeAnnotationClassNameWithoutConstructor("Some data")
170 $result = $parser->parse($docblock);
171 $this->assertEquals(count($result), 1);
174 $this->assertNotNull($annot);
175 $this->assertTrue($annot instanceof SomeAnnotationClassNameWithoutConstructor);
177 $this->assertNull($annot->name);
178 $this->assertNotNull($annot->data);
179 $this->assertEquals($annot->data, "Some data");
184 $docblock = <<<DOCBLOCK
186 * @SomeAnnotationClassNameWithoutConstructor(name="Some Name", data = "Some data")
191 $result = $parser->parse($docblock);
192 $this->assertEquals(count($result), 1);
195 $this->assertNotNull($annot);
196 $this->assertTrue($annot instanceof SomeAnnotationClassNameWithoutConstructor);
198 $this->assertEquals($annot->name, "Some Name");
199 $this->assertEquals($annot->data, "Some data");
204 $docblock = <<<DOCBLOCK
206 * @SomeAnnotationClassNameWithoutConstructor(data = "Some data")
210 $result = $parser->parse($docblock);
211 $this->assertEquals(count($result), 1);
214 $this->assertEquals($annot->data, "Some data");
215 $this->assertNull($annot->name);
218 $docblock = <<<DOCBLOCK
220 * @SomeAnnotationClassNameWithoutConstructor(name = "Some name")
224 $result = $parser->parse($docblock);
225 $this->assertEquals(count($result), 1);
228 $this->assertEquals($annot->name, "Some name");
229 $this->assertNull($annot->data);
231 $docblock = <<<DOCBLOCK
233 * @SomeAnnotationClassNameWithoutConstructor("Some data")
237 $result = $parser->parse($docblock);
238 $this->assertEquals(count($result), 1);
241 $this->assertEquals($annot->data, "Some data");
242 $this->assertNull($annot->name);
246 $docblock = <<<DOCBLOCK
248 * @SomeAnnotationClassNameWithoutConstructor("Some data",name = "Some name")
252 $result = $parser->parse($docblock);
253 $this->assertEquals(count($result), 1);
256 $this->assertEquals($annot->name, "Some name");
257 $this->assertEquals($annot->data, "Some data");
260 $docblock = <<<DOCBLOCK
262 * @SomeAnnotationWithConstructorWithoutParams(name = "Some name")
266 $result = $parser->parse($docblock);
267 $this->assertEquals(count($result), 1);
270 $this->assertEquals($annot->name, "Some name");
271 $this->assertEquals($annot->data, "Some data");
273 $docblock = <<<DOCBLOCK
275 * @SomeAnnotationClassNameWithoutConstructorAndProperties()
279 $result = $parser->parse($docblock);
280 $this->assertEquals(count($result), 1);
281 $this->assertTrue($result[0] instanceof SomeAnnotationClassNameWithoutConstructorAndProperties);
284 public function testAnnotationTarget()
287 $parser = new DocParser;
288 $parser->setImports(array(
289 '__NAMESPACE__' => 'Doctrine\Tests\Common\Annotations\Fixtures',
291 $class = new \ReflectionClass('Doctrine\Tests\Common\Annotations\Fixtures\ClassWithValidAnnotationTarget');
294 $context = 'class ' . $class->getName();
295 $docComment = $class->getDocComment();
297 $parser->setTarget(Target::TARGET_CLASS);
298 $this->assertNotNull($parser->parse($docComment,$context));
301 $property = $class->getProperty('foo');
302 $docComment = $property->getDocComment();
303 $context = 'property ' . $class->getName() . "::\$" . $property->getName();
305 $parser->setTarget(Target::TARGET_PROPERTY);
306 $this->assertNotNull($parser->parse($docComment,$context));
310 $method = $class->getMethod('someFunction');
311 $docComment = $property->getDocComment();
312 $context = 'method ' . $class->getName() . '::' . $method->getName() . '()';
314 $parser->setTarget(Target::TARGET_METHOD);
315 $this->assertNotNull($parser->parse($docComment,$context));
319 $class = new \ReflectionClass('Doctrine\Tests\Common\Annotations\Fixtures\ClassWithInvalidAnnotationTargetAtClass');
320 $context = 'class ' . $class->getName();
321 $docComment = $class->getDocComment();
323 $parser->setTarget(Target::TARGET_CLASS);
324 $parser->parse($class->getDocComment(),$context);
327 } catch (\Doctrine\Common\Annotations\AnnotationException $exc) {
328 $this->assertNotNull($exc->getMessage());
334 $class = new \ReflectionClass('Doctrine\Tests\Common\Annotations\Fixtures\ClassWithInvalidAnnotationTargetAtMethod');
335 $method = $class->getMethod('functionName');
336 $docComment = $method->getDocComment();
337 $context = 'method ' . $class->getName() . '::' . $method->getName() . '()';
339 $parser->setTarget(Target::TARGET_METHOD);
340 $parser->parse($docComment,$context);
343 } catch (\Doctrine\Common\Annotations\AnnotationException $exc) {
344 $this->assertNotNull($exc->getMessage());
349 $class = new \ReflectionClass('Doctrine\Tests\Common\Annotations\Fixtures\ClassWithInvalidAnnotationTargetAtProperty');
350 $property = $class->getProperty('foo');
351 $docComment = $property->getDocComment();
352 $context = 'property ' . $class->getName() . "::\$" . $property->getName();
354 $parser->setTarget(Target::TARGET_PROPERTY);
355 $parser->parse($docComment,$context);
358 } catch (\Doctrine\Common\Annotations\AnnotationException $exc) {
359 $this->assertNotNull($exc->getMessage());
364 public function getAnnotationVarTypeProviderValid()
366 //({attribute name}, {attribute value})
369 array('mixed', '"String Value"'),
370 array('mixed', 'true'),
371 array('mixed', 'false'),
373 array('mixed', '1.2'),
374 array('mixed', '@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll'),
377 array('boolean', 'true'),
378 array('boolean', 'false'),
380 // alias for internal type boolean
381 array('bool', 'true'),
382 array('bool', 'false'),
385 array('integer', '0'),
386 array('integer', '1'),
387 array('integer', '123456789'),
388 array('integer', '9223372036854775807'),
390 // alias for internal type double
391 array('float', '0.1'),
392 array('float', '1.2'),
393 array('float', '123.456'),
396 array('string', '"String Value"'),
397 array('string', '"true"'),
398 array('string', '"123"'),
401 array('array', '{@AnnotationExtendsAnnotationTargetAll}'),
402 array('array', '{@AnnotationExtendsAnnotationTargetAll,@AnnotationExtendsAnnotationTargetAll}'),
404 array('arrayOfIntegers', '1'),
405 array('arrayOfIntegers', '{1}'),
406 array('arrayOfIntegers', '{1,2,3,4}'),
407 array('arrayOfAnnotations', '@AnnotationExtendsAnnotationTargetAll'),
408 array('arrayOfAnnotations', '{@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll}'),
409 array('arrayOfAnnotations', '{@AnnotationExtendsAnnotationTargetAll, @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll}'),
411 // annotation instance
412 array('annotation', '@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll'),
413 array('annotation', '@AnnotationExtendsAnnotationTargetAll'),
417 public function getAnnotationVarTypeProviderInvalid()
419 //({attribute name}, {type declared type}, {attribute value} , {given type or class})
422 array('boolean','boolean','1','integer'),
423 array('boolean','boolean','1.2','double'),
424 array('boolean','boolean','"str"','string'),
425 array('boolean','boolean','{1,2,3}','array'),
426 array('boolean','boolean','@Name', 'an instance of Doctrine\Tests\Common\Annotations\Name'),
428 // alias for internal type boolean
429 array('bool','bool', '1','integer'),
430 array('bool','bool', '1.2','double'),
431 array('bool','bool', '"str"','string'),
432 array('bool','bool', '{"str"}','array'),
435 array('integer','integer', 'true','boolean'),
436 array('integer','integer', 'false','boolean'),
437 array('integer','integer', '1.2','double'),
438 array('integer','integer', '"str"','string'),
439 array('integer','integer', '{"str"}','array'),
440 array('integer','integer', '{1,2,3,4}','array'),
442 // alias for internal type double
443 array('float','float', 'true','boolean'),
444 array('float','float', 'false','boolean'),
445 array('float','float', '123','integer'),
446 array('float','float', '"str"','string'),
447 array('float','float', '{"str"}','array'),
448 array('float','float', '{12.34}','array'),
449 array('float','float', '{1,2,3}','array'),
452 array('string','string', 'true','boolean'),
453 array('string','string', 'false','boolean'),
454 array('string','string', '12','integer'),
455 array('string','string', '1.2','double'),
456 array('string','string', '{"str"}','array'),
457 array('string','string', '{1,2,3,4}','array'),
459 // annotation instance
460 array('annotation','Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll', 'true','boolean'),
461 array('annotation','Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll', 'false','boolean'),
462 array('annotation','Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll', '12','integer'),
463 array('annotation','Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll', '1.2','double'),
464 array('annotation','Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll', '{"str"}','array'),
465 array('annotation','Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll', '{1,2,3,4}','array'),
466 array('annotation','Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll', '@Name','an instance of Doctrine\Tests\Common\Annotations\Name'),
470 public function getAnnotationVarTypeArrayProviderInvalid()
472 //({attribute name}, {type declared type}, {attribute value} , {given type or class})
474 array('arrayOfIntegers','integer', 'true','boolean'),
475 array('arrayOfIntegers','integer', 'false','boolean'),
476 array('arrayOfIntegers','integer', '{true,true}','boolean'),
477 array('arrayOfIntegers','integer', '{1,true}','boolean'),
478 array('arrayOfIntegers','integer', '{1,2,1.2}','double'),
479 array('arrayOfIntegers','integer', '{1,2,"str"}','string'),
482 array('arrayOfAnnotations','Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll', 'true','boolean'),
483 array('arrayOfAnnotations','Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll', 'false','boolean'),
484 array('arrayOfAnnotations','Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll', '{@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll,true}','boolean'),
485 array('arrayOfAnnotations','Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll', '{@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll,true}','boolean'),
486 array('arrayOfAnnotations','Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll', '{@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll,1.2}','double'),
487 array('arrayOfAnnotations','Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll', '{@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll,@AnnotationExtendsAnnotationTargetAll,"str"}','string'),
492 * @dataProvider getAnnotationVarTypeProviderValid
494 public function testAnnotationWithVarType($attribute, $value)
496 $parser = $this->createTestParser();
497 $context = 'property SomeClassName::$invalidProperty.';
498 $docblock = sprintf('@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithVarType(%s = %s)',$attribute, $value);
499 $parser->setTarget(Target::TARGET_PROPERTY);
501 $result = $parser->parse($docblock, $context);
503 $this->assertTrue(sizeof($result) === 1);
504 $this->assertInstanceOf('Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithVarType', $result[0]);
505 $this->assertNotNull($result[0]->$attribute);
509 * @dataProvider getAnnotationVarTypeProviderInvalid
511 public function testAnnotationWithVarTypeError($attribute,$type,$value,$given)
513 $parser = $this->createTestParser();
514 $context = 'property SomeClassName::invalidProperty.';
515 $docblock = sprintf('@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithVarType(%s = %s)',$attribute, $value);
516 $parser->setTarget(Target::TARGET_PROPERTY);
519 $parser->parse($docblock, $context);
521 } catch (\Doctrine\Common\Annotations\AnnotationException $exc) {
522 $this->assertContains("[Type Error] Attribute \"$attribute\" of @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithVarType declared on property SomeClassName::invalidProperty. expects a(n) $type, but got $given.", $exc->getMessage());
528 * @dataProvider getAnnotationVarTypeArrayProviderInvalid
530 public function testAnnotationWithVarTypeArrayError($attribute,$type,$value,$given)
532 $parser = $this->createTestParser();
533 $context = 'property SomeClassName::invalidProperty.';
534 $docblock = sprintf('@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithVarType(%s = %s)',$attribute, $value);
535 $parser->setTarget(Target::TARGET_PROPERTY);
538 $parser->parse($docblock, $context);
540 } catch (\Doctrine\Common\Annotations\AnnotationException $exc) {
541 $this->assertContains("[Type Error] Attribute \"$attribute\" of @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithVarType declared on property SomeClassName::invalidProperty. expects either a(n) $type, or an array of {$type}s, but got $given.", $exc->getMessage());
546 * @dataProvider getAnnotationVarTypeProviderValid
548 public function testAnnotationWithAttributes($attribute, $value)
550 $parser = $this->createTestParser();
551 $context = 'property SomeClassName::$invalidProperty.';
552 $docblock = sprintf('@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithAttributes(%s = %s)',$attribute, $value);
553 $parser->setTarget(Target::TARGET_PROPERTY);
555 $result = $parser->parse($docblock, $context);
557 $this->assertTrue(sizeof($result) === 1);
558 $this->assertInstanceOf('Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithAttributes', $result[0]);
559 $getter = "get".ucfirst($attribute);
560 $this->assertNotNull($result[0]->$getter());
564 * @dataProvider getAnnotationVarTypeProviderInvalid
566 public function testAnnotationWithAttributesError($attribute,$type,$value,$given)
568 $parser = $this->createTestParser();
569 $context = 'property SomeClassName::invalidProperty.';
570 $docblock = sprintf('@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithAttributes(%s = %s)',$attribute, $value);
571 $parser->setTarget(Target::TARGET_PROPERTY);
574 $parser->parse($docblock, $context);
576 } catch (\Doctrine\Common\Annotations\AnnotationException $exc) {
577 $this->assertContains("[Type Error] Attribute \"$attribute\" of @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithAttributes declared on property SomeClassName::invalidProperty. expects a(n) $type, but got $given.", $exc->getMessage());
583 * @dataProvider getAnnotationVarTypeArrayProviderInvalid
585 public function testAnnotationWithAttributesWithVarTypeArrayError($attribute,$type,$value,$given)
587 $parser = $this->createTestParser();
588 $context = 'property SomeClassName::invalidProperty.';
589 $docblock = sprintf('@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithAttributes(%s = %s)',$attribute, $value);
590 $parser->setTarget(Target::TARGET_PROPERTY);
593 $parser->parse($docblock, $context);
595 } catch (\Doctrine\Common\Annotations\AnnotationException $exc) {
596 $this->assertContains("[Type Error] Attribute \"$attribute\" of @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithAttributes declared on property SomeClassName::invalidProperty. expects either a(n) $type, or an array of {$type}s, but got $given.", $exc->getMessage());
600 public function testAnnotationWithRequiredAttributes()
602 $parser = $this->createTestParser();
603 $context = 'property SomeClassName::invalidProperty.';
604 $parser->setTarget(Target::TARGET_PROPERTY);
607 $docblock = '@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithRequiredAttributes("Some Value", annot = @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAnnotation)';
608 $result = $parser->parse($docblock);
610 $this->assertTrue(sizeof($result) === 1);
611 $this->assertInstanceOf('Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithRequiredAttributes', $result[0]);
612 $this->assertEquals("Some Value",$result[0]->getValue());
613 $this->assertInstanceOf('Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAnnotation', $result[0]->getAnnot());
616 $docblock = '@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithRequiredAttributes("Some Value")';
618 $result = $parser->parse($docblock,$context);
620 } catch (\Doctrine\Common\Annotations\AnnotationException $exc) {
621 $this->assertContains('Attribute "annot" of @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithRequiredAttributes declared on property SomeClassName::invalidProperty. expects a(n) Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAnnotation. This value should not be null.', $exc->getMessage());
624 $docblock = '@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithRequiredAttributes(annot = @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAnnotation)';
626 $result = $parser->parse($docblock,$context);
628 } catch (\Doctrine\Common\Annotations\AnnotationException $exc) {
629 $this->assertContains('Attribute "value" of @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithRequiredAttributes declared on property SomeClassName::invalidProperty. expects a(n) string. This value should not be null.', $exc->getMessage());
634 public function testAnnotationWithRequiredAttributesWithoutContructor()
636 $parser = $this->createTestParser();
637 $context = 'property SomeClassName::invalidProperty.';
638 $parser->setTarget(Target::TARGET_PROPERTY);
641 $docblock = '@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithRequiredAttributesWithoutContructor("Some Value", annot = @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAnnotation)';
642 $result = $parser->parse($docblock);
644 $this->assertTrue(sizeof($result) === 1);
645 $this->assertInstanceOf('Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithRequiredAttributesWithoutContructor', $result[0]);
646 $this->assertEquals("Some Value", $result[0]->value);
647 $this->assertInstanceOf('Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAnnotation', $result[0]->annot);
650 $docblock = '@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithRequiredAttributesWithoutContructor("Some Value")';
652 $result = $parser->parse($docblock,$context);
654 } catch (\Doctrine\Common\Annotations\AnnotationException $exc) {
655 $this->assertContains('Attribute "annot" of @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithRequiredAttributesWithoutContructor declared on property SomeClassName::invalidProperty. expects a(n) Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAnnotation. This value should not be null.', $exc->getMessage());
658 $docblock = '@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithRequiredAttributesWithoutContructor(annot = @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAnnotation)';
660 $result = $parser->parse($docblock,$context);
662 } catch (\Doctrine\Common\Annotations\AnnotationException $exc) {
663 $this->assertContains('Attribute "value" of @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithRequiredAttributesWithoutContructor declared on property SomeClassName::invalidProperty. expects a(n) string. This value should not be null.', $exc->getMessage());
668 public function getConstantsProvider()
671 '@AnnotationWithConstants(PHP_EOL)',
675 '@AnnotationWithConstants(AnnotationWithConstants::INTEGER)',
676 AnnotationWithConstants::INTEGER
679 '@Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithConstants(AnnotationWithConstants::STRING)',
680 AnnotationWithConstants::STRING
683 '@AnnotationWithConstants(Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithConstants::FLOAT)',
684 AnnotationWithConstants::FLOAT
687 '@AnnotationWithConstants(ClassWithConstants::SOME_VALUE)',
688 ClassWithConstants::SOME_VALUE
691 '@AnnotationWithConstants(Doctrine\Tests\Common\Annotations\Fixtures\ClassWithConstants::SOME_VALUE)',
692 ClassWithConstants::SOME_VALUE
695 '@AnnotationWithConstants(IntefaceWithConstants::SOME_VALUE)',
696 IntefaceWithConstants::SOME_VALUE
699 '@AnnotationWithConstants(\Doctrine\Tests\Common\Annotations\Fixtures\IntefaceWithConstants::SOME_VALUE)',
700 IntefaceWithConstants::SOME_VALUE
703 '@AnnotationWithConstants({AnnotationWithConstants::STRING, AnnotationWithConstants::INTEGER, AnnotationWithConstants::FLOAT})',
704 array(AnnotationWithConstants::STRING, AnnotationWithConstants::INTEGER, AnnotationWithConstants::FLOAT)
707 '@AnnotationWithConstants({
708 AnnotationWithConstants::STRING = AnnotationWithConstants::INTEGER
710 array(AnnotationWithConstants::STRING => AnnotationWithConstants::INTEGER)
713 '@AnnotationWithConstants({
714 Doctrine\Tests\Common\Annotations\Fixtures\IntefaceWithConstants::SOME_KEY = AnnotationWithConstants::INTEGER
716 array(IntefaceWithConstants::SOME_KEY => AnnotationWithConstants::INTEGER)
719 '@AnnotationWithConstants({
720 \Doctrine\Tests\Common\Annotations\Fixtures\IntefaceWithConstants::SOME_KEY = AnnotationWithConstants::INTEGER
722 array(IntefaceWithConstants::SOME_KEY => AnnotationWithConstants::INTEGER)
725 '@AnnotationWithConstants({
726 AnnotationWithConstants::STRING = AnnotationWithConstants::INTEGER,
727 ClassWithConstants::SOME_KEY = ClassWithConstants::SOME_VALUE,
728 Doctrine\Tests\Common\Annotations\Fixtures\ClassWithConstants::SOME_KEY = IntefaceWithConstants::SOME_VALUE
731 AnnotationWithConstants::STRING => AnnotationWithConstants::INTEGER,
732 ClassWithConstants::SOME_KEY => ClassWithConstants::SOME_VALUE,
733 ClassWithConstants::SOME_KEY => IntefaceWithConstants::SOME_VALUE
740 * @dataProvider getConstantsProvider
742 public function testSupportClassConstants($docblock, $expected)
744 $parser = $this->createTestParser();
745 $parser->setImports(array(
746 'classwithconstants' => 'Doctrine\Tests\Common\Annotations\Fixtures\ClassWithConstants',
747 'intefacewithconstants' => 'Doctrine\Tests\Common\Annotations\Fixtures\IntefaceWithConstants',
748 'annotationwithconstants' => 'Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithConstants'
751 $result = $parser->parse($docblock);
752 $this->assertInstanceOf('\Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithConstants', $annotation = $result[0]);
753 $this->assertEquals($expected, $annotation->value);
757 * @expectedException Doctrine\Common\Annotations\AnnotationException
758 * @expectedExceptionMessage The annotation @SomeAnnotationClassNameWithoutConstructorAndProperties declared on does not accept any values, but got {"value":"Foo"}.
760 public function testWithoutConstructorWhenIsNotDefaultValue()
762 $parser = $this->createTestParser();
763 $docblock = <<<DOCBLOCK
765 * @SomeAnnotationClassNameWithoutConstructorAndProperties("Foo")
770 $parser->setTarget(Target::TARGET_CLASS);
771 $parser->parse($docblock);
775 * @expectedException Doctrine\Common\Annotations\AnnotationException
776 * @expectedExceptionMessage The annotation @SomeAnnotationClassNameWithoutConstructorAndProperties declared on does not accept any values, but got {"value":"Foo"}.
778 public function testWithoutConstructorWhenHasNoProperties()
780 $parser = $this->createTestParser();
781 $docblock = <<<DOCBLOCK
783 * @SomeAnnotationClassNameWithoutConstructorAndProperties(value = "Foo")
787 $parser->setTarget(Target::TARGET_CLASS);
788 $parser->parse($docblock);
792 * @expectedException Doctrine\Common\Annotations\AnnotationException
793 * @expectedExceptionMessage Expected namespace separator or identifier, got ')' at position 24 in class @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithTargetSyntaxError.
795 public function testAnnotationTargetSyntaxError()
797 $parser = $this->createTestParser();
798 $context = 'class ' . 'SomeClassName';
799 $docblock = <<<DOCBLOCK
801 * @Doctrine\Tests\Common\Annotations\Fixtures\AnnotationWithTargetSyntaxError()
805 $parser->setTarget(Target::TARGET_CLASS);
806 $parser->parse($docblock,$context);
810 * @expectedException \InvalidArgumentException
811 * @expectedExceptionMessage Invalid Target "Foo". Available targets: [ALL, CLASS, METHOD, PROPERTY, ANNOTATION]
813 public function testAnnotationWithInvalidTargetDeclarationError()
815 $parser = $this->createTestParser();
816 $context = 'class ' . 'SomeClassName';
817 $docblock = <<<DOCBLOCK
819 * @AnnotationWithInvalidTargetDeclaration()
823 $parser->setTarget(Target::TARGET_CLASS);
824 $parser->parse($docblock,$context);
828 * @expectedException \InvalidArgumentException
829 * @expectedExceptionMessage @Target expects either a string value, or an array of strings, "NULL" given.
831 public function testAnnotationWithTargetEmptyError()
833 $parser = $this->createTestParser();
834 $context = 'class ' . 'SomeClassName';
835 $docblock = <<<DOCBLOCK
837 * @AnnotationWithTargetEmpty()
841 $parser->setTarget(Target::TARGET_CLASS);
842 $parser->parse($docblock,$context);
848 public function testRegressionDDC575()
850 $parser = $this->createTestParser();
852 $docblock = <<<DOCBLOCK
856 * Will trigger error.
860 $result = $parser->parse($docblock);
862 $this->assertInstanceOf("Doctrine\Tests\Common\Annotations\Name", $result[0]);
864 $docblock = <<<DOCBLOCK
869 * Will trigger error.
873 $result = $parser->parse($docblock);
875 $this->assertInstanceOf("Doctrine\Tests\Common\Annotations\Name", $result[0]);
881 public function testAnnotationWithoutClassIsIgnoredWithoutWarning()
883 $parser = new DocParser();
884 $parser->setIgnoreNotImportedAnnotations(true);
885 $result = $parser->parse("@param");
887 $this->assertEquals(0, count($result));
891 * @expectedException Doctrine\Common\Annotations\AnnotationException
892 * @expectedExceptionMessage Expected PlainValue, got ''' at position 10.
894 public function testAnnotationDontAcceptSingleQuotes()
896 $parser = $this->createTestParser();
897 $parser->parse("@Name(foo='bar')");
903 public function testAnnotationDoesntThrowExceptionWhenAtSignIsNotFollowedByIdentifier()
905 $parser = new DocParser();
906 $result = $parser->parse("'@'");
908 $this->assertEquals(0, count($result));
913 * @expectedException Doctrine\Common\Annotations\AnnotationException
915 public function testAnnotationThrowsExceptionWhenAtSignIsNotFollowedByIdentifierInNestedAnnotation()
917 $parser = new DocParser();
918 $result = $parser->parse("@Doctrine\Tests\Common\Annotations\Name(@')");
924 public function testAutoloadAnnotation()
926 $this->assertFalse(class_exists('Doctrine\Tests\Common\Annotations\Fixture\Annotation\Autoload', false), 'Pre-condition: Doctrine\Tests\Common\Annotations\Fixture\Annotation\Autoload not allowed to be loaded.');
928 $parser = new DocParser();
930 AnnotationRegistry::registerAutoloadNamespace('Doctrine\Tests\Common\Annotations\Fixtures\Annotation', __DIR__ . '/../../../../');
932 $parser->setImports(array(
933 'autoload' => 'Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Autoload',
935 $annotations = $parser->parse('@Autoload');
937 $this->assertEquals(1, count($annotations));
938 $this->assertInstanceOf('Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Autoload', $annotations[0]);
941 public function createTestParser()
943 $parser = new DocParser();
944 $parser->setIgnoreNotImportedAnnotations(true);
945 $parser->setImports(array(
946 'name' => 'Doctrine\Tests\Common\Annotations\Name',
947 '__NAMESPACE__' => 'Doctrine\Tests\Common\Annotations',
955 * @expectedException Doctrine\Common\Annotations\AnnotationException
956 * @expectedExceptionMessage Expected PlainValue, got ''' at position 10 in class \Doctrine\Tests\Common\Annotations\Name
958 public function testSyntaxErrorWithContextDescription()
960 $parser = $this->createTestParser();
961 $parser->parse("@Name(foo='bar')", "class \Doctrine\Tests\Common\Annotations\Name");
967 public function testSyntaxErrorWithUnknownCharacters()
969 $docblock = <<<DOCBLOCK
977 //$lexer = new \Doctrine\Common\Annotations\Lexer();
978 //$lexer->setInput(trim($docblock, '/ *'));
982 $parser = $this->createTestParser();
983 $result = $parser->parse($docblock);
984 } catch (Exception $e) {
985 $this->fail($e->getMessage());
992 public function testIgnorePHPDocThrowTag()
994 $docblock = <<<DOCBLOCK
996 * @throws \RuntimeException
1003 $parser = $this->createTestParser();
1004 $result = $parser->parse($docblock);
1005 } catch (Exception $e) {
1006 $this->fail($e->getMessage());
1013 public function testCastInt()
1015 $parser = $this->createTestParser();
1017 $result = $parser->parse("@Name(foo=1234)");
1018 $annot = $result[0];
1019 $this->assertInternalType('int', $annot->foo);
1025 public function testCastNegativeInt()
1027 $parser = $this->createTestParser();
1029 $result = $parser->parse("@Name(foo=-1234)");
1030 $annot = $result[0];
1031 $this->assertInternalType('int', $annot->foo);
1037 public function testCastFloat()
1039 $parser = $this->createTestParser();
1041 $result = $parser->parse("@Name(foo=1234.345)");
1042 $annot = $result[0];
1043 $this->assertInternalType('float', $annot->foo);
1049 public function testCastNegativeFloat()
1051 $parser = $this->createTestParser();
1053 $result = $parser->parse("@Name(foo=-1234.345)");
1054 $annot = $result[0];
1055 $this->assertInternalType('float', $annot->foo);
1057 $result = $parser->parse("@Marker(-1234.345)");
1058 $annot = $result[0];
1059 $this->assertInternalType('float', $annot->value);
1062 public function testReservedKeywordsInAnnotations()
1064 $parser = $this->createTestParser();
1066 $result = $parser->parse('@Doctrine\Tests\Common\Annotations\True');
1067 $this->assertTrue($result[0] instanceof True);
1068 $result = $parser->parse('@Doctrine\Tests\Common\Annotations\False');
1069 $this->assertTrue($result[0] instanceof False);
1070 $result = $parser->parse('@Doctrine\Tests\Common\Annotations\Null');
1071 $this->assertTrue($result[0] instanceof Null);
1073 $result = $parser->parse('@True');
1074 $this->assertTrue($result[0] instanceof True);
1075 $result = $parser->parse('@False');
1076 $this->assertTrue($result[0] instanceof False);
1077 $result = $parser->parse('@Null');
1078 $this->assertTrue($result[0] instanceof Null);
1082 * @expectedException Doctrine\Common\Annotations\AnnotationException
1083 * @expectedExceptionMessage [Creation Error] The annotation @SomeAnnotationClassNameWithoutConstructor declared on some class does not have a property named "invalidaProperty". Available properties: data, name
1085 public function testSetValuesExeption()
1087 $docblock = <<<DOCBLOCK
1089 * @SomeAnnotationClassNameWithoutConstructor(invalidaProperty = "Some val")
1093 $this->createTestParser()->parse($docblock, 'some class');
1097 * @expectedException Doctrine\Common\Annotations\AnnotationException
1098 * @expectedExceptionMessage [Syntax Error] Expected Doctrine\Common\Annotations\DocLexer::T_IDENTIFIER or Doctrine\Common\Annotations\DocLexer::T_TRUE or Doctrine\Common\Annotations\DocLexer::T_FALSE or Doctrine\Common\Annotations\DocLexer::T_NULL, got '3.42' at position 5.
1100 public function testInvalidIdentifierInAnnotation()
1102 $parser = $this->createTestParser();
1103 $parser->parse('@Foo\3.42');
1106 public function testTrailingCommaIsAllowed()
1108 $parser = $this->createTestParser();
1110 $annots = $parser->parse('@Name({
1114 $this->assertEquals(1, count($annots));
1115 $this->assertEquals(array('Foo', 'Bar'), $annots[0]->value);
1118 public function testDefaultAnnotationValueIsNotOverwritten()
1120 $parser = $this->createTestParser();
1122 $annots = $parser->parse('@Doctrine\Tests\Common\Annotations\Fixtures\Annotation\AnnotWithDefaultValue');
1123 $this->assertEquals(1, count($annots));
1124 $this->assertEquals('bar', $annots[0]->foo);
1127 public function testArrayWithColon()
1129 $parser = $this->createTestParser();
1131 $annots = $parser->parse('@Name({"foo": "bar"})');
1132 $this->assertEquals(1, count($annots));
1133 $this->assertEquals(array('foo' => 'bar'), $annots[0]->value);
1137 * @expectedException Doctrine\Common\Annotations\AnnotationException
1138 * @expectedExceptionMessage [Semantical Error] Couldn't find constant foo.
1140 public function testInvalidContantName()
1142 $parser = $this->createTestParser();
1143 $parser->parse('@Name(foo: "bar")');
1148 class SomeAnnotationClassNameWithoutConstructor
1155 class SomeAnnotationWithConstructorWithoutParams
1157 function __construct()
1159 $this->data = "Some data";
1166 class SomeAnnotationClassNameWithoutConstructorAndProperties{}
1172 class AnnotationWithInvalidTargetDeclaration{}
1178 class AnnotationWithTargetEmpty{}
1181 class AnnotationExtendsAnnotationTargetAll extends \Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetAll
1186 class Name extends \Doctrine\Common\Annotations\Annotation {
1204 namespace Doctrine\Tests\Common\Annotations\FooBar;
1207 class Name extends \Doctrine\Common\Annotations\Annotation {