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.