CompositeTest.php$0 ➔ dataOptions()   B
last analyzed

Complexity

Conditions 1

Size

Total Lines 154

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 154
cc 1
rs 8

2 Methods

Rating   Name   Duplication   Size   Complexity  
A CompositeTest.php$0 ➔ getRules() 0 4 1
A CompositeTest.php$0 ➔ getOptions() 0 5 1

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Validator\Tests\Rule;
6
7
use Yiisoft\Validator\Result;
8
use Yiisoft\Validator\Rule\Callback;
9
use Yiisoft\Validator\Rule\Composite;
10
use Yiisoft\Validator\Rule\CompositeHandler;
11
use Yiisoft\Validator\Rule\Equal;
12
use Yiisoft\Validator\Rule\Number;
13
use Yiisoft\Validator\Rule\Required;
14
use Yiisoft\Validator\Tests\Rule\Base\DifferentRuleInHandlerTestTrait;
15
use Yiisoft\Validator\Tests\Rule\Base\RuleTestCase;
16
use Yiisoft\Validator\Tests\Rule\Base\RuleWithOptionsTestTrait;
17
use Yiisoft\Validator\Tests\Rule\Base\RuleWithProvidedRulesTrait;
18
use Yiisoft\Validator\Tests\Rule\Base\SkipOnErrorTestTrait;
19
use Yiisoft\Validator\Tests\Rule\Base\WhenTestTrait;
20
use Yiisoft\Validator\Tests\Support\Rule\CoordinatesRuleSet;
21
use Yiisoft\Validator\Tests\Support\Rule\RuleWithoutOptions;
22
23
final class CompositeTest extends RuleTestCase
24
{
25
    use DifferentRuleInHandlerTestTrait;
26
    use RuleWithOptionsTestTrait;
27
    use RuleWithProvidedRulesTrait;
28
    use SkipOnErrorTestTrait;
29
    use WhenTestTrait;
30
31
    public function testGetName(): void
32
    {
33
        $rule = new Composite([]);
34
        $this->assertSame(Composite::class, $rule->getName());
35
    }
36
37
    public function dataOptions(): array
38
    {
39
        return [
40
            [
41
                new Composite([
42
                    new Number(max: 13, pattern: '/1/'),
43
                    new Number(max: 14, pattern: '/2/'),
44
                ]),
45
                [
46
                    'skipOnEmpty' => false,
47
                    'skipOnError' => false,
48
                    'rules' => [
49
                        [
50
                            Number::class,
51
                            'min' => null,
52
                            'max' => 13,
53
                            'incorrectInputMessage' => [
54
                                'template' => 'The allowed types are integer, float and string.',
55
                                'parameters' => [],
56
                            ],
57
                            'notNumberMessage' => [
58
                                'template' => 'Value must be a number.',
59
                                'parameters' => [],
60
                            ],
61
                            'lessThanMinMessage' => [
62
                                'template' => 'Value must be no less than {min}.',
63
                                'parameters' => ['min' => null],
64
                            ],
65
                            'greaterThanMaxMessage' => [
66
                                'template' => 'Value must be no greater than {max}.',
67
                                'parameters' => ['max' => 13],
68
                            ],
69
                            'skipOnEmpty' => false,
70
                            'skipOnError' => false,
71
                            'pattern' => '/1/',
72
                        ],
73
                        [
74
                            Number::class,
75
                            'min' => null,
76
                            'max' => 14,
77
                            'incorrectInputMessage' => [
78
                                'template' => 'The allowed types are integer, float and string.',
79
                                'parameters' => [],
80
                            ],
81
                            'notNumberMessage' => [
82
                                'template' => 'Value must be a number.',
83
                                'parameters' => [],
84
                            ],
85
                            'lessThanMinMessage' => [
86
                                'template' => 'Value must be no less than {min}.',
87
                                'parameters' => ['min' => null],
88
                            ],
89
                            'greaterThanMaxMessage' => [
90
                                'template' => 'Value must be no greater than {max}.',
91
                                'parameters' => ['max' => 14],
92
                            ],
93
                            'skipOnEmpty' => false,
94
                            'skipOnError' => false,
95
                            'pattern' => '/2/',
96
                        ],
97
                    ],
98
                ],
99
            ],
100
            'rule without options' => [
101
                new Composite([
102
                    new Number(max: 13, pattern: '/1/'),
103
                    new RuleWithoutOptions(),
104
                ]),
105
                [
106
                    'skipOnEmpty' => false,
107
                    'skipOnError' => false,
108
                    'rules' => [
109
                        [
110
                            Number::class,
111
                            'min' => null,
112
                            'max' => 13,
113
                            'incorrectInputMessage' => [
114
                                'template' => 'The allowed types are integer, float and string.',
115
                                'parameters' => [],
116
                            ],
117
                            'notNumberMessage' => [
118
                                'template' => 'Value must be a number.',
119
                                'parameters' => [],
120
                            ],
121
                            'lessThanMinMessage' => [
122
                                'template' => 'Value must be no less than {min}.',
123
                                'parameters' => [
124
                                    'min' => null,
125
                                ],
126
                            ],
127
                            'greaterThanMaxMessage' => [
128
                                'template' => 'Value must be no greater than {max}.',
129
                                'parameters' => [
130
                                    'max' => 13,
131
                                ],
132
                            ],
133
                            'skipOnEmpty' => false,
134
                            'skipOnError' => false,
135
                            'pattern' => '/1/',
136
                        ],
137
                        [
138
                            RuleWithoutOptions::class,
139
                        ],
140
                    ],
141
                ],
142
            ],
143
            'callable' => [
144
                new Composite([
145
                    static fn () => (new Result())->addError('Bad value.'),
146
                ]),
147
                [
148
                    'skipOnEmpty' => false,
149
                    'skipOnError' => false,
150
                    'rules' => [
151
                        [
152
                            Callback::class,
153
                            'method' => null,
154
                            'skipOnEmpty' => false,
155
                            'skipOnError' => false,
156
                        ],
157
                    ],
158
                ],
159
            ],
160
            'inheritance' => [
161
                new class () extends Composite {
162
                    public function getRules(): iterable
163
                    {
164
                        return [
165
                            new Required(),
166
                        ];
167
                    }
168
169
                    public function getOptions(): array
170
                    {
171
                        return [
172
                            'specific-key' => 42,
173
                            'rules' => $this->dumpRulesAsArray(),
174
                        ];
175
                    }
176
                },
177
                [
178
                    'specific-key' => 42,
179
                    'rules' => [
180
                        [
181
                            Required::class,
182
                            'message' => [
183
                                'template' => 'Value cannot be blank.',
184
                                'parameters' => [],
185
                            ],
186
                            'notPassedMessage' => [
187
                                'template' => 'Value not passed.',
188
                                'parameters' => [],
189
                            ],
190
                            'skipOnError' => false,
191
                        ],
192
                    ],
193
                ],
194
            ],
195
        ];
196
    }
197
198
    public function testGetOptionsWithNotRule(): void
199
    {
200
        $this->testGetOptionsWithNotRuleInternal(Composite::class);
201
    }
202
203
    public function dataValidationPassed(): array
204
    {
205
        return [
206
            [
207
                20,
208
                [
209
                    new Composite(
210
                        [
211
                            new Number(max: 13),
212
                            new Number(max: 14),
213
                        ],
214
                        when: fn () => false,
215
                    ),
216
                ],
217
            ],
218
            'override constructor' => [
219
                20,
220
                [
221
                    new class () extends Composite {
222
                        public function __construct()
223
                        {
224
                        }
225
                    },
226
                ],
227
            ],
228
            [
229
                null,
230
                [
231
                    new Composite(
232
                        [
233
                            new Number(max: 13),
234
                            new Number(max: 14),
235
                        ],
236
                        skipOnEmpty: true,
237
                    ),
238
                ],
239
            ],
240
            'multiple attributes via subclass' => [
241
                ['latitude' => -90, 'longitude' => 180],
242
                [new CoordinatesRuleSet()],
243
            ],
244
        ];
245
    }
246
247
    public function dataValidationFailed(): array
248
    {
249
        return [
250
            'callable' => [
251
                20,
252
                [
253
                    new Composite([
254
                        static fn () => (new Result())->addError('Bad value.'),
255
                        static fn () => (new Result())->addError('Very bad value.'),
256
                    ]),
257
                ],
258
                [
259
                    '' => [
260
                        'Bad value.',
261
                        'Very bad value.',
262
                    ],
263
                ],
264
            ],
265
            'when true' => [
266
                20,
267
                [
268
                    new Composite(
269
                        [new Number(max: 13), new Number(min: 21)],
270
                        when: fn () => true,
271
                    ),
272
                ],
273
                [
274
                    '' => [
275
                        'Value must be no greater than 13.',
276
                        'Value must be no less than 21.',
277
                    ],
278
                ],
279
            ],
280
            'skip on error with previous error' => [
281
                20,
282
                [
283
                    new Equal(19),
284
                    new Composite(
285
                        [new Number(max: 13)],
286
                        skipOnError: true,
287
                    ),
288
                ],
289
                [
290
                    '' => ['Value must be equal to "19".'],
291
                ],
292
            ],
293
            'skip on error without previous error' => [
294
                20,
295
                [
296
                    new Composite(
297
                        [new Number(max: 13)],
298
                        skipOnError: true,
299
                    ),
300
                ],
301
                [
302
                    '' => ['Value must be no greater than 13.'],
303
                ],
304
            ],
305
            'custom error' => [
306
                20,
307
                [
308
                    new Composite(
309
                        [new Number(max: 13, greaterThanMaxMessage: 'Custom error')],
310
                        when: fn () => true,
311
                    ),
312
                ],
313
                ['' => ['Custom error']],
314
            ],
315
            'override constructor' => [
316
                null,
317
                [
318
                    new class () extends Composite {
319
                        public function __construct()
320
                        {
321
                            $this->rules = [new Required()];
322
                        }
323
                    },
324
                ],
325
                ['' => ['Value cannot be blank.']],
326
            ],
327
            'multiple attributes' => [
328
                ['latitude' => -91, 'longitude' => 181],
329
                [new CoordinatesRuleSet()],
330
                [
331
                    'latitude' => ['Value must be no less than -90.'],
332
                    'longitude' => ['Value must be no greater than 180.'],
333
                ],
334
            ],
335
        ];
336
    }
337
338
    public function testSkipOnError(): void
339
    {
340
        $this->testSkipOnErrorInternal(new Composite([]), new Composite([], skipOnError: true));
341
    }
342
343
    public function testWhen(): void
344
    {
345
        $when = static fn (mixed $value): bool => $value !== null;
346
        $this->testWhenInternal(new Composite([]), new Composite([], when: $when));
347
    }
348
349
    protected function getDifferentRuleInHandlerItems(): array
350
    {
351
        return [Composite::class, CompositeHandler::class];
352
    }
353
}
354