Merged with master and am ready to merge back
[dbsrgits/DBM-Deep.git] / t / 96_virtual_functions.t
CommitLineData
417f635b 1#vim: ft=perl
2
3use strict;
4use warnings FATAL => 'all';
5
6use Test::More;
7use Test::Exception;
8
9use lib 't/lib';
10
11use_ok( 'DBM::Deep' );
12
13throws_ok {
14 DBM::Deep->new({ _test => 1 });
15} qr/lock_exclusive must be implemented in a child class/, 'Must define lock_exclusive in Storage';
16
17{
18 no strict 'refs';
19 *{"DBM::Deep::Storage::Test::lock_exclusive"} = sub { 1 };
20}
21
22throws_ok {
23 DBM::Deep->new({ _test => 1 });
24} qr/setup must be implemented in a child class/, 'Must define setup in Engine';
25
26{
27 no strict 'refs';
28 *{"DBM::Deep::Engine::Test::setup"} = sub { 1 };
29}
30
31throws_ok {
32 DBM::Deep->new({ _test => 1 });
33} qr/unlock must be implemented in a child class/, 'Must define unlock in Storage';
34
35{
36 no strict 'refs';
37 *{"DBM::Deep::Storage::Test::unlock"} = sub { 1 };
38}
39
40throws_ok {
41 DBM::Deep->new({ _test => 1 });
42} qr/flush must be implemented in a child class/, 'Must define flush in Storage';
43
44{
45 no strict 'refs';
46 *{"DBM::Deep::Storage::Test::flush"} = sub { 1 };
47}
48
49my $db;
50lives_ok {
51 $db = DBM::Deep->new({ _test => 1 });
52} "We finally have enough defined to instantiate";
53
54throws_ok {
55 $db->lock_shared;
56} qr/lock_shared must be implemented in a child class/, 'Must define lock_shared in Storage';
57
58{
59 no strict 'refs';
60 *{"DBM::Deep::Storage::Test::lock_shared"} = sub { 1 };
61}
62
63lives_ok {
64 $db->lock_shared;
65} 'We have lock_shared defined';
66
67# Yes, this is ordered for good reason. Think about it.
68my @methods = (
69 'begin_work' => [
70 Engine => 'begin_work',
71 ],
72 'rollback' => [
73 Engine => 'rollback',
74 ],
75 'commit' => [
76 Engine => 'commit',
77 ],
78 'supports' => [
79 Engine => 'supports',
80 ],
81 'store' => [
82 Storage => 'is_writable',
83 Engine => 'write_value',
84 ],
85 'fetch' => [
86 Engine => 'read_value',
87 ],
88 'delete' => [
89 Engine => 'delete_key',
90 ],
91 'exists' => [
92 Engine => 'key_exists',
93 ],
94 # Why is this one's error message bleeding through?
95 'clear' => [
96 Engine => 'clear',
97 ],
98);
99
100# Add the following:
101# in_txn
102
103# If only I could use natatime(). *sighs*
104while ( @methods ) {
105 my ($entry, $requirements) = splice @methods, 0, 2;
417f635b 106 while ( @$requirements ) {
107 my ($class, $child_method) = splice @$requirements, 0, 2;
108
109 throws_ok {
110 $db->$entry( 1 );
111 } qr/$child_method must be implemented in a child class/,
112 "'$entry' requires '$child_method' to be defined in the '$class'";
113
114 {
115 no strict 'refs';
116 *{"DBM::Deep::${class}::Test::${child_method}"} = sub { 1 };
117 }
118 }
119
120 lives_ok {
121 $db->$entry( 1 );
122 } "Finally have enough for '$entry' to work";
123}
124
125throws_ok {
126 $db->_engine->sector_type;
127} qr/sector_type must be implemented in a child class/, 'Must define sector_type in Storage';
128
129{
130 no strict 'refs';
131 *{"DBM::Deep::Engine::Test::sector_type"} = sub { 'DBM::Deep::Iterator::Test' };
132}
133
134lives_ok {
135 $db->_engine->sector_type;
136} 'We have sector_type defined';
137
138throws_ok {
139 $db->first_key;
140} qr/iterator_class must be implemented in a child class/, 'Must define iterator_class in Iterator';
141
142{
143 no strict 'refs';
144 *{"DBM::Deep::Engine::Test::iterator_class"} = sub { 'DBM::Deep::Iterator::Test' };
145}
146
147throws_ok {
148 $db->first_key;
149} qr/reset must be implemented in a child class/, 'Must define reset in Iterator';
150
151{
152 no strict 'refs';
153 *{"DBM::Deep::Iterator::Test::reset"} = sub { 1 };
154}
155
156throws_ok {
157 $db->first_key;
158} qr/get_next_key must be implemented in a child class/, 'Must define get_next_key in Iterator';
159
160{
161 no strict 'refs';
162 *{"DBM::Deep::Iterator::Test::get_next_key"} = sub { 1 };
163}
164
165lives_ok {
166 $db->first_key;
167} 'Finally have enough for first_key to work.';
168
169done_testing;