Skip to content

Commit b08711a

Browse files
committed
Add validation rule for Start with and end with.
1 parent b2ccf4d commit b08711a

File tree

5 files changed

+259
-0
lines changed

5 files changed

+259
-0
lines changed

src/Rules/EndWith.php

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Webhkp\Pvalidate\Rules;
6+
7+
use Attribute;
8+
9+
#[Attribute(Attribute::TARGET_PROPERTY)]
10+
class EndWith extends ValidationRule {
11+
public function __construct(
12+
readonly private ?string $checkStr = null,
13+
readonly private ?bool $ignoreCase = false,
14+
) {
15+
16+
}
17+
18+
public function isValid(): bool {
19+
if (!$this->checkStr) {
20+
return true;
21+
}
22+
23+
if ($this->ignoreCase) {
24+
return str_ends_with(strtolower($this->value), strtolower($this->checkStr));
25+
}
26+
27+
return str_ends_with($this->value, $this->checkStr);
28+
}
29+
30+
public function getErrors(): array {
31+
$errors = [];
32+
33+
if (!$this->isValid()) {
34+
$errors['endWith'] = "({$this->value}) does not end with ({$this->checkStr})";
35+
}
36+
37+
return $errors;
38+
}
39+
}

src/Rules/StartWith.php

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Webhkp\Pvalidate\Rules;
6+
7+
use Attribute;
8+
9+
#[Attribute(Attribute::TARGET_PROPERTY)]
10+
class StartWith extends ValidationRule {
11+
public function __construct(
12+
readonly private ?string $checkStr = null,
13+
readonly private ?bool $ignoreCase = false,
14+
) {
15+
16+
}
17+
18+
public function isValid(): bool {
19+
if (!$this->checkStr) {
20+
return true;
21+
}
22+
23+
if ($this->ignoreCase) {
24+
return str_starts_with(strtolower($this->value), strtolower($this->checkStr));
25+
}
26+
27+
return str_starts_with($this->value, $this->checkStr);
28+
}
29+
30+
public function getErrors(): array {
31+
$errors = [];
32+
33+
if (!$this->isValid()) {
34+
$errors['startWith'] = "({$this->value}) does not start with ({$this->checkStr})";
35+
}
36+
37+
return $errors;
38+
}
39+
}

tests/Feature/StartEndWithTest.php

+95
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
<?php
2+
3+
use Webhkp\Pvalidate\Rules\EndWith;
4+
use Webhkp\Pvalidate\Rules\StartWith;
5+
use Webhkp\Pvalidate\ValidationBuilder;
6+
use Webhkp\Pvalidate\Validator;
7+
8+
beforeEach(function () {
9+
$this->testObj = new class {
10+
public function __construct(
11+
) {
12+
13+
}
14+
15+
#[StartWith('my')]
16+
public string $firstString = 'my first string';
17+
18+
#[StartWith('my')]
19+
public string $secondString = 'My second string';
20+
21+
#[StartWith('MY', true)]
22+
public string $thirdString = 'My third string';
23+
24+
#[EndWith('string')]
25+
public string $fourthString = 'my fourth string';
26+
27+
#[EndWith('STRING')]
28+
public string $fifthString = 'My fifth StrinG';
29+
30+
#[EndWith('string', true)]
31+
public string $sixthString = 'My sixth String';
32+
33+
#[StartWith('MY')]
34+
#[EndWith('string')]
35+
public string $seventhString = 'My seventh String';
36+
37+
#[StartWith('MY', true)]
38+
#[EndWith('STRING', true)]
39+
public string $eighthString = 'My eighth String';
40+
};
41+
});
42+
43+
describe("Start with Validation", function () {
44+
describe("Object attribute validation", function () {
45+
it('Should be valid', function () {
46+
$this->testObj->firstString = "my test string";
47+
$this->testObj->secondString = "my test string";
48+
$this->testObj->thirdString = "MY TEST string";
49+
$this->testObj->fourthString = "my test string";
50+
$this->testObj->fifthString = "my test STRING";
51+
$this->testObj->sixthString = "my test STRING";
52+
$this->testObj->seventhString = "MY test string";
53+
$this->testObj->eighthString = "my test STRING";
54+
55+
$validationResponse = Validator::validate($this->testObj);
56+
57+
expect($validationResponse->isValid())->toBeTrue();
58+
expect($validationResponse->getErrors())->toBeEmpty();
59+
});
60+
61+
it('Should return errors', function () {
62+
$validationResponse = Validator::validate($this->testObj);
63+
64+
expect($validationResponse->isValid())->toBeFalse();
65+
expect($validationResponse->getErrors())->toHaveKeys(['secondString', 'fifthString', 'seventhString']);
66+
});
67+
});
68+
69+
describe("Validation builder parsing", function () {
70+
it('Should return error for startwith violation', function () {
71+
$validation = ValidationBuilder::startWith("wrong wrong")->safeParse('quick brown fox jumps over the lazy dog');
72+
73+
expect($validation->isValid())->toBeFalse();
74+
expect($validation->getErrors())->toHaveKeys(['startWith.errors.startWith']);
75+
});
76+
77+
it('Should return error for endWtith violation', function () {
78+
$validation = ValidationBuilder::endWith('wrong')->safeParse('quick brown fox jumps over the lazy dog');
79+
80+
expect($validation->isValid())->toBeFalse();
81+
expect($validation->getErrors())->toHaveKeys(['endWith.errors.endWith']);
82+
});
83+
84+
it('Should return error for both startWith and endWith violation', function () {
85+
$validation = ValidationBuilder::startWith("wrong")->endWith('Something else');
86+
87+
$validationResult = $validation->safeParse('abc');
88+
89+
expect($validationResult->isValid())->toBeFalse();
90+
expect($validationResult->getErrors())->toHaveKeys(['startWith.errors.startWith', 'endWith.errors.endWith']);
91+
});
92+
});
93+
});
94+
95+

tests/Unit/EndWithRuleTest.php

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
use Webhkp\Pvalidate\Exceptions\PvalidateException;
4+
use Webhkp\Pvalidate\Rules\EndWith;
5+
6+
beforeEach(function () {
7+
$this->rule = new EndWith('dog');
8+
$this->ruleInsensitive = new EndWith('dog', true);
9+
});
10+
11+
describe("End with validation", function () {
12+
it('Should be valid', function () {
13+
$validationResult = $this->rule->safeParse('quick brown fox jumps over the lazy dog');
14+
15+
expect($validationResult->isValid())->toBeTrue();
16+
expect($validationResult->getErrors())->toBeEmpty();
17+
});
18+
19+
it('Should be valid for case insensitive comparison', function () {
20+
$validationResult = $this->ruleInsensitive->safeParse('quick brown fox jumps over the lazy Dog');
21+
22+
expect($validationResult->isValid())->toBeTrue();
23+
expect($validationResult->getErrors())->toBeEmpty();
24+
});
25+
26+
it('Should return \'endWith\' error on safeParse', function () {
27+
$validationResult = $this->rule->safeParse('quick brown fox jumps over the lazy dog, blah blah');
28+
29+
expect($validationResult->isValid())->toBeFalse();
30+
expect($validationResult->getErrors())->toHaveKey('endWith');
31+
});
32+
33+
it('Should return \'endWith\' error on safeParse for case insensitve comparison', function () {
34+
$validationResult = $this->ruleInsensitive->safeParse('quick brown fox jumps over the lazy dog, , blah blah');
35+
36+
expect($validationResult->isValid())->toBeFalse();
37+
expect($validationResult->getErrors())->toHaveKey('endWith');
38+
});
39+
40+
it('Should throw exception on parse', function () {
41+
$this->rule->parse('jumps over');
42+
})->throws(PvalidateException::class);
43+
});

tests/Unit/StartWithRuleTest.php

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
use Webhkp\Pvalidate\Exceptions\PvalidateException;
4+
use Webhkp\Pvalidate\Rules\StartWith;
5+
6+
beforeEach(function () {
7+
$this->rule = new StartWith('quick');
8+
$this->ruleInsensitive = new StartWith('quick', true);
9+
});
10+
11+
describe("Start with validation", function () {
12+
it('Should be valid', function () {
13+
$validationResult = $this->rule->safeParse('quick brown fox jumps over the lazy dog');
14+
15+
expect($validationResult->isValid())->toBeTrue();
16+
expect($validationResult->getErrors())->toBeEmpty();
17+
});
18+
19+
it('Should be valid for case insensitive comparison', function () {
20+
$validationResult = $this->ruleInsensitive->safeParse('QuiCK brown fox jumps over the lazy dog');
21+
22+
expect($validationResult->isValid())->toBeTrue();
23+
expect($validationResult->getErrors())->toBeEmpty();
24+
});
25+
26+
it('Should return \'startWith\' error on safeParse', function () {
27+
$validationResult = $this->rule->safeParse('blah blah, quick brown fox jumps over the lazy dog');
28+
29+
expect($validationResult->isValid())->toBeFalse();
30+
expect($validationResult->getErrors())->toHaveKey('startWith');
31+
});
32+
33+
it('Should return \'startWith\' error on safeParse for case insensitve comparison', function () {
34+
$validationResult = $this->ruleInsensitive->safeParse('blah blah, quick brown fox jumps over the lazy dog');
35+
36+
expect($validationResult->isValid())->toBeFalse();
37+
expect($validationResult->getErrors())->toHaveKey('startWith');
38+
});
39+
40+
it('Should throw exception on parse', function () {
41+
$this->rule->parse('jumps over the lazy dog');
42+
})->throws(PvalidateException::class);
43+
});

0 commit comments

Comments
 (0)