2016-12-06 19:49:57 +01:00
< ? php
namespace Psalm\Tests ;
2019-06-26 22:52:29 +02:00
use const DIRECTORY_SEPARATOR ;
2017-04-25 05:45:02 +02:00
class SwitchTypeTest extends TestCase
2016-12-06 19:49:57 +01:00
{
2018-11-06 03:57:36 +01:00
use Traits\InvalidCodeAnalysisTestTrait ;
use Traits\ValidCodeAnalysisTestTrait ;
2016-12-06 19:49:57 +01:00
/**
2019-03-01 21:55:20 +01:00
* @ return iterable < string , array { string , assertions ? : array < string , string > , error_levels ? : string []} >
2016-12-06 19:49:57 +01:00
*/
2018-11-06 03:57:36 +01:00
public function providerValidCodeParse ()
2016-12-06 19:49:57 +01:00
{
2017-04-25 05:45:02 +02:00
return [
2017-10-26 21:07:36 +02:00
'getClassConstArg' => [
' < ? php
class A {
/**
* @ return void
*/
public function fooFoo () {
}
}
class B {
/**
* @ return void
*/
public function barBar () {
}
}
2018-01-11 21:50:45 +01:00
$a = rand ( 0 , 10 ) ? new A () : new B ();
2017-10-26 21:07:36 +02:00
switch ( get_class ( $a )) {
case A :: class :
$a -> fooFoo ();
break ;
case B :: class :
$a -> barBar ();
break ;
} ' ,
],
2017-07-25 22:11:02 +02:00
'getClassExteriorArgClassConsts' => [
' < ? php
/** @return void */
function foo ( Exception $e ) {
switch ( get_class ( $e )) {
case InvalidArgumentException :: class :
$e -> getMessage ();
break ;
case LogicException :: class :
$e -> getMessage ();
break ;
}
}
' ,
],
2017-12-13 21:56:05 +01:00
'switchGetClassVar' => [
' < ? php
class A {}
class B extends A {
2020-02-06 22:32:26 +01:00
public function foo () : void {}
2017-07-25 22:11:02 +02:00
}
2018-01-11 21:50:45 +01:00
function takesA ( A $a ) : void {
2020-02-06 22:32:26 +01:00
$class = get_class ( $a );
switch ( $class ) {
case B :: class :
$a -> foo ();
break ;
}
2017-12-13 21:56:05 +01:00
} ' ,
2017-07-25 22:11:02 +02:00
],
2017-04-25 05:45:02 +02:00
'getTypeArg' => [
' < ? php
2018-01-11 21:50:45 +01:00
function testInt ( int $var ) : void {
2017-07-25 22:11:02 +02:00
2017-04-25 05:45:02 +02:00
}
2017-07-25 22:11:02 +02:00
2018-01-11 21:50:45 +01:00
function testString ( string $var ) : void {
2017-07-25 22:11:02 +02:00
2017-04-25 05:45:02 +02:00
}
2017-07-25 22:11:02 +02:00
2017-04-25 05:45:02 +02:00
$a = rand ( 0 , 10 ) ? 1 : " two " ;
2017-07-25 22:11:02 +02:00
2017-04-25 05:45:02 +02:00
switch ( gettype ( $a )) {
case " string " :
testString ( $a );
break ;
2017-07-25 22:11:02 +02:00
2017-09-11 17:52:34 +02:00
case " integer " :
2017-04-25 05:45:02 +02:00
testInt ( $a );
break ;
2017-05-27 02:05:57 +02:00
} ' ,
],
2017-10-23 01:53:53 +02:00
'switchTruthy' => [
' < ? php
class A {
/**
* @ var ? string
*/
public $a = null ;
/**
* @ var ? string
*/
public $b = null ;
}
function f ( A $obj ) : string {
switch ( true ) {
case $obj -> a !== null :
return $obj -> a ; // definitely not null
case ! is_null ( $obj -> b ) :
return $obj -> b ; // definitely not null
default :
throw new \InvalidArgumentException ( " $obj->a or $obj->b must be set " );
}
} ' ,
],
'switchMoTruthy' => [
' < ? php
class A {
/**
* @ var ? string
*/
public $a = null ;
/**
* @ var ? string
*/
public $b = null ;
}
function f ( A $obj ) : string {
switch ( true ) {
case $obj -> a :
return $obj -> a ; // definitely not null
case $obj -> b :
return $obj -> b ; // definitely not null
default :
throw new \InvalidArgumentException ( " $obj->a or $obj->b must be set " );
}
} ' ,
],
2017-11-28 06:25:21 +01:00
'switchWithBadBreak' => [
' < ? php
class A {}
function foo () : A {
switch ( rand ( 0 , 1 )) {
case true :
return new A ;
break ;
default :
return new A ;
}
} ' ,
],
'switchCaseExpression' => [
' < ? php
switch ( true ) {
case preg_match ( " /(d)ata/ " , " some data in subject string " , $matches ) :
return $matches [ 1 ];
default :
throw new RuntimeException ( " none found " );
} ' ,
],
2017-11-29 04:33:37 +01:00
'switchBools' => [
' < ? php
$x = false ;
$y = false ;
foreach ([ 1 , 2 , 3 ] as $v ) {
switch ( $v ) {
case 3 :
$y = true ;
break ;
case 2 :
$x = true ;
break ;
default :
break ;
}
} ' ,
'assertions' => [
'$x' => 'bool' ,
'$y' => 'bool' ,
],
],
2018-01-24 06:01:08 +01:00
'continueIsBreak' => [
' < ? php
switch ( 2 ) {
case 2 :
echo " two \n " ;
continue ;
} ' ,
],
2018-01-24 22:15:53 +01:00
'defaultAboveCase' => [
' < ? php
function foo ( string $a ) : string {
switch ( $a ) {
case " a " :
return " hello " ;
default :
case " b " :
return " goodbye " ;
}
} ' ,
],
2018-05-09 15:30:23 +02:00
'dontResolveTypesBadly' => [
' < ? php
$a = new A ;
switch ( rand ( 0 , 1 )) {
case 0 :
case 1 :
$dt = $a -> maybeReturnsDT ();
if ( ! is_null ( $dt )) {
$dt = $dt -> format ( \DateTime :: ISO8601 );
}
break ;
}
class A {
public function maybeReturnsDT () : ? \DateTimeInterface {
return rand ( 0 , 1 ) ? new \DateTime ( " now " ) : null ;
}
} ' ,
],
2018-05-12 18:55:24 +02:00
'issetInFallthrough' => [
' < ? php
function foo () : void {
switch ( rand () % 4 ) {
case 0 :
echo " here " ;
break ;
case 1 :
$x = rand () % 4 ;
case 2 :
if ( isset ( $x ) && $x > 2 ) {
echo " $x is large " ;
}
break ;
}
} ' ,
],
'switchManyGetClass' => [
' < ? php
class A {}
class B extends A {}
class C extends A {}
class D extends A {}
function foo ( A $a ) : void {
switch ( get_class ( $a )) {
case B :: class :
case C :: class :
case D :: class :
echo " goodbye " ;
}
} ' ,
],
2018-05-13 00:46:47 +02:00
'switchManyStrings' => [
' < ? php
function foo ( string $s ) : void {
switch ( $s ) {
case " a " :
case " b " :
case " c " :
echo " goodbye " ;
}
} ' ,
],
'allSwitchesMet' => [
' < ? php
$a = rand ( 0 , 1 ) ? " a " : " b " ;
switch ( $a ) {
case " a " :
$foo = " hello " ;
break ;
case " b " :
$foo = " goodbye " ;
break ;
}
echo $foo ; ' ,
],
'impossibleCaseDefaultWithThrow' => [
' < ? php
$a = rand ( 0 , 1 ) ? " a " : " b " ;
switch ( $a ) {
case " a " :
break ;
case " b " :
break ;
default :
throw new \Exception ( " should never happen " );
} ' ,
],
2018-05-13 02:08:22 +02:00
'switchOnUnknownInts' => [
' < ? php
function foo ( int $a , int $b , int $c ) : void {
switch ( $a ) {
case $b :
break ;
case $c :
break ;
}
} ' ,
],
2018-05-13 06:54:12 +02:00
'switchNullable1' => [
' < ? php
function foo ( ? string $s ) : void {
switch ( $s ) {
case " hello " :
case " goodbye " :
echo " cool " ;
break ;
case " hello again " :
echo " cool " ;
break ;
}
} ' ,
],
'switchNullable2' => [
' < ? php
function foo ( ? string $s ) : void {
switch ( $s ) {
case " hello " :
echo " cool " ;
case " goodbye " :
echo " cooler " ;
break ;
case " hello again " :
echo " cool " ;
break ;
}
} ' ,
],
'switchNullable3' => [
' < ? php
function foo ( ? string $s ) : void {
switch ( $s ) {
case " hello " :
echo " cool " ;
break ;
case " goodbye " :
echo " cool " ;
break ;
case " hello again " :
echo " cool " ;
break ;
}
} ' ,
],
2018-05-13 07:27:45 +02:00
'switchNullable4' => [
' < ? php
function foo ( ? string $s , string $a , string $b ) : void {
switch ( $s ) {
case $a :
case $b :
break ;
}
} ' ,
],
2018-05-14 22:29:51 +02:00
'removeChangedVarsFromReasonableClauses' => [
' < ? php
function r () : bool {
return ( bool ) rand ( 0 , 1 );
}
function foo ( string $s ) : void {
if (( $s === " a " || $s === " b " )
&& ( $s === " a " || r ())
&& ( $s === " b " || r ())
&& ( r () || r ())
) {
// do something
} else {
return ;
}
switch ( $s ) {
case " a " :
break ;
case " b " :
break ;
}
2019-03-23 19:27:54 +01:00
} ' ,
2018-05-14 22:29:51 +02:00
],
'preventBadClausesFromBleeding' => [
' < ? php
function foo ( string $s ) : void {
if ( $s === " a " && rand ( 0 , 1 )) {
} elseif ( $s === " b " && rand ( 0 , 1 )) {
} else {
return ;
}
switch ( $s ) {
case " a " :
echo " hello " ;
break ;
case " b " :
echo " goodbye " ;
break ;
}
} ' ,
],
2018-05-24 20:26:29 +02:00
'alwaysReturns' => [
' < ? php
/**
* @ param " a " | " b " $s
*/
function foo ( string $s ) : string {
switch ( $s ) {
case " a " :
return " hello " ;
case " b " :
return " goodbye " ;
}
} ' ,
],
2018-11-11 02:34:53 +01:00
'switchVarConditionalAssignment' => [
' < ? php
switch ( rand ( 0 , 4 )) {
case 0 :
2018-11-12 04:03:08 +01:00
$b = 2 ;
2018-11-11 02:34:53 +01:00
if ( rand ( 0 , 1 )) {
$a = false ;
break ;
}
default :
$a = true ;
$b = 1 ;
} ' ,
'assertions' => [
'$a' => 'bool' ,
'$b' => 'int' ,
],
],
'switchVarConditionalReAssignment' => [
' < ? php
$a = false ;
switch ( rand ( 0 , 4 )) {
case 0 :
$b = 1 ;
if ( rand ( 0 , 1 )) {
$a = false ;
break ;
}
default :
$a = true ;
} ' ,
'assertions' => [
'$a' => 'bool' ,
],
],
2018-11-28 21:12:08 +01:00
'moreThan30Cases' => [
' < ? php
function f ( string $a ) : void {
switch ( $a ) {
case " a " :
case " b " :
case " c " :
case " d " :
case " e " :
case " f " :
case " g " :
case " h " :
case " i " :
case " j " :
case " k " :
case " l " :
case " m " :
case " n " :
case " o " :
case " p " :
case " q " :
case " r " :
case " s " :
case " t " :
case " u " :
case " v " :
case " w " :
case " x " :
case " y " :
case " z " :
case " A " :
case " B " :
case " C " :
case " D " :
case " E " :
return ;
}
} ' ,
],
2019-11-25 17:44:54 +01:00
'anotherLongSwitch' => [
' < ? php
/**
* @ param ? string $fq_const_name
* @ param string $const_name
* @ param array < string , bool > $predefined_constants
*
* @ return string | null
*/
function getGlobalConstType (
? string $fq_const_name ,
string $const_name ,
array $predefined_constants
) {
if ( $const_name === " STDERR "
|| $const_name === " STDOUT "
|| $const_name === " STDIN "
) {
return " hello " ;
}
if ( isset ( $predefined_constants [ $fq_const_name ])
|| isset ( $predefined_constants [ $const_name ])
) {
switch ( $const_name ) {
case " PHP_MAJOR_VERSION " :
case " PHP_ZTS " :
return " int " ;
case " PHP_FLOAT_EPSILON " :
case " PHP_FLOAT_MAX " :
case " PHP_FLOAT_MIN " :
return " float " ;
}
if ( $fq_const_name && isset ( $predefined_constants [ $fq_const_name ])) {
return " mixed " ;
}
return " hello " ;
}
return null ;
} '
],
2020-03-30 06:20:00 +02:00
'evenLongerSwitch' => [
' < ? php
function foo ( string $f ) : string {
switch ( $f ) {
case " str1 " ;
return " foo1 " ;
case " str2 " ;
return " foo2 " ;
case " str3 " ;
return " foo3 " ;
case " str4 " ;
return " foo4 " ;
case " str5 " ;
return " foo5 " ;
case " str6 " ;
return " foo6 " ;
case " str7 " ;
return " foo7 " ;
case " str8 " ;
return " foo8 " ;
case " str9 " ;
return " foo9 " ;
case " str10 " ;
return " foo10 " ;
case " str11 " ;
return " foo11 " ;
case " str12 " ;
return " foo12 " ;
case " str13 " ;
return " foo13 " ;
case " str14 " ;
return " foo14 " ;
case " str15 " ;
return " foo15 " ;
case " str16 " ;
return " foo16 " ;
case " str17 " ;
return " foo17 " ;
case " str18 " ;
return " foo18 " ;
case " str19 " ;
return " foo19 " ;
case " str20 " ;
return " foo20 " ;
case " str21 " ;
return " foo21 " ;
case " str22 " ;
return " foo22 " ;
case " str23 " ;
return " foo23 " ;
case " str24 " ;
return " foo24 " ;
case " str25 " ;
return " foo25 " ;
case " str26 " ;
return " foo26 " ;
case " str27 " ;
return " foo27 " ;
case " str28 " ;
return " foo28 " ;
case " str29 " ;
return " foo29 " ;
case " str30 " ;
return " foo30 " ;
case " str31 " ;
return " foo31 " ;
case " str32 " ;
return " foo32 " ;
case " str33 " ;
return " foo33 " ;
case " str34 " ;
return " foo34 " ;
case " str35 " ;
return " foo35 " ;
case " str36 " ;
return " foo36 " ;
case " str37 " ;
return " foo37 " ;
case " str38 " ;
return " foo38 " ;
case " str39 " ;
return " foo39 " ;
case " str40 " ;
return " foo40 " ;
case " str41 " ;
return " foo41 " ;
case " str42 " ;
return " foo42 " ;
case " str43 " ;
return " foo43 " ;
case " str44 " ;
return " foo44 " ;
case " str45 " ;
return " foo45 " ;
case " str46 " ;
return " foo46 " ;
case " str47 " ;
return " foo47 " ;
case " str48 " ;
return " foo48 " ;
case " str49 " ;
return " foo49 " ;
case " str50 " ;
return " foo50 " ;
case " str51 " ;
return " foo51 " ;
case " str52 " ;
return " foo52 " ;
case " str53 " ;
return " foo53 " ;
case " str54 " ;
return " foo54 " ;
case " str55 " ;
return " foo55 " ;
case " str56 " ;
return " foo56 " ;
case " str57 " ;
return " foo57 " ;
case " str58 " ;
return " foo58 " ;
case " str59 " ;
return " foo59 " ;
case " str60 " ;
return " foo60 " ;
case " str61 " ;
return " foo61 " ;
case " str62 " ;
return " foo62 " ;
case " str63 " ;
return " foo63 " ;
case " str64 " ;
return " foo64 " ;
case " str65 " ;
return " foo65 " ;
case " str66 " ;
return " foo66 " ;
case " str67 " ;
return " foo67 " ;
case " str68 " ;
return " foo68 " ;
case " str70 " ;
return " foo70 " ;
case " str71 " ;
return " foo71 " ;
case " str72 " ;
return " foo72 " ;
case " str73 " ;
return " foo73 " ;
case " str74 " ;
return " foo74 " ;
case " str75 " ;
return " foo75 " ;
case " str76 " ;
return " foo76 " ;
case " str77 " ;
return " foo77 " ;
case " str78 " ;
return " foo78 " ;
case " str79 " ;
return " foo79 " ;
case " str80 " ;
return " foo80 " ;
case " str81 " ;
return " foo81 " ;
case " str82 " ;
return " foo82 " ;
case " str83 " ;
return " foo83 " ;
case " str84 " ;
return " foo84 " ;
case " str85 " ;
return " foo85 " ;
case " str86 " ;
return " foo86 " ;
case " str87 " ;
return " foo87 " ;
case " str88 " ;
return " foo88 " ;
case " str89 " ;
return " foo89 " ;
case " str90 " ;
return " foo90 " ;
case " str91 " ;
return " foo91 " ;
case " str92 " ;
return " foo92 " ;
case " str93 " ;
return " foo93 " ;
case " str94 " ;
return " foo94 " ;
case " str95 " ;
return " foo95 " ;
case " str96 " ;
return " foo96 " ;
case " str97 " ;
return " foo97 " ;
case " str98 " ;
return " foo98 " ;
case " str99 " ;
return " foo99 " ;
case " str100 " ;
return " foo100 " ;
case " str101 " ;
return " foo101 " ;
case " str102 " ;
return " foo102 " ;
case " str103 " ;
return " foo103 " ;
case " str104 " ;
return " foo104 " ;
case " str105 " ;
return " foo105 " ;
case " str106 " ;
return " foo106 " ;
case " str107 " ;
return " foo107 " ;
case " str108 " ;
return " foo108 " ;
case " str109 " ;
return " foo109 " ;
case " str110 " ;
return " foo110 " ;
case " str111 " ;
return " foo111 " ;
case " str112 " ;
return " foo112 " ;
case " str113 " ;
return " foo113 " ;
case " str114 " ;
return " foo114 " ;
case " str115 " ;
return " foo115 " ;
case " str116 " ;
return " foo116 " ;
case " str117 " ;
return " foo117 " ;
case " str118 " ;
return " foo118 " ;
case " str119 " ;
return " foo119 " ;
case " str120 " ;
return " foo120 " ;
case " str121 " ;
return " foo121 " ;
case " str122 " ;
return " foo122 " ;
case " str123 " ;
return " foo123 " ;
case " str124 " ;
return " foo124 " ;
case " str125 " ;
return " foo125 " ;
case " str126 " ;
return " foo126 " ;
case " str127 " ;
return " foo127 " ;
case " str128 " ;
return " foo128 " ;
case " str129 " ;
return " foo129 " ;
case " str130 " ;
return " foo130 " ;
case " str131 " ;
return " foo131 " ;
case " str132 " ;
return " foo132 " ;
case " str133 " ;
return " foo133 " ;
case " str134 " ;
return " foo134 " ;
case " str135 " ;
return " foo135 " ;
case " str136 " ;
return " foo136 " ;
case " str137 " ;
return " foo137 " ;
case " str138 " ;
return " foo138 " ;
case " str139 " ;
return " foo139 " ;
case " str140 " ;
return " foo140 " ;
case " str141 " ;
return " foo141 " ;
case " str142 " ;
return " foo142 " ;
case " str143 " ;
return " foo143 " ;
case " str144 " ;
return " foo144 " ;
case " str145 " ;
return " foo145 " ;
case " str146 " ;
return " foo146 " ;
case " str147 " ;
return " foo147 " ;
case " str148 " ;
return " foo148 " ;
case " str149 " ;
return " foo149 " ;
default ;
return " foo69 " ;
}
} '
],
2020-06-12 17:18:34 +02:00
'switchTruthyWithBoolean' => [
' < ? php
$a = rand ( 0 , 1 ) ? new \DateTime () : null ;
switch ( true ) {
case $a !== null && $a -> format ( " Y " ) === " 2020 " :
$a -> format ( " d-m-Y " );
} '
],
2020-06-15 22:23:19 +02:00
'evenWorseSwitch' => [
' < ? php
function foo ( string $locale ) : int {
switch ( $locale ) {
case " af " :
case " af_ZA " :
case " bn " :
case " bn_BD " :
case " bn_IN " :
case " bg " :
case " bg_BG " :
case " ca " :
case " ca_AD " :
case " ca_ES " :
case " ca_FR " :
case " ca_IT " :
case " da " :
case " da_DK " :
case " de " :
case " de_AT " :
case " de_BE " :
case " de_CH " :
case " de_DE " :
case " de_LI " :
case " de_LU " :
case " el " :
case " el_CY " :
case " el_GR " :
case " en " :
case " en_AG " :
case " en_AU " :
case " en_BW " :
case " en_CA " :
case " en_DK " :
case " en_GB " :
case " en_HK " :
case " en_IE " :
case " en_IN " :
case " en_NG " :
case " en_NZ " :
case " en_PH " :
case " en_SG " :
case " en_US " :
case " en_ZA " :
case " en_ZM " :
case " en_ZW " :
case " es_VE " :
return 3 ;
}
return 4 ;
} '
],
2017-04-25 05:45:02 +02:00
];
2016-12-06 19:49:57 +01:00
}
2017-01-13 20:07:23 +01:00
/**
2019-03-01 21:55:20 +01:00
* @ return iterable < string , array { string , error_message : string , 2 ? : string [], 3 ? : bool , 4 ? : string } >
2017-01-13 20:07:23 +01:00
*/
2018-11-06 03:57:36 +01:00
public function providerInvalidCodeParse ()
2016-12-06 19:49:57 +01:00
{
2017-04-25 05:45:02 +02:00
return [
2017-11-28 06:25:21 +01:00
'switchReturnTypeWithFallthroughAndBreak' => [
' < ? php
class A {
/** @return bool */
public function fooFoo () {
switch ( rand ( 0 , 10 )) {
case 1 :
break ;
default :
return true ;
}
}
} ' ,
2018-01-07 23:17:18 +01:00
'error_message' => 'InvalidNullableReturnType' ,
2017-11-28 06:25:21 +01:00
],
'switchReturnTypeWithFallthroughAndConditionalBreak' => [
' < ? php
class A {
/** @return bool */
public function fooFoo () {
switch ( rand ( 0 , 10 )) {
case 1 :
if ( rand ( 0 , 10 ) === 5 ) {
break ;
}
default :
return true ;
}
}
} ' ,
2018-01-07 23:17:18 +01:00
'error_message' => 'InvalidNullableReturnType' ,
2017-11-28 06:25:21 +01:00
],
'switchReturnTypeWithNoDefault' => [
' < ? php
class A {
/** @return bool */
public function fooFoo () {
switch ( rand ( 0 , 10 )) {
case 1 :
case 2 :
return true ;
}
}
} ' ,
2018-01-07 23:17:18 +01:00
'error_message' => 'InvalidNullableReturnType' ,
2017-11-28 06:25:21 +01:00
],
2017-04-25 05:45:02 +02:00
'getClassArgWrongClass' => [
' < ? php
class A {
/** @return void */
public function fooFoo () {
2017-07-25 22:11:02 +02:00
2017-04-25 05:45:02 +02:00
}
}
2017-07-25 22:11:02 +02:00
2017-04-25 05:45:02 +02:00
class B {
/** @return void */
public function barBar () {
2017-07-25 22:11:02 +02:00
2017-04-25 05:45:02 +02:00
}
}
2017-07-25 22:11:02 +02:00
2018-01-11 21:50:45 +01:00
$a = rand ( 0 , 10 ) ? new A () : new B ();
2017-07-25 22:11:02 +02:00
2017-04-25 05:45:02 +02:00
switch ( get_class ( $a )) {
2018-11-29 05:59:43 +01:00
case A :: class :
2017-04-25 05:45:02 +02:00
$a -> barBar ();
break ;
} ' ,
2017-05-27 02:05:57 +02:00
'error_message' => 'UndefinedMethod' ,
2017-04-25 05:45:02 +02:00
],
2017-09-11 17:52:34 +02:00
'getClassMissingClass' => [
' < ? php
class A {}
class B {}
2018-01-11 21:50:45 +01:00
$a = rand ( 0 , 10 ) ? new A () : new B ();
2017-09-11 17:52:34 +02:00
switch ( get_class ( $a )) {
2018-11-29 05:59:43 +01:00
case C :: class :
2017-09-11 17:52:34 +02:00
break ;
} ' ,
'error_message' => 'UndefinedClass' ,
],
'getTypeNotAType' => [
' < ? php
$a = rand ( 0 , 10 ) ? 1 : " two " ;
switch ( gettype ( $a )) {
case " int " :
break ;
} ' ,
'error_message' => 'UnevaluatedCode' ,
],
2017-04-25 05:45:02 +02:00
'getTypeArgWrongArgs' => [
' < ? php
2018-01-11 21:50:45 +01:00
function testInt ( int $var ) : void {
2017-07-25 22:11:02 +02:00
2017-04-25 05:45:02 +02:00
}
2017-07-25 22:11:02 +02:00
2018-01-11 21:50:45 +01:00
function testString ( string $var ) : void {
2017-07-25 22:11:02 +02:00
2017-04-25 05:45:02 +02:00
}
2017-07-25 22:11:02 +02:00
2017-04-25 05:45:02 +02:00
$a = rand ( 0 , 10 ) ? 1 : " two " ;
2017-07-25 22:11:02 +02:00
2017-04-25 05:45:02 +02:00
switch ( gettype ( $a )) {
case " string " :
testInt ( $a );
2017-07-25 22:11:02 +02:00
2017-09-11 17:52:34 +02:00
case " integer " :
2017-04-25 05:45:02 +02:00
testString ( $a );
} ' ,
2017-05-27 02:05:57 +02:00
'error_message' => 'InvalidScalarArgument' ,
],
2017-11-28 06:25:21 +01:00
'switchBadMethodCallInCase' => [
' < ? php
2018-01-11 21:50:45 +01:00
function f ( string $p ) : void { }
2017-11-28 06:25:21 +01:00
switch ( true ) {
case $q = ( bool ) rand ( 0 , 1 ) :
f ( $q ); // this type problem is not detected
break ;
} ' ,
'error_message' => 'InvalidScalarArgument' ,
],
2018-01-24 06:01:08 +01:00
'continueIsNotBreak' => [
' < ? php
switch ( 2 ) {
case 2 :
echo " two \n " ;
continue 2 ;
} ' ,
'error_message' => 'ContinueOutsideLoop' ,
],
2018-01-24 22:15:53 +01:00
'defaultAboveCaseThatBreaks' => [
' < ? php
function foo ( string $a ) : string {
switch ( $a ) {
case " a " :
return " hello " ;
default :
case " b " :
break ;
case " c " :
return " goodbye " ;
}
} ' ,
'error_message' => 'InvalidReturnType' ,
],
2018-05-18 17:02:50 +02:00
'SKIPPED-switchManyGetClassWithRepetitionWithProperLineNumber' => [
2018-05-12 18:55:24 +02:00
' < ? php
class A {}
class B extends A {}
class C extends A {}
class D extends A {}
function foo ( A $a ) : void {
switch ( get_class ( $a )) {
case B :: class :
case C :: class :
case B :: class :
case C :: class :
case D :: class :
echo " goodbye " ;
}
} ' ,
'error_message' => 'RedundantCondition - src/somefile.php:10' ,
'error_levels' => [ 'ParadoxicalCondition' ],
],
2018-05-13 00:46:47 +02:00
'repeatedCaseValue' => [
' < ? php
$a = rand ( 0 , 1 );
switch ( $a ) {
case 0 :
break ;
case 0 :
echo " I never get here " ;
} ' ,
2019-02-06 20:19:29 +01:00
'error_message' => 'ParadoxicalCondition - src' . DIRECTORY_SEPARATOR . 'somefile.php:7' ,
2018-05-13 00:46:47 +02:00
],
'impossibleCaseValue' => [
' < ? php
$a = rand ( 0 , 1 ) ? " a " : " b " ;
switch ( $a ) {
case " a " :
break ;
case " b " :
break ;
case " c " :
echo " impossible " ;
} ' ,
2019-02-06 20:19:29 +01:00
'error_message' => 'TypeDoesNotContainType - src' . DIRECTORY_SEPARATOR . 'somefile.php:11' ,
2018-05-13 00:46:47 +02:00
],
'impossibleCaseDefault' => [
' < ? php
$a = rand ( 0 , 1 ) ? " a " : " b " ;
switch ( $a ) {
case " a " :
break ;
case " b " :
break ;
default :
echo " impossible " ;
} ' ,
2019-02-06 20:19:29 +01:00
'error_message' => 'ParadoxicalCondition - src' . DIRECTORY_SEPARATOR . 'somefile.php:11' ,
2018-05-13 00:46:47 +02:00
],
2018-11-12 04:03:08 +01:00
'breakWithoutSettingVar' => [
' < ? php
function foo ( int $i ) : void {
switch ( $i ) {
case 0 :
if ( rand ( 0 , 1 )) {
break ;
}
default :
$a = true ;
}
if ( $a ) {}
} ' ,
2019-03-23 19:27:54 +01:00
'error_message' => 'PossiblyUndefinedVariable' ,
2018-11-12 04:03:08 +01:00
],
2018-11-29 05:59:43 +01:00
'getClassExteriorArgStringType' => [
' < ? php
/** @return void */
function foo ( Exception $e ) {
switch ( get_class ( $e )) {
case " InvalidArgumentException " :
break ;
}
} ' ,
2019-02-27 22:00:44 +01:00
'error_message' => 'TypeDoesNotContainType - src' . DIRECTORY_SEPARATOR . 'somefile.php:5:34 - string(InvalidArgumentException) cannot be identical to class-string' ,
2018-11-29 05:59:43 +01:00
],
2017-04-25 05:45:02 +02:00
];
2016-12-06 19:49:57 +01:00
}
}