Passed
Push — master ( 9f7d35...3f1c7e )
by Wilmer
08:50 queued 06:32
created

TestSchemaTrait::normalizeArrayKeys()   B

Complexity

Conditions 7
Paths 10

Size

Total Lines 33
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 7.1929

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 7
eloc 20
nc 10
nop 2
dl 0
loc 33
ccs 16
cts 19
cp 0.8421
crap 7.1929
rs 8.6666
c 1
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Db\TestUtility;
6
7
use PDO;
8
use Yiisoft\Db\Constraint\CheckConstraint;
9
use Yiisoft\Db\Constraint\Constraint;
10
use Yiisoft\Db\Constraint\ForeignKeyConstraint;
11
use Yiisoft\Db\Constraint\IndexConstraint;
12
use Yiisoft\Db\Schema\ColumnSchema;
13
use Yiisoft\Db\Schema\Schema;
14
use Yiisoft\Db\Schema\TableSchema;
15
16
use function array_keys;
17
use function fclose;
18
use function fopen;
19
use function gettype;
20
use function is_array;
21
use function json_encode;
22
use function ksort;
23
use function print_r;
24
use function sort;
25
use function sprintf;
26
use function strtolower;
27
28
trait TestSchemaTrait
29
{
30 4
    public function testGetTableSchemasWithAttrCase(): void
31
    {
32 4
        $db = $this->getConnection(false);
0 ignored issues
show
Bug introduced by
It seems like getConnection() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

32
        /** @scrutinizer ignore-call */ 
33
        $db = $this->getConnection(false);
Loading history...
33
34 4
        $db->getSlavePdo()->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER);
35
36 4
        $this->assertCount(count($db->getSchema()->getTableNames()), $db->getSchema()->getTableSchemas());
0 ignored issues
show
Bug introduced by
It seems like assertCount() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

36
        $this->/** @scrutinizer ignore-call */ 
37
               assertCount(count($db->getSchema()->getTableNames()), $db->getSchema()->getTableSchemas());
Loading history...
37
38 4
        $db->getSlavePdo()->setAttribute(PDO::ATTR_CASE, PDO::CASE_UPPER);
39
40 4
        $this->assertCount(count($db->getSchema()->getTableNames()), $db->getSchema()->getTableSchemas());
41 4
    }
42
43 4
    public function testGetNonExistingTableSchema(): void
44
    {
45 4
        $this->assertNull($this->getConnection()->getSchema()->getTableSchema('nonexisting_table'));
0 ignored issues
show
Bug introduced by
It seems like assertNull() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

45
        $this->/** @scrutinizer ignore-call */ 
46
               assertNull($this->getConnection()->getSchema()->getTableSchema('nonexisting_table'));
Loading history...
46 4
    }
47
48 4
    public function testSchemaCache(): void
49
    {
50 4
        $db = $this->getConnection();
51
52 4
        $schema = $db->getSchema();
53
54 4
        $schema->getDb()->setEnableSchemaCache(true);
55 4
        $schema->getDb()->setSchemaCache($this->cache);
56
57 4
        $noCacheTable = $schema->getTableSchema('type', true);
58 4
        $cachedTable = $schema->getTableSchema('type', false);
59
60 4
        $this->assertEquals($noCacheTable, $cachedTable);
0 ignored issues
show
Bug introduced by
It seems like assertEquals() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

60
        $this->/** @scrutinizer ignore-call */ 
61
               assertEquals($noCacheTable, $cachedTable);
Loading history...
61
62 4
        $db->createCommand()->renameTable('type', 'type_test');
63
64 4
        $noCacheTable = $schema->getTableSchema('type', true);
65
66 4
        $this->assertNotSame($noCacheTable, $cachedTable);
0 ignored issues
show
Bug introduced by
It seems like assertNotSame() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

66
        $this->/** @scrutinizer ignore-call */ 
67
               assertNotSame($noCacheTable, $cachedTable);
Loading history...
67
68 4
        $db->createCommand()->renameTable('type_test', 'type');
69 4
    }
70
71
    /**
72
     * @depends testSchemaCache
73
     */
74 4
    public function testRefreshTableSchema(): void
75
    {
76 4
        $schema = $this->getConnection()->getSchema();
77
78 4
        $schema->getDb()->setEnableSchemaCache(true);
79 4
        $schema->getDb()->setSchemaCache($this->cache);
80
81 4
        $noCacheTable = $schema->getTableSchema('type', true);
82
83 4
        $schema->refreshTableSchema('type');
84
85 4
        $refreshedTable = $schema->getTableSchema('type', false);
86
87 4
        $this->assertNotSame($noCacheTable, $refreshedTable);
88 4
    }
89
90 2
    public function testCompositeFk(): void
91
    {
92 2
        $schema = $this->getConnection()->getSchema();
93
94 2
        $table = $schema->getTableSchema('composite_fk');
95
96 2
        $fk = $table->getForeignKeys();
97
98 2
        $this->assertCount(1, $fk);
99 2
        $this->assertTrue(isset($fk['FK_composite_fk_order_item']));
0 ignored issues
show
Bug introduced by
It seems like assertTrue() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

99
        $this->/** @scrutinizer ignore-call */ 
100
               assertTrue(isset($fk['FK_composite_fk_order_item']));
Loading history...
100 2
        $this->assertEquals('order_item', $fk['FK_composite_fk_order_item'][0]);
101 2
        $this->assertEquals('order_id', $fk['FK_composite_fk_order_item']['order_id']);
102 2
        $this->assertEquals('item_id', $fk['FK_composite_fk_order_item']['item_id']);
103 2
    }
104
105 3
    public function testGetPDOType(): void
106
    {
107
        $values = [
108 3
            [null, PDO::PARAM_NULL],
109
            ['', PDO::PARAM_STR],
110
            ['hello', PDO::PARAM_STR],
111
            [0, PDO::PARAM_INT],
112
            [1, PDO::PARAM_INT],
113
            [1337, PDO::PARAM_INT],
114
            [true, PDO::PARAM_BOOL],
115
            [false, PDO::PARAM_BOOL],
116 3
            [$fp = fopen(__FILE__, 'rb'), PDO::PARAM_LOB],
117
        ];
118
119 3
        $schema = $this->getConnection()->getSchema();
120
121 3
        foreach ($values as $value) {
122 3
            $this->assertEquals($value[1], $schema->getPdoType($value[0]), 'type for value ' . print_r($value[0], true) . ' does not match.');
123
        }
124
125 3
        fclose($fp);
0 ignored issues
show
Bug introduced by
It seems like $fp can also be of type false; however, parameter $handle of fclose() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

125
        fclose(/** @scrutinizer ignore-type */ $fp);
Loading history...
126 3
    }
127
128 4
    public function testColumnSchema(): void
129
    {
130 4
        $columns = $this->getExpectedColumns();
0 ignored issues
show
Bug introduced by
It seems like getExpectedColumns() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

130
        /** @scrutinizer ignore-call */ 
131
        $columns = $this->getExpectedColumns();
Loading history...
131
132 4
        $table = $this->getConnection(false)->getSchema()->getTableSchema('type', true);
133
134 4
        $expectedColNames = array_keys($columns);
135
136 4
        sort($expectedColNames);
137
138 4
        $colNames = $table->getColumnNames();
139
140 4
        sort($colNames);
141
142 4
        $this->assertEquals($expectedColNames, $colNames);
143
144 4
        foreach ($table->getColumns() as $name => $column) {
145 4
            $expected = $columns[$name];
146 4
            $this->assertSame(
0 ignored issues
show
Bug introduced by
It seems like assertSame() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

146
            $this->/** @scrutinizer ignore-call */ 
147
                   assertSame(
Loading history...
147 4
                $expected['dbType'],
148 4
                $column->getDbType(),
149 4
                "dbType of column $name does not match. type is {$column->getType()}, dbType is {$column->getDbType()}."
150
            );
151 4
            $this->assertSame(
152 4
                $expected['phpType'],
153 4
                $column->getPhpType(),
154 4
                "phpType of column $name does not match. type is {$column->getType()}, dbType is {$column->getDbType()}."
155
            );
156 4
            $this->assertSame($expected['type'], $column->getType(), "type of column $name does not match.");
157 4
            $this->assertSame(
158 4
                $expected['allowNull'],
159 4
                $column->isAllowNull(),
160 4
                "allowNull of column $name does not match."
161
            );
162 4
            $this->assertSame(
163 4
                $expected['autoIncrement'],
164 4
                $column->isAutoIncrement(),
165 4
                "autoIncrement of column $name does not match."
166
            );
167 4
            $this->assertSame(
168 4
                $expected['enumValues'],
169 4
                $column->getEnumValues(),
170 4
                "enumValues of column $name does not match."
171
            );
172 4
            $this->assertSame($expected['size'], $column->getSize(), "size of column $name does not match.");
173 4
            $this->assertSame(
174 4
                $expected['precision'],
175 4
                $column->getPrecision(),
176 4
                "precision of column $name does not match."
177
            );
178 4
            $this->assertSame($expected['scale'], $column->getScale(), "scale of column $name does not match.");
179 4
            if (\is_object($expected['defaultValue'])) {
180 3
                $this->assertIsObject(
0 ignored issues
show
Bug introduced by
It seems like assertIsObject() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

180
                $this->/** @scrutinizer ignore-call */ 
181
                       assertIsObject(
Loading history...
181 3
                    $column->getDefaultValue(),
182 3
                    "defaultValue of column $name is expected to be an object but it is not."
183
                );
184 3
                $this->assertEquals(
185 3
                    (string) $expected['defaultValue'],
186 3
                    (string) $column->getDefaultValue(),
187 3
                    "defaultValue of column $name does not match."
188
                );
189
            } else {
190 4
                $this->assertEquals(
191 4
                    $expected['defaultValue'],
192 4
                    $column->getDefaultValue(),
193 4
                    "defaultValue of column $name does not match."
194
                );
195
            }
196
            /* Pgsql only */
197 4
            if (isset($expected['dimension'])) {
198 1
                $this->assertSame(
199 1
                    $expected['dimension'],
200 1
                    $column->getDimension(),
201 1
                    "dimension of column $name does not match"
202
                );
203
            }
204
        }
205 4
    }
206
207 4
    public function testColumnSchemaDbTypecastWithEmptyCharType(): void
208
    {
209 4
        $columnSchema = new ColumnSchema();
210
211 4
        $columnSchema->setType(Schema::TYPE_CHAR);
212
213 4
        $this->assertSame('', $columnSchema->dbTypecast(''));
214 4
    }
215
216 4
    public function testNegativeDefaultValues(): void
217
    {
218 4
        $schema = $this->getConnection()->getSchema();
219
220 4
        $table = $schema->getTableSchema('negative_default_values');
221
222 4
        $this->assertEquals(-123, $table->getColumn('tinyint_col')->getDefaultValue());
223 4
        $this->assertEquals(-123, $table->getColumn('smallint_col')->getDefaultValue());
224 4
        $this->assertEquals(-123, $table->getColumn('int_col')->getDefaultValue());
225 4
        $this->assertEquals(-123, $table->getColumn('bigint_col')->getDefaultValue());
226 4
        $this->assertEquals(-12345.6789, $table->getColumn('float_col')->getDefaultValue());
227 4
        $this->assertEquals(-33.22, $table->getColumn('numeric_col')->getDefaultValue());
228 4
    }
229
230 4
    public function testContraintTablesExistance(): void
231
    {
232
        $tableNames = [
233 4
            'T_constraints_1',
234
            'T_constraints_2',
235
            'T_constraints_3',
236
            'T_constraints_4',
237
        ];
238
239 4
        $schema = $this->getConnection()->getSchema();
240
241 4
        foreach ($tableNames as $tableName) {
242 4
            $tableSchema = $schema->getTableSchema($tableName);
243 4
            $this->assertInstanceOf(TableSchema::class, $tableSchema, $tableName);
0 ignored issues
show
Bug introduced by
It seems like assertInstanceOf() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

243
            $this->/** @scrutinizer ignore-call */ 
244
                   assertInstanceOf(TableSchema::class, $tableSchema, $tableName);
Loading history...
244
        }
245 4
    }
246
247 192
    private function assertMetadataEquals($expected, $actual): void
248
    {
249 192
        switch (strtolower(gettype($expected))) {
250 192
            case 'object':
251 36
                $this->assertIsObject($actual);
252 36
                break;
253 156
            case 'array':
254 144
                $this->assertIsArray($actual);
0 ignored issues
show
Bug introduced by
It seems like assertIsArray() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

254
                $this->/** @scrutinizer ignore-call */ 
255
                       assertIsArray($actual);
Loading history...
255 144
                break;
256 12
            case 'null':
257 12
                $this->assertNull($actual);
258 12
                break;
259
        }
260
261 192
        if (is_array($expected)) {
262 144
            $this->normalizeArrayKeys($expected, false);
263 144
            $this->normalizeArrayKeys($actual, false);
264
        }
265
266 192
        $this->normalizeConstraints($expected, $actual);
267
268 192
        if (is_array($expected)) {
269 144
            $this->normalizeArrayKeys($expected, true);
270 144
            $this->normalizeArrayKeys($actual, true);
271
        }
272
273 192
        $this->assertEquals($expected, $actual);
274 192
    }
275
276 144
    private function normalizeArrayKeys(array &$array, bool $caseSensitive): void
277
    {
278 144
        $newArray = [];
279
280 144
        foreach ($array as $value) {
281 87
            if ($value instanceof Constraint) {
282 87
                $key = (array) $value;
283
                unset(
284 87
                    $key["\000Yiisoft\Db\Constraint\Constraint\000name"],
285 87
                    $key["\u0000Yiisoft\\Db\\Constraint\\ForeignKeyConstraint\u0000foreignSchemaName"]
286
                );
287
288 87
                foreach ($key as $keyName => $keyValue) {
289 87
                    if ($keyValue instanceof AnyCaseValue) {
290
                        $key[$keyName] = $keyValue->value;
291 87
                    } elseif ($keyValue instanceof AnyValue) {
292
                        $key[$keyName] = '[AnyValue]';
293
                    }
294
                }
295
296 87
                ksort($key, SORT_STRING);
297
298 87
                $newArray[$caseSensitive
299 87
                    ? json_encode($key, JSON_THROW_ON_ERROR)
300 87
                    : strtolower(json_encode($key, JSON_THROW_ON_ERROR))] = $value;
301
            } else {
302
                $newArray[] = $value;
303
            }
304
        }
305
306 144
        ksort($newArray, SORT_STRING);
307
308 144
        $array = $newArray;
309 144
    }
310
311 192
    private function normalizeConstraints(&$expected, &$actual): void
312
    {
313 192
        if (is_array($expected)) {
314 144
            foreach ($expected as $key => $value) {
315 87
                if (!$value instanceof Constraint || !isset($actual[$key]) || !$actual[$key] instanceof Constraint) {
316
                    continue;
317
                }
318
319 87
                $this->normalizeConstraintPair($value, $actual[$key]);
320
            }
321 48
        } elseif ($expected instanceof Constraint && $actual instanceof Constraint) {
322 36
            $this->normalizeConstraintPair($expected, $actual);
323
        }
324 192
    }
325
326 123
    private function normalizeConstraintPair(Constraint $expectedConstraint, Constraint $actualConstraint): void
327
    {
328 123
        if (get_class($expectedConstraint) !== get_class($actualConstraint)) {
329
            return;
330
        }
331
332 123
        foreach (array_keys((array) $expectedConstraint) as $name) {
333 123
            if ($expectedConstraint->getName() instanceof AnyValue) {
334 63
                $actualConstraint->name($expectedConstraint->getName());
335 81
            } elseif ($expectedConstraint->getName() instanceof AnyCaseValue) {
336
                $actualConstraint->name(new AnyCaseValue($actualConstraint->getName()));
337
            }
338
        }
339 123
    }
340
341
    public function constraintsProviderTrait(): array
342
    {
343
        return [
344
            '1: primary key' => [
345
                'T_constraints_1',
346
                'primaryKey',
347
                (new Constraint())
348
                    ->name(AnyValue::getInstance())
349
                    ->columnNames(['C_id'])
350
            ],
351
            '1: check' => [
352
                'T_constraints_1',
353
                'checks',
354
                [
355
                    (new CheckConstraint())
356
                        ->name(AnyValue::getInstance())
357
                        ->columnNames(['C_check'])
358
                        ->expression("C_check <> ''")
359
                ]
360
            ],
361
            '1: unique' => [
362
                'T_constraints_1',
363
                'uniques',
364
                [
365
                    (new Constraint())
366
                        ->name('CN_unique')
367
                        ->columnNames(['C_unique'])
368
                ]
369
            ],
370
            '1: index' => [
371
                'T_constraints_1',
372
                'indexes',
373
                [
374
                    (new IndexConstraint())
375
                        ->name(AnyValue::getInstance())
376
                        ->columnNames(['C_id'])
377
                        ->unique(true)
378
                        ->primary(true),
379
                    (new IndexConstraint())
380
                        ->name('CN_unique')
381
                        ->columnNames(['C_unique'])
382
                        ->primary(false)
383
                        ->unique(true)
384
                ]
385
            ],
386
            '1: default' => ['T_constraints_1', 'defaultValues', false],
387
388
            '2: primary key' => [
389
                'T_constraints_2',
390
                'primaryKey',
391
                (new Constraint())
392
                    ->name('CN_pk')
393
                    ->columnNames(['C_id_1', 'C_id_2'])
394
            ],
395
            '2: unique' => [
396
                'T_constraints_2',
397
                'uniques',
398
                [
399
                    (new Constraint())
400
                        ->name('CN_constraints_2_multi')
401
                        ->columnNames(['C_index_2_1', 'C_index_2_2'])
402
                ]
403
            ],
404
            '2: index' => [
405
                'T_constraints_2',
406
                'indexes',
407
                [
408
                    (new IndexConstraint())
409
                        ->name(AnyValue::getInstance())
410
                        ->columnNames(['C_id_1', 'C_id_2'])
411
                        ->unique(true)
412
                        ->primary(true),
413
                    (new IndexConstraint())
414
                        ->name('CN_constraints_2_single')
415
                        ->columnNames(['C_index_1'])
416
                        ->primary(false)
417
                        ->unique(false),
418
                    (new IndexConstraint())
419
                        ->name('CN_constraints_2_multi')
420
                        ->columnNames(['C_index_2_1', 'C_index_2_2'])
421
                        ->primary(false)
422
                        ->unique(true)
423
                ]
424
            ],
425
            '2: check' => ['T_constraints_2', 'checks', []],
426
            '2: default' => ['T_constraints_2', 'defaultValues', false],
427
428
            '3: primary key' => ['T_constraints_3', 'primaryKey', null],
429
            '3: foreign key' => [
430
                'T_constraints_3',
431
                'foreignKeys',
432
                [
433
                    (new ForeignKeyConstraint())
434
                        ->name('CN_constraints_3')
435
                        ->columnNames(['C_fk_id_1', 'C_fk_id_2'])
436
                        ->foreignTableName('T_constraints_2')
437
                        ->foreignColumnNames(['C_id_1', 'C_id_2'])
438
                        ->onDelete('CASCADE')
439
                        ->onUpdate('CASCADE')
440
                ]
441
            ],
442
            '3: unique' => ['T_constraints_3', 'uniques', []],
443
            '3: index' => [
444
                'T_constraints_3',
445
                'indexes',
446
                [
447
                    (new IndexConstraint())
448
                        ->name('CN_constraints_3')
449
                        ->columnNames(['C_fk_id_1', 'C_fk_id_2'])
450
                        ->unique(false)
451
                        ->primary(false)
452
                ]
453
            ],
454
            '3: check' => ['T_constraints_3', 'checks', []],
455
            '3: default' => ['T_constraints_3', 'defaultValues', false],
456
457
            '4: primary key' => [
458
                'T_constraints_4',
459
                'primaryKey',
460
                (new Constraint())
461
                    ->name(AnyValue::getInstance())
462
                    ->columnNames(['C_id'])
463
            ],
464
            '4: unique' => [
465
                'T_constraints_4',
466
                'uniques',
467
                [
468
                    (new Constraint())
469
                        ->name('CN_constraints_4')
470
                        ->columnNames(['C_col_1', 'C_col_2'])
471
                ]
472
            ],
473
            '4: check' => ['T_constraints_4', 'checks', []],
474
            '4: default' => ['T_constraints_4', 'defaultValues', false],
475
        ];
476
    }
477
478
    public function pdoAttributesProviderTrait(): array
479
    {
480
        return [
481
            [[PDO::ATTR_EMULATE_PREPARES => true]],
482
            [[PDO::ATTR_EMULATE_PREPARES => false]],
483
        ];
484
    }
485
486
    public function tableSchemaCachePrefixesProviderTrait(): array
487
    {
488
        $configs = [
489
            [
490
                'prefix' => '',
491
                'name'   => 'type',
492
            ],
493
            [
494
                'prefix' => '',
495
                'name'   => '{{%type}}',
496
            ],
497
            [
498
                'prefix' => 'ty',
499
                'name'   => '{{%pe}}',
500
            ],
501
        ];
502
503
        $data = [];
504
        foreach ($configs as $config) {
505
            foreach ($configs as $testConfig) {
506
                if ($config === $testConfig) {
507
                    continue;
508
                }
509
510
                $description = sprintf(
511
                    "%s (with '%s' prefix) against %s (with '%s' prefix)",
512
                    $config['name'],
513
                    $config['prefix'],
514
                    $testConfig['name'],
515
                    $testConfig['prefix']
516
                );
517
                $data[$description] = [
518
                    $config['prefix'],
519
                    $config['name'],
520
                    $testConfig['prefix'],
521
                    $testConfig['name'],
522
                ];
523
            }
524
        }
525
526
        return $data;
527
    }
528
529
    public function lowercaseConstraintsProviderTrait(): array
530
    {
531
        return $this->constraintsProvider();
0 ignored issues
show
Bug introduced by
The method constraintsProvider() does not exist on Yiisoft\Db\TestUtility\TestSchemaTrait. Did you maybe mean constraintsProviderTrait()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

531
        return $this->/** @scrutinizer ignore-call */ constraintsProvider();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
532
    }
533
534
    public function uppercaseConstraintsProviderTrait(): array
535
    {
536
        return $this->constraintsProvider();
537
    }
538
}
539