$types * * @return void */ public function testValidTypeCombination($expected, $types) { $converted_types = []; foreach ($types as $type) { $converted_type = self::getAtomic($type); $converted_type->setFromDocblock(); $converted_types[] = $converted_type; } $this->assertSame( $expected, (string) TypeCombination::combineTypes($converted_types) ); } /** * @return iterable,error_levels?:string[]}> */ public function providerValidCodeParse() { return [ 'multipleValuedArray' => [ ' [ '}> */ public function providerTestValidTypeCombination() { return [ 'intOrString' => [ 'int|string', [ 'int', 'string', ], ], 'mixedOrNull' => [ 'mixed|null', [ 'mixed', 'null', ], ], 'mixedOrEmpty' => [ 'mixed', [ 'empty', 'mixed', ], ], 'mixedOrObject' => [ 'mixed|object', [ 'mixed', 'object', ], ], 'mixedOrEmptyArray' => [ 'array|mixed', [ 'mixed', 'array', ], ], 'falseTrueToBool' => [ 'bool', [ 'false', 'true', ], ], 'trueFalseToBool' => [ 'bool', [ 'true', 'false', ], ], 'trueBoolToBool' => [ 'bool', [ 'true', 'bool', ], ], 'boolTrueToBool' => [ 'bool', [ 'bool', 'true', ], ], 'intOrTrueOrFalseToBool' => [ 'bool|int', [ 'int', 'false', 'true', ], ], 'intOrBoolOrTrueToBool' => [ 'bool|int', [ 'int', 'bool', 'true', ], ], 'intOrTrueOrBoolToBool' => [ 'bool|int', [ 'int', 'true', 'bool', ], ], 'arrayOfIntOrString' => [ 'array', [ 'array', 'array', ], ], 'arrayOfIntOrAlsoString' => [ 'array|string', [ 'array', 'string', ], ], 'emptyArrays' => [ 'array', [ 'array', 'array', ], ], 'arrayStringOrEmptyArray' => [ 'array', [ 'array', 'array', ], ], 'arrayMixedOrString' => [ 'array', [ 'array', 'array', ], ], 'arrayMixedOrStringKeys' => [ 'array', [ 'array', 'array', ], ], 'arrayMixedOrEmpty' => [ 'array', [ 'array', 'array', ], ], 'arrayBigCombination' => [ 'array', [ 'array', 'array', ], ], 'arrayTraversableToIterable' => [ 'iterable', [ 'array', 'Traversable', ], ], 'arrayIterableToIterable' => [ 'iterable', [ 'array', 'iterable', ], ], 'iterableArrayToIterable' => [ 'iterable', [ 'iterable', 'array', ], ], 'traversableIterableToIterable' => [ 'iterable', [ 'Traversable', 'iterable', ], ], 'iterableTraversableToIterable' => [ 'iterable', [ 'iterable', 'Traversable', ], ], 'arrayTraversableToIterableWithParams' => [ 'iterable', [ 'array', 'Traversable', ], ], 'arrayIterableToIterableWithParams' => [ 'iterable', [ 'array', 'iterable', ], ], 'iterableArrayToIterableWithParams' => [ 'iterable', [ 'iterable', 'array', ], ], 'traversableIterableToIterableWithParams' => [ 'iterable', [ 'Traversable', 'iterable', ], ], 'iterableTraversableToIterableWithParams' => [ 'iterable', [ 'iterable', 'Traversable', ], ], 'arrayObjectAndParamsWithEmptyArray' => [ 'ArrayObject|array', [ 'ArrayObject', 'array', ], ], 'emptyArrayWithArrayObjectAndParams' => [ 'ArrayObject|array', [ 'array', 'ArrayObject', ], ], 'falseDestruction' => [ 'bool', [ 'false', 'bool', ], ], 'onlyFalse' => [ 'false', [ 'false', ], ], 'onlyTrue' => [ 'true', [ 'true', ], ], 'falseFalseDestruction' => [ 'false', [ 'false', 'false', ], ], 'aAndAOfB' => [ 'A|A', [ 'A', 'A', ], ], 'combineObjectType1' => [ 'array{a?: int, b?: string}', [ 'array{a: int}', 'array{b: string}', ], ], 'combineObjectType2' => [ 'array{a: int|string, b?: string}', [ 'array{a: int}', 'array{a: string,b: string}', ], ], 'combineObjectTypeWithIntKeyedArray' => [ 'array', [ 'array{a: int}', 'array', ], ], 'combineNestedObjectTypeWithObjectLikeIntKeyedArray' => [ 'array{a: array}', [ 'array{a: array{a: int}}', 'array{a: array}', ], ], 'combineIntKeyedObjectTypeWithNestedIntKeyedArray' => [ 'array>', [ 'array', 'array>', ], ], 'combineNestedObjectTypeWithNestedIntKeyedArray' => [ 'array>', [ 'array{a: array{a: int}}', 'array>', ], ], 'combinePossiblyUndefinedKeys' => [ 'array{a: bool, b?: mixed, d?: mixed}', [ 'array{a: false, b: mixed}', 'array{a: true, d: mixed}', 'array{a: true, d: mixed}', ], ], 'combinePossiblyUndefinedKeysAndString' => [ 'array{a: string, b?: int}|string', [ 'array{a: string, b?: int}', 'string', ], ], 'combineMixedArrayWithObjectLike' => [ 'array', [ 'array{a: int}', 'array', ], ], 'traversableAorB' => [ 'Traversable', [ 'Traversable', 'Traversable', ], ], 'iterableAorB' => [ 'iterable', [ 'iterable', 'iterable', ], ], 'FooAorB' => [ 'Foo|Foo', [ 'Foo', 'Foo', ], ], 'traversableOfMixed' => [ 'Traversable', [ 'Traversable', 'Traversable', ], ], 'traversableAndIterator' => [ 'Traversable&Iterator', [ 'Traversable&Iterator', 'Traversable&Iterator', ], ], 'traversableOfMixedAndIterator' => [ 'Traversable&Iterator', [ 'Traversable&Iterator', 'Traversable&Iterator', ], ], 'objectLikePlusArrayEqualsArray' => [ 'array', [ 'array<"a"|"b"|"c", 1|2|3>', 'array{a: 1|2, b: 2|3, c: 1|3}', ], ], 'combineClosures' => [ 'Closure(A):void|Closure(B):void', [ 'Closure(A):void', 'Closure(B):void', ], ], 'combineClassStringWithString' => [ 'string', [ 'class-string', 'string', ], ], 'combineClassStringWithFalse' => [ 'class-string|false', [ 'class-string', 'false', ], ], 'combineRefinedClassStringWithString' => [ 'string', [ 'class-string', 'string', ], ], 'combineRefinedClassStrings' => [ 'class-string|class-string', [ 'class-string', 'class-string', ], ], ]; } /** * @param string $string * * @return Type\Atomic */ private static function getAtomic($string) { return array_values(Type::parseString($string)->getTypes())[0]; } }