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