Completed
Push — master ( dbdf9d...5ad886 )
by Jaap
02:58 queued 10s
created

testResolvingIterableExpressionSimpleTypes()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 28
rs 9.472
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * This file is part of phpDocumentor.
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 *
11
 * @link      http://phpdoc.org
12
 */
13
14
namespace phpDocumentor\Reflection;
15
16
use InvalidArgumentException;
17
use Mockery as m;
18
use phpDocumentor\Reflection\Types\Array_;
19
use phpDocumentor\Reflection\Types\Boolean;
20
use phpDocumentor\Reflection\Types\Compound;
21
use phpDocumentor\Reflection\Types\Context;
22
use phpDocumentor\Reflection\Types\Iterable_;
23
use phpDocumentor\Reflection\Types\Nullable;
24
use phpDocumentor\Reflection\Types\Object_;
25
use phpDocumentor\Reflection\Types\String_;
26
use PHPUnit\Framework\TestCase;
27
use stdClass;
28
use function get_class;
29
30
/**
31
 * @coversDefaultClass \phpDocumentor\Reflection\TypeResolver
32
 */
33
class TypeResolverTest extends TestCase
34
{
35
    /**
36
     * Call Mockery::close after each test.
37
     *
38
     * @phpcsSuppress SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingReturnTypeHint
39
     */
40
    public function tearDown() : void
41
    {
42
        m::close();
43
    }
44
45
    /**
46
     * @uses         \phpDocumentor\Reflection\Types\Context
47
     * @uses         \phpDocumentor\Reflection\Types\Array_
48
     * @uses         \phpDocumentor\Reflection\Types\Object_
49
     *
50
     * @covers ::__construct
51
     * @covers ::resolve
52
     * @covers ::<private>
53
     *
54
     * @dataProvider provideKeywords
55
     */
56
    public function testResolvingKeywords(string $keyword, string $expectedClass) : void
57
    {
58
        $fixture = new TypeResolver();
59
60
        $resolvedType = $fixture->resolve($keyword, new Context(''));
61
62
        $this->assertInstanceOf($expectedClass, $resolvedType);
63
    }
64
65
    /**
66
     * @uses         \phpDocumentor\Reflection\Types\Context
67
     * @uses         \phpDocumentor\Reflection\Types\Object_
68
     * @uses         \phpDocumentor\Reflection\Fqsen
69
     * @uses         \phpDocumentor\Reflection\FqsenResolver
70
     *
71
     * @covers ::__construct
72
     * @covers ::resolve
73
     * @covers ::<private>
74
     *
75
     * @dataProvider provideFqcn
76
     */
77
    public function testResolvingFQSENs(string $fqsen) : void
78
    {
79
        $fixture = new TypeResolver();
80
81
        /** @var Object_ $resolvedType */
82
        $resolvedType = $fixture->resolve($fqsen, new Context(''));
83
84
        $this->assertInstanceOf(Object_::class, $resolvedType);
85
        $this->assertInstanceOf(Fqsen::class, $resolvedType->getFqsen());
86
        $this->assertSame($fqsen, (string) $resolvedType);
87
    }
88
89
    /**
90
     * @uses \phpDocumentor\Reflection\Types\Context
91
     * @uses \phpDocumentor\Reflection\Types\Object_
92
     * @uses \phpDocumentor\Reflection\Fqsen
93
     * @uses \phpDocumentor\Reflection\FqsenResolver
94
     *
95
     * @covers ::__construct
96
     * @covers ::resolve
97
     * @covers ::<private>
98
     */
99
    public function testResolvingRelativeQSENsBasedOnNamespace() : void
100
    {
101
        $fixture = new TypeResolver();
102
103
        /** @var Object_ $resolvedType */
104
        $resolvedType = $fixture->resolve('DocBlock', new Context('phpDocumentor\Reflection'));
105
106
        $this->assertInstanceOf(Object_::class, $resolvedType);
107
        $this->assertInstanceOf(Fqsen::class, $resolvedType->getFqsen());
108
        $this->assertSame('\phpDocumentor\Reflection\DocBlock', (string) $resolvedType);
109
    }
110
111
    /**
112
     * @uses \phpDocumentor\Reflection\Types\Context
113
     * @uses \phpDocumentor\Reflection\Types\Object_
114
     * @uses \phpDocumentor\Reflection\Fqsen
115
     * @uses \phpDocumentor\Reflection\FqsenResolver
116
     *
117
     * @covers ::__construct
118
     * @covers ::resolve
119
     * @covers ::<private>
120
     */
121
    public function testResolvingRelativeQSENsBasedOnNamespaceAlias() : void
122
    {
123
        $fixture = new TypeResolver();
124
125
        /** @var Object_ $resolvedType */
126
        $resolvedType = $fixture->resolve(
127
            'm\MockInterface',
128
            new Context('phpDocumentor\Reflection', ['m' => m::class])
129
        );
130
131
        $this->assertInstanceOf(Object_::class, $resolvedType);
132
        $this->assertInstanceOf(Fqsen::class, $resolvedType->getFqsen());
133
        $this->assertSame('\Mockery\MockInterface', (string) $resolvedType);
134
    }
135
136
    /**
137
     * @uses \phpDocumentor\Reflection\Types\Context
138
     * @uses \phpDocumentor\Reflection\Types\Array_
139
     * @uses \phpDocumentor\Reflection\Types\String_
140
     *
141
     * @covers ::__construct
142
     * @covers ::resolve
143
     * @covers ::<private>
144
     */
145
    public function testResolvingTypedArrays() : void
146
    {
147
        $fixture = new TypeResolver();
148
149
        /** @var Array_ $resolvedType */
150
        $resolvedType = $fixture->resolve('string[]', new Context(''));
151
152
        $this->assertInstanceOf(Array_::class, $resolvedType);
153
        $this->assertSame('string[]', (string) $resolvedType);
154
        $this->assertInstanceOf(Compound::class, $resolvedType->getKeyType());
155
        $this->assertInstanceOf(Types\String_::class, $resolvedType->getValueType());
156
    }
157
158
    /**
159
     * @uses \phpDocumentor\Reflection\Types\Context
160
     * @uses \phpDocumentor\Reflection\Types\Nullable
161
     * @uses \phpDocumentor\Reflection\Types\String_
162
     *
163
     * @covers ::__construct
164
     * @covers ::resolve
165
     * @covers ::<private>
166
     */
167
    public function testResolvingNullableTypes() : void
168
    {
169
        $fixture = new TypeResolver();
170
171
        /** @var Nullable $resolvedType */
172
        $resolvedType = $fixture->resolve('?string', new Context(''));
173
174
        $this->assertInstanceOf(Nullable::class, $resolvedType);
175
        $this->assertInstanceOf(String_::class, $resolvedType->getActualType());
176
        $this->assertSame('?string', (string) $resolvedType);
177
    }
178
179
    /**
180
     * @uses \phpDocumentor\Reflection\Types\Context
181
     * @uses \phpDocumentor\Reflection\Types\Array_
182
     * @uses \phpDocumentor\Reflection\Types\String_
183
     *
184
     * @covers ::__construct
185
     * @covers ::resolve
186
     * @covers ::<private>
187
     */
188
    public function testResolvingNestedTypedArrays() : void
189
    {
190
        $fixture = new TypeResolver();
191
192
        /** @var Array_ $resolvedType */
193
        $resolvedType = $fixture->resolve('string[][]', new Context(''));
194
195
        /** @var Array_ $childValueType */
196
        $childValueType = $resolvedType->getValueType();
197
198
        $this->assertInstanceOf(Array_::class, $resolvedType);
199
200
        $this->assertSame('string[][]', (string) $resolvedType);
201
        $this->assertInstanceOf(Compound::class, $resolvedType->getKeyType());
202
        $this->assertInstanceOf(Array_::class, $childValueType);
203
204
        $this->assertSame('string[]', (string) $childValueType);
205
        $this->assertInstanceOf(Compound::class, $childValueType->getKeyType());
206
        $this->assertInstanceOf(Types\String_::class, $childValueType->getValueType());
207
    }
208
209
    /**
210
     * @uses \phpDocumentor\Reflection\Types\Context
211
     * @uses \phpDocumentor\Reflection\Types\Compound
212
     * @uses \phpDocumentor\Reflection\Types\String_
213
     * @uses \phpDocumentor\Reflection\Types\Object_
214
     * @uses \phpDocumentor\Reflection\Fqsen
215
     * @uses \phpDocumentor\Reflection\FqsenResolver
216
     *
217
     * @covers ::__construct
218
     * @covers ::resolve
219
     * @covers ::<private>
220
     */
221
    public function testResolvingCompoundTypes() : void
222
    {
223
        $fixture = new TypeResolver();
224
225
        /** @var Compound $resolvedType */
226
        $resolvedType = $fixture->resolve('string|Reflection\DocBlock', new Context('phpDocumentor'));
227
228
        $this->assertInstanceOf(Compound::class, $resolvedType);
229
        $this->assertSame('string|\phpDocumentor\Reflection\DocBlock', (string) $resolvedType);
230
231
        /** @var string $secondType */
232
        $firstType = $resolvedType->get(0);
233
234
        /** @var Object_ $secondType */
235
        $secondType = $resolvedType->get(1);
236
237
        $this->assertInstanceOf(Types\String_::class, $firstType);
238
        $this->assertInstanceOf(Object_::class, $secondType);
239
        $this->assertInstanceOf(Fqsen::class, $secondType->getFqsen());
240
    }
241
242
    /**
243
     * @uses \phpDocumentor\Reflection\Types\Context
244
     * @uses \phpDocumentor\Reflection\Types\Compound
245
     * @uses \phpDocumentor\Reflection\Types\Array_
246
     * @uses \phpDocumentor\Reflection\Types\Object_
247
     * @uses \phpDocumentor\Reflection\Fqsen
248
     * @uses \phpDocumentor\Reflection\FqsenResolver
249
     *
250
     * @covers ::__construct
251
     * @covers ::resolve
252
     * @covers ::<private>
253
     */
254
    public function testResolvingCompoundTypedArrayTypes() : void
255
    {
256
        $fixture = new TypeResolver();
257
258
        /** @var Compound $resolvedType */
259
        $resolvedType = $fixture->resolve('\stdClass[]|Reflection\DocBlock[]', new Context('phpDocumentor'));
260
261
        $this->assertInstanceOf(Compound::class, $resolvedType);
262
        $this->assertSame('\stdClass[]|\phpDocumentor\Reflection\DocBlock[]', (string) $resolvedType);
263
264
        /** @var Array_ $firstType */
265
        $firstType = $resolvedType->get(0);
266
267
        /** @var Array_ $secondType */
268
        $secondType = $resolvedType->get(1);
269
270
        $this->assertInstanceOf(Array_::class, $firstType);
271
        $this->assertInstanceOf(Array_::class, $secondType);
272
        $this->assertInstanceOf(Object_::class, $firstType->getValueType());
273
        $this->assertInstanceOf(Object_::class, $secondType->getValueType());
274
    }
275
276
    /**
277
     * @uses \phpDocumentor\Reflection\Types\Context
278
     * @uses \phpDocumentor\Reflection\Types\Compound
279
     * @uses \phpDocumentor\Reflection\Types\String_
280
     * @uses \phpDocumentor\Reflection\Types\Nullable
281
     * @uses \phpDocumentor\Reflection\Types\Null_
282
     * @uses \phpDocumentor\Reflection\Types\Boolean
283
     * @uses \phpDocumentor\Reflection\Fqsen
284
     * @uses \phpDocumentor\Reflection\FqsenResolver
285
     *
286
     * @covers ::__construct
287
     * @covers ::resolve
288
     * @covers ::<private>
289
     */
290
    public function testResolvingNullableCompoundTypes() : void
291
    {
292
        $fixture = new TypeResolver();
293
294
        $resolvedType = $fixture->resolve('?string|null|?boolean');
295
296
        $this->assertSame('?string|null|?bool', (string) $resolvedType);
297
    }
298
299
    /**
300
     * @uses \phpDocumentor\Reflection\Types\Context
301
     * @uses \phpDocumentor\Reflection\Types\Compound
302
     * @uses \phpDocumentor\Reflection\Types\Array_
303
     * @uses \phpDocumentor\Reflection\Types\Object_
304
     * @uses \phpDocumentor\Reflection\Fqsen
305
     * @uses \phpDocumentor\Reflection\FqsenResolver
306
     *
307
     * @covers ::__construct
308
     * @covers ::resolve
309
     * @covers ::<private>
310
     */
311
    public function testResolvingArrayExpressionObjectsTypes() : void
312
    {
313
        $fixture = new TypeResolver();
314
315
        /** @var Array_ $resolvedType */
316
        $resolvedType = $fixture->resolve('(\stdClass|Reflection\DocBlock)[]', new Context('phpDocumentor'));
317
318
        $this->assertInstanceOf(Array_::class, $resolvedType);
319
        $this->assertSame('(\stdClass|\phpDocumentor\Reflection\DocBlock)[]', (string) $resolvedType);
320
321
        /** @var Compound $valueType */
322
        $valueType = $resolvedType->getValueType();
323
324
        $this->assertInstanceOf(Compound::class, $valueType);
325
326
        /** @var Object_ $firstType */
327
        $firstType = $valueType->get(0);
328
329
        /** @var Object_ $secondType */
330
        $secondType = $valueType->get(1);
331
332
        $this->assertInstanceOf(Object_::class, $firstType);
333
        $this->assertInstanceOf(Object_::class, $secondType);
334
    }
335
336
    /**
337
     * @uses \phpDocumentor\Reflection\Types\Context
338
     * @uses \phpDocumentor\Reflection\Types\Compound
339
     * @uses \phpDocumentor\Reflection\Types\Array_
340
     * @uses \phpDocumentor\Reflection\Types\Object_
341
     * @uses \phpDocumentor\Reflection\Fqsen
342
     * @uses \phpDocumentor\Reflection\FqsenResolver
343
     *
344
     * @covers ::__construct
345
     * @covers ::resolve
346
     * @covers ::<private>
347
     */
348
    public function testResolvingArrayExpressionSimpleTypes() : void
349
    {
350
        $fixture = new TypeResolver();
351
352
        /** @var Array_ $resolvedType */
353
        $resolvedType = $fixture->resolve('(string|\stdClass|boolean)[]', new Context(''));
354
355
        $this->assertInstanceOf(Array_::class, $resolvedType);
356
        $this->assertSame('(string|\stdClass|bool)[]', (string) $resolvedType);
357
358
        /** @var Compound $valueType */
359
        $valueType = $resolvedType->getValueType();
360
361
        $this->assertInstanceOf(Compound::class, $valueType);
362
363
        /** @var String_ $firstType */
364
        $firstType = $valueType->get(0);
365
366
        /** @var Object_ $secondType */
367
        $secondType = $valueType->get(1);
368
369
        /** @var Boolean $thirdType */
370
        $thirdType = $valueType->get(2);
371
372
        $this->assertInstanceOf(String_::class, $firstType);
373
        $this->assertInstanceOf(Object_::class, $secondType);
374
        $this->assertInstanceOf(Boolean::class, $thirdType);
375
    }
376
377
    /**
378
     * @uses \phpDocumentor\Reflection\Types\Context
379
     * @uses \phpDocumentor\Reflection\Types\Compound
380
     * @uses \phpDocumentor\Reflection\Types\Array_
381
     * @uses \phpDocumentor\Reflection\Types\Object_
382
     * @uses \phpDocumentor\Reflection\Fqsen
383
     * @uses \phpDocumentor\Reflection\FqsenResolver
384
     *
385
     * @covers ::__construct
386
     * @covers ::resolve
387
     * @covers ::<private>
388
     */
389
    public function testResolvingArrayOfArrayExpressionTypes() : void
390
    {
391
        $fixture = new TypeResolver();
392
393
        /** @var Array_ $resolvedType */
394
        $resolvedType = $fixture->resolve('(string|\stdClass)[][]', new Context(''));
395
396
        $this->assertInstanceOf(Array_::class, $resolvedType);
397
        $this->assertSame('(string|\stdClass)[][]', (string) $resolvedType);
398
399
        /** @var Array_ $parentArrayType */
400
        $parentArrayType = $resolvedType->getValueType();
401
        $this->assertInstanceOf(Array_::class, $parentArrayType);
402
403
        /** @var Compound $valueType */
404
        $valueType = $parentArrayType->getValueType();
405
        $this->assertInstanceOf(Compound::class, $valueType);
406
407
        /** @var String_ $firstType */
408
        $firstType = $valueType->get(0);
409
410
        /** @var Object_ $secondType */
411
        $secondType = $valueType->get(1);
412
413
        $this->assertInstanceOf(String_::class, $firstType);
414
        $this->assertInstanceOf(Object_::class, $secondType);
415
    }
416
417
    /**
418
     * @uses \phpDocumentor\Reflection\Types\Context
419
     * @uses \phpDocumentor\Reflection\Types\Compound
420
     * @uses \phpDocumentor\Reflection\Types\Array_
421
     * @uses \phpDocumentor\Reflection\Types\Object_
422
     * @uses \phpDocumentor\Reflection\Fqsen
423
     * @uses \phpDocumentor\Reflection\FqsenResolver
424
     *
425
     * @covers ::__construct
426
     * @covers ::resolve
427
     * @covers ::<private>
428
     */
429
    public function testReturnEmptyCompoundOnAnUnclosedArrayExpressionType() : void
430
    {
431
        $fixture = new TypeResolver();
432
433
        /** @var Compound $resolvedType */
434
        $resolvedType = $fixture->resolve('(string|\stdClass', new Context(''));
435
436
        $this->assertInstanceOf(Compound::class, $resolvedType);
437
        $this->assertSame('', (string) $resolvedType);
438
    }
439
440
    /**
441
     * @uses \phpDocumentor\Reflection\Types\Context
442
     * @uses \phpDocumentor\Reflection\Types\Compound
443
     * @uses \phpDocumentor\Reflection\Types\Array_
444
     * @uses \phpDocumentor\Reflection\Types\Object_
445
     * @uses \phpDocumentor\Reflection\Fqsen
446
     * @uses \phpDocumentor\Reflection\FqsenResolver
447
     *
448
     * @covers ::__construct
449
     * @covers ::resolve
450
     * @covers ::<private>
451
     */
452
    public function testResolvingArrayExpressionOrCompoundTypes() : void
453
    {
454
        $fixture = new TypeResolver();
455
456
        /** @var Compound $resolvedType */
457
        $resolvedType = $fixture->resolve('\stdClass|(string|\stdClass)[]|bool', new Context(''));
458
459
        $this->assertInstanceOf(Compound::class, $resolvedType);
460
        $this->assertSame('\stdClass|(string|\stdClass)[]|bool', (string) $resolvedType);
461
462
        /** @var Object_ $firstType */
463
        $firstType = $resolvedType->get(0);
464
        $this->assertInstanceOf(Object_::class, $firstType);
465
466
        /** @var Array_ $secondType */
467
        $secondType = $resolvedType->get(1);
468
        $this->assertInstanceOf(Array_::class, $secondType);
469
470
        /** @var Array_ $thirdType */
471
        $thirdType = $resolvedType->get(2);
472
        $this->assertInstanceOf(Boolean::class, $thirdType);
473
474
        /** @var Compound $valueType */
475
        $valueType = $secondType->getValueType();
476
        $this->assertInstanceOf(Compound::class, $valueType);
477
478
        /** @var String_ $firstArrayType */
479
        $firstArrayType = $valueType->get(0);
480
481
        /** @var Object_ $secondArrayType */
482
        $secondArrayType = $valueType->get(1);
483
484
        $this->assertInstanceOf(String_::class, $firstArrayType);
485
        $this->assertInstanceOf(Object_::class, $secondArrayType);
486
    }
487
488
    /**
489
     * @uses \phpDocumentor\Reflection\Types\Context
490
     * @uses \phpDocumentor\Reflection\Types\Compound
491
     * @uses \phpDocumentor\Reflection\Types\Iterable_
492
     * @uses \phpDocumentor\Reflection\Types\Object_
493
     * @uses \phpDocumentor\Reflection\Fqsen
494
     * @uses \phpDocumentor\Reflection\FqsenResolver
495
     *
496
     * @covers ::__construct
497
     * @covers ::resolve
498
     * @covers ::<private>
499
     */
500
    public function testResolvingIterableExpressionSimpleTypes() : void
501
    {
502
        $fixture = new TypeResolver();
503
504
        /** @var Iterable_ $resolvedType */
505
        $resolvedType = $fixture->resolve('iterable<string|\stdClass|boolean>', new Context(''));
506
507
        $this->assertInstanceOf(Iterable_::class, $resolvedType);
508
        $this->assertSame('iterable<string|\stdClass|bool>', (string) $resolvedType);
509
510
        /** @var Compound $valueType */
511
        $valueType = $resolvedType->getValueType();
512
513
        $this->assertInstanceOf(Compound::class, $valueType);
514
515
        /** @var String_ $firstType */
516
        $firstType = $valueType->get(0);
517
518
        /** @var Object_ $secondType */
519
        $secondType = $valueType->get(1);
520
521
        /** @var Boolean $thirdType */
522
        $thirdType = $valueType->get(2);
523
524
        $this->assertInstanceOf(String_::class, $firstType);
525
        $this->assertInstanceOf(Object_::class, $secondType);
526
        $this->assertInstanceOf(Boolean::class, $thirdType);
527
    }
528
529
    /**
530
     * This test asserts that the parameter order is correct.
531
     *
532
     * When you pass two arrays separated by the compound operator (i.e. 'integer[]|string[]') then we always split the
533
     * expression in its compound parts and then we parse the types with the array operators. If we were to switch the
534
     * order around then 'integer[]|string[]' would read as an array of string or integer array; which is something
535
     * other than what we intend.
536
     *
537
     * @uses \phpDocumentor\Reflection\Types\Context
538
     * @uses \phpDocumentor\Reflection\Types\Compound
539
     * @uses \phpDocumentor\Reflection\Types\Array_
540
     * @uses \phpDocumentor\Reflection\Types\Integer
541
     * @uses \phpDocumentor\Reflection\Types\String_
542
     *
543
     * @covers ::__construct
544
     * @covers ::resolve
545
     * @covers ::<private>
546
     */
547
    public function testResolvingCompoundTypesWithTwoArrays() : void
548
    {
549
        $fixture = new TypeResolver();
550
551
        /** @var Compound $resolvedType */
552
        $resolvedType = $fixture->resolve('integer[]|string[]', new Context(''));
553
554
        $this->assertInstanceOf(Compound::class, $resolvedType);
555
        $this->assertSame('int[]|string[]', (string) $resolvedType);
556
557
        /** @var Array_ $firstType */
558
        $firstType = $resolvedType->get(0);
559
560
        /** @var Array_ $secondType */
561
        $secondType = $resolvedType->get(1);
562
563
        $this->assertInstanceOf(Array_::class, $firstType);
564
        $this->assertInstanceOf(Types\Integer::class, $firstType->getValueType());
565
        $this->assertInstanceOf(Array_::class, $secondType);
566
        $this->assertInstanceOf(Types\String_::class, $secondType->getValueType());
567
    }
568
569
    /**
570
     * @uses \phpDocumentor\Reflection\TypeResolver::resolve
571
     * @uses \phpDocumentor\Reflection\TypeResolver::<private>
572
     * @uses \phpDocumentor\Reflection\Types\Context
573
     *
574
     * @covers ::__construct
575
     * @covers ::addKeyword
576
     */
577
    public function testAddingAKeyword() : void
578
    {
579
        // Assign
580
        $typeMock = m::mock(Type::class);
581
582
        // Act
583
        $fixture = new TypeResolver();
584
        $fixture->addKeyword('mock', get_class($typeMock));
585
586
        // Assert
587
        $result = $fixture->resolve('mock', new Context(''));
588
        $this->assertInstanceOf(get_class($typeMock), $result);
589
        $this->assertNotSame($typeMock, $result);
590
    }
591
592
    /**
593
     * @uses \phpDocumentor\Reflection\Types\Context
594
     *
595
     * @covers ::__construct
596
     * @covers ::addKeyword
597
     *
598
     * @expectedException InvalidArgumentException
599
     */
600
    public function testAddingAKeywordFailsIfTypeClassDoesNotExist() : void
601
    {
602
        $fixture = new TypeResolver();
603
        $fixture->addKeyword('mock', 'IDoNotExist');
604
    }
605
606
    /**
607
     * @uses \phpDocumentor\Reflection\Types\Context
608
     *
609
     * @covers ::__construct
610
     * @covers ::addKeyword
611
     *
612
     * @expectedException InvalidArgumentException
613
     */
614
    public function testAddingAKeywordFailsIfTypeClassDoesNotImplementTypeInterface() : void
615
    {
616
        $fixture = new TypeResolver();
617
        $fixture->addKeyword('mock', stdClass::class);
618
    }
619
620
    /**
621
     * @uses \phpDocumentor\Reflection\Types\Context
622
     *
623
     * @covers ::__construct
624
     * @covers ::resolve
625
     *
626
     * @expectedException InvalidArgumentException
627
     */
628
    public function testExceptionIsThrownIfTypeIsEmpty() : void
629
    {
630
        $fixture = new TypeResolver();
631
        $fixture->resolve(' ', new Context(''));
632
    }
633
634
    /**
635
     * Returns a list of keywords and expected classes that are created from them.
636
     *
637
     * @return string[][]
638
     */
639
    public function provideKeywords() : array
640
    {
641
        return [
642
            ['string', Types\String_::class],
643
            ['int', Types\Integer::class],
644
            ['integer', Types\Integer::class],
645
            ['float', Types\Float_::class],
646
            ['double', Types\Float_::class],
647
            ['bool', Types\Boolean::class],
648
            ['boolean', Types\Boolean::class],
649
            ['resource', Types\Resource_::class],
650
            ['null', Types\Null_::class],
651
            ['callable', Types\Callable_::class],
652
            ['callback', Types\Callable_::class],
653
            ['array', Array_::class],
654
            ['scalar', Types\Scalar::class],
655
            ['object', Object_::class],
656
            ['mixed', Types\Mixed_::class],
657
            ['void', Types\Void_::class],
658
            ['$this', Types\This::class],
659
            ['static', Types\Static_::class],
660
            ['self', Types\Self_::class],
661
            ['parent', Types\Parent_::class],
662
            ['iterable', Iterable_::class],
663
        ];
664
    }
665
666
    /**
667
     * Provides a list of FQSENs to test the resolution patterns with.
668
     *
669
     * @return string[][]
670
     */
671
    public function provideFqcn() : array
672
    {
673
        return [
674
            'namespace' => ['\phpDocumentor\Reflection'],
675
            'class' => ['\phpDocumentor\Reflection\DocBlock'],
676
        ];
677
    }
678
}
679