Skip to content

Commit 9e96b35

Browse files
moxixi527moxi
andauthored
feat: support boolean (#7)
Co-authored-by: moxi <hufengyun@kkguan.com>
1 parent 7e1dfe5 commit 9e96b35

2 files changed

Lines changed: 233 additions & 1 deletion

File tree

src/ValidationRuleset.php

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ class ValidationRuleset
4747
'integer' => 100,
4848
'string' => 100,
4949
'array' => 100,
50+
'boolean' => 100,
5051
'min' => 10,
5152
'max' => 10,
5253
'in' => 10,
@@ -75,7 +76,13 @@ class ValidationRuleset
7576
'integer',
7677
'numeric',
7778
'string',
78-
'array'
79+
'array',
80+
'boolean'
81+
];
82+
83+
protected static array $stringToBoolMap = [
84+
'1' => true, '0' => false,
85+
'true' => true, 'false' => false,
7986
];
8087

8188
/** @var int base flags */
@@ -184,6 +191,15 @@ protected function __construct(array $ruleMap)
184191
case 'ipv6':
185192
$rules[] = ValidationRule::make($rule, static::getClosure('validate' . strtoupper($rule)));
186193
break;
194+
case 'boolean':
195+
if (count($ruleArgs) === 0) {
196+
$rules[] = ValidationRule::make('boolean', static::getClosure('validateBoolean'));
197+
} elseif (count($ruleArgs) === 1 && $ruleArgs[0] === 'strict') {
198+
$rules[] = ValidationRule::make('boolean:strict', static::getClosure('validateBooleanStrict'));
199+
} else {
200+
throw new InvalidArgumentException("Rule 'boolean' only supports 'strict' parameter");
201+
}
202+
break;
187203
case 'bail':
188204
/* compatibility */
189205
break;
@@ -561,4 +577,23 @@ public static function validateIPV6(string $value, array $attributes): bool
561577
{
562578
return filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== false;
563579
}
580+
581+
protected static function validateBoolean(mixed $value, array $attributes): bool
582+
{
583+
return match (true) {
584+
is_bool($value), $value === 1, $value === 0 => true,
585+
is_string($value) => isset(static::$stringToBoolMap[strtolower($value)]),
586+
default => false,
587+
};
588+
}
589+
590+
protected static function validateBooleanStrict(mixed $value, array $attributes): bool
591+
{
592+
return is_bool($value);
593+
}
594+
595+
protected static function validateRequiredBoolean(bool $value, array $attributes): bool
596+
{
597+
return true;
598+
}
564599
}

tests/HyperfValidatorTest.php

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,203 @@ public function testValidatedAndErrors()
125125
$this->assertEquals($errors, $errors2);
126126
}
127127

128+
public function testBoolean()
129+
{
130+
// 测试普通 boolean 验证 - 应该通过的值
131+
$validator = $this->makeValidator(['flag' => true], ['flag' => 'boolean']);
132+
$this->assertFalse($validator->fails());
133+
134+
$validator = $this->makeValidator(['flag' => false], ['flag' => 'boolean']);
135+
$this->assertFalse($validator->fails());
136+
137+
$validator = $this->makeValidator(['flag' => 1], ['flag' => 'boolean']);
138+
$this->assertFalse($validator->fails());
139+
140+
$validator = $this->makeValidator(['flag' => 0], ['flag' => 'boolean']);
141+
$this->assertFalse($validator->fails());
142+
143+
$validator = $this->makeValidator(['flag' => '1'], ['flag' => 'boolean']);
144+
$this->assertFalse($validator->fails());
145+
146+
$validator = $this->makeValidator(['flag' => '0'], ['flag' => 'boolean']);
147+
$this->assertFalse($validator->fails());
148+
149+
$validator = $this->makeValidator(['flag' => 'true'], ['flag' => 'boolean']);
150+
$this->assertFalse($validator->fails());
151+
152+
$validator = $this->makeValidator(['flag' => 'false'], ['flag' => 'boolean']);
153+
$this->assertFalse($validator->fails());
154+
155+
$validator = $this->makeValidator(['flag' => 'TRUE'], ['flag' => 'boolean']);
156+
$this->assertFalse($validator->fails());
157+
158+
$validator = $this->makeValidator(['flag' => 'FALSE'], ['flag' => 'boolean']);
159+
$this->assertFalse($validator->fails());
160+
161+
// 测试普通 boolean 验证 - 应该失败的值
162+
$validator = $this->makeValidator(['flag' => 'yes'], ['flag' => 'boolean']);
163+
$this->assertTrue($validator->fails());
164+
165+
$validator = $this->makeValidator(['flag' => 'no'], ['flag' => 'boolean']);
166+
$this->assertTrue($validator->fails());
167+
168+
$validator = $this->makeValidator(['flag' => '2'], ['flag' => 'boolean']);
169+
$this->assertTrue($validator->fails());
170+
171+
$validator = $this->makeValidator(['flag' => 2], ['flag' => 'boolean']);
172+
$this->assertTrue($validator->fails());
173+
174+
$validator = $this->makeValidator(['flag' => []], ['flag' => 'boolean']);
175+
$this->assertTrue($validator->fails());
176+
177+
$validator = $this->makeValidator(['flag' => 'invalid'], ['flag' => 'boolean']);
178+
$this->assertTrue($validator->fails());
179+
}
180+
181+
public function testBooleanStrict()
182+
{
183+
// 测试严格 boolean 验证 - 应该通过的值
184+
$validator = $this->makeValidator(['flag' => true], ['flag' => 'boolean:strict']);
185+
$this->assertFalse($validator->fails());
186+
187+
$validator = $this->makeValidator(['flag' => false], ['flag' => 'boolean:strict']);
188+
$this->assertFalse($validator->fails());
189+
190+
// 测试严格 boolean 验证 - 应该失败的值
191+
$validator = $this->makeValidator(['flag' => 1], ['flag' => 'boolean:strict']);
192+
$this->assertTrue($validator->fails());
193+
194+
$validator = $this->makeValidator(['flag' => 0], ['flag' => 'boolean:strict']);
195+
$this->assertTrue($validator->fails());
196+
197+
$validator = $this->makeValidator(['flag' => '1'], ['flag' => 'boolean:strict']);
198+
$this->assertTrue($validator->fails());
199+
200+
$validator = $this->makeValidator(['flag' => '0'], ['flag' => 'boolean:strict']);
201+
$this->assertTrue($validator->fails());
202+
203+
$validator = $this->makeValidator(['flag' => 'true'], ['flag' => 'boolean:strict']);
204+
$this->assertTrue($validator->fails());
205+
206+
$validator = $this->makeValidator(['flag' => 'false'], ['flag' => 'boolean:strict']);
207+
$this->assertTrue($validator->fails());
208+
}
209+
210+
public function testRequiredBoolean()
211+
{
212+
// 测试 required boolean 组合 - 应该通过的值
213+
$validator = $this->makeValidator(['flag' => true], ['flag' => 'required|boolean']);
214+
$this->assertFalse($validator->fails());
215+
216+
$validator = $this->makeValidator(['flag' => false], ['flag' => 'required|boolean']);
217+
$this->assertFalse($validator->fails());
218+
219+
$validator = $this->makeValidator(['flag' => 1], ['flag' => 'required|boolean']);
220+
$this->assertFalse($validator->fails());
221+
222+
$validator = $this->makeValidator(['flag' => 0], ['flag' => 'required|boolean']);
223+
$this->assertFalse($validator->fails());
224+
225+
$validator = $this->makeValidator(['flag' => '1'], ['flag' => 'required|boolean']);
226+
$this->assertFalse($validator->fails());
227+
228+
$validator = $this->makeValidator(['flag' => '0'], ['flag' => 'required|boolean']);
229+
$this->assertFalse($validator->fails());
230+
231+
// 测试 required boolean 组合 - 应该失败的值
232+
$validator = $this->makeValidator([], ['flag' => 'required|boolean']);
233+
$this->assertTrue($validator->fails());
234+
235+
$validator = $this->makeValidator(['flag' => null], ['flag' => 'required|boolean']);
236+
$this->assertTrue($validator->fails());
237+
238+
$validator = $this->makeValidator(['flag' => ''], ['flag' => 'required|boolean']);
239+
$this->assertTrue($validator->fails());
240+
241+
$validator = $this->makeValidator(['flag' => 'invalid'], ['flag' => 'required|boolean']);
242+
$this->assertTrue($validator->fails());
243+
}
244+
245+
public function testRequiredBooleanStrict()
246+
{
247+
// 测试 required boolean:strict 组合 - 应该通过的值
248+
$validator = $this->makeValidator(['flag' => true], ['flag' => 'required|boolean:strict']);
249+
$this->assertFalse($validator->fails());
250+
251+
$validator = $this->makeValidator(['flag' => false], ['flag' => 'required|boolean:strict']);
252+
$this->assertFalse($validator->fails());
253+
254+
// 测试 required boolean:strict 组合 - 应该失败的值
255+
$validator = $this->makeValidator([], ['flag' => 'required|boolean:strict']);
256+
$this->assertTrue($validator->fails());
257+
258+
$validator = $this->makeValidator(['flag' => null], ['flag' => 'required|boolean:strict']);
259+
$this->assertTrue($validator->fails());
260+
261+
$validator = $this->makeValidator(['flag' => 1], ['flag' => 'required|boolean:strict']);
262+
$this->assertTrue($validator->fails());
263+
264+
$validator = $this->makeValidator(['flag' => 0], ['flag' => 'required|boolean:strict']);
265+
$this->assertTrue($validator->fails());
266+
267+
$validator = $this->makeValidator(['flag' => '1'], ['flag' => 'required|boolean:strict']);
268+
$this->assertTrue($validator->fails());
269+
270+
$validator = $this->makeValidator(['flag' => 'true'], ['flag' => 'required|boolean:strict']);
271+
$this->assertTrue($validator->fails());
272+
}
273+
274+
public function testNullableBoolean()
275+
{
276+
// 测试 nullable boolean 组合 - null 值应该通过
277+
$validator = $this->makeValidator(['flag' => null], ['flag' => 'nullable|boolean']);
278+
$this->assertFalse($validator->fails());
279+
280+
// 测试 nullable boolean 组合 - 有效的 boolean 值应该通过
281+
$validator = $this->makeValidator(['flag' => true], ['flag' => 'nullable|boolean']);
282+
$this->assertFalse($validator->fails());
283+
284+
$validator = $this->makeValidator(['flag' => false], ['flag' => 'nullable|boolean']);
285+
$this->assertFalse($validator->fails());
286+
287+
$validator = $this->makeValidator(['flag' => 1], ['flag' => 'nullable|boolean']);
288+
$this->assertFalse($validator->fails());
289+
290+
$validator = $this->makeValidator(['flag' => '0'], ['flag' => 'nullable|boolean']);
291+
$this->assertFalse($validator->fails());
292+
293+
// 测试 nullable boolean 组合 - 无效值应该失败
294+
$validator = $this->makeValidator(['flag' => 'invalid'], ['flag' => 'nullable|boolean']);
295+
$this->assertTrue($validator->fails());
296+
297+
$validator = $this->makeValidator(['flag' => []], ['flag' => 'nullable|boolean']);
298+
$this->assertTrue($validator->fails());
299+
}
300+
301+
public function testNullableBooleanStrict()
302+
{
303+
// 测试 nullable boolean:strict 组合 - null 值应该通过
304+
$validator = $this->makeValidator(['flag' => null], ['flag' => 'nullable|boolean:strict']);
305+
$this->assertFalse($validator->fails());
306+
307+
// 测试 nullable boolean:strict 组合 - 只有真正的 boolean 值应该通过
308+
$validator = $this->makeValidator(['flag' => true], ['flag' => 'nullable|boolean:strict']);
309+
$this->assertFalse($validator->fails());
310+
311+
$validator = $this->makeValidator(['flag' => false], ['flag' => 'nullable|boolean:strict']);
312+
$this->assertFalse($validator->fails());
313+
314+
// 测试 nullable boolean:strict 组合 - 非严格 boolean 值应该失败
315+
$validator = $this->makeValidator(['flag' => 1], ['flag' => 'nullable|boolean:strict']);
316+
$this->assertTrue($validator->fails());
317+
318+
$validator = $this->makeValidator(['flag' => '1'], ['flag' => 'nullable|boolean:strict']);
319+
$this->assertTrue($validator->fails());
320+
321+
$validator = $this->makeValidator(['flag' => 'true'], ['flag' => 'nullable|boolean:strict']);
322+
$this->assertTrue($validator->fails());
323+
}
324+
128325
protected function makeValidator(array $data, array $rules, array $messages = [], array $customAttributes = [])
129326
{
130327
$factory = new ValidatorFactory($this->getTranslator(), $this->getContainer());

0 commit comments

Comments
 (0)