Skip to content

Commit 7cd2f98

Browse files
phpstan-botclaude
andcommitted
Add non-regression tests for #13591, #12597, and #10422
- #13591: nsrt + rule test verifying conditional parameter type narrowing works with boolean-and guard (no false positive for int|null parameter) - #12597: rule test verifying variable definedness after in_array check (no false "Variable might not be defined" warning) - #10422: nsrt + rule test verifying method call on nullable after if/elseif guard with die() (no false "Cannot call method on null") Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 816fdb7 commit 7cd2f98

8 files changed

Lines changed: 144 additions & 0 deletions

File tree

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
declare(strict_types = 1);
4+
5+
namespace Bug10422;
6+
7+
use function PHPStan\Testing\assertType;
8+
9+
class TestClass {
10+
public function test(): void {}
11+
public function something(): bool { return true; }
12+
}
13+
14+
function test(?TestClass $test): void
15+
{
16+
$error = '';
17+
18+
if (!$test) {
19+
$error = 'missing test';
20+
} else if ($test->something()) {
21+
$error = 'another';
22+
}
23+
if ($error) {
24+
die('Done');
25+
}
26+
assertType('Bug10422\TestClass', $test);
27+
$test->test();
28+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
declare(strict_types = 1);
4+
5+
namespace Bug13591;
6+
7+
use function PHPStan\Testing\assertType;
8+
9+
function processHotel(int $hotelId): void {}
10+
11+
/**
12+
* @param 'get_rooms'|'get_hotels' $action
13+
*/
14+
function test(string $action, ?int $hotelId): void
15+
{
16+
if ($action === 'get_rooms' && $hotelId === null) {
17+
throw new \InvalidArgumentException('Hotel ID is required');
18+
}
19+
20+
if ($action === 'get_rooms') {
21+
assertType('int', $hotelId);
22+
processHotel($hotelId);
23+
}
24+
}

tests/PHPStan/Rules/Functions/CallToFunctionParametersRuleTest.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2828,4 +2828,9 @@ public function testBug4608(): void
28282828
]);
28292829
}
28302830

2831+
public function testBug13591(): void
2832+
{
2833+
$this->analyse([__DIR__ . '/data/bug-13591.php'], []);
2834+
}
2835+
28312836
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
declare(strict_types = 1);
4+
5+
namespace Bug13591Rule;
6+
7+
function processHotel(int $hotelId): void {}
8+
9+
/**
10+
* @param 'get_rooms'|'get_hotels' $action
11+
*/
12+
function test(string $action, ?int $hotelId): void
13+
{
14+
if ($action === 'get_rooms' && $hotelId === null) {
15+
throw new \InvalidArgumentException('Hotel ID is required');
16+
}
17+
18+
if ($action === 'get_rooms') {
19+
processHotel($hotelId);
20+
}
21+
}

tests/PHPStan/Rules/Methods/CallMethodsRuleTest.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4001,4 +4001,12 @@ public function testBug11978(): void
40014001
]);
40024002
}
40034003

4004+
public function testBug10422(): void
4005+
{
4006+
$this->checkThisOnly = false;
4007+
$this->checkNullables = true;
4008+
$this->checkUnionTypes = true;
4009+
$this->analyse([__DIR__ . '/data/bug-10422.php'], []);
4010+
}
4011+
40044012
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
declare(strict_types = 1);
4+
5+
namespace Bug10422Rule;
6+
7+
class TestClass {
8+
public function test(): void {}
9+
public function something(): bool { return true; }
10+
}
11+
12+
function test(?TestClass $test): void
13+
{
14+
$error = '';
15+
16+
if (!$test) {
17+
$error = 'missing test';
18+
} else if ($test->something()) {
19+
$error = 'another';
20+
}
21+
if ($error) {
22+
die('Done');
23+
}
24+
$test->test();
25+
}

tests/PHPStan/Rules/Variables/DefinedVariableRuleTest.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1499,4 +1499,13 @@ public function testBug14117(): void
14991499
]);
15001500
}
15011501

1502+
public function testBug12597(): void
1503+
{
1504+
$this->cliArgumentsVariablesRegistered = true;
1505+
$this->polluteScopeWithLoopInitialAssignments = false;
1506+
$this->checkMaybeUndefinedVariables = true;
1507+
$this->polluteScopeWithAlwaysIterableForeach = true;
1508+
$this->analyse([__DIR__ . '/data/bug-12597.php'], []);
1509+
}
1510+
15021511
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
declare(strict_types = 1);
4+
5+
namespace Bug12597;
6+
7+
class HelloWorld
8+
{
9+
private const TYPE_1 = 1;
10+
private const TYPE_2 = 2;
11+
12+
public function test(int $type): void
13+
{
14+
if (in_array($type, [self::TYPE_1, self::TYPE_2], true)) {
15+
$message = 'Hello!';
16+
}
17+
18+
if ($type === self::TYPE_1) {
19+
$this->message($message);
20+
}
21+
}
22+
23+
public function message(string $message): void {}
24+
}

0 commit comments

Comments
 (0)