| 1 | #!/usr/bin/perl |
|---|
| 2 | |
|---|
| 3 | # Movable Type (r) Open Source (C) 2001-2008 Six Apart, Ltd. |
|---|
| 4 | # This program is distributed under the terms of the |
|---|
| 5 | # GNU General Public License, version 2. |
|---|
| 6 | # |
|---|
| 7 | # $Id$ |
|---|
| 8 | |
|---|
| 9 | use strict; |
|---|
| 10 | use warnings; |
|---|
| 11 | use Data::Dumper; |
|---|
| 12 | use English qw( -no_watch_vars ); |
|---|
| 13 | |
|---|
| 14 | $OUTPUT_AUTOFLUSH = 1; |
|---|
| 15 | |
|---|
| 16 | # Run this script as a symlink, in the form of 99-driver.t, ie: |
|---|
| 17 | # ln -s driver-tests.pl 99-driver.t |
|---|
| 18 | |
|---|
| 19 | BEGIN { |
|---|
| 20 | # Set config to driver-test.cfg when run as /path/to/99-driver.t |
|---|
| 21 | $ENV{MT_CONFIG} = "$1-test.cfg" |
|---|
| 22 | if __FILE__ =~ m{ ([^\\/-]+) \.t \z }xms; |
|---|
| 23 | } |
|---|
| 24 | |
|---|
| 25 | use Test::More; |
|---|
| 26 | use lib 't/lib'; |
|---|
| 27 | use MT::Test; |
|---|
| 28 | use Test::Class; |
|---|
| 29 | |
|---|
| 30 | BEGIN { |
|---|
| 31 | plan skip_all => "Configuration file $ENV{MT_CONFIG} not found" |
|---|
| 32 | if !-r $ENV{MT_CONFIG}; |
|---|
| 33 | } |
|---|
| 34 | |
|---|
| 35 | |
|---|
| 36 | package Ddltest; |
|---|
| 37 | use base qw( MT::Object ); |
|---|
| 38 | |
|---|
| 39 | __PACKAGE__->install_properties({ |
|---|
| 40 | column_defs => { |
|---|
| 41 | id => 'integer not null auto_increment', |
|---|
| 42 | string_25 => 'string(25)', |
|---|
| 43 | string_25_nn => 'string(25) not null', |
|---|
| 44 | string_255 => 'string(255)', |
|---|
| 45 | string_1024 => 'string(1024)', |
|---|
| 46 | int_bool => 'boolean', |
|---|
| 47 | int_bool_nn => 'boolean not null', |
|---|
| 48 | int_small => 'smallint', |
|---|
| 49 | int_small_nn => 'smallint not null', |
|---|
| 50 | int_med => 'integer', |
|---|
| 51 | int_med_nn => 'integer not null', |
|---|
| 52 | int_big => 'bigint', |
|---|
| 53 | int_big_nn => 'bigint not null', |
|---|
| 54 | float => 'float', |
|---|
| 55 | float_nn => 'float not null', |
|---|
| 56 | text => 'text', |
|---|
| 57 | text_nn => 'text not null', |
|---|
| 58 | blob => 'blob', |
|---|
| 59 | blob_nn => 'blob not null', |
|---|
| 60 | datetime => 'datetime', |
|---|
| 61 | datetime_nn => 'datetime not null', |
|---|
| 62 | }, |
|---|
| 63 | indexes => { |
|---|
| 64 | string_25_nn => 1, |
|---|
| 65 | int_small_nn => 1, |
|---|
| 66 | string_dt => { |
|---|
| 67 | columns => [ qw( string_25 datetime_nn ) ], |
|---|
| 68 | }, |
|---|
| 69 | }, |
|---|
| 70 | audit => 1, |
|---|
| 71 | datasource => 'ddltest', |
|---|
| 72 | primary_key => 'id', |
|---|
| 73 | cacheable => 0, |
|---|
| 74 | }); |
|---|
| 75 | |
|---|
| 76 | |
|---|
| 77 | package Ddltest::InvalidType; |
|---|
| 78 | use base qw( MT::Object ); |
|---|
| 79 | |
|---|
| 80 | __PACKAGE__->install_properties({ |
|---|
| 81 | column_defs => { |
|---|
| 82 | id => 'integer not null auto_increment', |
|---|
| 83 | boo => 'asfdasf', |
|---|
| 84 | }, |
|---|
| 85 | datasource => 'ddltest_invalidtype', |
|---|
| 86 | primary_key => 'id', |
|---|
| 87 | cacheable => 0, |
|---|
| 88 | }); |
|---|
| 89 | |
|---|
| 90 | |
|---|
| 91 | package Test::DDL; |
|---|
| 92 | use base qw( Test::Class MT::Test ); |
|---|
| 93 | use Test::More; |
|---|
| 94 | |
|---|
| 95 | sub startup : Test(startup) { |
|---|
| 96 | my $self = shift; |
|---|
| 97 | |
|---|
| 98 | $self->init_testdb(); |
|---|
| 99 | |
|---|
| 100 | my $driver = MT::Object->dbi_driver; |
|---|
| 101 | my $dbh = $driver->rw_handle; |
|---|
| 102 | my $ddl_class = $driver->dbd->ddl_class; |
|---|
| 103 | |
|---|
| 104 | # The table may exist from a previous test, so delete it if it does. |
|---|
| 105 | eval { |
|---|
| 106 | if ($driver->table_exists('Ddltest')) { |
|---|
| 107 | my $sql = $driver->dbd->ddl_class->drop_table_sql('Ddltest'); |
|---|
| 108 | $driver->rw_handle->do($sql); |
|---|
| 109 | } |
|---|
| 110 | }; |
|---|
| 111 | } |
|---|
| 112 | |
|---|
| 113 | sub _00_table_does_not_exist : Tests(3) { |
|---|
| 114 | my $self = shift; |
|---|
| 115 | |
|---|
| 116 | my $driver = MT::Object->dbi_driver; |
|---|
| 117 | my $dbh = $driver->rw_handle; |
|---|
| 118 | my $ddl_class = $driver->dbd->ddl_class; |
|---|
| 119 | |
|---|
| 120 | ok(!$driver->table_exists('Ddltest'), 'Ddltest table does not yet exist'); |
|---|
| 121 | ok(!defined $ddl_class->column_defs('Ddltest'), 'Ddltest table has no column defs'); |
|---|
| 122 | ok(!defined $ddl_class->index_defs('Ddltest'), 'Ddltest table has no index defs'); |
|---|
| 123 | } |
|---|
| 124 | |
|---|
| 125 | sub _01_create_table : Tests(2) { |
|---|
| 126 | my $self = shift; |
|---|
| 127 | |
|---|
| 128 | my $driver = MT::Object->dbi_driver; |
|---|
| 129 | my $dbh = $driver->rw_handle; |
|---|
| 130 | my $ddl_class = $driver->dbd->ddl_class; |
|---|
| 131 | |
|---|
| 132 | my $create_sql = $ddl_class->create_table_sql('Ddltest'); |
|---|
| 133 | ok($create_sql, 'Create Table SQL for Ddltest is available'); |
|---|
| 134 | my $res = $dbh->do($create_sql); |
|---|
| 135 | ok($res, 'Driver could perform Create Table SQL for Ddltest'); |
|---|
| 136 | diag($dbh->errstr || $DBI::errstr) if !$res; |
|---|
| 137 | } |
|---|
| 138 | |
|---|
| 139 | sub _02_create_indexes : Tests(5) { |
|---|
| 140 | my $self = shift; |
|---|
| 141 | |
|---|
| 142 | my $driver = MT::Object->dbi_driver; |
|---|
| 143 | my $dbh = $driver->rw_handle; |
|---|
| 144 | my $ddl_class = $driver->dbd->ddl_class; |
|---|
| 145 | |
|---|
| 146 | my @index_sql = $ddl_class->index_table_sql('Ddltest'); |
|---|
| 147 | ok(@index_sql, 'Index Table SQL for Ddltest is available'); |
|---|
| 148 | is(scalar @index_sql, 3, 'Index Table SQL has 4 statements'); |
|---|
| 149 | for my $index_sql (@index_sql) { |
|---|
| 150 | my $res = $dbh->do($index_sql); |
|---|
| 151 | ok($res, 'Driver could perform Index Table SQL for Ddltest'); |
|---|
| 152 | if (!$res) { |
|---|
| 153 | diag($dbh->errstr || $DBI::errstr); |
|---|
| 154 | diag('SQL: ' . $index_sql); |
|---|
| 155 | } |
|---|
| 156 | } |
|---|
| 157 | } |
|---|
| 158 | |
|---|
| 159 | sub _def { |
|---|
| 160 | my ($auto, $not_null, $type, $size) = @_; |
|---|
| 161 | my $def = { |
|---|
| 162 | auto => $auto, |
|---|
| 163 | not_null => $not_null, |
|---|
| 164 | type => $type, |
|---|
| 165 | }; |
|---|
| 166 | $def->{size} = $size if defined $size; |
|---|
| 167 | return $def; |
|---|
| 168 | } |
|---|
| 169 | |
|---|
| 170 | sub is_def { |
|---|
| 171 | my ($got, $expected, $reason) = @_; |
|---|
| 172 | |
|---|
| 173 | for my $field (qw( not_null auto )) { |
|---|
| 174 | if ($expected->{$field} xor $got->{$field}) { |
|---|
| 175 | fail($reason); |
|---|
| 176 | diag($expected->{$field} |
|---|
| 177 | ? "Expected $field but didn't get it" |
|---|
| 178 | : "Expected not $field but got it"); |
|---|
| 179 | return; |
|---|
| 180 | } |
|---|
| 181 | } |
|---|
| 182 | |
|---|
| 183 | if ($expected->{type} ne $got->{type}) { |
|---|
| 184 | fail($reason); |
|---|
| 185 | diag("Expected type ", $expected->{type}, " but got ", $got->{type}); |
|---|
| 186 | return; |
|---|
| 187 | } |
|---|
| 188 | |
|---|
| 189 | if (defined $expected->{size} && $expected->{size} != $got->{size}) { |
|---|
| 190 | fail($reason); |
|---|
| 191 | diag("Expected size ", $expected->{size}, " but got ", $got->{size}); |
|---|
| 192 | return; |
|---|
| 193 | } |
|---|
| 194 | |
|---|
| 195 | pass($reason); |
|---|
| 196 | } |
|---|
| 197 | |
|---|
| 198 | sub table_defs : Tests(26) { |
|---|
| 199 | my $defs = MT::Object->driver->dbd->ddl_class->column_defs('Ddltest'); |
|---|
| 200 | ok($defs, 'Ddltest DDL settings are defined'); |
|---|
| 201 | |
|---|
| 202 | is_def($defs->{id}, _def(1, 1, 'integer'), 'Ddltest id column def is correct'); |
|---|
| 203 | |
|---|
| 204 | is_def($defs->{string_25}, _def(0, 0, 'string', 25), 'Ddltest string_25 column def is correct'); |
|---|
| 205 | is_def($defs->{string_25_nn}, _def(0, 1, 'string', 25), 'Ddltest string_25_nn column def is correct'); |
|---|
| 206 | is_def($defs->{string_255}, _def(0, 0, 'string', 255), 'Ddltest string_255 column def is correct'); |
|---|
| 207 | is_def($defs->{string_1024}, _def(0, 0, 'string', 1024), 'Ddltest string_1024 column def is correct'); |
|---|
| 208 | is_def($defs->{int_bool}, _def(0, 0, 'boolean'), 'Ddltest int_bool column def is correct'); |
|---|
| 209 | is_def($defs->{int_bool_nn}, _def(0, 1, 'boolean'), 'Ddltest int_bool_nn column def is correct'); |
|---|
| 210 | is_def($defs->{int_small}, _def(0, 0, 'smallint'), 'Ddltest int_small column def is correct'); |
|---|
| 211 | is_def($defs->{int_small_nn}, _def(0, 1, 'smallint'), 'Ddltest int_small_nn column def is correct'); |
|---|
| 212 | is_def($defs->{int_med}, _def(0, 0, 'integer'), 'Ddltest int_med column def is correct'); |
|---|
| 213 | is_def($defs->{int_med_nn}, _def(0, 1, 'integer'), 'Ddltest int_med_nn column def is correct'); |
|---|
| 214 | is_def($defs->{int_big}, _def(0, 0, 'bigint'), 'Ddltest int_big column def is correct'); |
|---|
| 215 | is_def($defs->{int_big_nn}, _def(0, 1, 'bigint'), 'Ddltest int_big_nn column def is correct'); |
|---|
| 216 | is_def($defs->{float}, _def(0, 0, 'float'), 'Ddltest float column def is correct'); |
|---|
| 217 | is_def($defs->{float_nn}, _def(0, 1, 'float'), 'Ddltest float_nn column def is correct'); |
|---|
| 218 | is_def($defs->{text}, _def(0, 0, 'text'), 'Ddltest text column def is correct'); |
|---|
| 219 | is_def($defs->{text_nn}, _def(0, 1, 'text'), 'Ddltest text_nn column def is correct'); |
|---|
| 220 | is_def($defs->{blob}, _def(0, 0, 'blob'), 'Ddltest blob column def is correct'); |
|---|
| 221 | is_def($defs->{blob_nn}, _def(0, 1, 'blob'), 'Ddltest blob_nn column def is correct'); |
|---|
| 222 | is_def($defs->{datetime}, _def(0, 0, 'datetime'), 'Ddltest datetime column def is correct'); |
|---|
| 223 | is_def($defs->{datetime_nn}, _def(0, 1, 'datetime'), 'Ddltest datetime_nn column def is correct'); |
|---|
| 224 | |
|---|
| 225 | # audit fields |
|---|
| 226 | is_def($defs->{created_on}, _def(0, 0, 'datetime'), 'Ddltest created_on column def is correct'); |
|---|
| 227 | is_def($defs->{created_by}, _def(0, 0, 'integer'), 'Ddltest created_by column def is correct'); |
|---|
| 228 | is_def($defs->{modified_on}, _def(0, 0, 'datetime'), 'Ddltest modified_on column def is correct'); |
|---|
| 229 | is_def($defs->{modified_by}, _def(0, 0, 'integer'), 'Ddltest modified_by column def is correct'); |
|---|
| 230 | } |
|---|
| 231 | |
|---|
| 232 | sub index_defs : Tests(5) { |
|---|
| 233 | my $index_defs = MT::Object->driver->dbd->ddl_class->index_defs('Ddltest'); |
|---|
| 234 | ok($index_defs, 'Ddltest table has index defs'); |
|---|
| 235 | |
|---|
| 236 | is(keys %$index_defs, 3, 'Ddltest table has three indexes'); |
|---|
| 237 | is($index_defs->{string_25_nn}, 1, 'Ddltest table has name index'); |
|---|
| 238 | is($index_defs->{int_small_nn}, 1, 'Ddltest table has status index'); |
|---|
| 239 | is_deeply($index_defs->{string_dt}, { |
|---|
| 240 | columns => [ qw( string_25 datetime_nn ) ] |
|---|
| 241 | }, 'Ddltest table has multi-column string_dt index'); |
|---|
| 242 | } |
|---|
| 243 | |
|---|
| 244 | sub invalid_type : Tests(3) { |
|---|
| 245 | my $self = shift; |
|---|
| 246 | |
|---|
| 247 | my $driver = MT::Object->dbi_driver; |
|---|
| 248 | my $dbh = $driver->rw_handle; |
|---|
| 249 | my $ddl_class = $driver->dbd->ddl_class; |
|---|
| 250 | |
|---|
| 251 | ok(!$driver->table_exists('Ddltest::InvalidType'), 'Ddltest::InvalidType table does not yet exist'); |
|---|
| 252 | ok(!defined $ddl_class->column_defs('Ddltest::InvalidType'), 'Ddltest::InvalidType table has no column defs'); |
|---|
| 253 | |
|---|
| 254 | ok(!eval { $ddl_class->create_table_sql('Ddltest::InvalidType') }, 'Ddltest::InvalidType cannot make creation sql'); |
|---|
| 255 | } |
|---|
| 256 | |
|---|
| 257 | sub _00_drop_table_test : Test(shutdown => 3) { |
|---|
| 258 | my $self = shift; |
|---|
| 259 | |
|---|
| 260 | my $driver = MT::Object->dbi_driver; |
|---|
| 261 | my $dbh = $driver->rw_handle; |
|---|
| 262 | my $ddl_class = $driver->dbd->ddl_class; |
|---|
| 263 | |
|---|
| 264 | my $drop_sql = $ddl_class->drop_table_sql('Ddltest'); |
|---|
| 265 | ok($drop_sql, 'Drop Table SQL for Ddltest is available'); |
|---|
| 266 | my $res = $dbh->do($drop_sql); |
|---|
| 267 | ok($res, 'Driver could perform Drop Table SQL for Ddltest'); |
|---|
| 268 | diag($dbh->errstr || $DBI::errstr) if !$res; |
|---|
| 269 | |
|---|
| 270 | ok(!defined $ddl_class->column_defs('Ddltest'), 'Ddltest table no longer exists'); |
|---|
| 271 | } |
|---|
| 272 | |
|---|
| 273 | package main; |
|---|
| 274 | |
|---|
| 275 | Test::DDL->runtests(); |
|---|
| 276 | |
|---|
| 277 | 1; |
|---|
| 278 | |
|---|