Commit | Line | Data |
70350518 |
1 | use strict; |
2 | use warnings; |
3 | |
4 | use Test::More; |
5 | use lib qw(t/lib); |
6 | use DBICTest; |
7 | |
a47e1233 |
8 | my $schema = DBICTest->init_schema(); |
70350518 |
9 | |
291bf95f |
10 | plan tests => 40; |
a62cf8d4 |
11 | |
12 | my $code = sub { |
13 | my ($artist, @cd_titles) = @_; |
14 | |
15 | $artist->create_related('cds', { |
16 | title => $_, |
17 | year => 2006, |
18 | }) foreach (@cd_titles); |
19 | |
20 | return $artist->cds->all; |
21 | }; |
22 | |
171dadd7 |
23 | # Test checking of parameters |
24 | { |
171dadd7 |
25 | eval { |
26 | (ref $schema)->txn_do(sub{}); |
27 | }; |
f32eb113 |
28 | like($@, qr/storage/, "can't call txn_do without storage"); |
171dadd7 |
29 | eval { |
30 | $schema->txn_do(''); |
31 | }; |
32 | like($@, qr/must be a CODE reference/, '$coderef parameter check ok'); |
33 | } |
34 | |
a62cf8d4 |
35 | # Test successful txn_do() - scalar context |
36 | { |
37 | my @titles = map {'txn_do test CD ' . $_} (1..5); |
38 | my $artist = $schema->resultset('Artist')->find(1); |
39 | my $count_before = $artist->cds->count; |
40 | my $count_after = $schema->txn_do($code, $artist, @titles); |
41 | is($count_after, $count_before+5, 'successful txn added 5 cds'); |
42 | is($artist->cds({ |
43 | title => "txn_do test CD $_", |
44 | })->first->year, 2006, "new CD $_ year correct") for (1..5); |
45 | } |
46 | |
47 | # Test successful txn_do() - list context |
48 | { |
49 | my @titles = map {'txn_do test CD ' . $_} (6..10); |
50 | my $artist = $schema->resultset('Artist')->find(1); |
51 | my $count_before = $artist->cds->count; |
52 | my @cds = $schema->txn_do($code, $artist, @titles); |
53 | is(scalar @cds, $count_before+5, 'added 5 CDs and returned in list context'); |
54 | is($artist->cds({ |
55 | title => "txn_do test CD $_", |
56 | })->first->year, 2006, "new CD $_ year correct") for (6..10); |
57 | } |
58 | |
59 | # Test nested successful txn_do() |
60 | { |
61 | my $nested_code = sub { |
62 | my ($schema, $artist, $code) = @_; |
63 | |
64 | my @titles1 = map {'nested txn_do test CD ' . $_} (1..5); |
65 | my @titles2 = map {'nested txn_do test CD ' . $_} (6..10); |
66 | |
67 | $schema->txn_do($code, $artist, @titles1); |
68 | $schema->txn_do($code, $artist, @titles2); |
69 | }; |
70 | |
71 | my $artist = $schema->resultset('Artist')->find(2); |
72 | my $count_before = $artist->cds->count; |
73 | |
74 | eval { |
75 | $schema->txn_do($nested_code, $schema, $artist, $code); |
76 | }; |
77 | |
78 | my $error = $@; |
79 | |
80 | ok(!$error, 'nested txn_do succeeded'); |
81 | is($artist->cds({ |
82 | title => 'nested txn_do test CD '.$_, |
83 | })->first->year, 2006, qq{nested txn_do CD$_ year ok}) for (1..10); |
84 | is($artist->cds->count, $count_before+10, 'nested txn_do added all CDs'); |
85 | } |
86 | |
87 | my $fail_code = sub { |
88 | my ($artist) = @_; |
89 | $artist->create_related('cds', { |
90 | title => 'this should not exist', |
91 | year => 2005, |
92 | }); |
93 | die "the sky is falling"; |
94 | }; |
95 | |
96 | # Test failed txn_do() |
97 | { |
98 | my $artist = $schema->resultset('Artist')->find(3); |
99 | |
100 | eval { |
101 | $schema->txn_do($fail_code, $artist); |
102 | }; |
103 | |
104 | my $error = $@; |
105 | |
106 | like($error, qr/the sky is falling/, 'failed txn_do threw an exception'); |
107 | my $cd = $artist->cds({ |
108 | title => 'this should not exist', |
109 | year => 2005, |
110 | })->first; |
111 | ok(!defined($cd), q{failed txn_do didn't change the cds table}); |
112 | } |
113 | |
114 | # Test failed txn_do() with failed rollback |
115 | { |
116 | my $artist = $schema->resultset('Artist')->find(3); |
117 | |
118 | # Force txn_rollback() to throw an exception |
119 | no warnings 'redefine'; |
58d387fe |
120 | no strict 'refs'; |
4012acd8 |
121 | local *{"DBIx::Class::Storage::DBI::SQLite::txn_rollback"} = sub{die 'FAILED'}; |
a62cf8d4 |
122 | |
123 | eval { |
124 | $schema->txn_do($fail_code, $artist); |
125 | }; |
126 | |
127 | my $error = $@; |
128 | |
129 | like($error, qr/Rollback failed/, 'failed txn_do with a failed '. |
130 | 'txn_rollback threw a rollback exception'); |
131 | like($error, qr/the sky is falling/, 'failed txn_do with a failed '. |
132 | 'txn_rollback included the original exception'); |
133 | |
134 | my $cd = $artist->cds({ |
135 | title => 'this should not exist', |
136 | year => 2005, |
137 | })->first; |
138 | isa_ok($cd, 'DBICTest::CD', q{failed txn_do with a failed txn_rollback }. |
139 | q{changed the cds table}); |
140 | $cd->delete; # Rollback failed |
141 | $cd = $artist->cds({ |
142 | title => 'this should not exist', |
143 | year => 2005, |
144 | })->first; |
145 | ok(!defined($cd), q{deleted the failed txn's cd}); |
146 | $schema->storage->{transaction_depth} = 0; # Must reset this or further tests |
147 | # will fail |
148 | } |
149 | |
150 | # Test nested failed txn_do() |
151 | { |
152 | my $nested_fail_code = sub { |
153 | my ($schema, $artist, $code1, $code2) = @_; |
154 | |
155 | my @titles = map {'nested txn_do test CD ' . $_} (1..5); |
156 | |
157 | $schema->txn_do($code1, $artist, @titles); # successful txn |
158 | $schema->txn_do($code2, $artist); # failed txn |
159 | }; |
160 | |
161 | my $artist = $schema->resultset('Artist')->find(3); |
162 | |
163 | eval { |
164 | $schema->txn_do($nested_fail_code, $schema, $artist, $code, $fail_code); |
165 | }; |
166 | |
167 | my $error = $@; |
168 | |
169 | like($error, qr/the sky is falling/, 'nested failed txn_do threw exception'); |
170 | ok(!defined($artist->cds({ |
171 | title => 'nested txn_do test CD '.$_, |
172 | year => 2006, |
173 | })->first), qq{failed txn_do didn't add first txn's cd $_}) for (1..5); |
174 | my $cd = $artist->cds({ |
175 | title => 'this should not exist', |
176 | year => 2005, |
177 | })->first; |
178 | ok(!defined($cd), q{failed txn_do didn't add failed txn's cd}); |
179 | } |
a62cf8d4 |
180 | |
291bf95f |
181 | # Grab a new schema to test txn before connect |
182 | { |
183 | my $schema2 = DBICTest->init_schema(no_deploy => 1); |
184 | eval { |
185 | $schema2->txn_begin(); |
186 | $schema2->txn_begin(); |
187 | }; |
188 | my $err = $@; |
189 | ok(($err eq ''), 'Pre-connection nested transactions.'); |
190 | } |