Passed
Pull Request — master (#428)
by Sergei
02:38
created

CompositeTest::testGetName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Validator\Tests\Rule;
6
7
use InvalidArgumentException;
8
use Yiisoft\Validator\Result;
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\Tests\Rule\Base\DifferentRuleInHandlerTestTrait;
14
use Yiisoft\Validator\Tests\Rule\Base\RuleTestCase;
15
use Yiisoft\Validator\Tests\Rule\Base\RuleWithOptionsTestTrait;
16
use Yiisoft\Validator\Tests\Rule\Base\SkipOnErrorTestTrait;
17
use Yiisoft\Validator\Tests\Rule\Base\WhenTestTrait;
18
use Yiisoft\Validator\Tests\Support\Rule\RuleWithoutOptions;
19
20
final class CompositeTest extends RuleTestCase
21
{
22
    use DifferentRuleInHandlerTestTrait;
23
    use RuleWithOptionsTestTrait;
24
    use SkipOnErrorTestTrait;
25
    use WhenTestTrait;
26
27
    public function testGetName(): void
28
    {
29
        $rule = new Composite([]);
30
        $this->assertSame('composite', $rule->getName());
31
    }
32
33
    public function dataOptions(): array
34
    {
35
        return [
36
            [
37
                new Composite([
38
                    new Number(max: 13, integerPattern: '/1/', numberPattern: '/1/'),
39
                    new Number(max: 14, integerPattern: '/2/', numberPattern: '/2/'),
40
                ]),
41
                [
42
                    'skipOnEmpty' => false,
43
                    'skipOnError' => false,
44
                    'rules' => [
45
                        [
46
                            'number',
47
                            'asInteger' => false,
48
                            'min' => null,
49
                            'max' => 13,
50
                            'incorrectInputMessage' => [
51
                                'template' => 'The allowed types are integer, float and string.',
52
                                'parameters' => [],
53
                            ],
54
                            'notNumberMessage' => [
55
                                'template' => 'Value must be a number.',
56
                                'parameters' => [],
57
                            ],
58
                            'tooSmallMessage' => [
59
                                'template' => 'Value must be no less than {min}.',
60
                                'parameters' => ['min' => null],
61
                            ],
62
                            'tooBigMessage' => [
63
                                'template' => 'Value must be no greater than {max}.',
64
                                'parameters' => ['max' => 13],
65
                            ],
66
                            'skipOnEmpty' => false,
67
                            'skipOnError' => false,
68
                            'integerPattern' => '/1/',
69
                            'numberPattern' => '/1/',
70
                        ],
71
                        [
72
                            'number',
73
                            'asInteger' => false,
74
                            'min' => null,
75
                            'max' => 14,
76
                            'incorrectInputMessage' => [
77
                                'template' => 'The allowed types are integer, float and string.',
78
                                'parameters' => [],
79
                            ],
80
                            'notNumberMessage' => [
81
                                'template' => 'Value must be a number.',
82
                                'parameters' => [],
83
                            ],
84
                            'tooSmallMessage' => [
85
                                'template' => 'Value must be no less than {min}.',
86
                                'parameters' => ['min' => null],
87
                            ],
88
                            'tooBigMessage' => [
89
                                'template' => 'Value must be no greater than {max}.',
90
                                'parameters' => ['max' => 14],
91
                            ],
92
                            'skipOnEmpty' => false,
93
                            'skipOnError' => false,
94
                            'integerPattern' => '/2/',
95
                            'numberPattern' => '/2/',
96
                        ],
97
                    ],
98
                ],
99
            ],
100
            'rule without options' => [
101
                new Composite([
102
                    new Number(max: 13, integerPattern: '/1/', numberPattern: '/1/'),
103
                    new RuleWithoutOptions(),
104
                ]),
105
                [
106
                    'skipOnEmpty' => false,
107
                    'skipOnError' => false,
108
                    'rules' => [
109
                        [
110
                            'number',
111
                            'asInteger' => false,
112
                            'min' => null,
113
                            'max' => 13,
114
                            'incorrectInputMessage' => [
115
                                'template' => 'The allowed types are integer, float and string.',
116
                                'parameters' => [],
117
                            ],
118
                            'notNumberMessage' => [
119
                                'template' => 'Value must be a number.',
120
                                'parameters' => [],
121
                            ],
122
                            'tooSmallMessage' => [
123
                                'template' => 'Value must be no less than {min}.',
124
                                'parameters' => [
125
                                    'min' => null,
126
                                ],
127
                            ],
128
                            'tooBigMessage' => [
129
                                'template' => 'Value must be no greater than {max}.',
130
                                'parameters' => [
131
                                    'max' => 13,
132
                                ],
133
                            ],
134
                            'skipOnEmpty' => false,
135
                            'skipOnError' => false,
136
                            'integerPattern' => '/1/',
137
                            'numberPattern' => '/1/',
138
                        ],
139
                        [
140
                            'test',
141
                        ],
142
                    ],
143
                ],
144
            ],
145
            'callable' => [
146
                new Composite([
147
                    static fn () => (new Result())->addError('Bad value.'),
148
                ]),
149
                [
150
                    'skipOnEmpty' => false,
151
                    'skipOnError' => false,
152
                    'rules' => [
153
                        [
154
                            'callback',
155
                            'method' => null,
156
                            'skipOnEmpty' => false,
157
                            'skipOnError' => false,
158
                        ],
159
                    ],
160
                ],
161
            ],
162
        ];
163
    }
164
165
    public function testOptionsWithNotRule(): void
166
    {
167
        $rule = new Composite([
168
            new Number(max: 13, integerPattern: '/1/', numberPattern: '/1/'),
169
            new class () {
170
            },
171
        ]);
172
173
        $this->expectException(InvalidArgumentException::class);
174
        $message = 'Rule should be either an instance of Yiisoft\Validator\RuleInterface or a callable, class@anonymous given.';
175
        $this->expectExceptionMessage($message);
176
        $rule->getOptions();
177
    }
178
179
    public function dataValidationPassed(): array
180
    {
181
        return [
182
            [
183
                20,
184
                [
185
                    new Composite(
186
                        rules: [new Number(max: 13)],
187
                        when: fn () => false,
188
                    ),
189
                ],
190
            ],
191
            [
192
                null,
193
                [
194
                    new Composite(
195
                        rules: [new Number(max: 13)],
196
                        skipOnEmpty: true,
197
                    ),
198
                ],
199
            ],
200
        ];
201
    }
202
203
    public function dataValidationFailed(): array
204
    {
205
        return [
206
            'callable' => [
207
                20,
208
                [
209
                    new Composite(
210
                        rules: [
211
                            static fn () => (new Result())->addError('Bad value.'),
212
                            static fn () => (new Result())->addError('Very bad value.'),
213
                        ],
214
                    ),
215
                ],
216
                [
217
                    '' => [
218
                        'Bad value.',
219
                        'Very bad value.',
220
                    ],
221
                ],
222
            ],
223
            'when true' => [
224
                20,
225
                [
226
                    new Composite(
227
                        rules: [new Number(max: 13), new Number(min: 21)],
228
                        when: fn () => true,
229
                    ),
230
                ],
231
                [
232
                    '' => [
233
                        'Value must be no greater than 13.',
234
                        'Value must be no less than 21.',
235
                    ],
236
                ],
237
            ],
238
            'skip on error with previous error' => [
239
                20,
240
                [
241
                    new Equal(19),
242
                    new Composite(
243
                        rules: [new Number(max: 13)],
244
                        skipOnError: true,
245
                    ),
246
                ],
247
                [
248
                    '' => ['Value must be equal to "19".'],
249
                ],
250
            ],
251
            'skip on error without previous error' => [
252
                20,
253
                [
254
                    new Composite(
255
                        rules: [new Number(max: 13)],
256
                        skipOnError: true,
257
                    ),
258
                ],
259
                [
260
                    '' => ['Value must be no greater than 13.'],
261
                ],
262
            ],
263
            'custom error' => [
264
                20,
265
                [
266
                    new Composite(
267
                        rules: [new Number(max: 13, tooBigMessage: 'Custom error')],
268
                        when: fn () => true,
269
                    ),
270
                ],
271
                ['' => ['Custom error']],
272
            ],
273
        ];
274
    }
275
276
    public function testSkipOnError(): void
277
    {
278
        $this->testSkipOnErrorInternal(new Composite([]), new Composite([], skipOnError: true));
279
    }
280
281
    public function testWhen(): void
282
    {
283
        $when = static fn (mixed $value): bool => $value !== null;
284
        $this->testWhenInternal(new Composite([]), new Composite([], when: $when));
285
    }
286
287
    protected function getDifferentRuleInHandlerItems(): array
288
    {
289
        return [Composite::class, CompositeHandler::class];
290
    }
291
}
292