|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
namespace Doctrine\Tests\Annotations; |
|
4
|
|
|
|
|
5
|
|
|
use Doctrine\Annotations\Annotation; |
|
6
|
|
|
use Doctrine\Annotations\AnnotationException; |
|
7
|
|
|
use Doctrine\Annotations\DocParser; |
|
8
|
|
|
use Doctrine\Annotations\Annotation\Target; |
|
9
|
|
|
use Doctrine\Tests\Annotations\Fixtures\AnnotationTargetAll; |
|
10
|
|
|
use Doctrine\Tests\Annotations\Fixtures\AnnotationWithConstants; |
|
11
|
|
|
use Doctrine\Tests\Annotations\Fixtures\ClassWithConstants; |
|
12
|
|
|
use Doctrine\Tests\Annotations\Fixtures\InterfaceWithConstants; |
|
13
|
|
|
use PHPUnit\Framework\TestCase; |
|
14
|
|
|
|
|
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() |
|
1029
|
|
|
{ |
|
1030
|
|
|
return [ |
|
1031
|
|
|
['Namespace', '@Namespace'], |
|
1032
|
|
|
['Namespace\\', '@Namespace'], |
|
1033
|
|
|
|
|
1034
|
|
|
['Namespace', '@Namespace\Subnamespace'], |
|
1035
|
|
|
['Namespace\\', '@Namespace\Subnamespace'], |
|
1036
|
|
|
|
|
1037
|
|
|
['Namespace', '@Namespace\Subnamespace\SubSubNamespace'], |
|
1038
|
|
|
['Namespace\\', '@Namespace\Subnamespace\SubSubNamespace'], |
|
1039
|
|
|
|
|
1040
|
|
|
['Namespace\Subnamespace', '@Namespace\Subnamespace'], |
|
1041
|
|
|
['Namespace\Subnamespace\\', '@Namespace\Subnamespace'], |
|
1042
|
|
|
|
|
1043
|
|
|
['Namespace\Subnamespace', '@Namespace\Subnamespace\SubSubNamespace'], |
|
1044
|
|
|
['Namespace\Subnamespace\\', '@Namespace\Subnamespace\SubSubNamespace'], |
|
1045
|
|
|
|
|
1046
|
|
|
['Namespace\Subnamespace\SubSubNamespace', '@Namespace\Subnamespace\SubSubNamespace'], |
|
1047
|
|
|
['Namespace\Subnamespace\SubSubNamespace\\', '@Namespace\Subnamespace\SubSubNamespace'], |
|
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() |
|
1078
|
|
|
{ |
|
1079
|
|
|
$parser = $this->createTestParser(); |
|
1080
|
|
|
$parser->parse("@Name(foo='bar')"); |
|
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() |
|
1231
|
|
|
{ |
|
1232
|
|
|
$parser = $this->createTestParser(); |
|
1233
|
|
|
|
|
1234
|
|
|
$result = $parser->parse('@Name(foo=-1234.345)'); |
|
1235
|
|
|
$annot = $result[0]; |
|
1236
|
|
|
self::assertInternalType('float', $annot->foo); |
|
|
|
|
|
|
1237
|
|
|
|
|
1238
|
|
|
$result = $parser->parse('@Marker(-1234.345)'); |
|
1239
|
|
|
$annot = $result[0]; |
|
1240
|
|
|
self::assertInternalType('float', $annot->value); |
|
|
|
|
|
|
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() |
|
1326
|
|
|
{ |
|
1327
|
|
|
$parser = $this->createTestParser(); |
|
1328
|
|
|
|
|
1329
|
|
|
$annots = $parser->parse('@Name({"foo": {}})'); |
|
1330
|
|
|
self::assertCount(1, $annots); |
|
1331
|
|
|
self::assertEquals(['foo' => []], $annots[0]->value); |
|
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
|
|
|
|
|
1378
|
|
|
self::assertCount(1, $result); |
|
1379
|
|
|
|
|
1380
|
|
|
} |
|
1381
|
|
|
} |
|
1382
|
|
|
|
|
1383
|
|
|
/** @Annotation */ |
|
1384
|
|
|
class SettingsAnnotation |
|
1385
|
|
|
{ |
|
1386
|
|
|
public $settings; |
|
1387
|
|
|
|
|
1388
|
|
|
public function __construct($settings) |
|
1389
|
|
|
{ |
|
1390
|
|
|
$this->settings = $settings; |
|
1391
|
|
|
} |
|
1392
|
|
|
} |
|
1393
|
|
|
|
|
1394
|
|
|
/** @Annotation */ |
|
1395
|
|
|
class SomeAnnotationClassNameWithoutConstructor |
|
1396
|
|
|
{ |
|
1397
|
|
|
public $data; |
|
1398
|
|
|
public $name; |
|
1399
|
|
|
} |
|
1400
|
|
|
|
|
1401
|
|
|
/** @Annotation */ |
|
1402
|
|
|
class SomeAnnotationWithConstructorWithoutParams |
|
1403
|
|
|
{ |
|
1404
|
|
|
public function __construct() |
|
1405
|
|
|
{ |
|
1406
|
|
|
$this->data = 'Some data'; |
|
1407
|
|
|
} |
|
1408
|
|
|
public $data; |
|
1409
|
|
|
public $name; |
|
1410
|
|
|
} |
|
1411
|
|
|
|
|
1412
|
|
|
/** @Annotation */ |
|
1413
|
|
|
class SomeAnnotationClassNameWithoutConstructorAndProperties{} |
|
1414
|
|
|
|
|
1415
|
|
|
/** |
|
1416
|
|
|
* @Annotation |
|
1417
|
|
|
* @Target("Foo") |
|
1418
|
|
|
*/ |
|
1419
|
|
|
class AnnotationWithInvalidTargetDeclaration{} |
|
1420
|
|
|
|
|
1421
|
|
|
/** |
|
1422
|
|
|
* @Annotation |
|
1423
|
|
|
* @Target |
|
1424
|
|
|
*/ |
|
1425
|
|
|
class AnnotationWithTargetEmpty{} |
|
1426
|
|
|
|
|
1427
|
|
|
/** @Annotation */ |
|
1428
|
|
|
class AnnotationExtendsAnnotationTargetAll extends AnnotationTargetAll |
|
1429
|
|
|
{ |
|
1430
|
|
|
} |
|
1431
|
|
|
|
|
1432
|
|
|
/** @Annotation */ |
|
1433
|
|
|
class Name extends Annotation { |
|
1434
|
|
|
public $foo; |
|
1435
|
|
|
} |
|
1436
|
|
|
|
|
1437
|
|
|
/** @Annotation */ |
|
1438
|
|
|
class Marker { |
|
1439
|
|
|
public $value; |
|
1440
|
|
|
} |
|
1441
|
|
|
|
|
1442
|
|
|
namespace Doctrine\Tests\Annotations\FooBar; |
|
1443
|
|
|
|
|
1444
|
|
|
use Doctrine\Annotations\Annotation; |
|
1445
|
|
|
|
|
1446
|
|
|
/** @Annotation */ |
|
1447
|
|
|
class Name extends Annotation { |
|
1448
|
|
|
} |
|
1449
|
|
|
|
This function has been deprecated. The supplier of the function has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.