Skip to content
This repository was archived by the owner on Sep 1, 2023. It is now read-only.

Commit a370a1b

Browse files
committed
Fix matches_type_structure where a shape should contain a genericized object
fixes #10
1 parent f5864dc commit a370a1b

File tree

3 files changed

+50
-4
lines changed

3 files changed

+50
-4
lines changed

src/PrivateImpl/TypeStructureImpl.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,11 @@ final public static function assertMatchesTypeStructure<T>(
114114
case TypeStructureKind::OF_INTERFACE:
115115
$class = TypeAssert::isNotNull($ts['classname']);
116116

117+
TypeAssert::isInstanceOf(
118+
TypeAssert::isNotNull($ts['classname']),
119+
$value,
120+
);
121+
117122
if (is_a($class, Traversable::class, /* strings = */ true)) {
118123
$generics = TypeAssert::isNotNull($ts['generic_types']);
119124
if (count($generics) === 2) {
@@ -130,10 +135,6 @@ final public static function assertMatchesTypeStructure<T>(
130135
}
131136
}
132137

133-
TypeAssert::isInstanceOf(
134-
TypeAssert::isNotNull($ts['classname']),
135-
$value,
136-
);
137138
return;
138139
case TypeStructureKind::OF_TRAIT:
139140
throw new UnsupportedTypeException('OF_TRAIT');

tests/TypeStructureTest.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,18 @@ public function getExampleValidTypes(
9696
type_structure(C::class, 'TStringStringMap'),
9797
Map { 'foo' => 'bar', 'herp' => 'derp' },
9898
),
99+
'Vector<Vector<string>>' => tuple(
100+
type_structure(C::class, 'TStringVectorVector'),
101+
Vector { Vector { 'foo' } },
102+
),
103+
'Vector<Vector<string>> with no outer elems' => tuple(
104+
type_structure(C::class, 'TStringVectorVector'),
105+
Vector { },
106+
),
107+
'Vector<Vector<string>> with no inner elems' => tuple(
108+
type_structure(C::class, 'TStringVectorVector'),
109+
Vector { Vector { } },
110+
),
99111
'shape with missing ?string field' => tuple(
100112
type_structure(C::class, 'TFlatShape'),
101113
shape('someString' => 'foo'),
@@ -130,6 +142,14 @@ public function getExampleValidTypes(
130142
),
131143
),
132144
),
145+
'shape with empty container' => tuple(
146+
type_structure(C::class, 'TShapeWithContainer'),
147+
array('container' => Vector {} ),
148+
),
149+
'shape with non-empty container' => tuple(
150+
type_structure(C::class, 'TShapeWithContainer'),
151+
array('container' => Vector { 'foo' } ),
152+
),
133153
'enum' => tuple(
134154
type_structure(C::class, 'TEnum'),
135155
ExampleEnum::DERP,
@@ -220,10 +240,22 @@ public function getExampleInvalidTypes(
220240
type_structure(C::class, 'TStringStringMap'),
221241
Map { 'foo' => 'bar', 'herp' => 123 },
222242
),
243+
'shape with missing field' => tuple(
244+
type_structure(C::class, 'TFlatShape'),
245+
shape(),
246+
),
223247
'shape with incorrect field' => tuple(
224248
type_structure(C::class, 'TFlatShape'),
225249
shape('someString' => 123),
226250
),
251+
'Vector<Vector<string>> with non-container child' => tuple(
252+
type_structure(C::class, 'TStringVectorVector'),
253+
Vector { 'foo' },
254+
),
255+
'Vector<Vector<string>> with incorrect container child' => tuple(
256+
type_structure(C::class, 'TStringVectorVector'),
257+
Vector { ImmVector { 'foo' } },
258+
),
227259
'nested shape with missing field' => tuple(
228260
type_structure(C::class, 'TNestedShape'),
229261
shape(
@@ -242,6 +274,14 @@ public function getExampleInvalidTypes(
242274
),
243275
),
244276
),
277+
'shape with missing container field' => tuple(
278+
type_structure(C::class, 'TShapeWithContainer'),
279+
array()
280+
),
281+
'shape with container of wrong kind' => tuple(
282+
type_structure(C::class, 'TShapeWithContainer'),
283+
array('container' => Vector { 123 }),
284+
),
245285
'enum' => tuple(
246286
type_structure(C::class, 'TEnum'),
247287
ExampleEnum::DERP.'HERP DERP DERP',

tests/fixtures/TypeConstants.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ class TypeConstants {
2525
const type TStdClass = \stdClass;
2626
const type TStringVector = Vector<string>;
2727
const type TStringStringMap = Map<string, string>;
28+
const type TStringVectorVector = Vector<Vector<string>>;
2829

2930
const type TFlatShape = shape(
3031
'someString' => string,
@@ -36,5 +37,9 @@ class TypeConstants {
3637
'someOtherShape' => self::TFlatShape,
3738
);
3839

40+
const type TShapeWithContainer = shape(
41+
'container' => Vector<string>,
42+
);
43+
3944
const type TEnum = ExampleEnum;
4045
}

0 commit comments

Comments
 (0)