Chris@0: setPass(new ValidClassNamePass()); Chris@0: } Chris@0: Chris@0: /** Chris@0: * @dataProvider getInvalid Chris@0: */ Chris@0: public function testProcessInvalid($code, $php54 = false) Chris@0: { Chris@0: try { Chris@0: $stmts = $this->parse($code); Chris@0: $this->traverse($stmts); Chris@0: $this->fail(); Chris@0: } catch (Exception $e) { Chris@0: if ($php54 && version_compare(PHP_VERSION, '5.4', '<')) { Chris@0: $this->assertInstanceOf('Psy\Exception\ParseErrorException', $e); Chris@0: } else { Chris@0: $this->assertInstanceOf('Psy\Exception\FatalErrorException', $e); Chris@0: } Chris@0: } Chris@0: } Chris@0: Chris@0: public function getInvalid() Chris@0: { Chris@0: // class declarations Chris@0: return array( Chris@0: // core class Chris@0: array('class stdClass {}'), Chris@0: // capitalization Chris@0: array('class stdClass {}'), Chris@0: Chris@0: // collisions with interfaces and traits Chris@0: array('interface stdClass {}'), Chris@0: array('trait stdClass {}', true), Chris@0: Chris@0: // collisions inside the same code snippet Chris@0: array(' Chris@0: class Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {} Chris@0: class Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {} Chris@0: '), Chris@0: array(' Chris@0: class Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {} Chris@0: trait Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {} Chris@0: ', true), Chris@0: array(' Chris@0: trait Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {} Chris@0: class Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {} Chris@0: ', true), Chris@0: array(' Chris@0: trait Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {} Chris@0: interface Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {} Chris@0: ', true), Chris@0: array(' Chris@0: interface Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {} Chris@0: trait Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {} Chris@0: ', true), Chris@0: array(' Chris@0: interface Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {} Chris@0: class Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {} Chris@0: '), Chris@0: array(' Chris@0: class Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {} Chris@0: interface Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {} Chris@0: '), Chris@0: Chris@0: // namespaced collisions Chris@0: array(' Chris@0: namespace Psy\\Test\\CodeCleaner { Chris@0: class ValidClassNamePassTest {} Chris@0: } Chris@0: '), Chris@0: array(' Chris@0: namespace Psy\\Test\\CodeCleaner\\ValidClassNamePass { Chris@0: class Beta {} Chris@0: } Chris@0: namespace Psy\\Test\\CodeCleaner\\ValidClassNamePass { Chris@0: class Beta {} Chris@0: } Chris@0: '), Chris@0: Chris@0: // extends and implements Chris@0: array('class ValidClassNamePassTest extends NotAClass {}'), Chris@0: array('class ValidClassNamePassTest extends ArrayAccess {}'), Chris@0: array('class ValidClassNamePassTest implements stdClass {}'), Chris@0: array('class ValidClassNamePassTest implements ArrayAccess, stdClass {}'), Chris@0: array('interface ValidClassNamePassTest extends stdClass {}'), Chris@0: array('interface ValidClassNamePassTest extends ArrayAccess, stdClass {}'), Chris@0: Chris@0: // class instantiations Chris@0: array('new Psy_Test_CodeCleaner_ValidClassNamePass_Gamma();'), Chris@0: array(' Chris@0: namespace Psy\\Test\\CodeCleaner\\ValidClassNamePass { Chris@0: new Psy_Test_CodeCleaner_ValidClassNamePass_Delta(); Chris@0: } Chris@0: '), Chris@0: Chris@0: // class constant fetch Chris@0: array('Psy\\Test\\CodeCleaner\\ValidClassNamePass\\NotAClass::FOO'), Chris@0: Chris@0: // static call Chris@0: array('Psy\\Test\\CodeCleaner\\ValidClassNamePass\\NotAClass::foo()'), Chris@0: array('Psy\\Test\\CodeCleaner\\ValidClassNamePass\\NotAClass::$foo()'), Chris@0: ); Chris@0: } Chris@0: Chris@0: /** Chris@0: * @dataProvider getValid Chris@0: */ Chris@0: public function testProcessValid($code) Chris@0: { Chris@0: $stmts = $this->parse($code); Chris@0: $this->traverse($stmts); Chris@12: Chris@12: // @todo a better thing to assert here? Chris@12: $this->assertTrue(true); Chris@0: } Chris@0: Chris@0: public function getValid() Chris@0: { Chris@0: $valid = array( Chris@0: // class declarations Chris@0: array('class Psy_Test_CodeCleaner_ValidClassNamePass_Epsilon {}'), Chris@0: array('namespace Psy\Test\CodeCleaner\ValidClassNamePass; class Zeta {}'), Chris@0: array(' Chris@0: namespace { class Psy_Test_CodeCleaner_ValidClassNamePass_Eta {}; } Chris@0: namespace Psy\\Test\\CodeCleaner\\ValidClassNamePass { Chris@0: class Psy_Test_CodeCleaner_ValidClassNamePass_Eta {} Chris@0: } Chris@0: '), Chris@0: array('namespace Psy\Test\CodeCleaner\ValidClassNamePass { class stdClass {} }'), Chris@0: Chris@0: // class instantiations Chris@0: array('new stdClass();'), Chris@0: array('new stdClass();'), Chris@0: array(' Chris@0: namespace Psy\\Test\\CodeCleaner\\ValidClassNamePass { Chris@0: class Theta {} Chris@0: } Chris@0: namespace Psy\\Test\\CodeCleaner\\ValidClassNamePass { Chris@0: new Theta(); Chris@0: } Chris@0: '), Chris@0: array(' Chris@0: namespace Psy\\Test\\CodeCleaner\\ValidClassNamePass { Chris@0: class Iota {} Chris@0: new Iota(); Chris@0: } Chris@0: '), Chris@0: array(' Chris@0: namespace Psy\\Test\\CodeCleaner\\ValidClassNamePass { Chris@0: class Kappa {} Chris@0: } Chris@0: namespace { Chris@0: new \\Psy\\Test\\CodeCleaner\\ValidClassNamePass\\Kappa(); Chris@0: } Chris@0: '), Chris@0: Chris@0: // Class constant fetch (ValidConstantPassTest validates the actual constant) Chris@0: array('class A {} A::FOO'), Chris@0: array('$a = new DateTime; $a::ATOM'), Chris@0: array('interface A { const B = 1; } A::B'), Chris@0: Chris@0: // static call Chris@0: array('DateTime::createFromFormat()'), Chris@0: array('DateTime::$someMethod()'), Chris@0: array('Psy\Test\CodeCleaner\Fixtures\ClassWithStatic::doStuff()'), Chris@0: array('Psy\Test\CodeCleaner\Fixtures\ClassWithCallStatic::doStuff()'), Chris@0: Chris@0: // Allow `self` and `static` as class names. Chris@0: array(' Chris@0: class Psy_Test_CodeCleaner_ValidClassNamePass_ClassWithStatic { Chris@0: public static function getInstance() { Chris@0: return new self(); Chris@0: } Chris@0: } Chris@0: '), Chris@0: array(' Chris@0: class Psy_Test_CodeCleaner_ValidClassNamePass_ClassWithStatic { Chris@0: public static function getInstance() { Chris@0: return new SELF(); Chris@0: } Chris@0: } Chris@0: '), Chris@0: array(' Chris@0: class Psy_Test_CodeCleaner_ValidClassNamePass_ClassWithStatic { Chris@0: public static function getInstance() { Chris@0: return new self; Chris@0: } Chris@0: } Chris@0: '), Chris@0: array(' Chris@0: class Psy_Test_CodeCleaner_ValidClassNamePass_ClassWithStatic { Chris@0: public static function getInstance() { Chris@0: return new static(); Chris@0: } Chris@0: } Chris@0: '), Chris@0: array(' Chris@0: class Psy_Test_CodeCleaner_ValidClassNamePass_ClassWithStatic { Chris@0: public static function getInstance() { Chris@0: return new Static(); Chris@0: } Chris@0: } Chris@0: '), Chris@0: array(' Chris@0: class Psy_Test_CodeCleaner_ValidClassNamePass_ClassWithStatic { Chris@0: public static function getInstance() { Chris@0: return new static; Chris@0: } Chris@0: } Chris@0: '), Chris@0: array(' Chris@0: class Psy_Test_CodeCleaner_ValidClassNamePass_ClassWithStatic { Chris@0: public static function foo() { Chris@0: return parent::bar(); Chris@0: } Chris@0: } Chris@0: '), Chris@0: array(' Chris@0: class Psy_Test_CodeCleaner_ValidClassNamePass_ClassWithStatic { Chris@0: public static function foo() { Chris@0: return self::bar(); Chris@0: } Chris@0: } Chris@0: '), Chris@0: array(' Chris@0: class Psy_Test_CodeCleaner_ValidClassNamePass_ClassWithStatic { Chris@0: public static function foo() { Chris@0: return static::bar(); Chris@0: } Chris@0: } Chris@0: '), Chris@0: Chris@0: array('class A { static function b() { return new A; } }'), Chris@0: array(' Chris@0: class A { Chris@0: const B = 123; Chris@0: function c() { Chris@0: return A::B; Chris@0: } Chris@0: } Chris@0: '), Chris@0: array('class A {} class B { function c() { return new A; } }'), Chris@0: Chris@0: // recursion Chris@0: array('class A { function a() { A::a(); } }'), Chris@0: Chris@0: // conditionally defined classes Chris@0: array(' Chris@0: class A {} Chris@0: if (false) { Chris@0: class A {} Chris@0: } Chris@0: '), Chris@0: array(' Chris@0: class A {} Chris@0: if (true) { Chris@0: class A {} Chris@0: } else if (false) { Chris@0: class A {} Chris@0: } else { Chris@0: class A {} Chris@0: } Chris@0: '), Chris@0: // ewww Chris@0: array(' Chris@0: class A {} Chris@0: if (true): Chris@0: class A {} Chris@0: elseif (false): Chris@0: class A {} Chris@0: else: Chris@0: class A {} Chris@0: endif; Chris@0: '), Chris@0: array(' Chris@0: class A {} Chris@0: while (false) { class A {} } Chris@0: '), Chris@0: array(' Chris@0: class A {} Chris@0: do { class A {} } while (false); Chris@0: '), Chris@0: array(' Chris@0: class A {} Chris@0: switch (1) { Chris@0: case 0: Chris@0: class A {} Chris@0: break; Chris@0: case 1: Chris@0: class A {} Chris@0: break; Chris@0: case 2: Chris@0: class A {} Chris@0: break; Chris@0: } Chris@0: '), Chris@0: ); Chris@0: Chris@0: // Ugh. There's gotta be a better way to test for this. Chris@0: if (class_exists('PhpParser\ParserFactory')) { Chris@0: // PHP 7.0 anonymous classes, only supported by PHP Parser v2.x Chris@0: $valid[] = array('$obj = new class() {}'); Chris@0: } Chris@0: Chris@0: if (version_compare(PHP_VERSION, '5.5', '>=')) { Chris@0: $valid[] = array('interface A {} A::class'); Chris@0: $valid[] = array('interface A {} A::CLASS'); Chris@0: $valid[] = array('class A {} A::class'); Chris@0: $valid[] = array('class A {} A::CLASS'); Chris@0: $valid[] = array('A::class'); Chris@0: $valid[] = array('A::CLASS'); Chris@0: } Chris@0: Chris@0: return $valid; Chris@0: } Chris@0: }