assertSame('static', (string) Type::parseString('$this')); } /** * @return void */ public function testThisToStaticUnion() { $this->assertSame('static|A', (string) Type::parseString('$this|A')); } /** * @return void */ public function testIntOrString() { $this->assertSame('int|string', (string) Type::parseString('int|string')); } /** * @return void */ public function testBracketedIntOrString() { $this->assertSame('int|string', (string) Type::parseString('(int|string)')); } /** * @return void */ public function testBoolOrIntOrString() { $this->assertSame('bool|int|string', (string) Type::parseString('bool|int|string')); } /** * @return void */ public function testNullable() { $this->assertSame('null|string', (string) Type::parseString('?string')); } /** * @return void */ public function testArray() { $this->assertSame('array', (string) Type::parseString('array')); $this->assertSame('array', (string) Type::parseString('array')); $this->assertSame('array', (string) Type::parseString('array')); } /** * @return void */ public function testArrayWithSingleArg() { $this->assertSame('array', (string) Type::parseString('array')); } /** * @return void */ public function testArrayWithNestedSingleArg() { $this->assertSame('array>', (string) Type::parseString('array>')); } /** * @return void */ public function testArrayWithUnion() { $this->assertSame('array', (string) Type::parseString('array')); } /** * @return void */ public function testGeneric() { $this->assertSame('B', (string) Type::parseString('B')); } /** * @return void */ public function testIntersection() { $this->assertSame('I1&I2', (string) Type::parseString('I1&I2')); } /** * @return void */ public function testIntersectionOrNull() { $this->assertSame('I1&I2|null', (string) Type::parseString('I1&I2|null')); } /** * @return void */ public function testNullOrIntersection() { $this->assertSame('null|I1&I2', (string) Type::parseString('null|I1&I2')); } /** * @return void */ public function testInteratorAndTraversable() { $this->assertSame('Iterator&Traversable', (string) Type::parseString('Iterator&Traversable')); } /** * @return void */ public function testTraversableAndIteratorOrNull() { $this->assertSame( 'Traversable&Iterator|null', (string) Type::parseString('Traversable&Iterator|null') ); } /** * @return void */ public function testPhpDocSimpleArray() { $this->assertSame('array', (string) Type::parseString('A[]')); } /** * @return void */ public function testPhpDocUnionArray() { $this->assertSame('array', (string) Type::parseString('(A|B)[]')); } /** * @return void */ public function testPhpDocMultiDimensionalArray() { $this->assertSame('array>', (string) Type::parseString('A[][]')); } /** * @return void */ public function testPhpDocMultidimensionalUnionArray() { $this->assertSame('array>', (string) Type::parseString('(A|B)[][]')); } /** * @return void */ public function testPhpDocObjectLikeArray() { $this->assertSame( 'array', (string) Type::parseString('array{b:bool,d:string}[]') ); } /** * @return void */ public function testPhpDocUnionOfArrays() { $this->assertSame('array', (string) Type::parseString('A[]|B[]')); } /** * @return void */ public function testPhpDocUnionOfArraysOrObject() { $this->assertSame('array|C', (string) Type::parseString('A[]|B[]|C')); } /** * @return void */ public function testPsalmOnlyAtomic() { $this->assertSame('class-string', (string) Type::parseString('class-string')); } /** * @expectedException \Psalm\Exception\TypeParseTreeException * * @return void */ public function testInvalidType() { Type::parseString('array(A)'); } /** * @expectedException \Psalm\Exception\TypeParseTreeException * * @return void */ public function testBracketedUnionAndIntersection() { Type::parseString('(A|B)&C'); } /** * @return void */ public function testObjectLikeWithSimpleArgs() { $this->assertSame('array{a:int, b:string}', (string) Type::parseString('array{a:int, b:string}')); } /** * @return void */ public function testObjectLikeWithUnionArgs() { $this->assertSame( 'array{a:int|string, b:string}', (string) Type::parseString('array{a:int|string, b:string}') ); } /** * @return void */ public function testObjectLikeWithGenericArgs() { $this->assertSame( 'array{a:array, b:string}', (string) Type::parseString('array{a:array, b:string}') ); } /** * @return void */ public function testObjectLikeWithIntKeysAndUnionArgs() { $this->assertSame( 'array{0:stdClass|null}', (string)Type::parseString('array{stdClass|null}') ); } /** * @return void */ public function testObjectLikeWithIntKeysAndGenericArgs() { $this->assertSame( 'array{0:array}', (string)Type::parseString('array{array}') ); $this->assertSame( 'array{0:array}', (string)Type::parseString('array{array}') ); } /** * @return void */ public function testObjectLikeOptional() { $this->assertSame( 'array{a:int, b?:int}', (string)Type::parseString('array{a:int, b?:int}') ); } /** * @return void */ public function testCallable() { $this->assertSame( 'callable(int, string):void', (string)Type::parseString('callable(int, string) : void') ); } /** * @return void */ public function testEmptyCallable() { $this->assertSame( 'callable():void', (string)Type::parseString('callable() : void') ); } /** * @return void */ public function testCallableWithUnionLastType() { $this->assertSame( 'callable(int, int|string):void', (string)Type::parseString('callable(int, int|string) : void') ); } /** * @return void */ public function testCallableWithVariadic() { $this->assertSame( 'callable(int, string...):void', (string)Type::parseString('callable(int, string...) : void') ); } /** * @return void */ public function testCallableThatReturnsACallable() { $this->assertSame( 'callable():callable():string', (string)Type::parseString('callable() : callable() : string') ); } /** * @expectedException \Psalm\Exception\TypeParseTreeException * * @return void */ public function testCallableWithBadVariadic() { Type::parseString('callable(int, ...string) : void'); } /** * @expectedException \Psalm\Exception\TypeParseTreeException * * @return void */ public function testCallableWithTrailingColon() { Type::parseString('callable(int):'); } /** * @expectedException \Psalm\Exception\TypeParseTreeException * * @return void */ public function testCallableWithAnotherBadVariadic() { Type::parseString('callable(int, string..) : void'); } /** * @expectedException \Psalm\Exception\TypeParseTreeException * * @return void */ public function testCallableWithVariadicAndDefault() { Type::parseString('callable(int, string...=) : void'); } /** * @expectedException \Psalm\Exception\TypeParseTreeException * * @return void */ public function testBadVariadic() { Type::parseString('string...'); } /** * @expectedException \Psalm\Exception\TypeParseTreeException * * @return void */ public function testBadFullStop() { Type::parseString('string.'); } /** * @expectedException \Psalm\Exception\TypeParseTreeException * * @return void */ public function testBadSemicolon() { Type::parseString('string;'); } /** * @expectedException \Psalm\Exception\TypeParseTreeException * * @return void */ public function testDoubleBar() { Type::parseString('PDO||Closure|numeric'); } /** * @return void */ public function testCallableWithDefault() { $this->assertSame( 'callable(int, string=):void', (string)Type::parseString('callable(int, string=) : void') ); } /** * @return void */ public function testCallableWithoutReturn() { $this->assertSame( 'callable(int, string)', (string)Type::parseString('callable(int, string)') ); } }