File Coverage

blib/lib/Qudo/Test.pm
Criterion Covered Total %
statement 55 123 44.7
branch 3 34 8.8
condition 0 8 0.0
subroutine 17 28 60.7
pod 0 16 0.0
total 75 209 35.8


line stmt bran cond sub pod time code
1             package Qudo::Test;
2 29     29   10174 use strict;
  29         38  
  29         839  
3 29     29   109 use warnings;
  29         31  
  29         816  
4 29     29   13153 use lib qw(./lib ./t/lib);
  29         16317  
  29         131  
5 29     29   3696 use Carp qw(croak);
  29         35  
  29         1538  
6 29     29   6860 use Qudo;
  29         58  
  29         242  
7 29     29   13730 use YAML;
  29         224721  
  29         1452  
8 29     29   37990 use DBI;
  29         407110  
  29         1773  
9 29     29   14955 use Test::More;
  29         116  
  29         267  
10              
11             our @SUPPORT_DRIVER = qw/Skinny DBI/;
12              
13             sub import {
14 29     29   243 my $caller = caller(0);
15              
16 29         158 strict->import;
17 29         293 warnings->import;
18              
19 29         61 for my $func (qw/run_tests run_tests_mysql run_tests_sqlite test_master teardown_dbs dsn_for/) {
20 29     29   149 no strict 'refs'; ## no critic.
  29         52  
  29         32640  
21 174         210 *{$caller.'::'.$func} = \&$func;
  174         1158  
22             }
23             }
24              
25             sub run_tests {
26 12     12 0 174 my ($n, $code) = @_;
27              
28 12         89 plan tests => $n*3*scalar(@SUPPORT_DRIVER);
29              
30 12         38 for my $driver (@SUPPORT_DRIVER) {
31 24         73 run_tests_mysql( $n, $driver, $code);
32 24         69 run_tests_innodb($n, $driver, $code);
33 24         77 run_tests_sqlite($n, $driver, $code);
34             }
35             }
36              
37             sub run_tests_innodb {
38 24     24 0 38 my ($n, $driver, $code) = @_;
39 24         61 run_tests_mysql($n, $driver, $code, 1);
40             }
41              
42             sub run_tests_mysql {
43 48     48 0 68 my ($n, $driver, $code, $innodb) = @_;
44              
45             SKIP: {
46 48         49 local $ENV{USE_MYSQL} = 1;
  48         278  
47 48         62 my $dbh = eval { mysql_dbh() }; ## no critic
  48         100  
48 48 50       32857 skip "MySQL not accessible as root on localhost", $n if $@;
49 0 0 0     0 skip "InnoDB not available on localhost's MySQL", $n if $innodb && ! has_innodb($dbh);
50 0         0 $code->($driver);
51             }
52             }
53              
54             sub run_tests_sqlite {
55 24     24 0 46 my ($n, $driver, $code) = @_;
56              
57             SKIP: {
58 12     12   1909 my $rv = eval "use DBD::SQLite; 1"; ## no critic
  0     12   0  
  0         0  
  12         1758  
  0         0  
  0         0  
  24         29  
  24         1530  
59 24 50       106 $rv = 0 if $ENV{SKIP_SQLITE};
60 24 50       104 skip "SQLite not installed", $n if !$rv;
61 0         0 $code->($driver);
62             }
63             }
64              
65             my $test_dbs;
66             sub test_master {
67 0     0 0 0 my %opts = @_;
68 0   0     0 my $dbs = delete $opts{dbs} || ['default'];
69 0         0 my $init = delete $opts{init};
70 0 0       0 $init = 1 unless defined $init;
71              
72 0         0 $test_dbs = $dbs;
73              
74 0 0       0 if ($init) {
75 0         0 setup_dbs($dbs);
76             }
77              
78             my $params = +{
79             databases => [
80 0         0 map {{
81 0         0 dsn => dsn_for($_),
82             username => 'root',
83             password => '',
84             }} @$dbs
85             ],
86             %opts,
87             };
88              
89 0         0 return Qudo->new(%$params);
90             }
91              
92             sub setup_dbs {
93 0     0 0 0 my $dbs = shift;
94              
95 0         0 my $schema = load_schema();
96 0         0 teardown_dbs($dbs);
97              
98 0         0 for my $db (@$dbs) {
99 0 0       0 if ($ENV{USE_MYSQL}) {
100 0         0 create_mysql_db(mysql_dbname($db));
101             }
102              
103 0 0       0 my $dbh = DBI->connect(
104             dsn_for($db),
105             'root',
106             '',
107             { RaiseError => 1, PrintError => 0 }
108             ) or die "Couldn't connect: $!\n";
109              
110 0 0       0 for my $sql (@{ $ENV{USE_MYSQL} ? $schema->{mysql} : $schema->{sqlite} }) {
  0         0  
111 0         0 $sql =~ s!^\s*create\s+table\s+(\w+)!CREATE TABLE $1!i;
112 0 0       0 $sql .= " ENGINE=INNODB\n" if $ENV{USE_MYSQL};
113 0         0 $dbh->do($sql);
114             }
115              
116 0         0 $dbh->disconnect;
117             }
118             }
119              
120             my $schema_data;
121             sub load_schema {
122 0     0 0 0 $schema_data->{mysql} = load_sql('doc/schema-mysql.sql');
123 0         0 $schema_data->{sqlite} = load_sql('doc/schema-sqlite.sql');
124 0         0 $schema_data;
125             }
126              
127             sub load_sql {
128 0     0 0 0 my($file) = @_;
129 0 0       0 open my $fh, '<', $file or die "Can't open $file: $!";
130 0         0 my $sql = do { local $/; <$fh> };
  0         0  
  0         0  
131 0         0 close $fh;
132 0         0 my @sql = split /;\s*/, $sql;
133 0         0 \@sql;
134             }
135              
136             sub mysql_dbh {
137 48 0   48 0 318 return DBI->connect(
138             "DBI:mysql:mysql",
139             "root",
140             "",
141             { RaiseError => 1 }
142             ) or die "Couldn't connect to database";
143             }
144              
145             sub dsn_for {
146 0     0 0   my $dbname = shift;
147 0 0         if ($ENV{USE_MYSQL}) {
148 0           return 'dbi:mysql:' . mysql_dbname($dbname);
149             } else {
150 0           return 'dbi:SQLite:dbname=' . db_filename($dbname);
151             }
152             }
153              
154             sub db_filename {
155 0     0 0   my($dbname) = @_;
156 0           return 'test_qudo_' . $dbname . '.db';
157             }
158              
159             sub mysql_dbname {
160 0     0 0   my($dbname) = @_;
161 0           return 'test_qudo_' . $dbname;
162             }
163              
164             sub create_mysql_db {
165 0     0 0   my $dbname = shift;
166 0           mysql_dbh()->do("CREATE DATABASE $dbname");
167             }
168              
169             sub drop_mysql_db {
170 0     0 0   my $dbname = shift;
171 0           mysql_dbh()->do("DROP DATABASE IF EXISTS $dbname");
172             }
173              
174             sub teardown_dbs {
175 0   0 0 0   my $dbs = shift || $test_dbs;
176              
177 0           for my $db (@$dbs) {
178 0 0         if ($ENV{USE_MYSQL}) {
179 0           drop_mysql_db(mysql_dbname($db));
180             } else {
181 0           my $file = db_filename($db);
182 0 0         return unless -e $file;
183 0 0         unlink $file or die "Can't teardown $db: $!";
184             }
185             }
186             }
187              
188             sub has_innodb {
189 0     0 0   my $dbh = shift;
190 0           my $tmpname = "test_to_see_if_innoavail";
191 0 0         $dbh->do("CREATE TABLE IF NOT EXISTS $tmpname (i int) ENGINE=INNODB")
192             or return 0;
193 0           my @row = $dbh->selectrow_array("SHOW CREATE TABLE $tmpname");
194 0           my $row = join(' ', @row);
195 0           my $has_it = ($row =~ /=InnoDB/i);
196 0           $dbh->do("DROP TABLE $tmpname");
197 0           return $has_it;
198             }
199              
200             1;
201