| 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 | |
|---|
| 38 | use base qw( MT::Object ); |
|---|
| 39 | |
|---|
| 40 | __PACKAGE__->install_properties({ |
|---|
| 41 | column_defs => { |
|---|
| 42 | id => 'integer not null auto_increment', |
|---|
| 43 | string_25 => 'string(25)', |
|---|
| 44 | string_25_nn => 'string(25) not null', |
|---|
| 45 | string_255 => 'string(255)', |
|---|
| 46 | string_1024 => 'string(1024)', |
|---|
| 47 | int_bool => 'boolean', |
|---|
| 48 | int_bool_nn => 'boolean not null', |
|---|
| 49 | int_small => 'smallint', |
|---|
| 50 | int_small_nn => 'smallint not null', |
|---|
| 51 | int_med => 'integer', |
|---|
| 52 | int_med_nn => 'integer not null', |
|---|
| 53 | int_big => 'bigint', |
|---|
| 54 | int_big_nn => 'bigint not null', |
|---|
| 55 | float => 'float', |
|---|
| 56 | float_nn => 'float not null', |
|---|
| 57 | text => 'text', |
|---|
| 58 | text_nn => 'text not null', |
|---|
| 59 | blob => 'blob', |
|---|
| 60 | blob_nn => 'blob not null', |
|---|
| 61 | datetime => 'datetime', |
|---|
| 62 | datetime_nn => 'datetime not null', |
|---|
| 63 | }, |
|---|
| 64 | indexes => { |
|---|
| 65 | string_25_nn => 1, |
|---|
| 66 | int_small_nn => 1, |
|---|
| 67 | string_dt => { |
|---|
| 68 | columns => [ qw( string_25 datetime_nn ) ], |
|---|
| 69 | }, |
|---|
| 70 | }, |
|---|
| 71 | audit => 1, |
|---|
| 72 | datasource => 'ddltest', |
|---|
| 73 | primary_key => 'id', |
|---|
| 74 | cacheable => 0, |
|---|
| 75 | }); |
|---|
| 76 | |
|---|
| 77 | |
|---|
| 78 | package Test::DDL; |
|---|
| 79 | use base qw( Test::Class MT::Test ); |
|---|
| 80 | use Test::More; |
|---|
| 81 | |
|---|
| 82 | sub startup : Test(startup) { |
|---|
| 83 | my $self = shift; |
|---|
| 84 | |
|---|
| 85 | $self->init_testdb(); |
|---|
| 86 | |
|---|
| 87 | my $driver = MT::Object->dbi_driver; |
|---|
| 88 | my $dbh = $driver->rw_handle; |
|---|
| 89 | my $ddl_class = $driver->dbd->ddl_class; |
|---|
| 90 | |
|---|
| 91 | # The table may exist from a previous test, so delete it if it does. |
|---|
| 92 | eval { |
|---|
| 93 | if ($driver->table_exists('Ddltest')) { |
|---|
| 94 | my $sql = $driver->dbd->ddl_class->drop_table_sql('Ddltest'); |
|---|
| 95 | $driver->rw_handle->do($sql); |
|---|
| 96 | } |
|---|
| 97 | }; |
|---|
| 98 | } |
|---|
| 99 | |
|---|
| 100 | sub _00_table_does_not_exist : Tests(3) { |
|---|
| 101 | my $self = shift; |
|---|
| 102 | |
|---|
| 103 | my $driver = MT::Object->dbi_driver; |
|---|
| 104 | my $dbh = $driver->rw_handle; |
|---|
| 105 | my $ddl_class = $driver->dbd->ddl_class; |
|---|
| 106 | |
|---|
| 107 | ok(!$driver->table_exists('Ddltest'), 'Ddltest table does not yet exist'); |
|---|
| 108 | ok(!defined $ddl_class->column_defs('Ddltest'), 'Ddltest table has no column defs'); |
|---|
| 109 | ok(!defined $ddl_class->index_defs('Ddltest'), 'Ddltest table has no index defs'); |
|---|
| 110 | } |
|---|
| 111 | |
|---|
| 112 | sub _01_create_table : Tests(2) { |
|---|
| 113 | my $self = shift; |
|---|
| 114 | |
|---|
| 115 | my $driver = MT::Object->dbi_driver; |
|---|
| 116 | my $dbh = $driver->rw_handle; |
|---|
| 117 | my $ddl_class = $driver->dbd->ddl_class; |
|---|
| 118 | |
|---|
| 119 | my $create_sql = $ddl_class->create_table_sql('Ddltest'); |
|---|
| 120 | ok($create_sql, 'Create Table SQL for Ddltest is available'); |
|---|
| 121 | my $res = $dbh->do($create_sql); |
|---|
| 122 | ok($res, 'Driver could perform Create Table SQL for Ddltest'); |
|---|
| 123 | diag($dbh->errstr || $DBI::errstr) if !$res; |
|---|
| 124 | } |
|---|
| 125 | |
|---|
| 126 | sub _02_create_indexes : Tests(5) { |
|---|
| 127 | my $self = shift; |
|---|
| 128 | |
|---|
| 129 | my $driver = MT::Object->dbi_driver; |
|---|
| 130 | my $dbh = $driver->rw_handle; |
|---|
| 131 | my $ddl_class = $driver->dbd->ddl_class; |
|---|
| 132 | |
|---|
| 133 | my @index_sql = $ddl_class->index_table_sql('Ddltest'); |
|---|
| 134 | ok(@index_sql, 'Index Table SQL for Ddltest is available'); |
|---|
| 135 | is(scalar @index_sql, 3, 'Index Table SQL has 4 statements'); |
|---|
| 136 | for my $index_sql (@index_sql) { |
|---|
| 137 | my $res = $dbh->do($index_sql); |
|---|
| 138 | ok($res, 'Driver could perform Index Table SQL for Ddltest'); |
|---|
| 139 | if (!$res) { |
|---|
| 140 | diag($dbh->errstr || $DBI::errstr); |
|---|
| 141 | diag('SQL: ' . $index_sql); |
|---|
| 142 | } |
|---|
| 143 | } |
|---|
| 144 | } |
|---|
| 145 | |
|---|
| 146 | sub _def { |
|---|
| 147 | my ($auto, $not_null, $type, $size) = @_; |
|---|
| 148 | my $def = { |
|---|
| 149 | auto => $auto, |
|---|
| 150 | not_null => $not_null, |
|---|
| 151 | type => $type, |
|---|
| 152 | }; |
|---|
| 153 | $def->{size} = $size if defined $size; |
|---|
| 154 | return $def; |
|---|
| 155 | } |
|---|
| 156 | |
|---|
| 157 | sub is_def { |
|---|
| 158 | my ($got, $expected, $reason) = @_; |
|---|
| 159 | |
|---|
| 160 | for my $field (qw( not_null auto )) { |
|---|
| 161 | if ($expected->{$field} xor $got->{$field}) { |
|---|
| 162 | fail($reason); |
|---|
| 163 | diag($expected->{$field} |
|---|
| 164 | ? "Expected $field but didn't get it" |
|---|
| 165 | : "Expected not $field but got it"); |
|---|
| 166 | return; |
|---|
| 167 | } |
|---|
| 168 | } |
|---|
| 169 | |
|---|
| 170 | if ($expected->{type} ne $got->{type}) { |
|---|
| 171 | fail($reason); |
|---|
| 172 | diag("Expected type ", $expected->{type}, " but got ", $got->{type}); |
|---|
| 173 | return; |
|---|
| 174 | } |
|---|
| 175 | |
|---|
| 176 | if (defined $expected->{size} && $expected->{size} != $got->{size}) { |
|---|
| 177 | fail($reason); |
|---|
| 178 | diag("Expected size ", $expected->{size}, " but got ", $got->{size}); |
|---|
| 179 | return; |
|---|
| 180 | } |
|---|
| 181 | |
|---|
| 182 | pass($reason); |
|---|
| 183 | } |
|---|
| 184 | |
|---|
| 185 | sub table_defs : Tests(26) { |
|---|
| 186 | my $defs = MT::Object->driver->dbd->ddl_class->column_defs('Ddltest'); |
|---|
| 187 | ok($defs, 'Ddltest DDL settings are defined'); |
|---|
| 188 | |
|---|
| 189 | is_def($defs->{id}, _def(1, 1, 'integer'), 'Ddltest id column def is correct'); |
|---|
| 190 | |
|---|
| 191 | is_def($defs->{string_25}, _def(0, 0, 'string', 25), 'Ddltest string_25 column def is correct'); |
|---|
| 192 | is_def($defs->{string_25_nn}, _def(0, 1, 'string', 25), 'Ddltest string_25_nn column def is correct'); |
|---|
| 193 | is_def($defs->{string_255}, _def(0, 0, 'string', 255), 'Ddltest string_255 column def is correct'); |
|---|
| 194 | is_def($defs->{string_1024}, _def(0, 0, 'string', 1024), 'Ddltest string_1024 column def is correct'); |
|---|
| 195 | is_def($defs->{int_bool}, _def(0, 0, 'boolean'), 'Ddltest int_bool column def is correct'); |
|---|
| 196 | is_def($defs->{int_bool_nn}, _def(0, 1, 'boolean'), 'Ddltest int_bool_nn column def is correct'); |
|---|
| 197 | is_def($defs->{int_small}, _def(0, 0, 'smallint'), 'Ddltest int_small column def is correct'); |
|---|
| 198 | is_def($defs->{int_small_nn}, _def(0, 1, 'smallint'), 'Ddltest int_small_nn column def is correct'); |
|---|
| 199 | is_def($defs->{int_med}, _def(0, 0, 'integer'), 'Ddltest int_med column def is correct'); |
|---|
| 200 | is_def($defs->{int_med_nn}, _def(0, 1, 'integer'), 'Ddltest int_med_nn column def is correct'); |
|---|
| 201 | is_def($defs->{int_big}, _def(0, 0, 'bigint'), 'Ddltest int_big column def is correct'); |
|---|
| 202 | is_def($defs->{int_big_nn}, _def(0, 1, 'bigint'), 'Ddltest int_big_nn column def is correct'); |
|---|
| 203 | is_def($defs->{float}, _def(0, 0, 'float'), 'Ddltest float column def is correct'); |
|---|
| 204 | is_def($defs->{float_nn}, _def(0, 1, 'float'), 'Ddltest float_nn column def is correct'); |
|---|
| 205 | is_def($defs->{text}, _def(0, 0, 'text'), 'Ddltest text column def is correct'); |
|---|
| 206 | is_def($defs->{text_nn}, _def(0, 1, 'text'), 'Ddltest text_nn column def is correct'); |
|---|
| 207 | is_def($defs->{blob}, _def(0, 0, 'blob'), 'Ddltest blob column def is correct'); |
|---|
| 208 | is_def($defs->{blob_nn}, _def(0, 1, 'blob'), 'Ddltest blob_nn column def is correct'); |
|---|
| 209 | is_def($defs->{datetime}, _def(0, 0, 'datetime'), 'Ddltest datetime column def is correct'); |
|---|
| 210 | is_def($defs->{datetime_nn}, _def(0, 1, 'datetime'), 'Ddltest datetime_nn column def is correct'); |
|---|
| 211 | |
|---|
| 212 | # audit fields |
|---|
| 213 | is_def($defs->{created_on}, _def(0, 0, 'datetime'), 'Ddltest created_on column def is correct'); |
|---|
| 214 | is_def($defs->{created_by}, _def(0, 0, 'integer'), 'Ddltest created_by column def is correct'); |
|---|
| 215 | is_def($defs->{modified_on}, _def(0, 0, 'datetime'), 'Ddltest modified_on column def is correct'); |
|---|
| 216 | is_def($defs->{modified_by}, _def(0, 0, 'integer'), 'Ddltest modified_by column def is correct'); |
|---|
| 217 | } |
|---|
| 218 | |
|---|
| 219 | sub index_defs : Tests(5) { |
|---|
| 220 | my $index_defs = MT::Object->driver->dbd->ddl_class->index_defs('Ddltest'); |
|---|
| 221 | ok($index_defs, 'Ddltest table has index defs'); |
|---|
| 222 | |
|---|
| 223 | is(keys %$index_defs, 3, 'Ddltest table has three indexes'); |
|---|
| 224 | is($index_defs->{string_25_nn}, 1, 'Ddltest table has name index'); |
|---|
| 225 | is($index_defs->{int_small_nn}, 1, 'Ddltest table has status index'); |
|---|
| 226 | is_deeply($index_defs->{string_dt}, { |
|---|
| 227 | columns => [ qw( string_25 datetime_nn ) ] |
|---|
| 228 | }, 'Ddltest table has multi-column string_dt index'); |
|---|
| 229 | } |
|---|
| 230 | |
|---|
| 231 | package main; |
|---|
| 232 | |
|---|
| 233 | Test::DDL->runtests(); |
|---|
| 234 | |
|---|
| 235 | 1; |
|---|
| 236 | |
|---|