Skip to content

Commit bba1aca

Browse files
committed
Remove the "OddNumber" and "EveneNUmber" rules. As they are both extremely similar classes, avoid duplication by combining both rules into a single "NumberPartity" class.
1 parent 365e320 commit bba1aca

File tree

9 files changed

+227
-169
lines changed

9 files changed

+227
-169
lines changed

README.md

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,12 @@ Alternatively use the rule directly with a [Laravel form request object](https:/
4848
- [`Base64EncodedString`](#base64encodedstring)
4949
- [`Coordinate`](#coordinate)
5050
- [`DomainRestrictedEmail`](#domainrestrictedemail)
51-
- [`EvenNumber`](#evennumber)
5251
- [`ExcludesHtml`](#excludeshtml)
5352
- [`HexColourCode`](#hexcolourcode)
5453
- [`Honorific`](#honorific)
5554
- [`IncludesHtml`](#includeshtml)
5655
- [`NoWhitespace`](#nowhitespace)
57-
- [`OddNumber`](#oddnumber)
56+
- [`NumberParity`](#numberparity)
5857
- [`StringContains`](#stringcontains)
5958
- [`StrongPassword`](#strongpassword)
6059
- [`TitleCase`](#titlecase)
@@ -93,10 +92,6 @@ $request->validate([
9392

9493
The validation message will include the list of whitelisted domains based upon the provided configuration.
9594

96-
### `EvenNumber`
97-
98-
Ensure the passed attribute is an even number.
99-
10095
### `ExcludesHtml`
10196

10297
Ensure the passed attribute does not contain HTML.
@@ -133,9 +128,39 @@ Ensure the passed attribute contains HTML.
133128

134129
Ensure the passed attribute contains no whitespace.
135130

136-
### `OddNumber`
131+
### `NumberParity`
132+
133+
Validate the number parity.
134+
135+
An odd number:
136+
137+
```php
138+
use F9Web\ValidationRules\Rules\NumberParity;
139+
140+
// ...
141+
142+
$request->validate([
143+
'amount' => [
144+
'required',
145+
(new NumberParity())->odd(),
146+
],
147+
]);
148+
```
149+
150+
An even number:
151+
152+
```php
153+
use F9Web\ValidationRules\Rules\NumberParity;
154+
155+
// ...
137156

138-
Ensure the passed attribute is an odd number.
157+
$request->validate([
158+
'amount' => [
159+
'required',
160+
(new NumberParity())->even(),
161+
],
162+
]);
163+
```
139164

140165
### `StringContains`
141166

resources/lang/en/messages.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
return [
44
'uppercase' => 'The :attribute field must only contain uppercase characters',
55
'title-case' => 'The :attribute must be in title case form',
6-
'even-number' => 'The :attribute must be an even number',
7-
'odd-number' => 'The :attribute must be an odd number',
86
'domain-restricted-email' => 'The :attribute must be an email address ending with any of the following :plural: :domains',
97
'excludes-html' => 'The :attribute contains html',
108
'includes-html' => 'The :attribute must contain html',
@@ -29,4 +27,8 @@
2927
],
3028
'u-k-mobile-phone' => 'The :attribute must be a valid UK mobile number',
3129
'base64-encoded-string' => 'The :attribute must be a valid base64 encoded string',
30+
'number-parity' => [
31+
'even' => 'The :attribute must be an even number',
32+
'odd' => 'The :attribute must be an odd number',
33+
],
3234
];
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
namespace F9Web\ValidationRules\Exceptions;
4+
5+
use InvalidArgumentException;
6+
7+
class NumberParityException extends InvalidArgumentException
8+
{
9+
}

src/Rules/EvenNumber.php

Lines changed: 0 additions & 27 deletions
This file was deleted.

src/Rules/NumberParity.php

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace F9Web\ValidationRules\Rules;
6+
7+
use F9Web\ValidationRules\Exceptions\NumberParityException;
8+
use F9Web\ValidationRules\Rule;
9+
use function __;
10+
use function filter_var;
11+
12+
class NumberParity extends Rule
13+
{
14+
/** @var null|string */
15+
protected $mode = null;
16+
17+
/**
18+
* @param string $attribute
19+
* @param mixed $value
20+
* @return bool
21+
* @throws NumberParityException
22+
*/
23+
public function passes($attribute, $value): bool
24+
{
25+
$this->setAttribute($attribute);
26+
27+
if (filter_var($value, FILTER_VALIDATE_INT) === false) {
28+
return false;
29+
}
30+
31+
if (null === $this->mode) {
32+
throw new NumberParityException('Ensure the "odd()" or "even()" methods are called');
33+
}
34+
35+
return $this->mode === 'odd'
36+
? (int) $value % 2 !== 0
37+
: (int) $value % 2 === 0;
38+
}
39+
40+
/**
41+
* @return $this
42+
*/
43+
public function odd(): self
44+
{
45+
$this->mode = 'odd';
46+
47+
return $this;
48+
}
49+
50+
/**
51+
* @return $this
52+
*/
53+
public function even(): self
54+
{
55+
$this->mode = 'even';
56+
57+
return $this;
58+
}
59+
60+
/**
61+
* @return string
62+
*/
63+
public function message(): string
64+
{
65+
return __(
66+
'f9web-validation-rules::messages.'.$this->getMessageKey().'.'.$this->mode,
67+
[
68+
'attribute' => $this->getAttribute(),
69+
]
70+
);
71+
}
72+
}

src/Rules/OddNumber.php

Lines changed: 0 additions & 27 deletions
This file was deleted.

tests/Rules/EvenNumberTest.php

Lines changed: 0 additions & 54 deletions
This file was deleted.

tests/Rules/NumberParityTest.php

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace F9Web\ValidationRules\Tests;
6+
7+
use F9Web\ValidationRules\Exceptions\NumberParityException;
8+
use F9Web\ValidationRules\Rules\NumberParity;
9+
use stdClass;
10+
11+
class NumberParityTest extends TestCase
12+
{
13+
public function setUp(): void
14+
{
15+
parent::setUp();
16+
17+
$this->rule = new NumberParity();
18+
}
19+
20+
/** @test */
21+
public function it_throws_an_exception_when_no_mode_is_defined()
22+
{
23+
$this->expectException(NumberParityException::class);
24+
$this->expectExceptionMessage('Ensure the "odd()" or "even()" methods are called');
25+
26+
$this->rule->passes('field', 1);
27+
}
28+
29+
/**
30+
* @test
31+
* @dataProvider evenNumbersDataProvider
32+
* @param mixed $value
33+
* @param bool $shouldBeValid
34+
*/
35+
public function it_validates_even_numbers($value, bool $shouldBeValid)
36+
{
37+
$this->rule->even();
38+
39+
$result = $this->rule->passes('field', $value);
40+
41+
$this->{$shouldBeValid ? 'assertTrue' : 'assertFalse'}($result);
42+
}
43+
44+
/**
45+
* @test
46+
* @dataProvider oddNumbersDataProvider
47+
* @param mixed $value
48+
* @param bool $shouldBeValid
49+
*/
50+
public function it_validates_odd_numbers($value, bool $shouldBeValid)
51+
{
52+
$this->rule->odd();
53+
54+
$result = $this->rule->passes('field', $value);
55+
56+
$this->{$shouldBeValid ? 'assertTrue' : 'assertFalse'}($result);
57+
}
58+
59+
/** @test */
60+
public function it_passes_relevant_data_to_the_validation_message()
61+
{
62+
$this->rule->even();
63+
$this->rule->passes('quantity', 'abc');
64+
$this->assertEquals('The quantity must be an even number', $this->rule->message());
65+
66+
$this->rule->odd();
67+
$this->assertEquals('The quantity must be an odd number', $this->rule->message());
68+
}
69+
70+
/**
71+
* @return array|\string[][]
72+
*/
73+
public function evenNumbersDataProvider(): array
74+
{
75+
return [
76+
['1', false],
77+
['2', true],
78+
['100', true],
79+
[-4, true],
80+
[0, true],
81+
[2.8, false],
82+
[82, true],
83+
[178, true],
84+
['232323', false],
85+
[new stdClass, false],
86+
[['123'], false],
87+
];
88+
}
89+
90+
/**
91+
* @return array|\string[][]
92+
*/
93+
public function oddNumbersDataProvider(): array
94+
{
95+
return [
96+
['1', true],
97+
['2', false],
98+
['100', false],
99+
[2.8, false],
100+
[10, false],
101+
['232323', true],
102+
['-5', true],
103+
[-5, true],
104+
[3, true],
105+
[29, true],
106+
[73, true],
107+
];
108+
}
109+
}

0 commit comments

Comments
 (0)