Passed
Push — master ( 102bf2...5e6609 )
by
unknown
20:09 queued 17:40
created

ObjectDataSetTest.php$9 ➔ toArray()   A

Complexity

Conditions 2

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
c 0
b 0
f 0
dl 0
loc 3
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Validator\Tests\TestEnvironments\Php81\DataSet;
6
7
use PHPUnit\Framework\TestCase;
8
use Traversable;
9
use Yiisoft\Validator\DataSet\ObjectDataSet;
10
use Yiisoft\Validator\Rule\Count;
11
use Yiisoft\Validator\Rule\Each;
12
use Yiisoft\Validator\Rule\HasLength;
13
use Yiisoft\Validator\Rule\Nested;
14
use Yiisoft\Validator\Rule\Number;
15
use Yiisoft\Validator\Rule\Required;
16
use Yiisoft\Validator\RuleInterface;
17
use Yiisoft\Validator\Tests\Support\Data\Charts\Chart;
18
use Yiisoft\Validator\Tests\Support\Data\TitleTrait;
19
use Yiisoft\Validator\Tests\Support\Rule\NotRuleAttribute;
20
21
final class ObjectDataSetTest extends TestCase
22
{
23
    /**
24
     * @dataProvider dataProvider
25
     *
26
     * @param RuleInterface[]|RuleInterface[][]|RuleInterface[][][] $expectedRules
27
     */
28
    public function testCollectRules(object $object, array $expectedRules): void
29
    {
30
        $dataSet = new ObjectDataSet($object);
31
32
        $rulesArray = $this->toNestedArray($dataSet->getRules());
33
34
        $this->assertEquals($expectedRules, $rulesArray);
35
    }
36
37
    public function dataProvider(): array
38
    {
39
        return [
40
            [
41
                new class () {
42
                },
43
                [],
44
            ],
45
            [
46
                new class () {
47
                    private $property1;
48
                },
49
                [],
50
            ],
51
            [
52
                new class () {
53
                    #[NotRuleAttribute]
54
                    private $property1;
55
                },
56
                [],
57
            ],
58
            [
59
                new class () {
60
                    #[Required()]
61
                    private $property1;
62
                },
63
                [
64
                    'property1' => [
65
                        new Required(),
66
                    ],
67
                ],
68
            ],
69
            [
70
                new class () {
71
                    use TitleTrait;
72
                },
73
                [
74
                    'title' => [
75
                        new HasLength(max: 255),
76
                    ],
77
                ],
78
            ],
79
            [
80
                new class () {
81
                    #[Required()]
82
                    #[HasLength(max: 255, skipOnEmpty: true)]
83
                    private $property1;
84
                    #[Required()]
85
                    #[HasLength(max: 255, skipOnEmpty: true)]
86
                    private $property2;
87
                },
88
                [
89
                    'property1' => [
90
                        new Required(),
91
                        new HasLength(max: 255, skipOnEmpty: true),
92
                    ],
93
                    'property2' => [
94
                        new Required(),
95
                        new HasLength(max: 255, skipOnEmpty: true),
96
                    ],
97
                ],
98
            ],
99
            [
100
                new class () {
101
                    #[Each([
102
                        new Required(),
103
                        new HasLength(max: 255, skipOnEmpty: true),
104
                    ])]
105
                    #[HasLength(max: 255, skipOnEmpty: true)]
106
                    private $property1;
107
                },
108
                [
109
                    'property1' => [
110
                        new Each([
111
                            new Required(),
112
                            new HasLength(max: 255, skipOnEmpty: true),
113
                        ]),
114
                        new HasLength(max: 255, skipOnEmpty: true),
115
                    ],
116
                ],
117
            ],
118
            [
119
                new class () {
120
                    #[Nested([
121
                        new Required(),
122
                        new HasLength(max: 255, skipOnEmpty: true),
123
                    ])]
124
                    #[Each([
125
                        new Required(),
126
                        new HasLength(max: 255, skipOnEmpty: true),
127
                    ])]
128
                    #[HasLength(max: 255, skipOnEmpty: true)]
129
                    private $property1;
130
                },
131
                [
132
                    'property1' => [
133
                        new Nested([
134
                            new Required(),
135
                            new HasLength(max: 255, skipOnEmpty: true),
136
                        ]),
137
                        new Each([
138
                            new Required(),
139
                            new HasLength(max: 255, skipOnEmpty: true),
140
                        ]),
141
                        new HasLength(max: 255, skipOnEmpty: true),
142
                    ],
143
                ],
144
            ],
145
            [
146
                new class () {
147
                    #[HasLength(max: 255, skipOnEmpty: true)]
148
                    #[HasLength(max: 255, skipOnEmpty: false)]
149
                    private $property1;
150
                },
151
                [
152
                    'property1' => [
153
                        new HasLength(max: 255, skipOnEmpty: true),
154
                        new HasLength(max: 255, skipOnEmpty: false),
155
                    ],
156
                ],
157
            ],
158
            [
159
                new class () {
160
                    #[Nested([
161
                        new Required(),
162
                        new HasLength(max: 255, skipOnEmpty: true),
163
                    ])]
164
                    #[Nested([
165
                        new Required(),
166
                        new HasLength(max: 255, skipOnEmpty: true),
167
                    ])]
168
                    #[HasLength(max: 255, skipOnEmpty: true)]
169
                    #[HasLength(max: 255, skipOnEmpty: false)]
170
                    private $property1;
171
                },
172
                [
173
                    'property1' => [
174
                        new Nested([
175
                            new Required(),
176
                            new HasLength(max: 255, skipOnEmpty: true),
177
                        ]),
178
                        new Nested([
179
                            new Required(),
180
                            new HasLength(max: 255, skipOnEmpty: true),
181
                        ]),
182
                        new HasLength(max: 255, skipOnEmpty: true),
183
                        new HasLength(max: 255, skipOnEmpty: false),
184
                    ],
185
                ],
186
            ],
187
        ];
188
    }
189
190
    public function testMoreComplexEmbeddedRule(): void
191
    {
192
        $dataSet = new ObjectDataSet(new Chart());
193
        $secondEmbeddedRules = [
194
            'x' => [new Number(min: -10, max: 10)],
195
            'y' => [new Number(min: -10, max: 10)],
196
        ];
197
        $firstEmbeddedRules = [
198
            'coordinates' => new Nested(
199
                $secondEmbeddedRules,
200
                requirePropertyPath: true,
201
                noPropertyPathMessage: 'Custom message 4.'
202
            ),
203
            'rgb' => [
204
                new Count(exactly: 3),
205
                new Each(
206
                    [new Number(min: 0, max: 255)],
207
                    incorrectInputMessage: 'Custom message 5.',
208
                ),
209
            ],
210
        ];
211
212
        $actualRules = $this->toNestedArray($dataSet->getRules());
213
214
        // check Chart structure has right structure
215
        $this->assertIsArray($actualRules);
216
        $this->assertArrayHasKey('points', $actualRules);
217
        $this->assertCount(1, $actualRules = $this->toArray($actualRules['points']));
218
        $this->assertInstanceOf(Each::class, $actualRules[0]);
219
220
        // check Chart structure has right structure
221
        $actualFirstEmbeddedRules = $this->toArray($actualRules[0]->getRules());
222
        $this->assertIsArray($actualFirstEmbeddedRules);
223
        $this->assertCount(1, $actualFirstEmbeddedRules);
224
        $this->assertInstanceOf(Nested::class, $actualFirstEmbeddedRules[0]);
225
226
        // check Point structure has right structure
227
        $innerRules = $this->toArray($actualFirstEmbeddedRules[0]->getRules());
228
        // rgb has usual structure. We can check as is
229
        $this->assertEquals($firstEmbeddedRules['rgb'], $this->toArray($innerRules['rgb']));
230
231
        // coordinates has embedded structure, so we need to unpack rules before check it
232
        $this->assertIsArray($innerRules = $this->toArray($innerRules['coordinates']));
233
        $this->assertCount(1, $innerRules);
234
        $this->assertInstanceOf(Each::class, $innerRules[0]);
235
236
        $secondInnerRules = $this->toArray($innerRules[0]->getRules());
237
        $this->assertIsArray($secondInnerRules);
238
        $this->assertCount(1, $secondInnerRules);
239
        $this->assertInstanceOf(Nested::class, $secondInnerRules[0]);
240
        $this->assertEquals($secondEmbeddedRules, $this->toNestedArray($secondInnerRules[0]->getRules()));
241
    }
242
243
    public function toArray(iterable $rules): array
244
    {
245
        return $rules instanceof Traversable ? iterator_to_array($rules) : (array) $rules;
246
    }
247
248
    private function toNestedArray(iterable $doubleIterable): array
249
    {
250
        $actualRules = [];
251
        foreach ($doubleIterable as $key => $iterable) {
252
            $actualRules[$key] = $this->toArray($iterable);
253
        }
254
255
        return $actualRules;
256
    }
257
}
258