@@ -109,6 +109,132 @@ public function testAccepts(Type $type, Type $otherType, TrinaryLogic $expectedR
109109 );
110110 }
111111
112+ /**
113+ * @return Iterator<int, array{Type, Type, TrinaryLogic}>
114+ */
115+ public static function dataIsAcceptedBy (): Iterator
116+ {
117+ // array&callable isAcceptedBy array - success
118+ yield [
119+ new IntersectionType ([new ArrayType (new MixedType (), new MixedType ()), new CallableType ()]),
120+ new ArrayType (new MixedType (), new MixedType ()),
121+ TrinaryLogic::createYes (),
122+ ];
123+
124+ // array&callable isAcceptedBy array<int> - failure
125+ yield [
126+ new IntersectionType ([new ArrayType (new MixedType (), new MixedType ()), new CallableType ()]),
127+ new ArrayType (new MixedType (), new IntegerType ()),
128+ TrinaryLogic::createNo (),
129+ ];
130+
131+ // array&callable isAcceptedBy constantArray{stdClass, string} - maybe
132+ yield [
133+ new IntersectionType ([new ArrayType (new MixedType (), new MixedType ()), new CallableType ()]),
134+ new ConstantArrayType (
135+ [new ConstantIntegerType (0 ), new ConstantIntegerType (1 )],
136+ [new UnionType ([new ObjectType ('stdClass ' ), new StringType ()]), new StringType ()],
137+ ),
138+ TrinaryLogic::createMaybe (),
139+ ];
140+
141+ // array&callable isAcceptedBy constantArray{string, string} - maybe
142+ yield [
143+ new IntersectionType ([new ArrayType (new MixedType (), new MixedType ()), new CallableType ()]),
144+ new ConstantArrayType (
145+ [new ConstantIntegerType (0 ), new ConstantIntegerType (1 )],
146+ [new StringType (), new StringType ()],
147+ ),
148+ TrinaryLogic::createMaybe (),
149+ ];
150+
151+ // array&hasOffsetValue isAcceptedBy array - success
152+ yield [
153+ new IntersectionType ([
154+ new ArrayType (new MixedType (), new MixedType ()),
155+ new NonEmptyArrayType (),
156+ new HasOffsetValueType (new ConstantIntegerType (3 ), new IntegerType ()),
157+ ]),
158+ new ArrayType (new MixedType (), new MixedType ()),
159+ TrinaryLogic::createYes (),
160+ ];
161+
162+ // array&hasOffsetValue isAcceptedBy array - failure
163+ yield [
164+ new IntersectionType ([
165+ new ArrayType (new MixedType (), new MixedType ()),
166+ new NonEmptyArrayType (),
167+ new HasOffsetValueType (new ConstantIntegerType (3 ), new IntegerType ()),
168+ ]),
169+ new ArrayType (new MixedType (), new StringType ()),
170+ TrinaryLogic::createNo (),
171+ ];
172+
173+ // array&hasOffsetValue isAcceptedBy array<int> - success (matching value type)
174+ yield [
175+ new IntersectionType ([
176+ new ArrayType (new MixedType (), new MixedType ()),
177+ new NonEmptyArrayType (),
178+ new HasOffsetValueType (new ConstantIntegerType (3 ), new IntegerType ()),
179+ ]),
180+ new ArrayType (new MixedType (), new IntegerType ()),
181+ TrinaryLogic::createYes (),
182+ ];
183+
184+ // array&hasOffsetValue isAcceptedBy constantArray{int, int} - success
185+ yield [
186+ new IntersectionType ([
187+ new ArrayType (new MixedType (), new MixedType ()),
188+ new NonEmptyArrayType (),
189+ new HasOffsetValueType (new ConstantIntegerType (0 ), new IntegerType ()),
190+ ]),
191+ new ConstantArrayType (
192+ [new ConstantIntegerType (0 ), new ConstantIntegerType (1 )],
193+ [new IntegerType (), new IntegerType ()],
194+ ),
195+ TrinaryLogic::createMaybe (),
196+ ];
197+
198+ // array&hasOffsetValue isAcceptedBy constantArray{string, string} - failure
199+ yield [
200+ new IntersectionType ([
201+ new ArrayType (new MixedType (), new MixedType ()),
202+ new NonEmptyArrayType (),
203+ new HasOffsetValueType (new ConstantIntegerType (0 ), new IntegerType ()),
204+ ]),
205+ new ConstantArrayType (
206+ [new ConstantIntegerType (0 ), new ConstantIntegerType (1 )],
207+ [new StringType (), new StringType ()],
208+ ),
209+ TrinaryLogic::createNo (),
210+ ];
211+
212+ // array&hasOffsetValue(3, int) isAcceptedBy array<int>|array<string> - yes (array<int> accepts it)
213+ yield [
214+ new IntersectionType ([
215+ new ArrayType (new MixedType (), new MixedType ()),
216+ new NonEmptyArrayType (),
217+ new HasOffsetValueType (new ConstantIntegerType (3 ), new IntegerType ()),
218+ ]),
219+ new UnionType ([
220+ new ArrayType (new MixedType (), new IntegerType ()),
221+ new ArrayType (new MixedType (), new StringType ()),
222+ ]),
223+ TrinaryLogic::createYes (),
224+ ];
225+ }
226+
227+ #[DataProvider('dataIsAcceptedBy ' )]
228+ public function testIsAcceptedBy (Type $ type , Type $ acceptingType , TrinaryLogic $ expectedResult ): void
229+ {
230+ $ actualResult = $ acceptingType ->accepts ($ type , true )->result ;
231+ $ this ->assertSame (
232+ $ expectedResult ->describe (),
233+ $ actualResult ->describe (),
234+ sprintf ('%s -> isAcceptedBy(%s) ' , $ type ->describe (VerbosityLevel::precise ()), $ acceptingType ->describe (VerbosityLevel::precise ())),
235+ );
236+ }
237+
112238 public static function dataIsCallable (): array
113239 {
114240 return [
@@ -362,6 +488,53 @@ public static function dataIsSubTypeOf(): Iterator
362488 ]),
363489 TrinaryLogic::createYes (),
364490 ];
491+
492+ // array&callable isSubTypeOf array - success
493+ yield [
494+ new IntersectionType ([new ArrayType (new MixedType (), new MixedType ()), new CallableType ()]),
495+ new ArrayType (new MixedType (), new MixedType ()),
496+ TrinaryLogic::createYes (),
497+ ];
498+
499+ // array&callable isSubTypeOf array<int> - failure
500+ yield [
501+ new IntersectionType ([new ArrayType (new MixedType (), new MixedType ()), new CallableType ()]),
502+ new ArrayType (new MixedType (), new IntegerType ()),
503+ TrinaryLogic::createNo (),
504+ ];
505+
506+ // array&hasOffsetValue isSubTypeOf array - success
507+ yield [
508+ new IntersectionType ([
509+ new ArrayType (new MixedType (), new MixedType ()),
510+ new NonEmptyArrayType (),
511+ new HasOffsetValueType (new ConstantIntegerType (3 ), new IntegerType ()),
512+ ]),
513+ new ArrayType (new MixedType (), new MixedType ()),
514+ TrinaryLogic::createYes (),
515+ ];
516+
517+ // array&hasOffsetValue isSubTypeOf array<int> - maybe
518+ yield [
519+ new IntersectionType ([
520+ new ArrayType (new MixedType (), new MixedType ()),
521+ new NonEmptyArrayType (),
522+ new HasOffsetValueType (new ConstantIntegerType (3 ), new IntegerType ()),
523+ ]),
524+ new ArrayType (new MixedType (), new IntegerType ()),
525+ TrinaryLogic::createMaybe (),
526+ ];
527+
528+ // array&hasOffsetValue isSubTypeOf array<string> - failure
529+ yield [
530+ new IntersectionType ([
531+ new ArrayType (new MixedType (), new MixedType ()),
532+ new NonEmptyArrayType (),
533+ new HasOffsetValueType (new ConstantIntegerType (3 ), new IntegerType ()),
534+ ]),
535+ new ArrayType (new MixedType (), new StringType ()),
536+ TrinaryLogic::createNo (),
537+ ];
365538 }
366539
367540 #[DataProvider('dataIsSubTypeOf ' )]
0 commit comments