Skip to content

Commit 866cd74

Browse files
authored
Merge 7817d66 into e9bec51
2 parents e9bec51 + 7817d66 commit 866cd74

File tree

4 files changed

+129
-49
lines changed

4 files changed

+129
-49
lines changed

src/Rule/InRange.php

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -44,22 +44,9 @@ public function __construct(iterable $range)
4444

4545
protected function validateValue($value, ValidationContext $context = null): Result
4646
{
47-
$in = false;
48-
49-
if (
50-
(is_iterable($value)) &&
51-
ArrayHelper::isSubset($value, $this->range, $this->strict)
52-
) {
53-
$in = true;
54-
}
55-
56-
if (!$in && ArrayHelper::isIn($value, $this->range, $this->strict)) {
57-
$in = true;
58-
}
59-
6047
$result = new Result();
6148

62-
if ($this->not === $in) {
49+
if ($this->not === ArrayHelper::isIn($value, $this->range, $this->strict)) {
6350
$result->addError($this->formatMessage($this->message));
6451
}
6552

src/Rule/Subset.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 Yiisoft\Validator\Rule;
6+
7+
use Yiisoft\Arrays\ArrayHelper;
8+
use Yiisoft\Validator\Result;
9+
use Yiisoft\Validator\Rule;
10+
use Yiisoft\Validator\ValidationContext;
11+
12+
class Subset extends Rule
13+
{
14+
/**
15+
* @var iterable
16+
*/
17+
private iterable $values;
18+
/**
19+
* @var bool whether the comparison is strict (both type and value must be the same)
20+
*/
21+
private bool $strict = false;
22+
23+
private string $iterableMessage = 'Value must be iterable';
24+
25+
private string $subsetMessage = 'Values must be ones of {values}.';
26+
27+
public function __construct(iterable $values)
28+
{
29+
$this->values = $values;
30+
}
31+
32+
protected function validateValue($value, ValidationContext $context = null): Result
33+
{
34+
$result = new Result();
35+
36+
if (!is_iterable($value)) {
37+
$result->addError($this->formatMessage($this->iterableMessage));
38+
return $result;
39+
}
40+
41+
if (!ArrayHelper::isSubset($value, $this->values, $this->strict)) {
42+
43+
$valuesString = '"' . implode('", "', (is_array($this->values) ? $values : iterator_to_array($this->values))) . '"'
44+
45+
$result->addError($this->formatMessage($this->subsetMessage, [
46+
'values' => $valuesString,
47+
]));
48+
}
49+
50+
return $result;
51+
}
52+
53+
public function strict(): self
54+
{
55+
$new = clone $this;
56+
$new->strict = true;
57+
return $new;
58+
}
59+
60+
public function getOptions(): array
61+
{
62+
return array_merge(
63+
parent::getOptions(),
64+
[
65+
'iterableMessage' => $this->formatMessage($this->iterableMessage),
66+
'subsetMessage' => $this->formatMessage($this->subsetMessage),
67+
'values' => $this->values,
68+
'strict' => $this->strict,
69+
],
70+
);
71+
}
72+
}

tests/Rule/InRangeTest.php

Lines changed: 9 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -32,22 +32,20 @@ public function testValidateEmpty(): void
3232
$this->assertFalse($rule->validate('0')->isValid());
3333
$this->assertFalse($rule->validate(0)->isValid());
3434
$this->assertFalse($rule->validate('')->isValid());
35-
36-
$rule = (new InRange(range(10, 20, 1)))
37-
->skipOnEmpty(false);
38-
39-
$this->assertTrue($rule->validate([])->isValid());
4035
}
4136

4237
public function testValidateArrayValue(): void
4338
{
44-
$rule = (new InRange(range(1, 10)));
39+
// Test in array, values are arrays. IE: ['a'] in [['a'], ['b']]
40+
$rule = (new InRange([['a'], ['b']]));
41+
42+
$this->assertTrue($rule->validate(['a'])->isValid());
43+
4544

46-
$this->assertTrue($rule->validate([1, 2, 3, 4, 5])->isValid());
47-
$this->assertTrue($rule->validate([6, 7, 8, 9, 10])->isValid());
48-
$this->assertFalse($rule->validate([0, 1, 2])->isValid());
49-
$this->assertFalse($rule->validate([10, 11, 12])->isValid());
50-
$this->assertTrue($rule->validate(['1', '2', '3', 4, 5, 6])->isValid());
45+
// Test range as ArrayObject.
46+
$rule = (new InRange(new \ArrayObject(['a', 'b'])));
47+
48+
$this->assertTrue($rule->validate('a')->isValid());
5149
}
5250

5351
public function testValidateStrict(): void
@@ -86,30 +84,6 @@ public function testValidateNot()
8684
$this->assertFalse($rule->validate('5')->isValid());
8785
}
8886

89-
public function testValidateSubsetArrayable(): void
90-
{
91-
// Test in array, values are arrays. IE: ['a'] in [['a'], ['b']]
92-
$rule = (new InRange([['a'], ['b']]));
93-
94-
$this->assertTrue($rule->validate(['a'])->isValid());
95-
96-
// Test in array, values are arrays. IE: ['a', 'b'] subset [['a', 'b', 'c']
97-
$rule = (new InRange(['a', 'b', 'c']));
98-
99-
$this->assertTrue($rule->validate(['a', 'b'])->isValid());
100-
101-
// Test in array, values are arrays. IE: ['a', 'b'] subset [['a', 'b', 'c']
102-
$rule = (new InRange(['a', 'b', 'c']));
103-
104-
$this->assertTrue($rule->validate(new \ArrayObject(['a', 'b']))->isValid());
105-
106-
107-
// Test range as ArrayObject.
108-
$rule = (new InRange(new \ArrayObject(['a', 'b'])));
109-
110-
$this->assertTrue($rule->validate('a')->isValid());
111-
}
112-
11387
public function testName(): void
11488
{
11589
$this->assertEquals('inRange', (new InRange(range(1, 10)))->getName());

tests/Rule/SubsetTest.php

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Yiisoft\Validator\Tests\Rule;
6+
7+
use Yiisoft\Validator\Rule\Subset;
8+
use PHPUnit\Framework\TestCase;
9+
10+
class SubsetTest extends TestCase
11+
{
12+
public function testValidateArrayValue(): void
13+
{
14+
$rule = (new Subset(range(1, 10)));
15+
$this->assertTrue($rule->validate([1, 2, 3, 4, 5])->isValid());
16+
$this->assertTrue($rule->validate([6, 7, 8, 9, 10])->isValid());
17+
$this->assertFalse($rule->validate([0, 1, 2])->isValid());
18+
$this->assertFalse($rule->validate([10, 11, 12])->isValid());
19+
$this->assertTrue($rule->validate(['1', '2', '3', 4, 5, 6])->isValid());
20+
}
21+
22+
public function testValidateSubsetArrayable(): void
23+
{
24+
// Test in array, values are arrays. IE: ['a', 'b'] subset [['a', 'b', 'c']
25+
$rule = (new Subset(['a', 'b', 'c']));
26+
27+
$this->assertTrue($rule->validate(['a', 'b'])->isValid());
28+
29+
// Test in array, values are arrays. IE: ['a', 'b'] subset [['a', 'b', 'c']
30+
$rule = (new Subset(['a', 'b', 'c']));
31+
32+
$this->assertTrue($rule->validate(new \ArrayObject(['a', 'b']))->isValid());
33+
}
34+
35+
public function testValidateEmpty()
36+
{
37+
$rule = (new Subset(range(10, 20, 1)))
38+
->skipOnEmpty(false);
39+
40+
$this->assertTrue($rule->validate([])->isValid());
41+
}
42+
43+
public function testName(): void
44+
{
45+
$this->assertEquals('subset', (new Subset(range(1, 10)))->getName());
46+
}
47+
}

0 commit comments

Comments
 (0)