|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
namespace Graze\Morphism\Parse; |
|
4
|
|
|
|
|
5
|
|
|
use Exception; |
|
6
|
|
|
use Graze\Morphism\Test\Parse\TestCase; |
|
7
|
|
|
|
|
8
|
|
|
class CreateTableTest extends TestCase |
|
9
|
|
|
{ |
|
10
|
|
|
public function testConstructor() |
|
11
|
|
|
{ |
|
12
|
|
|
$collation = new CollationInfo(); |
|
13
|
|
|
$table = new CreateTable($collation); |
|
14
|
|
|
$this->assertThat($table, $this->isInstanceOf(__NAMESPACE__ . '\CreateTable')); |
|
15
|
|
|
} |
|
16
|
|
|
|
|
17
|
|
|
public function testSetDefaultEngine() |
|
18
|
|
|
{ |
|
19
|
|
|
$table = new CreateTable(new CollationInfo()); |
|
20
|
|
|
$table->setDefaultEngine('InnoDB'); |
|
21
|
|
|
// we're really just checking no exception got thrown |
|
22
|
|
|
$this->assertTrue(true); |
|
23
|
|
|
} |
|
24
|
|
|
|
|
25
|
|
|
/** |
|
26
|
|
|
* @dataProvider providerParse |
|
27
|
|
|
* @param string $text |
|
28
|
|
|
* @param string $expected |
|
29
|
|
|
* @throws Exception |
|
30
|
|
|
*/ |
|
31
|
|
|
public function testParse($text, $expected) |
|
32
|
|
|
{ |
|
33
|
|
|
$stream = $this->makeStream($text); |
|
34
|
|
|
$collation = new CollationInfo(); |
|
35
|
|
|
$table = new CreateTable($collation); |
|
36
|
|
|
$table->setDefaultEngine('InnoDB'); |
|
37
|
|
|
|
|
38
|
|
|
$threw = null; |
|
39
|
|
|
try { |
|
40
|
|
|
$table->parse($stream); |
|
41
|
|
|
} catch (Exception $e) { |
|
42
|
|
|
$threw = $e; |
|
43
|
|
|
} |
|
44
|
|
|
if (preg_match('/^exception/i', $expected)) { |
|
45
|
|
|
if (!preg_match('/^exception\\s+(\\S+)\s+"(.*)"/i', $expected, $pregMatch)) { |
|
46
|
|
|
throw new Exception("garbled exception specification: $expected"); |
|
47
|
|
|
} |
|
48
|
|
|
list(, $expectedExceptionType, $expectedMessageRegex) = $pregMatch; |
|
|
|
|
|
|
49
|
|
|
if (is_null($threw)) { |
|
50
|
|
|
$this->fail("expected an $expectedExceptionType exception, but none was thrown"); |
|
51
|
|
|
} else { |
|
52
|
|
|
$this->assertInstanceOf($expectedExceptionType, $threw, "wrong exception type thrown"); |
|
53
|
|
|
$this->assertRegExp("/$expectedMessageRegex/", $e->getMessage(), "wrong exception message"); |
|
|
|
|
|
|
54
|
|
|
} |
|
55
|
|
|
} elseif (is_null($threw)) { |
|
56
|
|
|
$ddl = $table->getDDL(); |
|
57
|
|
|
$actual = $ddl[0] . ';'; |
|
58
|
|
|
$this->assertCount(1, $ddl); |
|
59
|
|
|
$this->assertSame( |
|
60
|
|
|
trim(preg_replace('/\s+/', ' ', $expected)), |
|
61
|
|
|
trim(preg_replace('/\s+/', ' ', $actual)) |
|
62
|
|
|
); |
|
63
|
|
|
} else { |
|
64
|
|
|
$this->fail("Unexpected exception " . get_class($threw) . ": " . $threw->getMessage()); |
|
65
|
|
|
} |
|
66
|
|
|
} |
|
67
|
|
|
|
|
68
|
|
|
/** |
|
69
|
|
|
* @return array |
|
70
|
|
|
*/ |
|
71
|
|
|
public function providerParse() |
|
72
|
|
|
{ |
|
73
|
|
|
$tests = []; |
|
74
|
|
|
|
|
75
|
|
|
foreach ([ |
|
76
|
|
|
'simpleCreateTable.sql', |
|
77
|
|
|
'default.sql', |
|
78
|
|
|
'primaryKey.sql', |
|
79
|
|
|
'nonUniqueIndex.sql', |
|
80
|
|
|
'fullTextIndex.sql', |
|
81
|
|
|
'uniqueIndex.sql', |
|
82
|
|
|
'foreignKey.sql', |
|
83
|
|
|
'indexes.sql', |
|
84
|
|
|
'timestamp.sql', |
|
85
|
|
|
] as $file) { |
|
86
|
|
|
$path = __DIR__ . '/sql/' . $file; |
|
87
|
|
|
$sql = @file_get_contents(__DIR__ . '/sql/' . $file); |
|
88
|
|
|
if ($sql === false) { |
|
89
|
|
|
$this->fail("could not open $path"); |
|
90
|
|
|
} |
|
91
|
|
View Code Duplication |
foreach (preg_split('/^-- test .*$/m', $sql) as $pair) { |
|
|
|
|
|
|
92
|
|
|
if (trim($pair) != '') { |
|
93
|
|
|
list($text, $expected) = preg_split('/(?<=;)/', $pair); |
|
94
|
|
|
$tests[] = [ |
|
95
|
|
|
trim($text), |
|
96
|
|
|
trim($expected) |
|
97
|
|
|
]; |
|
98
|
|
|
} |
|
99
|
|
|
} |
|
100
|
|
|
} |
|
101
|
|
|
|
|
102
|
|
|
return $tests; |
|
103
|
|
|
} |
|
104
|
|
|
|
|
105
|
|
|
/** |
|
106
|
|
|
* @param string $firstTableText |
|
107
|
|
|
* @param string $secondTableText |
|
108
|
|
|
* @param string $expected |
|
109
|
|
|
* @dataProvider diffProvider |
|
110
|
|
|
*/ |
|
111
|
|
View Code Duplication |
public function testDiff($firstTableText, $secondTableText, $expected) |
|
|
|
|
|
|
112
|
|
|
{ |
|
113
|
|
|
$collation = new CollationInfo(); |
|
114
|
|
|
|
|
115
|
|
|
$firstStream = $this->makeStream($firstTableText); |
|
116
|
|
|
$firstTable = new CreateTable($collation); |
|
117
|
|
|
$firstTable->setDefaultEngine('InnoDB'); |
|
118
|
|
|
$firstTable->parse($firstStream); |
|
119
|
|
|
|
|
120
|
|
|
$secondStream = $this->makeStream($secondTableText); |
|
121
|
|
|
$secondTable = new CreateTable($collation); |
|
122
|
|
|
$secondTable->setDefaultEngine('InnoDB'); |
|
123
|
|
|
$secondTable->parse($secondStream); |
|
124
|
|
|
|
|
125
|
|
|
$diff = $firstTable->diff($secondTable); |
|
126
|
|
|
|
|
127
|
|
|
$this->assertEquals($expected == "" ? [] : [$expected], $diff); |
|
128
|
|
|
} |
|
129
|
|
|
|
|
130
|
|
|
/** |
|
131
|
|
|
* @return array |
|
132
|
|
|
*/ |
|
133
|
|
|
public function diffProvider() |
|
134
|
|
|
{ |
|
135
|
|
|
$tests = []; |
|
136
|
|
|
|
|
137
|
|
|
foreach ([ |
|
138
|
|
|
'columns.sql', |
|
139
|
|
|
'indexes.sql', |
|
140
|
|
|
'simpleDiff.sql' |
|
141
|
|
|
] as $file) { |
|
142
|
|
|
$path = __DIR__ . '/sql/diff/' . $file; |
|
143
|
|
|
$sql = @file_get_contents($path); |
|
144
|
|
|
if ($sql === false) { |
|
145
|
|
|
$this->fail("could not open $path"); |
|
146
|
|
|
} |
|
147
|
|
View Code Duplication |
foreach (preg_split('/^-- test .*$/m', $sql) as $pair) { |
|
|
|
|
|
|
148
|
|
|
if (trim($pair) != '') { |
|
149
|
|
|
list($firstText, $secondText, $expected) = preg_split('/(?<=;)/', $pair); |
|
150
|
|
|
$tests[] = [ |
|
151
|
|
|
trim($firstText), |
|
152
|
|
|
trim($secondText), |
|
153
|
|
|
trim($expected) |
|
154
|
|
|
]; |
|
155
|
|
|
} |
|
156
|
|
|
} |
|
157
|
|
|
} |
|
158
|
|
|
|
|
159
|
|
|
return $tests; |
|
160
|
|
|
} |
|
161
|
|
|
|
|
162
|
|
|
/** |
|
163
|
|
|
* Test that the "alterEngine" flag works. |
|
164
|
|
|
* @dataProvider alterEngineProvider |
|
165
|
|
|
* @param array $flags |
|
166
|
|
|
* @param string $expected |
|
167
|
|
|
*/ |
|
168
|
|
View Code Duplication |
public function testAlterEngineDiff(array $flags, $expected) |
|
|
|
|
|
|
169
|
|
|
{ |
|
170
|
|
|
$sql = 'create table t (a int)'; |
|
171
|
|
|
$collation = new CollationInfo(); |
|
172
|
|
|
|
|
173
|
|
|
$firstStream = $this->makeStream($sql); |
|
174
|
|
|
$firstTable = new CreateTable($collation); |
|
175
|
|
|
$firstTable->setDefaultEngine('InnoDb'); |
|
176
|
|
|
$firstTable->parse($firstStream); |
|
177
|
|
|
|
|
178
|
|
|
$secondStream = $this->makeStream($sql); |
|
179
|
|
|
$secondTable = new CreateTable($collation); |
|
180
|
|
|
$secondTable->setDefaultEngine('MyISAM'); |
|
181
|
|
|
$secondTable->parse($secondStream); |
|
182
|
|
|
|
|
183
|
|
|
$diff = $firstTable->diff($secondTable, $flags); |
|
184
|
|
|
|
|
185
|
|
|
$this->assertEquals($expected, $diff); |
|
186
|
|
|
} |
|
187
|
|
|
|
|
188
|
|
|
/** |
|
189
|
|
|
* @return array |
|
190
|
|
|
*/ |
|
191
|
|
|
public function alterEngineProvider() |
|
192
|
|
|
{ |
|
193
|
|
|
return [ |
|
194
|
|
|
// [ alter engine flag, expected diff ] |
|
195
|
|
|
[ [ 'alterEngine' => true ], ["ALTER TABLE `t`\nENGINE=MyISAM"] ], |
|
196
|
|
|
[ [ 'alterEngine' => false ], [] ], |
|
197
|
|
|
[ [], ["ALTER TABLE `t`\nENGINE=MyISAM"] ], |
|
198
|
|
|
]; |
|
199
|
|
|
} |
|
200
|
|
|
} |
|
201
|
|
|
|
Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.