CountTest.php$1 ➔ dataValidationFailed()   B
last analyzed

Complexity

Conditions 1

Size

Total Lines 138

Duplication

Lines 0
Ratio 0 %

Importance

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

1 Method

Rating   Name   Duplication   Size   Complexity  
A CountTest.php$1 ➔ count() 0 3 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 ArrayIterator;
8
use Countable;
9
use stdClass;
10
use Yiisoft\Validator\DataSet\SingleValueDataSet;
11
use Yiisoft\Validator\Rule\Count;
12
use Yiisoft\Validator\Rule\CountHandler;
13
use Yiisoft\Validator\Tests\Rule\Base\DifferentRuleInHandlerTestTrait;
14
use Yiisoft\Validator\Tests\Rule\Base\CountableLimitTestTrait;
15
use Yiisoft\Validator\Tests\Rule\Base\RuleTestCase;
16
use Yiisoft\Validator\Tests\Rule\Base\RuleWithOptionsTestTrait;
17
use Yiisoft\Validator\Tests\Rule\Base\SkipOnErrorTestTrait;
18
use Yiisoft\Validator\Tests\Rule\Base\WhenTestTrait;
19
use Yiisoft\Validator\Tests\Support\Data\CountDto;
20
21
final class CountTest extends RuleTestCase
22
{
23
    use CountableLimitTestTrait;
24
    use DifferentRuleInHandlerTestTrait;
25
    use RuleWithOptionsTestTrait;
26
    use SkipOnErrorTestTrait;
27
    use WhenTestTrait;
28
29
    public function testGetName(): void
30
    {
31
        $rule = new Count(min: 3);
32
        $this->assertSame(Count::class, $rule->getName());
33
    }
34
35
    public function dataOptions(): array
36
    {
37
        return [
38
            [
39
                new Count(min: 3),
40
                [
41
                    'min' => 3,
42
                    'max' => null,
43
                    'exactly' => null,
44
                    'lessThanMinMessage' => [
45
                        'template' => 'This value must contain at least {min, number} {min, plural, one{item} ' .
46
                            'other{items}}.',
47
                        'parameters' => ['min' => 3],
48
                    ],
49
                    'greaterThanMaxMessage' => [
50
                        'template' => 'This value must contain at most {max, number} {max, plural, one{item} ' .
51
                            'other{items}}.',
52
                        'parameters' => ['max' => null],
53
                    ],
54
                    'notExactlyMessage' => [
55
                        'template' => 'This value must contain exactly {exactly, number} {exactly, plural, one{item} ' .
56
                            'other{items}}.',
57
                        'parameters' => ['exactly' => null],
58
                    ],
59
                    'incorrectInputMessage' => [
60
                        'template' => 'This value must be an array or implement \Countable interface.',
61
                        'parameters' => [],
62
                    ],
63
                    'skipOnEmpty' => false,
64
                    'skipOnError' => false,
65
                ],
66
            ],
67
        ];
68
    }
69
70
    public function dataValidationPassed(): array
71
    {
72
        return [
73
            [[0, 0, 0], [new Count(min: 3)]],
74
            [[0, 0, 0, 0], [new Count(min: 3)]],
75
            [[0, 0, 0], [new Count(3)]],
76
            [[], [new Count(max: 3)]],
77
            [[0, 0], [new Count(max: 3)]],
78
            [[0, 0, 0], [new Count(max: 3)]],
79
            'value: array iterator with min allowed count, min: positive' => [
80
                new ArrayIterator([0, 0, 0]),
81
                [new Count(min: 3)],
82
            ],
83
            [
84
                new SingleValueDataSet(
85
                    new class () implements Countable {
86
                        protected int $myCount = 3;
87
88
                        public function count(): int
89
                        {
90
                            return $this->myCount;
91
                        }
92
                    }
93
                ),
94
                [new Count(min: 3)],
95
            ],
96
            'class attribute' => [
97
                new CountDto(7),
98
            ],
99
            'value: empty array, exactly: 0' => [
100
                [],
101
                [new Count(0)],
102
            ],
103
            'value: empty array, min: 0' => [
104
                [],
105
                [new Count(min: 0)],
106
            ],
107
            'value: empty array, max: 0' => [
108
                [],
109
                [new Count(max: 0)],
110
            ],
111
            'value: empty array iterator, exactly: 0' => [
112
                new ArrayIterator(),
113
                [new Count(0)],
114
            ],
115
            'value: empty array iterator, exactly: positive, skipOnEmpty: true' => [
116
                new ArrayIterator(),
117
                [new Count(1, skipOnEmpty: true)],
118
            ],
119
        ];
120
    }
121
122
    public function dataValidationFailed(): array
123
    {
124
        $lessThanMinmessage = 'This value must contain at least 3 items.';
125
        $greaterThanMaxMessage = 'This value must contain at most 3 items.';
126
127
        return [
128
            'incorrect input' => [
129
                1,
130
                [new Count(min: 3)],
131
                ['' => ['This value must be an array or implement \Countable interface.']],
132
            ],
133
            'custom incorrect input message' => [
134
                1,
135
                [new Count(min: 3, incorrectInputMessage: 'Custom incorrect input message.')],
136
                ['' => ['Custom incorrect input message.']],
137
            ],
138
            'custom incorrect input message with parameters' => [
139
                1,
140
                [new Count(min: 3, incorrectInputMessage: 'Attribute - {attribute}, type - {type}.')],
141
                ['' => ['Attribute - , type - int.']],
142
            ],
143
            'custom incorrect input message, attribute set' => [
144
                ['data' => 1],
145
                ['data' => new Count(min: 3, incorrectInputMessage: 'Attribute - {attribute}, type - {type}.')],
146
                ['data' => ['Attribute - data, type - int.']],
147
            ],
148
149
            [[1], new Count(3), ['' => ['This value must contain exactly 3 items.']]],
150
            [[1], [new Count(min: 3)], ['' => [$lessThanMinmessage]]],
151
            [[], [new Count(min: 3)], ['' => [$lessThanMinmessage]]],
152
            [[0, 0], [new Count(min: 3)], ['' => [$lessThanMinmessage]]],
153
            [[1.1], [new Count(min: 3)], ['' => [$lessThanMinmessage]]],
154
            [[''], [new Count(min: 3)], ['' => [$lessThanMinmessage]]],
155
            [['some string'], [new Count(min: 3)], ['' => [$lessThanMinmessage]]],
156
            [[new stdClass()], [new Count(min: 3)], ['' => [$lessThanMinmessage]]],
157
            'value: array iterator with lower count, min: positive' => [
158
                new ArrayIterator([0, 0]),
159
                [new Count(min: 3)],
160
                ['' => [$lessThanMinmessage]],
161
            ],
162
            // https://www.php.net/manual/ru/class.countable.php
163
            'value: class with min count returned from count method but not implenting Countable interface, min: 3' => [
164
                [
165
                    new class () {
166
                        protected int $myCount = 3;
167
168
                        public function count(): int
169
                        {
170
                            return $this->myCount;
171
                        }
172
                    },
173
                ],
174
                [new Count(min: 3)],
175
                ['' => [$lessThanMinmessage]],
176
            ],
177
            [[0, 0, 0, 0], [new Count(max: 3)], ['' => [$greaterThanMaxMessage]]],
178
179
            'custom less than min message' => [
180
                [0, 0],
181
                [new Count(min: 3, lessThanMinMessage: 'Custom less than min message.')],
182
                ['' => ['Custom less than min message.']],
183
            ],
184
            'custom less than min message with parameters' => [
185
                [0, 0],
186
                [new Count(min: 3, lessThanMinMessage: 'Min - {min}, attribute - {attribute}, number - {number}.')],
187
                ['' => ['Min - 3, attribute - , number - 2.']],
188
            ],
189
            'custom less than min message with parameters, attribute set' => [
190
                ['data' => [0, 0]],
191
                [
192
                    'data' => new Count(
193
                        min: 3,
194
                        lessThanMinMessage: 'Min - {min}, attribute - {attribute}, number - {number}.',
195
                    ),
196
                ],
197
                ['data' => ['Min - 3, attribute - data, number - 2.']],
198
            ],
199
200
            'custom greater than max message' => [
201
                [0, 0, 0, 0],
202
                [new Count(max: 3, greaterThanMaxMessage: 'Custom greater than max message.')],
203
                ['' => ['Custom greater than max message.']],
204
            ],
205
            'custom greater than max message with parameters' => [
206
                [0, 0, 0, 0],
207
                [new Count(max: 3, greaterThanMaxMessage: 'Max - {max}, attribute - {attribute}, number - {number}.')],
208
                ['' => ['Max - 3, attribute - , number - 4.']],
209
            ],
210
            'custom greater than max message with parameters, attribute set' => [
211
                ['data' => [0, 0, 0, 0]],
212
                [
213
                    'data' => new Count(
214
                        max: 3,
215
                        greaterThanMaxMessage: 'Max - {max}, attribute - {attribute}, number - {number}.',
216
                    ),
217
                ],
218
                ['data' => ['Max - 3, attribute - data, number - 4.']],
219
            ],
220
221
            'custom not exactly message' => [
222
                [0, 0, 0, 0],
223
                [new Count(3, notExactlyMessage: 'Custom not exactly message.')],
224
                ['' => ['Custom not exactly message.']],
225
            ],
226
            'custom not exactly message with parameters' => [
227
                [0, 0, 0, 0],
228
                [
229
                    new Count(
230
                        exactly: 3,
231
                        notExactlyMessage: 'Exactly - {exactly}, attribute - {attribute}, number - {number}.',
232
                    ),
233
                ],
234
                ['' => ['Exactly - 3, attribute - , number - 4.']],
235
            ],
236
            'custom not exactly message with parameters, attribute set' => [
237
                ['data' => [0, 0, 0, 0]],
238
                [
239
                    'data' => new Count(
240
                        exactly: 3,
241
                        notExactlyMessage: 'Exactly - {exactly}, attribute - {attribute}, number - {number}.',
242
                    ),
243
                ],
244
                ['data' => ['Exactly - 3, attribute - data, number - 4.']],
245
            ],
246
            'class attribute' => [
247
                new CountDto(),
248
                null,
249
                ['' => ['This value must contain at least 2 items.']],
250
            ],
251
            'value: array with greater count, exactly: 0' => [
252
                [0],
253
                [new Count(0)],
254
                ['' => ['This value must contain exactly 0 items.']],
255
            ],
256
            'value: empty array iterator, exactly: positive' => [
257
                new ArrayIterator(),
258
                [new Count(1)],
259
                ['' => ['This value must contain exactly 1 item.']],
260
            ],
261
        ];
262
    }
263
264
    public function testSkipOnError(): void
265
    {
266
        $this->testSkipOnErrorInternal(new Count(min: 3), new Count(min: 3, skipOnError: true));
267
    }
268
269
    public function testWhen(): void
270
    {
271
        $when = static fn (mixed $value): bool => $value !== null;
272
        $this->testWhenInternal(new Count(min: 3), new Count(min: 3, when: $when));
273
    }
274
275
    protected function getRuleClass(): string
276
    {
277
        return Count::class;
278
    }
279
280
    protected function getDifferentRuleInHandlerItems(): array
281
    {
282
        return [Count::class, CountHandler::class];
283
    }
284
}
285