File: SQLiteTest.pm

package info (click to toggle)
libdbd-sqlite3-perl 1.76-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 11,004 kB
  • sloc: ansic: 167,715; perl: 1,788; pascal: 277; makefile: 9
file content (240 lines) | stat: -rw-r--r-- 5,547 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
package SQLiteTest;

# Support code for DBD::SQLite tests

use strict;
use Exporter   ();
use File::Spec ();
use Test::More ();

our @ISA     = 'Exporter';
our @EXPORT  = qw/
    connect_ok dies dbfile @CALL_FUNCS $sqlite_call
    has_sqlite requires_sqlite requires_unicode_support
    allow_warnings has_compile_option has_fts
/;
our @CALL_FUNCS;
our $sqlite_call;

my $parent;
my %dbfiles;

BEGIN {
	# Allow tests to load modules bundled in /inc
	unshift @INC, 'inc';

	$parent = $$;
}

# Always load the DBI module
use DBI ();

sub dbfile { $dbfiles{$_[0]} ||= (defined $_[0] && length $_[0] && $_[0] ne ':memory:') ? $_[0] . $$ : $_[0] }

# Delete temporary files
sub clean {
	return
		if $$ != $parent;
	for my $dbfile (values %dbfiles) {
		next if $dbfile eq ':memory:';
		unlink $dbfile if -f $dbfile;
		my $journal = $dbfile . '-journal';
		unlink $journal if -f $journal;
	}
}

# Clean up temporary test files both at the beginning and end of the
# test script.
BEGIN { clean() }
END   { clean() }

# A simplified connect function for the most common case
sub connect_ok {
	my $attr = { @_ };
	my $dbfile = dbfile(defined $attr->{dbfile} ? delete $attr->{dbfile} : ':memory:');
	my @params = ( "dbi:SQLite:dbname=$dbfile", '', '' );
	if ( %$attr ) {
		push @params, $attr;
	}
	my $dbh = DBI->connect( @params );
	Test::More::isa_ok( $dbh, 'DBI::db' );
	return $dbh;
}

=head2 dies

  dies(sub {...}, $regex_expected_error, $msg)

Tests that the given coderef (most probably a closure) dies with the
expected error message.

=cut

sub dies {
	my ($coderef, $regex, $msg) = @_;
        eval {$coderef->()};
        my $exception = $@;
	Test::More::ok($exception =~ $regex, 
                       $msg || "dies with exception: $exception");
}



=head2 @CALL_FUNCS

The exported array C<@CALL_FUNCS> contains a list of coderefs
for testing several ways of calling driver-private methods.
On DBI versions prior to 1.608, such methods were called
through "func". Starting from 1.608, methods should be installed
within the driver (see L<DBI::DBD>) and are called through
C<< $dbh->sqlite_method_name(...) >>. This array helps to test
both ways. Usage :

  for my $call_func (@CALL_FUNCS) {
    my $dbh = connect_ok();
    ...
    $dbh->$call_func(@args, 'method_to_call');
    ...
  }

On DBI versions prior to 1.608, the loop will run only once
and the method call will be equivalent to 
C<< $dbh->func(@args, 'method_to_call') >>.
On more recent versions, the loop will run twice;
the second execution will call
C<< $dbh->sqlite_method_to_call(@args) >>.

=cut


# old_style way ("func")
push @CALL_FUNCS, sub {
  my $dbh = shift;
  return $dbh->func(@_);
};

# new_style, using $dbh->sqlite_*(...) --- starting from DBI v1.608
$DBI::VERSION >= 1.608 and push @CALL_FUNCS, sub {
  my $dbh       = shift;
  my $func_name = pop;
  my $method    = "sqlite_" . $func_name;
  return $dbh->$method(@_);
};


=head2 $sqlite_call

  $dbh->$sqlite_call(meth_name => @args);

This is another way of testing driver-private methods, in a portable
manner that works for DBI versions before or after 1.608. Unlike
C<@CALL_FUNCS>, this does not require to loop -- because after all,
it doesn't make much sense to test the old ->func() interface if
we have support for the new ->sqlite_*() interface. With C<$sqlite_call>,
the most appropriate API is chosen automatically and called only once.

=cut

$sqlite_call = sub {
  my $dbh = shift;
  my $func_to_call = shift;
  $CALL_FUNCS[-1]->($dbh, @_, $func_to_call);
};

=head2 has_compile_option

  has_compile_option('ENABLE_FTS3');
  has_compile_option(qr/^ENABLE_FTS[345]/);

returns true if DBD::SQLite is built with a specified compile option.

=cut

sub has_compile_option {
  my $option = shift;
  require DBD::SQLite;
  return unless DBD::SQLite->can('compile_options');
  my $re = ref $option eq ref qr// ? $option : qr/\b$option\b/;
  grep /$re/, DBD::SQLite::compile_options();
}

=head2 has_fts

  has_fts();
  has_fts(3);

returns true if DBD::SQLite is built with FTS.

=cut

sub has_fts {
  if (my $version = shift) {
    has_compile_option("ENABLE_FTS$version");
  } else {
    has_compile_option(qr/\bENABLE_FTS\d\b/);
  }
}

=head2 has_sqlite

  has_sqlite('3.6.11');

returns true if DBD::SQLite is built with a version of SQLite equal to or higher than the specified version.

=cut

sub has_sqlite {
  my $version = shift;
  my @version_parts = split /\./, $version;
  my $format = '%d%03d%03d';
  my $version_number = sprintf $format, @version_parts[0..2];
  use DBD::SQLite;
  return ($DBD::SQLite::sqlite_version_number && $DBD::SQLite::sqlite_version_number >= $version_number) ? 1 : 0;
}

=head2 requires_sqlite

  BEGIN { requires_sqlite('3.6.11'); }

skips all the tests if DBD::SQLite is not built with a version of SQLite equal to or higher than the specified version.

=cut

sub requires_sqlite {
  my $version = shift;
  unless (has_sqlite($version)) {
    Test::More::plan skip_all => "this test requires SQLite $version and newer";
    exit;
  }
}

=head2 requires_unicode_support

  BEGIN { requires_unicode_support(); }

skips all the tests if Perl does not have sane Unicode support.

=cut

sub requires_unicode_support {
  unless ($] >= 5.008005) {
    Test::More::plan skip_all => "Unicode is not supported before 5.8.5";
    exit;
  }
}

=head2 allow_warnings

  allow_warnings { eval {...} };

hides SQLite warnings from Test::FailWarnings.

=cut

sub allow_warnings (&) {
  my $code = shift;
  local $SIG{__WARN__} = sub { Test::More::note @_ };
  $code->();
}

1;