allow_coercion_from_string_to_class_const = false; $this->addFile( 'somefile.php', 'analyzeFile('somefile.php', new Context()); } /** * @expectedException \Psalm\Exception\CodeException * @expectedExceptionMessage InvalidStringClass * * @return void */ public function testDontAllowStringStandInForNewClass() { Config::getInstance()->allow_string_standin_for_class = false; $this->addFile( 'somefile.php', 'analyzeFile('somefile.php', new Context()); } /** * @expectedException \Psalm\Exception\CodeException * @expectedExceptionMessage InvalidStringClass * * @return void */ public function testDontAllowStringStandInForStaticMethodCall() { Config::getInstance()->allow_string_standin_for_class = false; $this->addFile( 'somefile.php', 'analyzeFile('somefile.php', new Context()); } /** * @return array */ public function providerFileCheckerValidCodeParse() { return [ 'arrayOfClassConstants' => [ ' $arr */ function takesClassConstants(array $arr) : void {} class A {} class B {} takesClassConstants([A::class, B::class]);', ], 'arrayOfStringClasses' => [ ' $arr */ function takesClassConstants(array $arr) : void {} class A {} class B {} takesClassConstants(["A", "B"]);', 'annotations' => [], 'error_levels' => ['TypeCoercion'], ], 'singleClassConstantAsConstant' => [ ' [ ' [], 'error_levels' => ['TypeCoercion'], ], 'returnClassConstant' => [ ' [ ' [], 'error_levels' => ['LessSpecificReturnStatement', 'MoreSpecificReturnType'], ], 'returnClassConstantArray' => [ ' */ function takesClassConstants() : array { return [A::class, B::class]; }', ], 'returnClassConstantArrayAllowCoercion' => [ ' */ function takesClassConstants() : array { return ["A", "B"]; }', 'annotations' => [], 'error_levels' => ['LessSpecificReturnStatement', 'MoreSpecificReturnType'], ], 'ifClassStringEquals' => [ ' [ ' [ ' [ ' "bar", ]; } class B {} /** @param class-string $s */ function bar(string $s) : void {} foreach (A::FOO as $class => $_) { bar($class); }', ], 'arrayEquivalence' => [ ' [ ' [ ' $arr */ function takesClassConstants(array $arr) : void {} class A {} class B {} takesClassConstants(["A", "B"]);', 'error_message' => 'TypeCoercion', ], 'arrayOfNonExistentStringClasses' => [ ' $arr */ function takesClassConstants(array $arr) : void {} takesClassConstants(["A", "B"]);', 'error_message' => 'UndefinedClass', 'error_levels' => ['TypeCoercion'], ], 'singleClassConstantWithInvalidDocblock' => [ ' 'InvalidDocblock', ], 'returnClassConstantDisallowCoercion' => [ ' 'LessSpecificReturnStatement', ], 'returnClassConstantArrayDisallowCoercion' => [ ' */ function takesClassConstants() : array { return ["A", "B"]; }', 'error_message' => 'LessSpecificReturnStatement', ], 'returnClassConstantArrayAllowCoercionWithUndefinedClass' => [ ' */ function takesClassConstants() : array { return ["A", "B"]; }', 'error_message' => 'UndefinedClass', 'error_levels' => ['LessSpecificReturnStatement', 'MoreSpecificReturnType'], ], ]; } }