Skip to content

Commit 9e186b6

Browse files
phpstan-botclaude
andcommitted
Add tests for all IntegerRangeType count comparison conditions
Cover all branches in the IntegerRangeType handling in TypeSpecifier: - Falsey context with orEqual (count < bounded range) - Falsey context without orEqual (count <= bounded range) - Truthy context with orEqual (range <= count) - Truthy context without orEqual (range < count) - Fallback branch with unbounded min range (int<min, N>) - Unbounded max range (int<N, max>) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent bd08780 commit 9e186b6

File tree

1 file changed

+94
-0
lines changed

1 file changed

+94
-0
lines changed

tests/PHPStan/Analyser/nsrt/bug-13705.php

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,100 @@ function whileLoop(): void
1717
}
1818
}
1919

20+
/**
21+
* @param list<string> $arr
22+
* @param int<2, 5> $boundedRange
23+
* @param int<2, max> $unboundedMaxRange
24+
* @param int<min, 5> $unboundedMinRange
25+
*/
26+
function countLessThanRange(array $arr, int $boundedRange, int $unboundedMaxRange, int $unboundedMinRange): void
27+
{
28+
// count($arr) < $range → inverted to NOT($range <= count($arr))
29+
// Inner: orEqual=true, false context → falsey + max !== null + orEqual (branch 1)
30+
// Else: orEqual=true, true context → truthy + min !== null + orEqual (branch 3)
31+
if (count($arr) < $boundedRange) {
32+
assertType('list<string>', $arr);
33+
} else {
34+
assertType('non-empty-list<string>&hasOffsetValue(1, string)', $arr);
35+
}
36+
37+
// count($arr) < unbounded max range → falsey + max is null → fallback via min (branch 3/4)
38+
if (count($arr) < $unboundedMaxRange) {
39+
assertType('list<string>', $arr);
40+
} else {
41+
assertType('non-empty-list<string>&hasOffsetValue(1, string)', $arr);
42+
}
43+
44+
// count($arr) < unbounded min range → fallback branch (min is null)
45+
if (count($arr) < $unboundedMinRange) {
46+
assertType('list<string>', $arr);
47+
} else {
48+
assertType('list<string>', $arr);
49+
}
50+
}
51+
52+
/**
53+
* @param list<string> $arr
54+
* @param int<2, 5> $boundedRange
55+
*/
56+
function countLessThanOrEqualRange(array $arr, int $boundedRange): void
57+
{
58+
// count($arr) <= $range → inverted to NOT($range < count($arr))
59+
// Inner: orEqual=false, false context → falsey + max !== null + !orEqual (branch 2)
60+
// Else: orEqual=false, true context → truthy + min !== null + !orEqual (branch 4)
61+
if (count($arr) <= $boundedRange) {
62+
assertType('list<string>', $arr);
63+
} else {
64+
assertType('non-empty-list<string>&hasOffsetValue(1, string)&hasOffsetValue(2, string)', $arr);
65+
}
66+
}
67+
68+
/**
69+
* @param list<string> $arr
70+
* @param int<2, 5> $boundedRange
71+
*/
72+
function rangeGreaterThanOrEqualCount(array $arr, int $boundedRange): void
73+
{
74+
// $range >= count($arr) → same as count($arr) <= $range
75+
if ($boundedRange >= count($arr)) {
76+
assertType('list<string>', $arr);
77+
} else {
78+
assertType('non-empty-list<string>&hasOffsetValue(1, string)&hasOffsetValue(2, string)', $arr);
79+
}
80+
}
81+
82+
/**
83+
* @param list<string> $arr
84+
* @param int<2, 5> $boundedRange
85+
*/
86+
function rangeLessThanOrEqualCount(array $arr, int $boundedRange): void
87+
{
88+
// $range <= count($arr) → direct, orEqual=true
89+
// True context: truthy + orEqual + min !== null (branch 3)
90+
// False context: falsey + orEqual + max !== null (branch 1)
91+
if ($boundedRange <= count($arr)) {
92+
assertType('non-empty-list<string>&hasOffsetValue(1, string)', $arr);
93+
} else {
94+
assertType('list<string>', $arr);
95+
}
96+
}
97+
98+
/**
99+
* @param list<string> $arr
100+
* @param int<2, 5> $boundedRange
101+
*/
102+
function rangeLessThanCount(array $arr, int $boundedRange): void
103+
{
104+
// $range < count($arr) → direct, orEqual=false
105+
// True context: truthy + !orEqual + min !== null (branch 4)
106+
// False context: falsey + !orEqual + max !== null (branch 2)
107+
if ($boundedRange < count($arr)) {
108+
assertType('non-empty-list<string>&hasOffsetValue(1, string)&hasOffsetValue(2, string)', $arr);
109+
} else {
110+
assertType('list<string>', $arr);
111+
}
112+
}
113+
20114
function whileLoopOriginal(int $length, int $quantity): void
21115
{
22116
if ($length < 8) {

0 commit comments

Comments
 (0)