Skip to content

Commit 93c108b

Browse files
committed
Add units
1 parent 81fb3df commit 93c108b

File tree

6 files changed

+541
-1
lines changed

6 files changed

+541
-1
lines changed

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
._*
2+
.DS_Store
3+
.sass-cache
4+
composer.lock
5+
vendor

README.md

Lines changed: 217 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,218 @@
1+
Here's an improved version of your markdown guide for your PHP testing library:
2+
13
# Unitary
2-
PHP Unitary is a light weight PHP testing library.
4+
**PHP Unitary** is a lightweight PHP testing library.
5+
6+
## Example
7+
8+
### 1. Create a Test File
9+
Start by creating a test file with a name that starts with "unitary-", e.g., "unitary-lib-name.php".
10+
```php
11+
<?php
12+
// If you add the argument "true" to the Unit class, it will run in quiet mode
13+
// and only report if it finds any errors.
14+
$unit = new MaplePHP\Unitary\Unit(true);
15+
16+
// Add a title to your tests (optional)
17+
$unit->addTitle("Testing MaplePHP Unitary library!");
18+
19+
$unit->add("Checking data type", function($inst) {
20+
21+
$inst->add("Lorem ipsum dolor", [
22+
"string" => [],
23+
"length" => [1, 200]
24+
25+
])->add(92928, [
26+
"int" => []
27+
28+
])->add("Lorem", [
29+
"string" => [],
30+
"length" => function($valid) {
31+
return $valid->length(1, 50);
32+
}
33+
], "The length is not correct!");
34+
35+
});
36+
37+
$unit->execute();
38+
```
39+
The example above uses either built-in validation or custom validation (see below for all built-in validation options).
40+
41+
You can create as many test files as you want, then move on to step 2.
42+
43+
### 2. Create a Bash File
44+
Create an executable bash file. You can name it whatever you like; in this example, it's named "test.php".
45+
```php
46+
#!/usr/bin/env php
47+
<?php
48+
require_once("vendor/autoload.php");
49+
$unit = new MaplePHP\Unitary\Unit();
50+
$unit->executeAll("path/to/directory/");
51+
```
52+
53+
#### Run the Tests
54+
1. Open your terminal.
55+
2. Navigate to the "test.php" file.
56+
3. Execute the command below to run all tests.
57+
```
58+
php test.php
59+
```
60+
61+
The script will recursively find all test files named "unitary-*.php" in the directory "path/to/directory/" and run all the tests.
62+
63+
64+
## Validation List
65+
66+
Each prompt can have validation rules and custom error messages. Validation can be defined using built-in rules (e.g., length, email) or custom functions. Errors can be specified as static messages or dynamic functions based on the error type.
67+
68+
1. **required**
69+
- **Description**: Checks if the value is not empty (e.g., not `""`, `0`, `NULL`).
70+
- **Usage**: `"required" => []`
71+
72+
2. **length**
73+
- **Description**: Checks if the string length is between a specified start and end length.
74+
- **Usage**: `"length" => [1, 200]`
75+
76+
3. **email**
77+
- **Description**: Validates email addresses.
78+
- **Usage**: `"email" => []`
79+
80+
4. **number**
81+
- **Description**: Checks if the value is numeric.
82+
- **Usage**: `"number" => []`
83+
84+
5. **min**
85+
- **Description**: Checks if the value is greater than or equal to a specified minimum.
86+
- **Usage**: `"min" => [10]`
87+
88+
6. **max**
89+
- **Description**: Checks if the value is less than or equal to a specified maximum.
90+
- **Usage**: `"max" => [100]`
91+
92+
7. **url**
93+
- **Description**: Checks if the value is a valid URL (http|https is required).
94+
- **Usage**: `"url" => []`
95+
96+
8. **phone**
97+
- **Description**: Validates phone numbers.
98+
- **Usage**: `"phone" => []`
99+
100+
9. **date**
101+
- **Description**: Checks if the value is a valid date with the specified format.
102+
- **Usage**: `"date" => ["Y-m-d"]`
103+
104+
10. **dateTime**
105+
- **Description**: Checks if the value is a valid date and time with the specified format.
106+
- **Usage**: `"dateTime" => ["Y-m-d H:i"]`
107+
108+
11. **bool**
109+
- **Description**: Checks if the value is a boolean.
110+
- **Usage**: `"bool" => []`
111+
112+
12. **oneOf**
113+
- **Description**: Validates if one of the provided conditions is met.
114+
- **Usage**: `"oneOf" => [["length", [1, 200]], "email"]`
115+
116+
13. **allOf**
117+
- **Description**: Validates if all of the provided conditions are met.
118+
- **Usage**: `"allOf" => [["length", [1, 200]], "email"]`
119+
120+
14. **float**
121+
- **Description**: Checks if the value is a float.
122+
- **Usage**: `"float" => []`
123+
124+
15. **int**
125+
- **Description**: Checks if the value is an integer.
126+
- **Usage**: `"int" => []`
127+
128+
16. **positive**
129+
- **Description**: Checks if the value is a positive number.
130+
- **Usage**: `"positive" => []`
131+
132+
17. **negative**
133+
- **Description**: Checks if the value is a negative number.
134+
- **Usage**: `"negative" => []`
135+
136+
18. **validVersion**
137+
- **Description**: Checks if the value is a valid version number.
138+
- **Usage**: `"validVersion" => [true]`
139+
140+
19. **versionCompare**
141+
- **Description**: Validates and compares if a version is equal/more/equalMore/less... e.g., than withVersion.
142+
- **Usage**: `"versionCompare" => ["1.0.0", ">="]`
143+
144+
20. **zip**
145+
- **Description**: Validates ZIP codes within a specified length range.
146+
- **Usage**: `"zip" => [5, 9]`
147+
148+
21. **hex**
149+
- **Description**: Checks if the value is a valid hex color code.
150+
- **Usage**: `"hex" => []`
151+
152+
22. **age**
153+
- **Description**: Checks if the value represents an age equal to or greater than the specified minimum.
154+
- **Usage**: `"age" => [18]`
155+
156+
23. **domain**
157+
- **Description**: Checks if the value is a valid domain.
158+
- **Usage**: `"domain" => [true]`
159+
160+
24. **dns**
161+
- **Description**: Checks if the host/domain has a valid DNS record (A, AAAA, MX).
162+
- **Usage**: `"dns" => []`
163+
164+
25. **matchDNS**
165+
- **Description**: Matches DNS records by searching for a specific type and value.
166+
- **Usage**: `"matchDNS" => [DNS_A]`
167+
168+
26. **equal**
169+
- **Description**: Checks if the value is equal to a specified value.
170+
- **Usage**: `"equal" => ["someValue"]`
171+
172+
27. **notEqual**
173+
- **Description**: Checks if the value is not equal to a specified value.
174+
- **Usage**: `"notEqual" => ["someValue"]`
175+
176+
28. **string**
177+
- **Description**: Checks if the value is a string.
178+
- **Usage**: `"string" => []`
179+
180+
29. **equalLength**
181+
- **Description**: Checks if the string length is equal to a specified length.
182+
- **Usage**: `"equalLength" => [10]`
183+
184+
30. **lossyPassword**
185+
- **Description**: Validates password with allowed characters `[a-zA-Z\d$@$!%*?&]` and a minimum length.
186+
- **Usage**: `"lossyPassword" => [8]`
187+
188+
31. **strictPassword**
189+
- **Description**: Validates strict password with specific character requirements and a minimum length.
190+
- **Usage**: `"strictPassword" => [8]`
191+
192+
32. **pregMatch**
193+
- **Description**: Validates if the value matches a given regular expression pattern.
194+
- **Usage**: `"pregMatch" => ["a-zA-Z"]`
195+
196+
33. **atoZ**
197+
- **Description**: Checks if the value consists of characters between `a-z` or `A-Z`.
198+
- **Usage**: `"atoZ" => []`
199+
200+
34. **lowerAtoZ**
201+
- **Description**: Checks if the value consists of lowercase characters between `a-z`.
202+
- **Usage**: `"lowerAtoZ" => []`
203+
204+
35. **upperAtoZ**
205+
- **Description**: Checks if the value consists of uppercase characters between `A-Z`.
206+
- **Usage**: `"upperAtoZ" => []`
207+
208+
36. **isArray**
209+
- **Description**: Checks if the value is an array.
210+
- **Usage**: `"isArray" => []`
211+
212+
37. **isObject**
213+
- **Description**: Checks if the value is an object.
214+
- **Usage**: `"isObject" => []`
215+
216+
38. **boolVal**
217+
- **Description**: Checks if the value is a boolean-like value (e.g., "on", "yes", "1", "true").
218+
- **Usage**: `"boolVal" => []`

Test.php

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace MaplePHP\Unitary;
5+
6+
use MaplePHP\DTO\Format\Str;
7+
use MaplePHP\Validate\Inp;
8+
use InvalidArgumentException;
9+
10+
class Test
11+
{
12+
private array $test = [];
13+
14+
/**
15+
* Add a test
16+
* @param mixed $value
17+
* @param array $validation
18+
* @param string|null $message
19+
* @return $this
20+
*/
21+
public function add(mixed $value, array $validation, ?string $message = null): self
22+
{
23+
foreach($validation as $method => $args) {
24+
if(is_callable($args)) {
25+
$bool = $args($this->valid($value), $value);
26+
if(!is_bool($bool)) {
27+
throw new InvalidArgumentException("A callable validation must return a boolean!");
28+
}
29+
} else {
30+
if(!method_exists(Inp::class, $method)) {
31+
throw new InvalidArgumentException("The validation {$method} does not exist!");
32+
}
33+
34+
if(!is_array($args)) {
35+
$args = [];
36+
}
37+
$bool = $this->valid($value)->{$method}(...$args);
38+
}
39+
40+
$readableValue = $this->getReadableValue($value);
41+
$message = (is_string($message)) ? $message : "Validation-error: %s";
42+
$this->test[] = [
43+
"method" => $method,
44+
"args" => $args,
45+
"test" => $bool,
46+
"message" => sprintf($message, $method),
47+
"readableValue" => $readableValue,
48+
];
49+
}
50+
51+
return $this;
52+
}
53+
54+
/**
55+
* Will return the test results as an array
56+
* @return array
57+
*/
58+
public function getTestResult(): array
59+
{
60+
return $this->test;
61+
}
62+
63+
/**
64+
* Init MaplePHP validation
65+
* @param mixed $value
66+
* @return Inp
67+
*/
68+
protected function valid(mixed $value): Inp {
69+
return new Inp($value);
70+
}
71+
72+
/**
73+
* Used to get a readable value
74+
* @param mixed $value
75+
* @return string
76+
*/
77+
protected function getReadableValue(mixed $value): string {
78+
if (is_bool($value)) {
79+
return "(bool): " . ($value ? "true" : "false");
80+
}
81+
if (is_int($value)) {
82+
return "(int): " . $this->excerpt((string)$value);
83+
}
84+
if (is_float($value)) {
85+
return "(float): " . $this->excerpt((string)$value);
86+
}
87+
if (is_string($value)) {
88+
return "(string): " . $this->excerpt($value);
89+
}
90+
if (is_array($value)) {
91+
return "(array): " . $this->excerpt(json_encode($value));
92+
}
93+
if (is_object($value)) {
94+
return "(object): " . $this->excerpt(get_class($value));
95+
}
96+
if (is_null($value)) {
97+
return "(null)";
98+
}
99+
if (is_resource($value)) {
100+
return "(resource): " . $this->excerpt(get_resource_type($value));
101+
}
102+
103+
return "(unknown type)";
104+
}
105+
106+
/**
107+
* Used to get exception to the readable value
108+
* @param string $value
109+
* @return string
110+
*/
111+
final protected function excerpt(string $value): string
112+
{
113+
$format = new Str($value);
114+
return $format->excerpt(40)->get();
115+
}
116+
}

0 commit comments

Comments
 (0)