GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

ColumnDefinitionTest   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 455
Duplicated Lines 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 270
c 3
b 0
f 0
dl 0
loc 455
rs 10
wmc 13

13 Methods

Rating   Name   Duplication   Size   Complexity  
A testParseInvalidDatatypes() 0 5 1
A testApplyTableCollationEffectOnColumnType() 0 10 1
A applyTableCollationEffectOnColumnTypeProvider() 0 13 1
A testApplyTableCollationSetsCollation() 0 13 1
A testParseDatatypes() 0 9 1
A testParseIndexes() 0 14 1
A testParseInvalidDefaultValues() 0 5 1
A parseInvalidDefaultValuesProvider() 0 13 1
A testGetUninitialisedValues() 0 7 1
A parseIndexesProvider() 0 10 1
B parseDatatypesProvider() 0 222 1
A getUninitialisedValuesProvider() 0 10 1
A parseInvalidDatatypesProvider() 0 45 1
1
<?php
2
3
namespace Graze\Morphism\Parse;
4
5
use Exception;
6
use Graze\Morphism\Test\Parse\TestCase;
7
use RuntimeException;
8
9
class ColumnDefinitionTest extends TestCase
10
{
11
    /**
12
     * @dataProvider parseDatatypesProvider
13
     * @param string $text
14
     * @param string $expected
15
     */
16
    public function testParseDatatypes($text, $expected)
17
    {
18
        $stream = $this->makeStream($text);
19
        $collation = new CollationInfo();
20
21
        $column = new ColumnDefinition();
22
        $column->parse($stream);
23
24
        $this->assertSame($expected, $column->toString($collation));
25
    }
26
27
    /**
28
     * @return array
29
     */
30
    public function parseDatatypesProvider()
31
    {
32
        return [
33
            ["x int",                       "`x` int DEFAULT NULL"],
34
            ["x int signed",                "`x` int DEFAULT NULL"],
35
            ["x int unsigned",              "`x` int unsigned DEFAULT NULL"],
36
            ["x int(5)",                    "`x` int DEFAULT NULL"],
37
            ["x int(5) default null",       "`x` int DEFAULT NULL"],
38
            ["x int not null default 1",    "`x` int NOT NULL DEFAULT '1'"],
39
            ["x int default 1",             "`x` int DEFAULT '1'"],
40
            ["x int auto_increment",        "`x` int NOT NULL AUTO_INCREMENT"],
41
            ["x int comment 'blah'",        "`x` int DEFAULT NULL COMMENT 'blah'"],
42
            ["x int serial default value",  "`x` int NOT NULL AUTO_INCREMENT"],
43
44
            ["x int primary key",           "`x` int NOT NULL"],
45
            ["x int key",                   "`x` int NOT NULL"],
46
            ["x int unique",                "`x` int DEFAULT NULL"],
47
            ["x int unique key",            "`x` int DEFAULT NULL"],
48
49
            ["x bit",                       "`x` bit DEFAULT NULL"],
50
            ["x bit(4)",                    "`x` bit(4) DEFAULT NULL"],
51
            ["x bit(4) default 4",          "`x` bit(4) DEFAULT b'100'"],
52
            ["x bit(4) default b'0101'",    "`x` bit(4) DEFAULT b'101'"],
53
            ["x bit(8) default x'e4'",      "`x` bit(8) DEFAULT b'11100100'"],
54
55
            ["x tinyint",                   "`x` tinyint DEFAULT NULL"],
56
            ["x tinyint unsigned",          "`x` tinyint unsigned DEFAULT NULL"],
57
            ["x smallint",                  "`x` smallint DEFAULT NULL"],
58
            ["x smallint unsigned",         "`x` smallint unsigned DEFAULT NULL"],
59
            ["x mediumint",                 "`x` mediumint DEFAULT NULL"],
60
            ["x mediumint unsigned",        "`x` mediumint unsigned DEFAULT NULL"],
61
            ["x bigint",                    "`x` bigint DEFAULT NULL"],
62
            ["x bigint unsigned",           "`x` bigint unsigned DEFAULT NULL"],
63
64
            ["x double",                    "`x` double DEFAULT NULL"],
65
            ["x double unsigned",           "`x` double unsigned DEFAULT NULL"],
66
            ["x double(12,4)",              "`x` double(12,4) DEFAULT NULL"],
67
68
            ["x float",                     "`x` float DEFAULT NULL"],
69
            ["x float unsigned",            "`x` float unsigned DEFAULT NULL"],
70
            ["x float(8,3)",                "`x` float(8,3) DEFAULT NULL"],
71
72
            ["x decimal",                   "`x` decimal(10,0) DEFAULT NULL"],
73
            ["x decimal unsigned",          "`x` decimal(10,0) unsigned DEFAULT NULL"],
74
            ["x decimal(8)",                "`x` decimal(8,0) DEFAULT NULL"],
75
            ["x decimal(8,3)",              "`x` decimal(8,3) DEFAULT NULL"],
76
            ["x decimal default 1",         "`x` decimal(10,0) DEFAULT '1'"],
77
            ["x decimal(5,3) default 1",    "`x` decimal(5,3) DEFAULT '1.000'"],
78
            ["x decimal(7,3) unsigned default 1",    "`x` decimal(7,3) unsigned DEFAULT '1.000'"],
79
80
            ["x date",                      "`x` date DEFAULT NULL"],
81
            ["x date default 0",            "`x` date DEFAULT '0000-00-00'"],
82
            ["x date default '1970-08-12'", "`x` date DEFAULT '1970-08-12'"],
83
84
            ["x time",                      "`x` time DEFAULT NULL"],
85
            ["x time default 0",            "`x` time DEFAULT '00:00:00'"],
86
            ["x time default '23:59:59'",   "`x` time DEFAULT '23:59:59'"],
87
88
            ["x datetime",                               "`x` datetime DEFAULT NULL"],
89
            ["x datetime default 0",                     "`x` datetime DEFAULT '0000-00-00 00:00:00'"],
90
            ["x datetime default '1970-08-12 23:58:57'", "`x` datetime DEFAULT '1970-08-12 23:58:57'"],
91
            ["x datetime default current_timestamp",     "`x` datetime DEFAULT CURRENT_TIMESTAMP"],
92
            ["x datetime on update current_timestamp",   "`x` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP"],
93
            ["x datetime default current_timestamp on update current_timestamp",
94
                "`x` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP"],
95
            ["x datetime default current_timestamp default_generated on update current_timestamp",
96
                "`x` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP"],
97
98
            ["x timestamp",                               "`x` timestamp NOT NULL"],
99
            ["x timestamp default 0",                     "`x` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'"],
100
            ["x timestamp default '1970-08-12 19:18:17'", "`x` timestamp NOT NULL DEFAULT '1970-08-12 19:18:17'"],
101
            ["x timestamp default current_timestamp",     "`x` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP"],
102
            ["x timestamp default localtime",             "`x` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP"],
103
            ["x timestamp default localtimestamp",        "`x` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP"],
104
            ["x timestamp default now()",                 "`x` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP"],
105
            ["x timestamp on update current_timestamp",   "`x` timestamp NOT NULL ON UPDATE CURRENT_TIMESTAMP"],
106
            ["x timestamp on update localtime",           "`x` timestamp NOT NULL ON UPDATE CURRENT_TIMESTAMP"],
107
            ["x timestamp on update localtimestamp",      "`x` timestamp NOT NULL ON UPDATE CURRENT_TIMESTAMP"],
108
            ["x timestamp on update now()",               "`x` timestamp NOT NULL ON UPDATE CURRENT_TIMESTAMP"],
109
            ["x timestamp default current_timestamp on update current_timestamp",
110
                "`x` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP"],
111
            ["x timestamp on update current_timestamp default current_timestamp",
112
                "`x` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP"],
113
114
            ["x year",             "`x` year(4) DEFAULT NULL"],
115
            ["x year(4)",          "`x` year(4) DEFAULT NULL"],
116
            ["x year default 0",   "`x` year(4) DEFAULT '0000'"],
117
            ["x year default '0'", "`x` year(4) DEFAULT '2000'"],
118
            ["x year default 69",  "`x` year(4) DEFAULT '2069'"],
119
            ["x year default 70",  "`x` year(4) DEFAULT '1970'"],
120
            ["x year default 99",  "`x` year(4) DEFAULT '1999'"],
121
            ["x year default 1901","`x` year(4) DEFAULT '1901'"],
122
            ["x year default 2155","`x` year(4) DEFAULT '2155'"],
123
124
            ["x char",           "`x` char(1) DEFAULT NULL"],
125
            ["x char(4)",        "`x` char(4) DEFAULT NULL"],
126
127
            ["x varchar(255)",   "`x` varchar(255) DEFAULT NULL"],
128
129
            ["x binary",                "`x` binary(1) DEFAULT NULL"],
130
            ["x binary(255)",           "`x` binary(255) DEFAULT NULL"],
131
            ["x binary default 'a'",    "`x` binary(1) DEFAULT 'a'"],
132
133
            ["x varbinary(255)",        "`x` varbinary(255) DEFAULT NULL"],
134
135
            ["x tinyblob",            "`x` tinyblob"],
136
            ["x tinyblob NULL",       "`x` tinyblob"],
137
            ["x tinyblob NOT NULL",   "`x` tinyblob NOT NULL"],
138
139
            ["x blob",                "`x` blob"],
140
            ["x blob NULL",           "`x` blob"],
141
            ["x blob NOT NULL",       "`x` blob NOT NULL"],
142
143
            ["x mediumblob",          "`x` mediumblob"],
144
            ["x mediumblob NULL",     "`x` mediumblob"],
145
            ["x mediumblob NOT NULL", "`x` mediumblob NOT NULL"],
146
147
            ["x longblob",            "`x` longblob"],
148
            ["x longblob NULL",       "`x` longblob"],
149
            ["x longblob NOT NULL",   "`x` longblob NOT NULL"],
150
151
            ["x tinytext",            "`x` tinytext"],
152
            ["x tinytext NULL",       "`x` tinytext"],
153
            ["x tinytext NOT NULL",   "`x` tinytext NOT NULL"],
154
155
            ["x text",                "`x` text"],
156
            ["x text NULL",           "`x` text"],
157
            ["x text NOT NULL",       "`x` text NOT NULL"],
158
            ["x text binary",         "`x` text"],
159
            ["x text charset utf8",   "`x` text CHARACTER SET utf8"],
160
            ["x text collate utf8_unicode_ci", "`x` text CHARACTER SET utf8 COLLATE utf8_unicode_ci"],
161
162
            ["x mediumtext",          "`x` mediumtext"],
163
            ["x mediumtext NULL",     "`x` mediumtext"],
164
            ["x mediumtext NOT NULL", "`x` mediumtext NOT NULL"],
165
166
            ["x longtext",            "`x` longtext"],
167
            ["x longtext NULL",       "`x` longtext"],
168
            ["x longtext NOT NULL",   "`x` longtext NOT NULL"],
169
170
            ["x varchar(3) default 'abc'",  "`x` varchar(3) DEFAULT 'abc'"],
171
172
            ["x enum('a', 'b', 'c')",             "`x` enum('a','b','c') DEFAULT NULL"],
173
            ["x enum('a', 'b', 'c') DEFAULT 'b'", "`x` enum('a','b','c') DEFAULT 'b'"],
174
            ["x enum('a', 'b', 'c') NOT NULL",    "`x` enum('a','b','c') NOT NULL"],
175
176
            ["x set('a', 'b', 'c')",               "`x` set('a','b','c') DEFAULT NULL"],
177
            ["x set('a', 'b', 'c') DEFAULT 'a,c'", "`x` set('a','b','c') DEFAULT 'a,c'"],
178
            ["x set('a', 'b', 'c') NOT NULL",      "`x` set('a','b','c') NOT NULL"],
179
            ["x set('a', 'b', 'c') default ''",      "`x` set('a','b','c') DEFAULT ''"],
180
181
            ["x serial",                 "`x` bigint unsigned NOT NULL AUTO_INCREMENT"],
182
183
            ["x character",              "`x` char(1) DEFAULT NULL"],
184
            ["x character(10)",          "`x` char(10) DEFAULT NULL"],
185
            ["x character varying(100)", "`x` varchar(100) DEFAULT NULL"],
186
187
            ["x double precision",          "`x` double DEFAULT NULL"],
188
            ["x double precision unsigned", "`x` double unsigned DEFAULT NULL"],
189
            ["x double precision(12,4)",    "`x` double(12,4) DEFAULT NULL"],
190
191
            ["x long varbinary",      "`x` mediumblob"],
192
            ["x long varchar",        "`x` mediumtext"],
193
            ["x long",                "`x` mediumtext"],
194
195
            ["x bool",                "`x` tinyint DEFAULT NULL"],
196
            ["x boolean",             "`x` tinyint DEFAULT NULL"],
197
            ["x bool NOT NULL",       "`x` tinyint NOT NULL"],
198
            ["x boolean NOT NULL",    "`x` tinyint NOT NULL"],
199
200
            ["x int1",                "`x` tinyint DEFAULT NULL"],
201
            ["x int1(3)",             "`x` tinyint DEFAULT NULL"],
202
            ["x int1 NOT NULL",       "`x` tinyint NOT NULL"],
203
204
            ["x int2",                "`x` smallint DEFAULT NULL"],
205
            ["x int2(3)",             "`x` smallint DEFAULT NULL"],
206
            ["x int2 NOT NULL",       "`x` smallint NOT NULL"],
207
208
            ["x int3",                "`x` mediumint DEFAULT NULL"],
209
            ["x int3(3)",             "`x` mediumint DEFAULT NULL"],
210
            ["x int3 NOT NULL",       "`x` mediumint NOT NULL"],
211
212
            ["x middleint",           "`x` mediumint DEFAULT NULL"],
213
            ["x middleint(3)",        "`x` mediumint DEFAULT NULL"],
214
            ["x middleint NOT NULL",  "`x` mediumint NOT NULL"],
215
216
            ["x int4",                "`x` int DEFAULT NULL"],
217
            ["x int4(3)",             "`x` int DEFAULT NULL"],
218
            ["x int4 NOT NULL",       "`x` int NOT NULL"],
219
220
            ["x integer",             "`x` int DEFAULT NULL"],
221
            ["x integer(3)",          "`x` int DEFAULT NULL"],
222
            ["x integer NOT NULL",    "`x` int NOT NULL"],
223
224
            ["x int8",                "`x` bigint DEFAULT NULL"],
225
            ["x int8(3)",             "`x` bigint DEFAULT NULL"],
226
            ["x int8 NOT NULL",       "`x` bigint NOT NULL"],
227
228
            ["x dec",                 "`x` decimal(10,0) DEFAULT NULL"],
229
            ["x dec(8)",              "`x` decimal(8,0) DEFAULT NULL"],
230
            ["x dec(8,3)",            "`x` decimal(8,3) DEFAULT NULL"],
231
            ["x dec NOT NULL",        "`x` decimal(10,0) NOT NULL"],
232
233
            ["x numeric",             "`x` decimal(10,0) DEFAULT NULL"],
234
            ["x numeric(8)",          "`x` decimal(8,0) DEFAULT NULL"],
235
            ["x numeric(8,3)",        "`x` decimal(8,3) DEFAULT NULL"],
236
            ["x numeric NOT NULL",    "`x` decimal(10,0) NOT NULL"],
237
238
            ["x fixed",               "`x` decimal(10,0) DEFAULT NULL"],
239
            ["x fixed(8)",            "`x` decimal(8,0) DEFAULT NULL"],
240
            ["x fixed(8,3)",          "`x` decimal(8,3) DEFAULT NULL"],
241
            ["x fixed NOT NULL",      "`x` decimal(10,0) NOT NULL"],
242
243
            ["x real",                "`x` double DEFAULT NULL"],
244
            ["x real(8,3)",           "`x` double(8,3) DEFAULT NULL"],
245
246
            ["x json",                "`x` json"],
247
            ["x json NULL",           "`x` json"],
248
            ["x json NOT NULL",       "`x` json NOT NULL"],
249
250
            // Ignore unrecognised column options
251
            ["x int foo",             "`x` int DEFAULT NULL"],
252
        ];
253
    }
254
255
    /**
256
     * @param string $text
257
     * @dataProvider parseInvalidDatatypesProvider
258
     * @expectedException RuntimeException
259
     */
260
    public function testParseInvalidDatatypes($text)
261
    {
262
        $stream = $this->makeStream($text);
263
        $column = new ColumnDefinition();
264
        $column->parse($stream);
265
    }
266
267
    /**
268
     * @return array
269
     */
270
    public function parseInvalidDatatypesProvider()
271
    {
272
        return [
273
            // Invalid type
274
            ["x foo"],
275
            // Another invalid type
276
            ["x null"],
277
            // No identifier
278
            ["int"],
279
            // Unexpected ZEROFILL keyword
280
            ["x int zerofill"],
281
            // No comma separator
282
            ["x set('a'|'b')"],
283
            // Unexpected parentheses
284
            ["x text ()"],
285
            // Unexpected comma
286
            ["x year (1,)"],
287
            // No comma separator
288
            ["x double(1 2)"],
289
            // No parentheses
290
            ["x varchar"],
291
            // Unexpected ZEROFILL keyword
292
            ["x date zerofill"],
293
            // Unexpected UNSIGNED keyword
294
            ["x date unsigned"],
295
            // Unexpected SIGNED keyword
296
            ["x date signed"],
297
            // Unexpected BINARY keyword
298
            ["x date binary"],
299
            // Unexpected CHARSET keyword
300
            ["x date charset"],
301
            // Unexpected COLLATE keyword
302
            ["x date collate"],
303
            // Unexpected AUTO_INCREMENT keyword
304
            ["x date auto_increment"],
305
            // Unexpected SERIAL DEFAULT VALUE keywords
306
            ["x date serial default value"],
307
            // Invalid year length
308
            ["x year(1)"],
309
            ["x year(5)"],
310
            // Missing parentheses after keyword NOW
311
            ["x timestamp default now"],
312
            ["x timestamp on update now"],
313
            // "on update" with the current timestamp only available for datetime and timestamp
314
            ["x date on update current_timestamp"],
315
        ];
316
    }
317
318
    /**
319
     * @param string $text
320
     * @dataProvider parseInvalidDefaultValuesProvider
321
     * @expectedException Exception
322
     */
323
    public function testParseInvalidDefaultValues($text)
324
    {
325
        $stream = $this->makeStream($text);
326
        $column = new ColumnDefinition();
327
        $column->parse($stream);
328
    }
329
330
    /**
331
     * @return array
332
     */
333
    public function parseInvalidDefaultValuesProvider()
334
    {
335
        return [
336
            ["x timestamp default null"],
337
            ["x date default current_timestamp"],
338
            ["x int default "],
339
            ["x year default 1900"],
340
            ["x year default 2156"],
341
            ["x enum('a', 'b', 'c') default 1"],
342
            ["x enum('a', 'b', 'c') default 'd'"],
343
            ["x set('a', 'b', 'c') default 1"],
344
            ["x set('a', 'b', 'c') default 'd'"],
345
            ["x text default 'abc'"],
346
        ];
347
    }
348
349
    /**
350
     * @dataProvider parseIndexesProvider
351
     * @param string $in
352
     * @param array $expectCount
353
     */
354
    public function testParseIndexes($in, array $expectCount)
355
    {
356
        $stream = $this->makeStream($in);
357
358
        $column = new ColumnDefinition();
359
        $column->parse($stream);
360
361
        $count = array_count_values(array_map(function ($e) {
362
            return $e->type;
363
        }, $column->indexes));
364
        ksort($count);
365
        ksort($expectCount);
366
367
        $this->assertSame($expectCount, $count);
368
    }
369
370
    /**
371
     * @return array
372
     */
373
    public function parseIndexesProvider()
374
    {
375
        return [
376
            ["x int",                       []],
377
            ["x serial",                    ['UNIQUE KEY' => 1]],
378
            ["x int serial default value",  ['UNIQUE KEY' => 1]],
379
            ["x int unique",                ['UNIQUE KEY'  => 1]],
380
            ["x int unique key",            ['UNIQUE KEY'  => 1]],
381
            ["x int primary key",           ['PRIMARY KEY' => 1]],
382
            ["x int key",                   ['PRIMARY KEY' => 1]],
383
        ];
384
    }
385
386
    /**
387
     * @param string $text
388
     * @param string|null $expected
389
     * @dataProvider getUninitialisedValuesProvider
390
     */
391
    public function testGetUninitialisedValues($text, $expected)
392
    {
393
        $stream = $this->makeStream($text);
394
        $column = new ColumnDefinition();
395
        $column->parse($stream);
396
397
        $this->assertSame($expected, $column->getUninitialisedValue());
398
    }
399
400
    /**
401
     * @return array
402
     */
403
    public function getUninitialisedValuesProvider()
404
    {
405
        return [
406
            // [ Column definition, uninitialised value ]
407
            ["x enum('a', 'b', 'c')",   "a"],
408
            ["x int",                   "0"],
409
            ["x decimal",               "0"],
410
            ["x decimal(5,3)",          "0.000"],
411
            ["x char",                  ""],
412
            ["x blob",                  null],
413
        ];
414
    }
415
416
    public function testApplyTableCollationSetsCollation()
417
    {
418
        // Make sure the given collation is applied if none exists
419
        $column = new ColumnDefinition();
420
        $utf8Collation = new CollationInfo("utf8");
421
        $column->applyTableCollation($utf8Collation);
422
423
        $this->assertEquals($utf8Collation, $column->collation);
424
425
        // Make sure the given collation is NOT applied in one exists
426
        $latin1Collation = new CollationInfo("latin1");
427
        $column->applyTableCollation($latin1Collation);
428
        $this->assertNotEquals($latin1Collation, $column->collation);
429
    }
430
431
    /**
432
     * @param string $text
433
     * @param string $expected
434
     * @dataProvider applyTableCollationEffectOnColumnTypeProvider
435
     */
436
    public function testApplyTableCollationEffectOnColumnType($text, $expected)
437
    {
438
        $stream = $this->makeStream($text);
439
        $column = new ColumnDefinition();
440
        $column->parse($stream);
441
442
        $collation = new CollationInfo("binary");
443
        $column->applyTableCollation($collation);
444
445
        $this->assertSame($expected, $column->type);
446
    }
447
448
    /**
449
     * @return array
450
     */
451
    public function applyTableCollationEffectOnColumnTypeProvider()
452
    {
453
        return [
454
            // [ Column definition, expected column type ]
455
            // These are all types that will change
456
            ["x char",          "binary"],
457
            ["x varchar(1)",    "varbinary"],
458
            ["x tinytext",      "tinyblob"],
459
            ["x text",          "blob"],
460
            ["x mediumtext",    "mediumblob"],
461
            ["x longtext",      "longblob"],
462
            // An example of one that doesn't change
463
            ["x int",           "int"],
464
        ];
465
    }
466
}
467