@@ -19,6 +19,8 @@ class ClassConstantRuleTest extends RuleTestCase
1919
2020 private int $ phpVersion ;
2121
22+ private bool $ checkNonStringableDynamicAccess ;
23+
2224 protected function getRule (): Rule
2325 {
2426 $ reflectionProvider = $ this ->createReflectionProvider ();
@@ -30,12 +32,14 @@ protected function getRule(): Rule
3032 new ClassForbiddenNameCheck (self ::getContainer ()),
3133 ),
3234 new PhpVersion ($ this ->phpVersion ),
35+ $ this ->checkNonStringableDynamicAccess ,
3336 );
3437 }
3538
3639 public function testClassConstant (): void
3740 {
3841 $ this ->phpVersion = PHP_VERSION_ID ;
42+ $ this ->checkNonStringableDynamicAccess = true ;
3943 $ this ->analyse (
4044 [
4145 __DIR__ . '/data/class-constant.php ' ,
@@ -99,6 +103,7 @@ public function testClassConstant(): void
99103 public function testClassConstantVisibility (): void
100104 {
101105 $ this ->phpVersion = PHP_VERSION_ID ;
106+ $ this ->checkNonStringableDynamicAccess = true ;
102107 $ this ->analyse ([__DIR__ . '/data/class-constant-visibility.php ' ], [
103108 [
104109 'Access to private constant PRIVATE_BAR of class ClassConstantVisibility\Bar. ' ,
@@ -168,6 +173,7 @@ public function testClassConstantVisibility(): void
168173 public function testClassExists (): void
169174 {
170175 $ this ->phpVersion = PHP_VERSION_ID ;
176+ $ this ->checkNonStringableDynamicAccess = true ;
171177 $ this ->analyse ([__DIR__ . '/data/class-exists.php ' ], [
172178 [
173179 'Class UnknownClass\Bar not found. ' ,
@@ -242,12 +248,14 @@ public function dataClassConstantOnExpression(): array
242248 public function testClassConstantOnExpression (int $ phpVersion , array $ errors ): void
243249 {
244250 $ this ->phpVersion = $ phpVersion ;
251+ $ this ->checkNonStringableDynamicAccess = true ;
245252 $ this ->analyse ([__DIR__ . '/data/class-constant-on-expr.php ' ], $ errors );
246253 }
247254
248255 public function testAttributes (): void
249256 {
250257 $ this ->phpVersion = PHP_VERSION_ID ;
258+ $ this ->checkNonStringableDynamicAccess = true ;
251259 $ this ->analyse ([__DIR__ . '/data/class-constant-attribute.php ' ], [
252260 [
253261 'Access to undefined constant ClassConstantAttribute\Foo::BAR. ' ,
@@ -287,18 +295,21 @@ public function testRuleWithNullsafeVariant(): void
287295 }
288296
289297 $ this ->phpVersion = PHP_VERSION_ID ;
298+ $ this ->checkNonStringableDynamicAccess = true ;
290299 $ this ->analyse ([__DIR__ . '/data/class-constant-nullsafe.php ' ], []);
291300 }
292301
293302 public function testBug7675 (): void
294303 {
295304 $ this ->phpVersion = PHP_VERSION_ID ;
305+ $ this ->checkNonStringableDynamicAccess = true ;
296306 $ this ->analyse ([__DIR__ . '/data/bug-7675.php ' ], []);
297307 }
298308
299309 public function testBug8034 (): void
300310 {
301311 $ this ->phpVersion = PHP_VERSION_ID ;
312+ $ this ->checkNonStringableDynamicAccess = true ;
302313 $ this ->analyse ([__DIR__ . '/data/bug-8034.php ' ], [
303314 [
304315 'Access to undefined constant static(Bug8034\HelloWorld)::FIELDS. ' ,
@@ -310,6 +321,7 @@ public function testBug8034(): void
310321 public function testClassConstFetchDefined (): void
311322 {
312323 $ this ->phpVersion = PHP_VERSION_ID ;
324+ $ this ->checkNonStringableDynamicAccess = true ;
313325 $ this ->analyse ([__DIR__ . '/data/class-const-fetch-defined.php ' ], [
314326 [
315327 'Access to undefined constant ClassConstFetchDefined\Foo::TEST. ' ,
@@ -411,6 +423,7 @@ public function testPhpstanInternalClass(): void
411423 $ tip = 'This is most likely unintentional. Did you mean to type \AClass? ' ;
412424
413425 $ this ->phpVersion = PHP_VERSION_ID ;
426+ $ this ->checkNonStringableDynamicAccess = true ;
414427 $ this ->analyse ([__DIR__ . '/data/phpstan-internal-class.php ' ], [
415428 [
416429 'Referencing prefixed PHPStan class: _PHPStan_156ee64ba\AClass. ' ,
@@ -427,6 +440,7 @@ public function testClassConstantAccessedOnTrait(): void
427440 }
428441
429442 $ this ->phpVersion = PHP_VERSION_ID ;
443+ $ this ->checkNonStringableDynamicAccess = true ;
430444 $ this ->analyse ([__DIR__ . '/data/class-constant-accessed-on-trait.php ' ], [
431445 [
432446 'Cannot access constant TEST on trait ClassConstantAccessedOnTrait\Foo. ' ,
@@ -442,8 +456,17 @@ public function testDynamicAccess(): void
442456 }
443457
444458 $ this ->phpVersion = PHP_VERSION_ID ;
459+ $ this ->checkNonStringableDynamicAccess = true ;
445460
446461 $ this ->analyse ([__DIR__ . '/data/dynamic-constant-access.php ' ], [
462+ [
463+ 'Access to undefined constant ClassConstantDynamicAccess\Foo::FOO. ' ,
464+ 17 ,
465+ ],
466+ [
467+ 'Cannot fetch class constant with a non-stringable type object. ' ,
468+ 19 ,
469+ ],
447470 [
448471 'Access to undefined constant ClassConstantDynamicAccess\Foo::FOO. ' ,
449472 20 ,
@@ -479,4 +502,40 @@ public function testDynamicAccess(): void
479502 ]);
480503 }
481504
505+ public function testStringableDynamicAccess (): void
506+ {
507+ if (PHP_VERSION_ID < 80300 ) {
508+ $ this ->markTestSkipped ('Test requires PHP 8.3. ' );
509+ }
510+
511+ $ this ->phpVersion = PHP_VERSION_ID ;
512+ $ this ->checkNonStringableDynamicAccess = true ;
513+
514+ $ this ->analyse ([__DIR__ . '/data/dynamic-constant-stringable-access.php ' ], [
515+ [
516+ 'Cannot fetch class constant with a non-stringable type mixed. ' ,
517+ 13 ,
518+ ],
519+ [
520+ 'Cannot fetch class constant with a non-stringable type string|null. ' ,
521+ 14 ,
522+ ],
523+ [
524+ 'Cannot fetch class constant with a non-stringable type Stringable|null. ' ,
525+ 15 ,
526+ ],
527+ [
528+ 'Cannot fetch class constant with a non-stringable type int. ' ,
529+ 16 ,
530+ ],
531+ [
532+ 'Cannot fetch class constant with a non-stringable type int|null. ' ,
533+ 17 ,
534+ ],
535+ [
536+ 'Cannot fetch class constant with a non-stringable type DateTime|string. ' ,
537+ 16 ,
538+ ],
539+ ]);
540+ }
482541}
0 commit comments