Skip to content

Commit 5a6e4eb

Browse files
committed
uses nette/phpstan-rules
1 parent 015ecc8 commit 5a6e4eb

3 files changed

Lines changed: 279 additions & 1 deletion

File tree

composer.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@
2020
"require-dev": {
2121
"nette/tester": "^2.5",
2222
"tracy/tracy": "^2.9",
23-
"phpstan/phpstan-nette": "^2.0@stable",
23+
"phpstan/phpstan": "^2.1@stable",
24+
"phpstan/extension-installer": "^1.4@stable",
25+
"nette/phpstan-rules": "^1.0",
2426
"jetbrains/phpstorm-attributes": "^1.2"
2527
},
2628
"conflict": {
@@ -50,5 +52,10 @@
5052
"branch-alias": {
5153
"dev-master": "4.1-dev"
5254
}
55+
},
56+
"config": {
57+
"allow-plugins": {
58+
"phpstan/extension-installer": true
59+
}
5360
}
5461
}

tests/types/TypesTest.phpt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
require __DIR__ . '/../bootstrap.php';
6+
7+
use Nette\PHPStan\Tester\TypeAssert;
8+
9+
TypeAssert::assertTypes(__DIR__ . '/utils-types.php');

tests/types/utils-types.php

Lines changed: 262 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
<?php
2+
3+
/**
4+
* PHPStan type tests for Utils.
5+
* Run: vendor/bin/phpstan analyse tests/types
6+
*/
7+
8+
declare(strict_types=1);
9+
10+
use Nette\Iterators\CachingIterator;
11+
use Nette\Utils\ArrayHash;
12+
use Nette\Utils\Arrays;
13+
use Nette\Utils\Helpers;
14+
use Nette\Utils\Html;
15+
use Nette\Utils\Iterables;
16+
use Nette\Utils\Type;
17+
use Nette\Utils\Validators;
18+
use function PHPStan\Testing\assertType;
19+
20+
21+
/** @param ArrayHash<mixed> $hash */
22+
function testArrayHash(ArrayHash $hash): void
23+
{
24+
foreach ($hash as $key => $value) {
25+
assertType('(int|string)', $key);
26+
assertType('mixed', $value);
27+
}
28+
29+
assertType('mixed', $hash['key']);
30+
}
31+
32+
33+
function testHtml(Html $html): void
34+
{
35+
foreach ($html as $key => $child) {
36+
assertType('int', $key);
37+
assertType('Nette\Utils\Html|string', $child);
38+
}
39+
40+
assertType('Nette\Utils\Html|string', $html[0]);
41+
}
42+
43+
44+
function testArraysSome(): void
45+
{
46+
$result = Arrays::some([1, 2, 3], function ($value, $key) {
47+
assertType('1|2|3', $value);
48+
assertType('0|1|2', $key);
49+
return $value > 2;
50+
});
51+
assertType('bool', $result);
52+
}
53+
54+
55+
function testArraysEvery(): void
56+
{
57+
$result = Arrays::every([1, 2, 3], function ($value, $key) {
58+
assertType('1|2|3', $value);
59+
assertType('0|1|2', $key);
60+
return true;
61+
});
62+
assertType('bool', $result);
63+
}
64+
65+
66+
function testArraysMap(): void
67+
{
68+
$result = Arrays::map([1, 2, 3], function ($value) {
69+
assertType('1|2|3', $value);
70+
return $value * 2;
71+
});
72+
assertType('array<0|1|2, float|int>', $result);
73+
}
74+
75+
76+
/** @param array<string, int> $array */
77+
function testArraysMapWithKeys(array $array): void
78+
{
79+
$result = Arrays::mapWithKeys($array, fn($v, $k) => [$k, $v * 10]);
80+
assertType('array<string, float|int>', $result);
81+
}
82+
83+
84+
/** @param array<string, int> $array */
85+
function testArraysFilter(array $array): void
86+
{
87+
$result = Arrays::filter($array, fn($v) => $v > 1);
88+
assertType('array<string, int>', $result);
89+
}
90+
91+
92+
/** @param array<int, int> $array */
93+
function testArraysFirst(array $array): void
94+
{
95+
assertType('int|null', Arrays::first($array));
96+
assertType('int|null', Arrays::first($array, fn($v) => $v > 2));
97+
}
98+
99+
100+
/** @param array<string, int> $array */
101+
function testArraysFirstKey(array $array): void
102+
{
103+
assertType('string|null', Arrays::firstKey($array));
104+
}
105+
106+
107+
/** @param array<int, int> $array */
108+
function testArraysLast(array $array): void
109+
{
110+
assertType('int|null', Arrays::last($array));
111+
}
112+
113+
114+
/** @param array<string, int> $array */
115+
function testArraysLastKey(array $array): void
116+
{
117+
assertType('string|null', Arrays::lastKey($array));
118+
}
119+
120+
121+
/** @param array<int> $array */
122+
function testArraysGet(array $array): void
123+
{
124+
assertType('int|null', Arrays::get($array, 0));
125+
assertType('int|null', Arrays::get($array, 0, null));
126+
}
127+
128+
129+
/** @param array<int> $array */
130+
function testArraysGetRef(array &$array): void
131+
{
132+
assertType('int|null', Arrays::getRef($array, 'a'));
133+
}
134+
135+
136+
/** @param array<int|null> $array */
137+
function testArraysPick(array &$array): void
138+
{
139+
assertType('int|null', Arrays::pick($array, 'a'));
140+
}
141+
142+
143+
function testArraysToObject(): void
144+
{
145+
$obj = new stdClass;
146+
assertType('stdClass', Arrays::toObject(['a' => 1], $obj));
147+
}
148+
149+
150+
function testHelpersClamp(): void
151+
{
152+
assertType('int', Helpers::clamp(5, 1, 10));
153+
assertType('float', Helpers::clamp(5.0, 1, 10));
154+
assertType('float', Helpers::clamp(5, 1.0, 10));
155+
assertType('float', Helpers::clamp(5, 1, 10.0));
156+
}
157+
158+
159+
function testValidatorsIsNumeric(): void
160+
{
161+
$int = 42;
162+
assertType('true', Validators::isNumeric($int));
163+
assertType('bool', Validators::isNumeric('hello'));
164+
}
165+
166+
167+
function testValidatorsIsNone(mixed $value): void
168+
{
169+
if (Validators::isNone($value)) {
170+
assertType("0|0.0|''|false|null", $value);
171+
}
172+
}
173+
174+
175+
/** @param iterable<int, int> $iterable */
176+
function testIterablesFirst(iterable $iterable): void
177+
{
178+
assertType('int|null', Iterables::first($iterable));
179+
assertType('int|null', Iterables::first($iterable, fn($v) => $v > 2));
180+
}
181+
182+
183+
/** @param iterable<string, int> $iterable */
184+
function testIterablesFirstKey(iterable $iterable): void
185+
{
186+
assertType('string|null', Iterables::firstKey($iterable));
187+
}
188+
189+
190+
/** @param iterable<int, int> $iterable */
191+
function testIterablesFilter(iterable $iterable): void
192+
{
193+
$result = Iterables::filter($iterable, fn($v) => $v > 1);
194+
assertType('Generator<int, int, mixed, mixed>', $result);
195+
}
196+
197+
198+
/** @param iterable<int, int> $iterable */
199+
function testIterablesMap(iterable $iterable): void
200+
{
201+
$result = Iterables::map($iterable, fn($v) => (string) $v);
202+
assertType('Generator<int, string, mixed, mixed>', $result);
203+
}
204+
205+
206+
/** @param iterable<string, int> $iterable */
207+
function testIterablesMapWithKeys(iterable $iterable): void
208+
{
209+
$result = Iterables::mapWithKeys($iterable, fn($v, $k) => [$k, $v * 10]);
210+
assertType('Generator<string, float|int, mixed, mixed>', $result);
211+
}
212+
213+
214+
/** @param CachingIterator<string, int> $iterator */
215+
function testCachingIterator(CachingIterator $iterator): void
216+
{
217+
assertType('string', $iterator->getNextKey());
218+
assertType('int', $iterator->getNextValue());
219+
}
220+
221+
222+
function testTypeFromReflection(): void
223+
{
224+
$ref = new ReflectionFunction('strlen');
225+
$type = Type::fromReflection($ref);
226+
assertType('Nette\Utils\Type|null', $type);
227+
}
228+
229+
230+
function testTypeGetTypes(): void
231+
{
232+
$type = Type::fromString('int|string');
233+
assertType('list<Nette\Utils\Type>', $type->getTypes());
234+
}
235+
236+
237+
/** @param array<int, int> $array */
238+
function testArraysFirstWithElse(array $array): void
239+
{
240+
assertType('int', Arrays::first($array, else: fn() => 0));
241+
}
242+
243+
244+
/** @param array<int, int> $array */
245+
function testArraysLastWithElse(array $array): void
246+
{
247+
assertType('int', Arrays::last($array, else: fn() => 0));
248+
}
249+
250+
251+
/** @param iterable<int, int> $iterable */
252+
function testIterablesFirstWithElse(iterable $iterable): void
253+
{
254+
assertType('int', Iterables::first($iterable, else: fn() => 0));
255+
}
256+
257+
258+
/** @param iterable<string, int> $iterable */
259+
function testIterablesFirstKeyWithElse(iterable $iterable): void
260+
{
261+
assertType('string', Iterables::firstKey($iterable, else: fn() => 'default'));
262+
}

0 commit comments

Comments
 (0)