annotate vendor/psy/psysh/test/Psy/Test/CodeCleaner/ValidClassNamePassTest.php @ 8:50b0d041100e

Further files for download
author Chris Cannam
date Mon, 05 Feb 2018 10:56:40 +0000
parents 4c8ae668cc8c
children 7a779792577d
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 /*
Chris@0 4 * This file is part of Psy Shell.
Chris@0 5 *
Chris@0 6 * (c) 2012-2017 Justin Hileman
Chris@0 7 *
Chris@0 8 * For the full copyright and license information, please view the LICENSE
Chris@0 9 * file that was distributed with this source code.
Chris@0 10 */
Chris@0 11
Chris@0 12 namespace Psy\Test\CodeCleaner;
Chris@0 13
Chris@0 14 use Psy\CodeCleaner\ValidClassNamePass;
Chris@0 15 use Psy\Exception\Exception;
Chris@0 16
Chris@0 17 class ValidClassNamePassTest extends CodeCleanerTestCase
Chris@0 18 {
Chris@0 19 public function setUp()
Chris@0 20 {
Chris@0 21 $this->setPass(new ValidClassNamePass());
Chris@0 22 }
Chris@0 23
Chris@0 24 /**
Chris@0 25 * @dataProvider getInvalid
Chris@0 26 */
Chris@0 27 public function testProcessInvalid($code, $php54 = false)
Chris@0 28 {
Chris@0 29 try {
Chris@0 30 $stmts = $this->parse($code);
Chris@0 31 $this->traverse($stmts);
Chris@0 32 $this->fail();
Chris@0 33 } catch (Exception $e) {
Chris@0 34 if ($php54 && version_compare(PHP_VERSION, '5.4', '<')) {
Chris@0 35 $this->assertInstanceOf('Psy\Exception\ParseErrorException', $e);
Chris@0 36 } else {
Chris@0 37 $this->assertInstanceOf('Psy\Exception\FatalErrorException', $e);
Chris@0 38 }
Chris@0 39 }
Chris@0 40 }
Chris@0 41
Chris@0 42 public function getInvalid()
Chris@0 43 {
Chris@0 44 // class declarations
Chris@0 45 return array(
Chris@0 46 // core class
Chris@0 47 array('class stdClass {}'),
Chris@0 48 // capitalization
Chris@0 49 array('class stdClass {}'),
Chris@0 50
Chris@0 51 // collisions with interfaces and traits
Chris@0 52 array('interface stdClass {}'),
Chris@0 53 array('trait stdClass {}', true),
Chris@0 54
Chris@0 55 // collisions inside the same code snippet
Chris@0 56 array('
Chris@0 57 class Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {}
Chris@0 58 class Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {}
Chris@0 59 '),
Chris@0 60 array('
Chris@0 61 class Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {}
Chris@0 62 trait Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {}
Chris@0 63 ', true),
Chris@0 64 array('
Chris@0 65 trait Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {}
Chris@0 66 class Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {}
Chris@0 67 ', true),
Chris@0 68 array('
Chris@0 69 trait Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {}
Chris@0 70 interface Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {}
Chris@0 71 ', true),
Chris@0 72 array('
Chris@0 73 interface Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {}
Chris@0 74 trait Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {}
Chris@0 75 ', true),
Chris@0 76 array('
Chris@0 77 interface Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {}
Chris@0 78 class Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {}
Chris@0 79 '),
Chris@0 80 array('
Chris@0 81 class Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {}
Chris@0 82 interface Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {}
Chris@0 83 '),
Chris@0 84
Chris@0 85 // namespaced collisions
Chris@0 86 array('
Chris@0 87 namespace Psy\\Test\\CodeCleaner {
Chris@0 88 class ValidClassNamePassTest {}
Chris@0 89 }
Chris@0 90 '),
Chris@0 91 array('
Chris@0 92 namespace Psy\\Test\\CodeCleaner\\ValidClassNamePass {
Chris@0 93 class Beta {}
Chris@0 94 }
Chris@0 95 namespace Psy\\Test\\CodeCleaner\\ValidClassNamePass {
Chris@0 96 class Beta {}
Chris@0 97 }
Chris@0 98 '),
Chris@0 99
Chris@0 100 // extends and implements
Chris@0 101 array('class ValidClassNamePassTest extends NotAClass {}'),
Chris@0 102 array('class ValidClassNamePassTest extends ArrayAccess {}'),
Chris@0 103 array('class ValidClassNamePassTest implements stdClass {}'),
Chris@0 104 array('class ValidClassNamePassTest implements ArrayAccess, stdClass {}'),
Chris@0 105 array('interface ValidClassNamePassTest extends stdClass {}'),
Chris@0 106 array('interface ValidClassNamePassTest extends ArrayAccess, stdClass {}'),
Chris@0 107
Chris@0 108 // class instantiations
Chris@0 109 array('new Psy_Test_CodeCleaner_ValidClassNamePass_Gamma();'),
Chris@0 110 array('
Chris@0 111 namespace Psy\\Test\\CodeCleaner\\ValidClassNamePass {
Chris@0 112 new Psy_Test_CodeCleaner_ValidClassNamePass_Delta();
Chris@0 113 }
Chris@0 114 '),
Chris@0 115
Chris@0 116 // class constant fetch
Chris@0 117 array('Psy\\Test\\CodeCleaner\\ValidClassNamePass\\NotAClass::FOO'),
Chris@0 118
Chris@0 119 // static call
Chris@0 120 array('Psy\\Test\\CodeCleaner\\ValidClassNamePass\\NotAClass::foo()'),
Chris@0 121 array('Psy\\Test\\CodeCleaner\\ValidClassNamePass\\NotAClass::$foo()'),
Chris@0 122 );
Chris@0 123 }
Chris@0 124
Chris@0 125 /**
Chris@0 126 * @dataProvider getValid
Chris@0 127 */
Chris@0 128 public function testProcessValid($code)
Chris@0 129 {
Chris@0 130 $stmts = $this->parse($code);
Chris@0 131 $this->traverse($stmts);
Chris@0 132 }
Chris@0 133
Chris@0 134 public function getValid()
Chris@0 135 {
Chris@0 136 $valid = array(
Chris@0 137 // class declarations
Chris@0 138 array('class Psy_Test_CodeCleaner_ValidClassNamePass_Epsilon {}'),
Chris@0 139 array('namespace Psy\Test\CodeCleaner\ValidClassNamePass; class Zeta {}'),
Chris@0 140 array('
Chris@0 141 namespace { class Psy_Test_CodeCleaner_ValidClassNamePass_Eta {}; }
Chris@0 142 namespace Psy\\Test\\CodeCleaner\\ValidClassNamePass {
Chris@0 143 class Psy_Test_CodeCleaner_ValidClassNamePass_Eta {}
Chris@0 144 }
Chris@0 145 '),
Chris@0 146 array('namespace Psy\Test\CodeCleaner\ValidClassNamePass { class stdClass {} }'),
Chris@0 147
Chris@0 148 // class instantiations
Chris@0 149 array('new stdClass();'),
Chris@0 150 array('new stdClass();'),
Chris@0 151 array('
Chris@0 152 namespace Psy\\Test\\CodeCleaner\\ValidClassNamePass {
Chris@0 153 class Theta {}
Chris@0 154 }
Chris@0 155 namespace Psy\\Test\\CodeCleaner\\ValidClassNamePass {
Chris@0 156 new Theta();
Chris@0 157 }
Chris@0 158 '),
Chris@0 159 array('
Chris@0 160 namespace Psy\\Test\\CodeCleaner\\ValidClassNamePass {
Chris@0 161 class Iota {}
Chris@0 162 new Iota();
Chris@0 163 }
Chris@0 164 '),
Chris@0 165 array('
Chris@0 166 namespace Psy\\Test\\CodeCleaner\\ValidClassNamePass {
Chris@0 167 class Kappa {}
Chris@0 168 }
Chris@0 169 namespace {
Chris@0 170 new \\Psy\\Test\\CodeCleaner\\ValidClassNamePass\\Kappa();
Chris@0 171 }
Chris@0 172 '),
Chris@0 173
Chris@0 174 // Class constant fetch (ValidConstantPassTest validates the actual constant)
Chris@0 175 array('class A {} A::FOO'),
Chris@0 176 array('$a = new DateTime; $a::ATOM'),
Chris@0 177 array('interface A { const B = 1; } A::B'),
Chris@0 178
Chris@0 179 // static call
Chris@0 180 array('DateTime::createFromFormat()'),
Chris@0 181 array('DateTime::$someMethod()'),
Chris@0 182 array('Psy\Test\CodeCleaner\Fixtures\ClassWithStatic::doStuff()'),
Chris@0 183 array('Psy\Test\CodeCleaner\Fixtures\ClassWithCallStatic::doStuff()'),
Chris@0 184
Chris@0 185 // Allow `self` and `static` as class names.
Chris@0 186 array('
Chris@0 187 class Psy_Test_CodeCleaner_ValidClassNamePass_ClassWithStatic {
Chris@0 188 public static function getInstance() {
Chris@0 189 return new self();
Chris@0 190 }
Chris@0 191 }
Chris@0 192 '),
Chris@0 193 array('
Chris@0 194 class Psy_Test_CodeCleaner_ValidClassNamePass_ClassWithStatic {
Chris@0 195 public static function getInstance() {
Chris@0 196 return new SELF();
Chris@0 197 }
Chris@0 198 }
Chris@0 199 '),
Chris@0 200 array('
Chris@0 201 class Psy_Test_CodeCleaner_ValidClassNamePass_ClassWithStatic {
Chris@0 202 public static function getInstance() {
Chris@0 203 return new self;
Chris@0 204 }
Chris@0 205 }
Chris@0 206 '),
Chris@0 207 array('
Chris@0 208 class Psy_Test_CodeCleaner_ValidClassNamePass_ClassWithStatic {
Chris@0 209 public static function getInstance() {
Chris@0 210 return new static();
Chris@0 211 }
Chris@0 212 }
Chris@0 213 '),
Chris@0 214 array('
Chris@0 215 class Psy_Test_CodeCleaner_ValidClassNamePass_ClassWithStatic {
Chris@0 216 public static function getInstance() {
Chris@0 217 return new Static();
Chris@0 218 }
Chris@0 219 }
Chris@0 220 '),
Chris@0 221 array('
Chris@0 222 class Psy_Test_CodeCleaner_ValidClassNamePass_ClassWithStatic {
Chris@0 223 public static function getInstance() {
Chris@0 224 return new static;
Chris@0 225 }
Chris@0 226 }
Chris@0 227 '),
Chris@0 228 array('
Chris@0 229 class Psy_Test_CodeCleaner_ValidClassNamePass_ClassWithStatic {
Chris@0 230 public static function foo() {
Chris@0 231 return parent::bar();
Chris@0 232 }
Chris@0 233 }
Chris@0 234 '),
Chris@0 235 array('
Chris@0 236 class Psy_Test_CodeCleaner_ValidClassNamePass_ClassWithStatic {
Chris@0 237 public static function foo() {
Chris@0 238 return self::bar();
Chris@0 239 }
Chris@0 240 }
Chris@0 241 '),
Chris@0 242 array('
Chris@0 243 class Psy_Test_CodeCleaner_ValidClassNamePass_ClassWithStatic {
Chris@0 244 public static function foo() {
Chris@0 245 return static::bar();
Chris@0 246 }
Chris@0 247 }
Chris@0 248 '),
Chris@0 249
Chris@0 250 array('class A { static function b() { return new A; } }'),
Chris@0 251 array('
Chris@0 252 class A {
Chris@0 253 const B = 123;
Chris@0 254 function c() {
Chris@0 255 return A::B;
Chris@0 256 }
Chris@0 257 }
Chris@0 258 '),
Chris@0 259 array('class A {} class B { function c() { return new A; } }'),
Chris@0 260
Chris@0 261 // recursion
Chris@0 262 array('class A { function a() { A::a(); } }'),
Chris@0 263
Chris@0 264 // conditionally defined classes
Chris@0 265 array('
Chris@0 266 class A {}
Chris@0 267 if (false) {
Chris@0 268 class A {}
Chris@0 269 }
Chris@0 270 '),
Chris@0 271 array('
Chris@0 272 class A {}
Chris@0 273 if (true) {
Chris@0 274 class A {}
Chris@0 275 } else if (false) {
Chris@0 276 class A {}
Chris@0 277 } else {
Chris@0 278 class A {}
Chris@0 279 }
Chris@0 280 '),
Chris@0 281 // ewww
Chris@0 282 array('
Chris@0 283 class A {}
Chris@0 284 if (true):
Chris@0 285 class A {}
Chris@0 286 elseif (false):
Chris@0 287 class A {}
Chris@0 288 else:
Chris@0 289 class A {}
Chris@0 290 endif;
Chris@0 291 '),
Chris@0 292 array('
Chris@0 293 class A {}
Chris@0 294 while (false) { class A {} }
Chris@0 295 '),
Chris@0 296 array('
Chris@0 297 class A {}
Chris@0 298 do { class A {} } while (false);
Chris@0 299 '),
Chris@0 300 array('
Chris@0 301 class A {}
Chris@0 302 switch (1) {
Chris@0 303 case 0:
Chris@0 304 class A {}
Chris@0 305 break;
Chris@0 306 case 1:
Chris@0 307 class A {}
Chris@0 308 break;
Chris@0 309 case 2:
Chris@0 310 class A {}
Chris@0 311 break;
Chris@0 312 }
Chris@0 313 '),
Chris@0 314 );
Chris@0 315
Chris@0 316 // Ugh. There's gotta be a better way to test for this.
Chris@0 317 if (class_exists('PhpParser\ParserFactory')) {
Chris@0 318 // PHP 7.0 anonymous classes, only supported by PHP Parser v2.x
Chris@0 319 $valid[] = array('$obj = new class() {}');
Chris@0 320 }
Chris@0 321
Chris@0 322 if (version_compare(PHP_VERSION, '5.5', '>=')) {
Chris@0 323 $valid[] = array('interface A {} A::class');
Chris@0 324 $valid[] = array('interface A {} A::CLASS');
Chris@0 325 $valid[] = array('class A {} A::class');
Chris@0 326 $valid[] = array('class A {} A::CLASS');
Chris@0 327 $valid[] = array('A::class');
Chris@0 328 $valid[] = array('A::CLASS');
Chris@0 329 }
Chris@0 330
Chris@0 331 return $valid;
Chris@0 332 }
Chris@0 333 }