Passed
Pull Request — master (#542)
by
unknown
02:31
created

CompareTest::testInitWithoutTarget()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 0
dl 0
loc 6
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 stdClass;
9
use Yiisoft\Validator\DataWrapperInterface;
10
use Yiisoft\Validator\Rule\Compare;
11
use Yiisoft\Validator\Rule\CompareType;
12
use Yiisoft\Validator\Tests\Rule\Base\RuleTestCase;
13
use Yiisoft\Validator\Tests\Rule\Base\RuleWithOptionsTestTrait;
14
use Yiisoft\Validator\Tests\Rule\Base\SkipOnErrorTestTrait;
15
use Yiisoft\Validator\Tests\Rule\Base\WhenTestTrait;
16
17
final class CompareTest extends RuleTestCase
18
{
19
    use RuleWithOptionsTestTrait;
20
    use SkipOnErrorTestTrait;
21
    use WhenTestTrait;
22
23
    public function testInitWithoutTarget(): void
24
    {
25
        $this->expectException(InvalidArgumentException::class);
26
        $this->expectExceptionMessage('Either "targetValue" or "targetAttribute" must be specified');
27
28
        new Compare();
29
    }
30
31
    public function testInitWithWrongType(): void
32
    {
33
        $this->expectException(InvalidArgumentException::class);
34
        $message = 'Type "float" is not supported. The valid types are: "number", "string".';
35
        $this->expectExceptionMessage($message);
36
37
        new Compare(1, type: 'float');
38
    }
39
40
    public function testInitWithWrongOperator(): void
41
    {
42
        $this->expectException(InvalidArgumentException::class);
43
        $message = 'Operator "=" is not supported. The valid operators are: "==", "===", "!=", "!==", ">", ">=", ' .
44
            '"<", "<=".';
45
        $this->expectExceptionMessage($message);
46
47
        new Compare(1, operator: '=');
48
    }
49
50
    public function testGetName(): void
51
    {
52
        $rule = new Compare(1);
53
        $this->assertSame('compare', $rule->getName());
54
    }
55
56
    public function dataOptions(): array
57
    {
58
        return [
59
            [
60
                new Compare(1),
61
                [
62
                    'targetValue' => 1,
63
                    'targetAttribute' => null,
64
                    'incorrectInputMessage' => [
65
                        'template' => 'The allowed types are integer, float, string, boolean and null.',
66
                        'parameters' => [
67
                            'targetValue' => 1,
68
                            'targetAttribute' => null,
69
                            'targetValueOrAttribute' => 1,
70
                        ],
71
                    ],
72
                    'incorrectDataSetTypeMessage' => [
73
                        'template' => 'The attribute value returned from a custom data set must have a scalar type.',
74
                        'parameters' => [
75
                            'targetValue' => 1,
76
                            'targetAttribute' => null,
77
                            'targetValueOrAttribute' => 1,
78
                        ],
79
                    ],
80
                    'message' => [
81
                        'template' => 'Value must be equal to "{targetValueOrAttribute}".',
82
                        'parameters' => [
83
                            'targetValue' => 1,
84
                            'targetAttribute' => null,
85
                            'targetValueOrAttribute' => 1,
86
                        ],
87
                    ],
88
                    'type' => 'string',
89
                    'operator' => '==',
90
                    'skipOnEmpty' => false,
91
                    'skipOnError' => false,
92
                ],
93
            ],
94
            [
95
                new Compare(1, type: CompareType::NUMBER),
96
                [
97
                    'targetValue' => 1,
98
                    'targetAttribute' => null,
99
                    'incorrectInputMessage' => [
100
                        'template' => 'The allowed types are integer, float, string, boolean and null.',
101
                        'parameters' => [
102
                            'targetValue' => 1,
103
                            'targetAttribute' => null,
104
                            'targetValueOrAttribute' => 1,
105
                        ],
106
                    ],
107
                    'incorrectDataSetTypeMessage' => [
108
                        'template' => 'The attribute value returned from a custom data set must have a scalar type.',
109
                        'parameters' => [
110
                            'targetValue' => 1,
111
                            'targetAttribute' => null,
112
                            'targetValueOrAttribute' => 1,
113
                        ],
114
                    ],
115
                    'message' => [
116
                        'template' => 'Value must be equal to "{targetValueOrAttribute}".',
117
                        'parameters' => [
118
                            'targetValue' => 1,
119
                            'targetAttribute' => null,
120
                            'targetValueOrAttribute' => 1,
121
                        ],
122
                    ],
123
                    'type' => 'number',
124
                    'operator' => '==',
125
                    'skipOnEmpty' => false,
126
                    'skipOnError' => false,
127
                ],
128
            ],
129
            [
130
                new Compare(1, type: CompareType::NUMBER, operator: '>='),
131
                [
132
                    'targetValue' => 1,
133
                    'targetAttribute' => null,
134
                    'incorrectInputMessage' => [
135
                        'template' => 'The allowed types are integer, float, string, boolean and null.',
136
                        'parameters' => [
137
                            'targetValue' => 1,
138
                            'targetAttribute' => null,
139
                            'targetValueOrAttribute' => 1,
140
                        ],
141
                    ],
142
                    'incorrectDataSetTypeMessage' => [
143
                        'template' => 'The attribute value returned from a custom data set must have a scalar type.',
144
                        'parameters' => [
145
                            'targetValue' => 1,
146
                            'targetAttribute' => null,
147
                            'targetValueOrAttribute' => 1,
148
                        ],
149
                    ],
150
                    'message' => [
151
                        'template' => 'Value must be greater than or equal to "{targetValueOrAttribute}".',
152
                        'parameters' => [
153
                            'targetValue' => 1,
154
                            'targetAttribute' => null,
155
                            'targetValueOrAttribute' => 1,
156
                        ],
157
                    ],
158
                    'type' => 'number',
159
                    'operator' => '>=',
160
                    'skipOnEmpty' => false,
161
                    'skipOnError' => false,
162
                ],
163
            ],
164
            [
165
                new Compare('YES'),
166
                [
167
                    'targetValue' => 'YES',
168
                    'targetAttribute' => null,
169
                    'incorrectInputMessage' => [
170
                        'template' => 'The allowed types are integer, float, string, boolean and null.',
171
                        'parameters' => [
172
                            'targetValue' => 'YES',
173
                            'targetAttribute' => null,
174
                            'targetValueOrAttribute' => 'YES',
175
                        ],
176
                    ],
177
                    'incorrectDataSetTypeMessage' => [
178
                        'template' => 'The attribute value returned from a custom data set must have a scalar type.',
179
                        'parameters' => [
180
                            'targetValue' => 'YES',
181
                            'targetAttribute' => null,
182
                            'targetValueOrAttribute' => 'YES',
183
                        ],
184
                    ],
185
                    'message' => [
186
                        'template' => 'Value must be equal to "{targetValueOrAttribute}".',
187
                        'parameters' => [
188
                            'targetValue' => 'YES',
189
                            'targetAttribute' => null,
190
                            'targetValueOrAttribute' => 'YES',
191
                        ],
192
                    ],
193
                    'type' => 'string',
194
                    'operator' => '==',
195
                    'skipOnEmpty' => false,
196
                    'skipOnError' => false,
197
                ],
198
            ],
199
            [
200
                new Compare('YES', skipOnEmpty: true),
201
                [
202
                    'targetValue' => 'YES',
203
                    'targetAttribute' => null,
204
                    'incorrectInputMessage' => [
205
                        'template' => 'The allowed types are integer, float, string, boolean and null.',
206
                        'parameters' => [
207
                            'targetValue' => 'YES',
208
                            'targetAttribute' => null,
209
                            'targetValueOrAttribute' => 'YES',
210
                        ],
211
                    ],
212
                    'incorrectDataSetTypeMessage' => [
213
                        'template' => 'The attribute value returned from a custom data set must have a scalar type.',
214
                        'parameters' => [
215
                            'targetValue' => 'YES',
216
                            'targetAttribute' => null,
217
                            'targetValueOrAttribute' => 'YES',
218
                        ],
219
                    ],
220
                    'message' => [
221
                        'template' => 'Value must be equal to "{targetValueOrAttribute}".',
222
                        'parameters' => [
223
                            'targetValue' => 'YES',
224
                            'targetAttribute' => null,
225
                            'targetValueOrAttribute' => 'YES',
226
                        ],
227
                    ],
228
                    'type' => 'string',
229
                    'operator' => '==',
230
                    'skipOnEmpty' => true,
231
                    'skipOnError' => false,
232
                ],
233
            ],
234
            [
235
                new Compare('YES', operator: '!=='),
236
                [
237
                    'targetValue' => 'YES',
238
                    'targetAttribute' => null,
239
                    'incorrectInputMessage' => [
240
                        'template' => 'The allowed types are integer, float, string, boolean and null.',
241
                        'parameters' => [
242
                            'targetValue' => 'YES',
243
                            'targetAttribute' => null,
244
                            'targetValueOrAttribute' => 'YES',
245
                        ],
246
                    ],
247
                    'incorrectDataSetTypeMessage' => [
248
                        'template' => 'The attribute value returned from a custom data set must have a scalar type.',
249
                        'parameters' => [
250
                            'targetValue' => 'YES',
251
                            'targetAttribute' => null,
252
                            'targetValueOrAttribute' => 'YES',
253
                        ],
254
                    ],
255
                    'message' => [
256
                        'template' => 'Value must not be equal to "{targetValueOrAttribute}".',
257
                        'parameters' => [
258
                            'targetValue' => 'YES',
259
                            'targetAttribute' => null,
260
                            'targetValueOrAttribute' => 'YES',
261
                        ],
262
                    ],
263
                    'type' => 'string',
264
                    'operator' => '!==',
265
                    'skipOnEmpty' => false,
266
                    'skipOnError' => false,
267
                ],
268
            ],
269
            [
270
                new Compare('YES', message: 'Custom message for {targetValueOrAttribute}.'),
271
                [
272
                    'targetValue' => 'YES',
273
                    'targetAttribute' => null,
274
                    'incorrectInputMessage' => [
275
                        'template' => 'The allowed types are integer, float, string, boolean and null.',
276
                        'parameters' => [
277
                            'targetValue' => 'YES',
278
                            'targetAttribute' => null,
279
                            'targetValueOrAttribute' => 'YES',
280
                        ],
281
                    ],
282
                    'incorrectDataSetTypeMessage' => [
283
                        'template' => 'The attribute value returned from a custom data set must have a scalar type.',
284
                        'parameters' => [
285
                            'targetValue' => 'YES',
286
                            'targetAttribute' => null,
287
                            'targetValueOrAttribute' => 'YES',
288
                        ],
289
                    ],
290
                    'message' => [
291
                        'template' => 'Custom message for {targetValueOrAttribute}.',
292
                        'parameters' => [
293
                            'targetValue' => 'YES',
294
                            'targetAttribute' => null,
295
                            'targetValueOrAttribute' => 'YES',
296
                        ],
297
                    ],
298
                    'type' => 'string',
299
                    'operator' => '==',
300
                    'skipOnEmpty' => false,
301
                    'skipOnError' => false,
302
                ],
303
            ],
304
            [
305
                new Compare(null, 'test'),
306
                [
307
                    'targetValue' => null,
308
                    'targetAttribute' => 'test',
309
                    'incorrectInputMessage' => [
310
                        'template' => 'The allowed types are integer, float, string, boolean and null.',
311
                        'parameters' => [
312
                            'targetValue' => null,
313
                            'targetAttribute' => 'test',
314
                            'targetValueOrAttribute' => 'test',
315
                        ],
316
                    ],
317
                    'incorrectDataSetTypeMessage' => [
318
                        'template' => 'The attribute value returned from a custom data set must have a scalar type.',
319
                        'parameters' => [
320
                            'targetValue' => null,
321
                            'targetAttribute' => 'test',
322
                            'targetValueOrAttribute' => 'test',
323
                        ],
324
                    ],
325
                    'message' => [
326
                        'template' => 'Value must be equal to "{targetValueOrAttribute}".',
327
                        'parameters' => [
328
                            'targetValue' => null,
329
                            'targetAttribute' => 'test',
330
                            'targetValueOrAttribute' => 'test',
331
                        ],
332
                    ],
333
                    'type' => 'string',
334
                    'operator' => '==',
335
                    'skipOnEmpty' => false,
336
                    'skipOnError' => false,
337
                ],
338
            ],
339
            [
340
                new Compare(
341
                    null,
342
                    'test',
343
                    incorrectInputMessage: 'Custom message 1.',
344
                    incorrectDataSetTypeMessage: 'Custom message 2.',
345
                    message: 'Custom message 3.',
346
                ),
347
                [
348
                    'targetValue' => null,
349
                    'targetAttribute' => 'test',
350
                    'incorrectInputMessage' => [
351
                        'template' => 'Custom message 1.',
352
                        'parameters' => [
353
                            'targetValue' => null,
354
                            'targetAttribute' => 'test',
355
                            'targetValueOrAttribute' => 'test',
356
                        ],
357
                    ],
358
                    'incorrectDataSetTypeMessage' => [
359
                        'template' => 'Custom message 2.',
360
                        'parameters' => [
361
                            'targetValue' => null,
362
                            'targetAttribute' => 'test',
363
                            'targetValueOrAttribute' => 'test',
364
                        ],
365
                    ],
366
                    'message' => [
367
                        'template' => 'Custom message 3.',
368
                        'parameters' => [
369
                            'targetValue' => null,
370
                            'targetAttribute' => 'test',
371
                            'targetValueOrAttribute' => 'test',
372
                        ],
373
                    ],
374
                    'type' => 'string',
375
                    'operator' => '==',
376
                    'skipOnEmpty' => false,
377
                    'skipOnError' => false,
378
                ],
379
            ],
380
            [
381
                new Compare(1, 'test'),
382
                [
383
                    'targetValue' => 1,
384
                    'targetAttribute' => 'test',
385
                    'incorrectInputMessage' => [
386
                        'template' => 'The allowed types are integer, float, string, boolean and null.',
387
                        'parameters' => [
388
                            'targetValue' => 1,
389
                            'targetAttribute' => 'test',
390
                            'targetValueOrAttribute' => 1,
391
                        ],
392
                    ],
393
                    'incorrectDataSetTypeMessage' => [
394
                        'template' => 'The attribute value returned from a custom data set must have a scalar type.',
395
                        'parameters' => [
396
                            'targetValue' => 1,
397
                            'targetAttribute' => 'test',
398
                            'targetValueOrAttribute' => 1,
399
                        ],
400
                    ],
401
                    'message' => [
402
                        'template' => 'Value must be equal to "{targetValueOrAttribute}".',
403
                        'parameters' => [
404
                            'targetValue' => 1,
405
                            'targetAttribute' => 'test',
406
                            'targetValueOrAttribute' => 1,
407
                        ],
408
                    ],
409
                    'type' => 'string',
410
                    'operator' => '==',
411
                    'skipOnEmpty' => false,
412
                    'skipOnError' => false,
413
                ],
414
            ],
415
        ];
416
    }
417
418
    public function dataValidationPassed(): array
419
    {
420
        return [
421
            [null, [new Compare('')]],
422
            [null, [new Compare('', operator: '===')]],
423
424
            [100, [new Compare(100)]],
425
            [['attribute' => 100, 'number' => 100], ['number' => new Compare(null, 'attribute')]],
426
            ['100', [new Compare(100)]],
427
428
            [100, [new Compare(100, operator: '===')]],
429
            ['100', [new Compare(100, operator: '===')]],
430
            [100.0, [new Compare(100, operator: '===')]],
431
432
            [100.00001, [new Compare(100, operator: '!=')]],
433
            [false, [new Compare(100, operator: '!=')]],
434
435
            [false, [new Compare(100, operator: '!==')]],
436
437
            [101, [new Compare(100, operator: '>')]],
438
439
            [100, [new Compare(100, operator: '>=')]],
440
            [101, [new Compare(100, operator: '>=')]],
441
            [99, [new Compare(100, operator: '<')]],
442
443
            [100, [new Compare(100, operator: '<=')]],
444
            [99, [new Compare(100, operator: '<=')]],
445
            [['attribute' => 100, 'number' => 99], ['number' => new Compare(null, 'attribute', operator: '<=')]],
446
447
            ['100.50', [new Compare('100.5', type: CompareType::NUMBER)]],
448
            ['100.50', [new Compare('100.5', type: CompareType::NUMBER, operator: '===')]],
449
        ];
450
    }
451
452
    public function dataValidationFailed(): array
453
    {
454
        $incorrectDataSet = new class () implements DataWrapperInterface {
455
            public function getAttributeValue(string $attribute): mixed
456
            {
457
                return new stdClass();
458
            }
459
460
            public function getData(): ?array
461
            {
462
                return null;
463
            }
464
465
            public function getSource(): mixed
466
            {
467
                return false;
468
            }
469
470
            public function hasAttribute(string $attribute): bool
471
            {
472
                return false;
473
            }
474
        };
475
        $messageEqual = 'Value must be equal to "100".';
476
        $messageNotEqual = 'Value must not be equal to "100".';
477
        $messageGreaterThan = 'Value must be greater than "100".';
478
        $messageGreaterOrEqualThan = 'Value must be greater than or equal to "100".';
479
        $messageLessThan = 'Value must be less than "100".';
480
        $messageLessOrEqualThan = 'Value must be less than or equal to "100".';
481
482
        return [
483
            'incorrect input' => [
484
                [],
485
                [new Compare(false)],
486
                ['' => ['The allowed types are integer, float, string, boolean and null.']],
487
            ],
488
            'custom incorrect input message' => [
489
                [],
490
                [new Compare(false, incorrectInputMessage: 'Custom incorrect input message.')],
491
                ['' => ['Custom incorrect input message.']],
492
            ],
493
            'custom incorrect input message with parameters' => [
494
                [],
495
                [new Compare(false, incorrectInputMessage: 'Attribute - {attribute}, type - {type}.')],
496
                ['' => ['Attribute - , type - array.']],
497
            ],
498
            'custom incorrect input message with parameters, attribute set' => [
499
                ['data' => []],
500
                ['data' => new Compare(false, incorrectInputMessage: 'Attribute - {attribute}, type - {type}.')],
501
                ['data' => ['Attribute - data, type - array.']],
502
            ],
503
504
            'incorrect data set type' => [
505
                $incorrectDataSet,
506
                [new Compare(targetAttribute: 'test')],
507
                ['' => ['The attribute value returned from a custom data set must have a scalar type.']],
508
            ],
509
            'custom incorrect data set type message' => [
510
                $incorrectDataSet,
511
                [
512
                    new Compare(
513
                        targetAttribute: 'test',
514
                        incorrectDataSetTypeMessage: 'Custom incorrect data set type message.',
515
                    ),
516
                ],
517
                ['' => ['Custom incorrect data set type message.']],
518
            ],
519
            'custom incorrect data set type message with parameters' => [
520
                $incorrectDataSet,
521
                [
522
                    new Compare(
523
                        targetAttribute: 'test',
524
                        incorrectDataSetTypeMessage: 'Type - {type}.',
525
                    ),
526
                ],
527
                ['' => ['Type - stdClass.']],
528
            ],
529
530
            [null, [new Compare(0)], ['' => ['Value must be equal to "0".']]],
531
532
            [101, [new Compare(100)], ['' => [$messageEqual]]],
533
534
            [101, [new Compare(100, operator: '===')], ['' => [$messageEqual]]],
535
            [
536
                ['attribute' => 100, 'number' => 101],
537
                ['number' => new Compare(null, 'attribute', operator: '===')],
538
                ['number' => [$messageEqual]],
539
            ],
540
541
            [100, [new Compare(100, operator: '!=')], ['' => [$messageNotEqual]]],
542
            ['100', [new Compare(100, operator: '!=')], ['' => [$messageNotEqual]]],
543
            [100.0, [new Compare(100, operator: '!=')], ['' => [$messageNotEqual]]],
544
545
            [100, [new Compare(100, operator: '!==')], ['' => [$messageNotEqual]]],
546
            ['100', [new Compare(100, operator: '!==')], ['' => [$messageNotEqual]]],
547
            [100.0, [new Compare(100, operator: '!==')], ['' => [$messageNotEqual]]],
548
549
            [100, [new Compare(100, operator: '>')], ['' => [$messageGreaterThan]]],
550
            [99, [new Compare(100, operator: '>')], ['' => [$messageGreaterThan]]],
551
552
            [99, [new Compare(100, operator: '>=')], ['' => [$messageGreaterOrEqualThan]]],
553
554
            [100, [new Compare(100, operator: '<')], ['' => [$messageLessThan]]],
555
            [101, [new Compare(100, operator: '<')], ['' => [$messageLessThan]]],
556
557
            [101, [new Compare(100, operator: '<=')], ['' => [$messageLessOrEqualThan]]],
558
            [
559
                ['attribute' => 100, 'number' => 101],
560
                ['number' => new Compare(null, 'attribute', operator: '<=')],
561
                ['number' => [$messageLessOrEqualThan]],
562
            ],
563
564
            'custom message' => [101, [new Compare(100, message: 'Custom message.')], ['' => ['Custom message.']]],
565
            'custom message with parameters, target value set' => [
566
                101,
567
                [
568
                    new Compare(
569
                        100,
570
                        message: 'Attribute - {attribute}, target value - {targetValue}, target attribute - ' .
571
                        '{targetAttribute}, target value or attribute - {targetValueOrAttribute}, value - {value}.',
572
                    ),
573
                ],
574
                [
575
                    '' => [
576
                        'Attribute - , target value - 100, target attribute - , target value or attribute - 100, ' .
577
                        'value - 101.',
578
                    ],
579
                ],
580
            ],
581
            'custom message with parameters, attribute and target attribute set' => [
582
                ['attribute' => 100, 'number' => 101],
583
                [
584
                    'number' => new Compare(
585
                        null,
586
                        'attribute',
587
                        message: 'Attribute - {attribute}, target value - {targetValue}, target attribute - ' .
588
                        '{targetAttribute}, target value or attribute - {targetValueOrAttribute}, value - {value}.',
589
                        operator: '===',
590
                    ),
591
                ],
592
                [
593
                    'number' => [
594
                        'Attribute - number, target value - , target attribute - attribute, target value or ' .
595
                        'attribute - 100, value - 101.',
596
                    ],
597
                ],
598
            ],
599
600
            ['100.50', [new Compare('100.5', operator: '===')], ['' => ['Value must be equal to "100.5".']]],
601
        ];
602
    }
603
604
    public function testSkipOnError(): void
605
    {
606
        $this->testSkipOnErrorInternal(new Compare(1), new Compare(1, skipOnError: true));
607
    }
608
609
    public function testWhen(): void
610
    {
611
        $when = static fn (mixed $value): bool => $value !== null;
612
        $this->testWhenInternal(new Compare(1), new Compare(1, when: $when));
613
    }
614
}
615