Skip to content

Commit 911bf98

Browse files
authored
Add isNegativeInteger and notNegativeInteger (#301)
1 parent 672e80b commit 911bf98

File tree

7 files changed

+310
-1
lines changed

7 files changed

+310
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Changelog
1616
- All assertion methods now return the checked value.
1717
- Added `notInArray` and `notOneOf`.
1818
- Added `isInitialized`, to check if a class property is initialized.
19+
- Added `notNegativeInteger` and `negativeInteger`
1920

2021
### Fixed
2122

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ Method | Description
8989
`integer($value, $message = '')` | Check that a value is an integer
9090
`integerish($value, $message = '')` | Check that a value casts to an integer
9191
`positiveInteger($value, $message = '')` | Check that a value is a positive (non-zero) integer
92+
`negativeInteger($value, $message = '')` | Check that a value is a negative integer
93+
`notNegativeInteger($value, $message = '')` | Check that a value is a non-negative integer
9294
`float($value, $message = '')` | Check that a value is a float
9395
`numeric($value, $message = '')` | Check that a value is numeric
9496
`natural($value, $message = '')` | Check that a value is a non-negative integer

src/Assert.php

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,9 @@ public static function integerish(mixed $value, string $message = ''): int|float
117117
*/
118118
public static function positiveInteger(mixed $value, string $message = ''): int
119119
{
120-
if (!(\is_int($value) && $value > 0)) {
120+
self::integer($value);
121+
122+
if ($value < 1) {
121123
static::reportInvalidArgument(\sprintf(
122124
$message ?: 'Expected a positive integer. Got: %s',
123125
static::valueToString($value)
@@ -127,6 +129,50 @@ public static function positiveInteger(mixed $value, string $message = ''): int
127129
return $value;
128130
}
129131

132+
/**
133+
* @psalm-pure
134+
* @psalm-assert non-negative-int $value
135+
*
136+
* @psalm-return non-negative-int
137+
*
138+
* @throws InvalidArgumentException
139+
*/
140+
public static function notNegativeInteger(mixed $value, string $message = ''): int
141+
{
142+
self::integer($value);
143+
144+
if ($value < 0) {
145+
static::reportInvalidArgument(\sprintf(
146+
$message ?: 'Expected a non negative integer. Got: %s',
147+
static::valueToString($value)
148+
));
149+
}
150+
151+
return $value;
152+
}
153+
154+
/**
155+
* @psalm-pure
156+
* @psalm-assert negative-int $value
157+
*
158+
* @psalm-return negative-int
159+
*
160+
* @throws InvalidArgumentException
161+
*/
162+
public static function negativeInteger(mixed $value, string $message = ''): int
163+
{
164+
self::integer($value);
165+
166+
if ($value >= 0) {
167+
static::reportInvalidArgument(\sprintf(
168+
$message ?: 'Expected a negative integer. Got: %s',
169+
static::valueToString($value)
170+
));
171+
}
172+
173+
return $value;
174+
}
175+
130176
/**
131177
* @psalm-pure
132178
*

src/Mixin.php

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,118 @@ public static function allNullOrPositiveInteger(?iterable $value, string $messag
293293
return $value;
294294
}
295295

296+
/**
297+
* @psalm-pure
298+
*
299+
* @psalm-assert non-negative-int|null $value
300+
*
301+
* @return non-negative-int|null
302+
*
303+
* @throws InvalidArgumentException
304+
*/
305+
public static function nullOrNotNegativeInteger(mixed $value, string $message = ''): mixed
306+
{
307+
null === $value || static::notNegativeInteger($value, $message);
308+
309+
return $value;
310+
}
311+
312+
/**
313+
* @psalm-pure
314+
*
315+
* @psalm-assert iterable<non-negative-int> $value
316+
*
317+
* @return iterable<non-negative-int>
318+
*
319+
* @throws InvalidArgumentException
320+
*/
321+
public static function allNotNegativeInteger(iterable $value, string $message = ''): iterable
322+
{
323+
static::isIterable($value);
324+
325+
foreach ($value as $entry) {
326+
static::notNegativeInteger($entry, $message);
327+
}
328+
329+
return $value;
330+
}
331+
332+
/**
333+
* @psalm-pure
334+
*
335+
* @psalm-assert iterable<non-negative-int|null> $value
336+
*
337+
* @return iterable<non-negative-int|null>
338+
*
339+
* @throws InvalidArgumentException
340+
*/
341+
public static function allNullOrNotNegativeInteger(?iterable $value, string $message = ''): ?iterable
342+
{
343+
static::isIterable($value);
344+
345+
foreach ($value as $entry) {
346+
null === $entry || static::notNegativeInteger($entry, $message);
347+
}
348+
349+
return $value;
350+
}
351+
352+
/**
353+
* @psalm-pure
354+
*
355+
* @psalm-assert negative-int|null $value
356+
*
357+
* @return negative-int|null
358+
*
359+
* @throws InvalidArgumentException
360+
*/
361+
public static function nullOrNegativeInteger(mixed $value, string $message = ''): mixed
362+
{
363+
null === $value || static::negativeInteger($value, $message);
364+
365+
return $value;
366+
}
367+
368+
/**
369+
* @psalm-pure
370+
*
371+
* @psalm-assert iterable<negative-int> $value
372+
*
373+
* @return iterable<negative-int>
374+
*
375+
* @throws InvalidArgumentException
376+
*/
377+
public static function allNegativeInteger(iterable $value, string $message = ''): iterable
378+
{
379+
static::isIterable($value);
380+
381+
foreach ($value as $entry) {
382+
static::negativeInteger($entry, $message);
383+
}
384+
385+
return $value;
386+
}
387+
388+
/**
389+
* @psalm-pure
390+
*
391+
* @psalm-assert iterable<negative-int|null> $value
392+
*
393+
* @return iterable<negative-int|null>
394+
*
395+
* @throws InvalidArgumentException
396+
*/
397+
public static function allNullOrNegativeInteger(?iterable $value, string $message = ''): ?iterable
398+
{
399+
static::isIterable($value);
400+
401+
foreach ($value as $entry) {
402+
null === $entry || static::negativeInteger($entry, $message);
403+
}
404+
405+
return $value;
406+
}
407+
296408
/**
297409
* @psalm-pure
298410
*

tests/AssertTest.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,26 @@ public static function getTests(): array
7979
['positiveInteger', ['0'], false],
8080
['positiveInteger', [1.0], false],
8181
['positiveInteger', [1.23], false],
82+
['notNegativeInteger', [123], true],
83+
['notNegativeInteger', [1], true],
84+
['notNegativeInteger', [-123], false],
85+
['notNegativeInteger', [0], true],
86+
['notNegativeInteger', [0.0], false],
87+
['notNegativeInteger', ['123'], false],
88+
['notNegativeInteger', ['-123'], false],
89+
['notNegativeInteger', ['0'], false],
90+
['notNegativeInteger', [1.0], false],
91+
['notNegativeInteger', [1.23], false],
92+
['negativeInteger', [123], false],
93+
['negativeInteger', [1], false],
94+
['negativeInteger', [-123], true],
95+
['negativeInteger', [0], false],
96+
['negativeInteger', [0.0], false],
97+
['negativeInteger', ['123'], false],
98+
['negativeInteger', ['-123'], false],
99+
['negativeInteger', ['0'], false],
100+
['negativeInteger', [1.0], false],
101+
['negativeInteger', [1.23], false],
82102
['float', [1.0], true],
83103
['float', [1.23], true],
84104
['float', [123], false],
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Webmozart\Assert\Tests\StaticAnalysis;
6+
7+
use Webmozart\Assert\Assert;
8+
9+
/**
10+
* @psalm-pure
11+
*
12+
* @param mixed $value
13+
*
14+
* @psalm-return negative-int
15+
*/
16+
function negativeInteger(mixed $value): int
17+
{
18+
Assert::negativeInteger($value);
19+
20+
return $value;
21+
}
22+
23+
/**
24+
* @psalm-pure
25+
*
26+
* @param mixed $value
27+
*
28+
* @psalm-return negative-int|null
29+
*/
30+
function nullOrNegativeInteger(mixed $value): ?int
31+
{
32+
Assert::nullOrNegativeInteger($value);
33+
34+
return $value;
35+
}
36+
37+
/**
38+
* @psalm-pure
39+
*
40+
* @param mixed $value
41+
*
42+
* @return iterable<negative-int>
43+
*/
44+
function allNegativeInteger(mixed $value): iterable
45+
{
46+
Assert::allNegativeInteger($value);
47+
48+
return $value;
49+
}
50+
51+
/**
52+
* @psalm-pure
53+
*
54+
* @param mixed $value
55+
*
56+
* @return iterable<negative-int|null>
57+
*/
58+
function allNullOrNegativeInteger(mixed $value): iterable
59+
{
60+
Assert::allNullOrNegativeInteger($value);
61+
62+
return $value;
63+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Webmozart\Assert\Tests\StaticAnalysis;
6+
7+
use Webmozart\Assert\Assert;
8+
9+
/**
10+
* @psalm-pure
11+
*
12+
* @param mixed $value
13+
*
14+
* @psalm-return non-negative-int
15+
*/
16+
function nonNegativeInteger(mixed $value): int
17+
{
18+
Assert::notNegativeInteger($value);
19+
20+
$value *= -1;
21+
22+
return $value;
23+
}
24+
25+
/**
26+
* @psalm-pure
27+
*
28+
* @param mixed $value
29+
*
30+
* @psalm-return non-negative-int|null
31+
*/
32+
function nullOrNonNegativeInteger(mixed $value): ?int
33+
{
34+
Assert::nullOrNotNegativeInteger($value);
35+
36+
return $value;
37+
}
38+
39+
/**
40+
* @psalm-pure
41+
*
42+
* @param mixed $value
43+
*
44+
* @return iterable<non-negative-int>
45+
*/
46+
function allNonNegativeInteger(mixed $value): iterable
47+
{
48+
Assert::allNotNegativeInteger($value);
49+
50+
return $value;
51+
}
52+
53+
/**
54+
* @psalm-pure
55+
*
56+
* @param mixed $value
57+
*
58+
* @return iterable<non-negative-int|null>
59+
*/
60+
function allNullOrNonNegativeInteger(mixed $value): iterable
61+
{
62+
Assert::allNullOrPositiveInteger($value);
63+
64+
return $value;
65+
}

0 commit comments

Comments
 (0)