Code Coverage |
||||||||||||||||
Lines |
Branches |
Paths |
Functions and Methods |
Classes and Traits |
||||||||||||
| Total | |
100.00% |
48 / 48 |
|
100.00% |
23 / 23 |
|
100.00% |
21 / 21 |
|
100.00% |
19 / 19 |
CRAP | |
100.00% |
1 / 1 |
| Shape | |
100.00% |
48 / 48 |
|
100.00% |
23 / 23 |
|
100.00% |
21 / 21 |
|
100.00% |
19 / 19 |
21 | |
100.00% |
1 / 1 |
| __construct | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| list | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| asList | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| extra | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| strict | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| coerce | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| rule | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| rules | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| type | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| message | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| messages | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| types | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| ruleParser | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| prepare | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| add | |
100.00% |
7 / 7 |
|
100.00% |
3 / 3 |
|
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
2 | |||
| review | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| validate | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| parse | |
100.00% |
4 / 4 |
|
100.00% |
3 / 3 |
|
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
2 | |||
| definition | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| 1 | <?php |
| 2 | |
| 3 | declare(strict_types=1); |
| 4 | |
| 5 | namespace Celemas\Sire; |
| 6 | |
| 7 | use Celemas\Sire\Exception\ValidationError; |
| 8 | use Closure; |
| 9 | use Override; |
| 10 | use ValueError; |
| 11 | |
| 12 | /** @api */ |
| 13 | final class Shape implements Contract\Shape |
| 14 | { |
| 15 | private Config $config; |
| 16 | /** @var array<string, Field> */ |
| 17 | private array $fields = []; |
| 18 | /** @var list<Closure(array<array-key, mixed>): array<array-key, mixed>> */ |
| 19 | private array $prepareCallbacks = []; |
| 20 | /** @var list<Closure(Review): void> */ |
| 21 | private array $reviewCallbacks = []; |
| 22 | |
| 23 | public function __construct() |
| 24 | { |
| 25 | $this->config = new Config(); |
| 26 | } |
| 27 | |
| 28 | public static function list(): self |
| 29 | { |
| 30 | return new self()->asList(); |
| 31 | } |
| 32 | |
| 33 | public function asList(bool $list = true): self |
| 34 | { |
| 35 | $this->config->asList($list); |
| 36 | |
| 37 | return $this; |
| 38 | } |
| 39 | |
| 40 | public function extra(Extra|string $extra): self |
| 41 | { |
| 42 | $this->config->extra($extra); |
| 43 | |
| 44 | return $this; |
| 45 | } |
| 46 | |
| 47 | public function strict(): self |
| 48 | { |
| 49 | $this->config->coercionMode(CoercionMode::Strict); |
| 50 | |
| 51 | return $this; |
| 52 | } |
| 53 | |
| 54 | public function coerce(): self |
| 55 | { |
| 56 | $this->config->coercionMode(CoercionMode::Coerce); |
| 57 | |
| 58 | return $this; |
| 59 | } |
| 60 | |
| 61 | public function rule(string $name, Contract\Rule $rule): self |
| 62 | { |
| 63 | $this->config->rule($name, $rule); |
| 64 | |
| 65 | return $this; |
| 66 | } |
| 67 | |
| 68 | public function rules(Contract\RuleRegistry $registry): self |
| 69 | { |
| 70 | $this->config->rules($registry); |
| 71 | |
| 72 | return $this; |
| 73 | } |
| 74 | |
| 75 | public function type(string $name, Contract\Coercer $coercer): self |
| 76 | { |
| 77 | $this->config->coercer($name, $coercer); |
| 78 | |
| 79 | return $this; |
| 80 | } |
| 81 | |
| 82 | public function message(string $key, string $message): self |
| 83 | { |
| 84 | $this->config->message($key, $message); |
| 85 | |
| 86 | return $this; |
| 87 | } |
| 88 | |
| 89 | /** @param array<string, string> $messages */ |
| 90 | public function messages(array $messages): self |
| 91 | { |
| 92 | $this->config->messages($messages); |
| 93 | |
| 94 | return $this; |
| 95 | } |
| 96 | |
| 97 | public function types(Contract\CoercerRegistry $registry): self |
| 98 | { |
| 99 | $this->config->coercers($registry); |
| 100 | |
| 101 | return $this; |
| 102 | } |
| 103 | |
| 104 | public function ruleParser(Contract\RuleParser $parser): self |
| 105 | { |
| 106 | $this->config->ruleParser($parser); |
| 107 | |
| 108 | return $this; |
| 109 | } |
| 110 | |
| 111 | /** @param Closure(array<array-key, mixed>): array<array-key, mixed> $callback */ |
| 112 | public function prepare(Closure $callback): self |
| 113 | { |
| 114 | $this->prepareCallbacks[] = $callback; |
| 115 | |
| 116 | return $this; |
| 117 | } |
| 118 | |
| 119 | public function add( |
| 120 | string $field, |
| 121 | string|Contract\Validator $type, |
| 122 | ): Field { |
| 123 | if (!$field) { |
| 124 | throw new ValueError( |
| 125 | 'Shape definition error: field must not be empty', |
| 126 | ); |
| 127 | } |
| 128 | |
| 129 | $definition = new Field($field, $type); |
| 130 | $this->fields[$field] = $definition; |
| 131 | |
| 132 | return $definition; |
| 133 | } |
| 134 | |
| 135 | /** @param Closure(Review): void $callback */ |
| 136 | public function review(Closure $callback): self |
| 137 | { |
| 138 | $this->reviewCallbacks[] = $callback; |
| 139 | |
| 140 | return $this; |
| 141 | } |
| 142 | |
| 143 | #[Override] |
| 144 | public function validate(array $data): Result |
| 145 | { |
| 146 | return new ValidationRun( |
| 147 | $this->definition(), |
| 148 | $data, |
| 149 | )->validate(); |
| 150 | } |
| 151 | |
| 152 | /** |
| 153 | * @return array<array-key, mixed> |
| 154 | * @throws ValidationError |
| 155 | */ |
| 156 | #[Override] |
| 157 | public function parse(array $data): array |
| 158 | { |
| 159 | $result = $this->validate($data); |
| 160 | |
| 161 | if (!$result->valid()) { |
| 162 | throw new ValidationError($result); |
| 163 | } |
| 164 | |
| 165 | return $result->values(); |
| 166 | } |
| 167 | |
| 168 | private function definition(): ShapeDefinition |
| 169 | { |
| 170 | return $this->config->definition( |
| 171 | $this->fields, |
| 172 | $this->prepareCallbacks, |
| 173 | $this->reviewCallbacks, |
| 174 | ); |
| 175 | } |
| 176 | } |
Below are the source code lines that represent each code branch as identified by Xdebug. Please note a branch is not
necessarily coterminous with a line, a line may contain multiple branches and therefore show up more than once.
Please also be aware that some branches may be implicit rather than explicit, e.g. an if statement
always has an else as part of its logical flow even if you didn't write one.
| 25 | $this->config = new Config(); |
| 26 | } |
| 120 | string $field, |
| 121 | string|Contract\Validator $type, |
| 122 | ): Field { |
| 123 | if (!$field) { |
| 124 | throw new ValueError( |
| 125 | 'Shape definition error: field must not be empty', |
| 129 | $definition = new Field($field, $type); |
| 130 | $this->fields[$field] = $definition; |
| 131 | |
| 132 | return $definition; |
| 133 | } |
| 33 | public function asList(bool $list = true): self |
| 34 | { |
| 35 | $this->config->asList($list); |
| 36 | |
| 37 | return $this; |
| 38 | } |
| 56 | $this->config->coercionMode(CoercionMode::Coerce); |
| 57 | |
| 58 | return $this; |
| 59 | } |
| 170 | return $this->config->definition( |
| 171 | $this->fields, |
| 172 | $this->prepareCallbacks, |
| 173 | $this->reviewCallbacks, |
| 174 | ); |
| 175 | } |
| 40 | public function extra(Extra|string $extra): self |
| 41 | { |
| 42 | $this->config->extra($extra); |
| 43 | |
| 44 | return $this; |
| 45 | } |
| 30 | return new self()->asList(); |
| 31 | } |
| 82 | public function message(string $key, string $message): self |
| 83 | { |
| 84 | $this->config->message($key, $message); |
| 85 | |
| 86 | return $this; |
| 87 | } |
| 90 | public function messages(array $messages): self |
| 91 | { |
| 92 | $this->config->messages($messages); |
| 93 | |
| 94 | return $this; |
| 95 | } |
| 157 | public function parse(array $data): array |
| 158 | { |
| 159 | $result = $this->validate($data); |
| 160 | |
| 161 | if (!$result->valid()) { |
| 162 | throw new ValidationError($result); |
| 165 | return $result->values(); |
| 166 | } |
| 112 | public function prepare(Closure $callback): self |
| 113 | { |
| 114 | $this->prepareCallbacks[] = $callback; |
| 115 | |
| 116 | return $this; |
| 117 | } |
| 136 | public function review(Closure $callback): self |
| 137 | { |
| 138 | $this->reviewCallbacks[] = $callback; |
| 139 | |
| 140 | return $this; |
| 141 | } |
| 61 | public function rule(string $name, Contract\Rule $rule): self |
| 62 | { |
| 63 | $this->config->rule($name, $rule); |
| 64 | |
| 65 | return $this; |
| 66 | } |
| 104 | public function ruleParser(Contract\RuleParser $parser): self |
| 105 | { |
| 106 | $this->config->ruleParser($parser); |
| 107 | |
| 108 | return $this; |
| 109 | } |
| 68 | public function rules(Contract\RuleRegistry $registry): self |
| 69 | { |
| 70 | $this->config->rules($registry); |
| 71 | |
| 72 | return $this; |
| 73 | } |
| 49 | $this->config->coercionMode(CoercionMode::Strict); |
| 50 | |
| 51 | return $this; |
| 52 | } |
| 75 | public function type(string $name, Contract\Coercer $coercer): self |
| 76 | { |
| 77 | $this->config->coercer($name, $coercer); |
| 78 | |
| 79 | return $this; |
| 80 | } |
| 97 | public function types(Contract\CoercerRegistry $registry): self |
| 98 | { |
| 99 | $this->config->coercers($registry); |
| 100 | |
| 101 | return $this; |
| 102 | } |
| 144 | public function validate(array $data): Result |
| 145 | { |
| 146 | return new ValidationRun( |
| 147 | $this->definition(), |
| 148 | $data, |
| 149 | )->validate(); |
| 150 | } |