Skip to content

Commit b72f6ee

Browse files
ondrejmirtesclaude
andcommitted
Add regression tests for #13663, #10349, #8648
Closes phpstan/phpstan#13663 Closes phpstan/phpstan#10349 Closes phpstan/phpstan#8648 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 761c482 commit b72f6ee

5 files changed

Lines changed: 179 additions & 0 deletions

File tree

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Bug13663;
4+
5+
use function PHPStan\Testing\assertType;
6+
7+
/**
8+
* @param array<int, array{foo: array<int, mixed>, count: int}> $usageDetailMap
9+
*/
10+
function test(array $usageDetailMap): void {
11+
assertType('array<int, array{foo: array<int, mixed>, count: int}>', $usageDetailMap);
12+
13+
foreach ([1,2] as $projectNumberId) {
14+
assertType('array<int, array{foo: array<int, mixed>, count: int}>', $usageDetailMap);
15+
if (!array_key_exists($projectNumberId, $usageDetailMap)) {
16+
$usageDetailMap[$projectNumberId] = [
17+
'foo' => [],
18+
'count' => 0,
19+
];
20+
}
21+
22+
$usageDetailMap[$projectNumberId]['count'] = $usageDetailMap[$projectNumberId]['count'] + 1;
23+
24+
foreach ($usageDetailMap as $existingProjectNumberId => $value) {
25+
$usageDetailMap[$existingProjectNumberId]['foo'][] = 'foo';
26+
}
27+
28+
$usageDetailMap[$projectNumberId]['count'] = $usageDetailMap[$projectNumberId]['count'] + 1;
29+
}
30+
}

tests/PHPStan/Rules/Arrays/OffsetAccessAssignmentRuleTest.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,4 +201,10 @@ public function testBug11572(): void
201201
]);
202202
}
203203

204+
public function testBug8648(): void
205+
{
206+
$this->checkUnionTypes = true;
207+
$this->analyse([__DIR__ . '/data/bug-8648.php'], []);
208+
}
209+
204210
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Bug8648;
4+
5+
class Data
6+
{
7+
}
8+
9+
class HelloWorld
10+
{
11+
/**
12+
* @var mixed[]
13+
*/
14+
private $data;
15+
16+
/**
17+
* @return mixed[]
18+
*/
19+
public function processData(): array
20+
{
21+
$this->data['foo'] = [
22+
'id' => 'some_id',
23+
];
24+
25+
foreach (['a' => 'aa', 'b' => 'bb', 'c' => 'cc'] as $type => $value) {
26+
$this->data['foo']['bar'][] = [
27+
'type' => $type,
28+
'value' => $value,
29+
];
30+
}
31+
32+
return $this->data;
33+
}
34+
}

tests/PHPStan/Rules/Operators/InvalidBinaryOperationRuleTest.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -835,4 +835,22 @@ public function testBug14080(): void
835835
$this->analyse([__DIR__ . '/data/bug-14080.php'], []);
836836
}
837837

838+
public function testBug10349(): void
839+
{
840+
$this->analyse([__DIR__ . '/data/bug-10349.php'], [
841+
[
842+
'Binary operation "+=" between bool|float|int|string and int results in an error.',
843+
36,
844+
],
845+
[
846+
'Binary operation "+=" between bool|float|int|string and int results in an error.',
847+
63,
848+
],
849+
[
850+
'Binary operation "+=" between bool|float|int|string and int results in an error.',
851+
82,
852+
],
853+
]);
854+
}
855+
838856
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
<?php
2+
3+
namespace Bug10349;
4+
5+
class Foo
6+
{
7+
/** @return void */
8+
public function testSomething()
9+
{
10+
$expected = [];
11+
$expected[0] = [
12+
'number-1' => 3, // Offset
13+
'name' => '$a',
14+
'number-2' => 3, // Offset
15+
'number-3' => 3, // Offset
16+
'has_something' => false,
17+
];
18+
19+
$this->issue_1_A(10, $expected);
20+
$this->issue_1_B(10, $expected);
21+
$this->issue_2(10, $expected);
22+
}
23+
24+
/**
25+
* Test helper.
26+
*
27+
* @param int $ptr
28+
* @param array<int, array<string, scalar>> $expected
29+
*
30+
* @return array<int, array<string, scalar>>
31+
*/
32+
private function issue_1_A($ptr, $expected)
33+
{
34+
foreach ($expected as $key => $param) {
35+
if ($param['number-1'] !== false) {
36+
$expected[$key]['number-1'] += $ptr;
37+
}
38+
39+
if ($param['number-2'] !== false) {
40+
$expected[$key]['number-2'] += $ptr;
41+
}
42+
}
43+
44+
return $expected;
45+
}
46+
47+
/**
48+
* Test helper.
49+
*
50+
* @param int $ptr
51+
* @param array<int, array<string, scalar>> $expected
52+
*
53+
* @return array<int, array<string, scalar>>
54+
*/
55+
private function issue_1_B($ptr, $expected)
56+
{
57+
foreach ($expected as $key => $param) {
58+
if (is_int($expected[$key]['number-1'])) {
59+
$expected[$key]['number-1'] += $ptr;
60+
}
61+
62+
if ($param['number-2'] !== false) {
63+
$expected[$key]['number-2'] += $ptr;
64+
}
65+
}
66+
67+
return $expected;
68+
}
69+
70+
/**
71+
* Test helper.
72+
*
73+
* @param int $ptr
74+
* @param array<int, array<string, scalar>> $expected
75+
*
76+
* @return array<int, array<string, scalar>>
77+
*/
78+
private function issue_2($ptr, $expected)
79+
{
80+
foreach ($expected as $key => $param) {
81+
if (is_int($param['number-1'])) {
82+
$expected[$key]['number-1'] += $ptr;
83+
}
84+
if (is_int($param['number-2'])) {
85+
$expected[$key]['number-2'] += $ptr;
86+
}
87+
}
88+
89+
return $expected;
90+
}
91+
}

0 commit comments

Comments
 (0)