|
17 | 17 | use Symfony\Component\TypeInfo\Type;
|
18 | 18 | use Symfony\Component\TypeInfo\Type\BuiltinType;
|
19 | 19 | use Symfony\Component\TypeInfo\Type\IntersectionType;
|
| 20 | +use Symfony\Component\TypeInfo\Type\ObjectType; |
20 | 21 | use Symfony\Component\TypeInfo\TypeIdentifier;
|
21 | 22 |
|
22 | 23 | class IntersectionTypeTest extends TestCase
|
23 | 24 | {
|
24 |
| - public function testCannotCreateWithOnlyOneType() |
| 25 | + public function testCannotCreateWithOnlyOneType(): void |
25 | 26 | {
|
26 | 27 | $this->expectException(InvalidArgumentException::class);
|
27 |
| - new IntersectionType(Type::int()); |
| 28 | + new IntersectionType(Type::object('Foo')); |
28 | 29 | }
|
29 | 30 |
|
30 |
| - public function testCannotCreateWithIntersectionTypeParts() |
| 31 | + public static function getInvalidParts(): iterable |
| 32 | + { |
| 33 | + $foo = Type::object('Foo'); |
| 34 | + $bar = Type::object('Bar'); |
| 35 | + |
| 36 | + yield 'intersection' => [Type::intersection($foo, $bar), Type::intersection($foo, $bar)]; |
| 37 | + yield 'union' => [Type::intersection($foo, $bar), Type::intersection($foo, $bar)]; |
| 38 | + foreach (TypeIdentifier::cases() as $case) { |
| 39 | + yield $case->value => [Type::builtin($case), Type::builtin($case)]; |
| 40 | + } |
| 41 | + yield 'generic<builtin>' => [Type::object('Foo'), Type::generic(Type::builtin('array'), Type::string())]; |
| 42 | + yield 'collection<builtin>' => [Type::object('Foo'), Type::collection(Type::generic(Type::builtin('array')))]; |
| 43 | + } |
| 44 | + |
| 45 | + /** |
| 46 | + * @dataProvider getInvalidParts |
| 47 | + */ |
| 48 | + public function testCannotCreateWithNonObjectParts(Type ...$parts): void |
31 | 49 | {
|
32 | 50 | $this->expectException(InvalidArgumentException::class);
|
33 |
| - new IntersectionType(Type::int(), new IntersectionType()); |
| 51 | + |
| 52 | + new IntersectionType(...$parts); |
34 | 53 | }
|
35 | 54 |
|
36 |
| - public function testSortTypesOnCreation() |
| 55 | + public function testCreateWithObjectParts(): void |
37 | 56 | {
|
38 |
| - $type = new IntersectionType(Type::int(), Type::string(), Type::bool()); |
39 |
| - $this->assertEquals([Type::bool(), Type::int(), Type::string()], $type->getTypes()); |
| 57 | + $foo = Type::object('Foo'); |
| 58 | + $bar = Type::generic(Type::object('Bar'), Type::string()); |
| 59 | + $baz = Type::collection(Type::generic(Type::object('Baz'), Type::string())); |
| 60 | + |
| 61 | + $type = new IntersectionType($foo, $bar, $baz); |
| 62 | + $this->assertEquals([$bar, $baz, $foo], $type->getTypes()); |
40 | 63 | }
|
41 | 64 |
|
42 | 65 | public function testAtLeastOneTypeIs()
|
43 | 66 | {
|
44 |
| - $type = new IntersectionType(Type::int(), Type::string(), Type::bool()); |
| 67 | + $type = new IntersectionType(Type::object('Foo'), Type::object('Bar'), Type::object('Baz')); |
45 | 68 |
|
46 |
| - $this->assertTrue($type->atLeastOneTypeIs(fn (Type $t) => 'int' === (string) $t)); |
47 |
| - $this->assertFalse($type->atLeastOneTypeIs(fn (Type $t) => 'float' === (string) $t)); |
| 69 | + $this->assertTrue($type->atLeastOneTypeIs(fn (Type $t) => 'Bar' === (string) $t)); |
| 70 | + $this->assertFalse($type->atLeastOneTypeIs(fn (Type $t) => 'Blip' === (string) $t)); |
48 | 71 | }
|
49 | 72 |
|
50 | 73 | public function testEveryTypeIs()
|
51 | 74 | {
|
52 |
| - $type = new IntersectionType(Type::int(), Type::string(), Type::bool()); |
53 |
| - $this->assertTrue($type->everyTypeIs(fn (Type $t) => $t instanceof BuiltinType)); |
| 75 | + $type = new IntersectionType(Type::object('Foo'), Type::object('Bar'), Type::object('Baz')); |
| 76 | + $this->assertTrue($type->everyTypeIs(fn (Type $t) => $t instanceof ObjectType)); |
54 | 77 |
|
55 |
| - $type = new IntersectionType(Type::int(), Type::string(), Type::template('T')); |
56 |
| - $this->assertFalse($type->everyTypeIs(fn (Type $t) => $t instanceof BuiltinType)); |
| 78 | + $type = new IntersectionType(Type::object('Foo'), Type::object('Bar'), Type::generic(Type::object('Baz'))); |
| 79 | + $this->assertFalse($type->everyTypeIs(fn (Type $t) => $t instanceof ObjectType)); |
57 | 80 | }
|
58 | 81 |
|
59 | 82 | public function testGetBaseType()
|
60 | 83 | {
|
61 | 84 | $this->expectException(LogicException::class);
|
62 |
| - (new IntersectionType(Type::string(), Type::int()))->getBaseType(); |
| 85 | + (new IntersectionType(Type::object('Bar'), Type::object('Foo')))->getBaseType(); |
63 | 86 | }
|
64 | 87 |
|
65 | 88 | public function testToString()
|
66 | 89 | {
|
67 |
| - $type = new IntersectionType(Type::int(), Type::string(), Type::float()); |
68 |
| - $this->assertSame('float&int&string', (string) $type); |
69 |
| - |
70 |
| - $type = new IntersectionType(Type::int(), Type::string(), Type::union(Type::float(), Type::bool())); |
71 |
| - $this->assertSame('(bool|float)&int&string', (string) $type); |
72 |
| - } |
73 |
| - |
74 |
| - public function testIsNullable() |
75 |
| - { |
76 |
| - $this->assertFalse((new IntersectionType(Type::int(), Type::string(), Type::float()))->isNullable()); |
77 |
| - $this->assertTrue((new IntersectionType(Type::null(), Type::union(Type::int(), Type::mixed())))->isNullable()); |
78 |
| - } |
79 |
| - |
80 |
| - public function testAsNonNullable() |
81 |
| - { |
82 |
| - $type = new IntersectionType(Type::int(), Type::string(), Type::float()); |
83 |
| - |
84 |
| - $this->assertSame($type, $type->asNonNullable()); |
85 |
| - } |
86 |
| - |
87 |
| - public function testCannotTurnNullIntersectionAsNonNullable() |
88 |
| - { |
89 |
| - $this->expectException(LogicException::class); |
90 |
| - |
91 |
| - $type = (new IntersectionType(Type::null(), Type::mixed()))->asNonNullable(); |
| 90 | + $type = new IntersectionType(Type::object('Foo'), Type::object('Bar'), Type::generic(Type::object('Baz'), Type::string())); |
| 91 | + $this->assertSame('Bar&Baz<string>&Foo', (string) $type); |
92 | 92 | }
|
93 | 93 |
|
94 | 94 | public function testIsA()
|
95 | 95 | {
|
96 |
| - $type = new IntersectionType(Type::int(), Type::string(), Type::float()); |
| 96 | + $type = new IntersectionType(Type::object('Foo'), Type::object('Bar')); |
97 | 97 | $this->assertFalse($type->isA(TypeIdentifier::ARRAY));
|
98 | 98 |
|
99 |
| - $type = new IntersectionType(Type::int(), Type::string(), Type::union(Type::float(), Type::bool())); |
| 99 | + $type = new IntersectionType(Type::object('Foo'), Type::object('Bar')); |
100 | 100 | $this->assertFalse($type->isA(TypeIdentifier::INT));
|
101 | 101 |
|
102 |
| - $type = new IntersectionType(Type::int(), Type::union(Type::int(), Type::int())); |
103 |
| - $this->assertTrue($type->isA(TypeIdentifier::INT)); |
| 102 | + $type = new IntersectionType(Type::object('Foo'), Type::object('Bar')); |
| 103 | + $this->assertTrue($type->isA(TypeIdentifier::OBJECT)); |
104 | 104 | }
|
105 | 105 | }
|
0 commit comments