Better exception when things get really really bad with prepare()
[dbsrgits/DBIx-Class.git] / t / cdbi / 04-lazy.t
1 use strict;
2 use warnings;
3 use Test::More;
4 use Test::Warn;
5
6 #----------------------------------------------------------------------
7 # Test lazy loading
8 #----------------------------------------------------------------------
9
10 BEGIN {
11   eval "use DBIx::Class::CDBICompat;";
12   plan $@ 
13     ? (skip_all => 'Class::Trigger and DBIx::ContextualFetch required')
14     : (tests => 36)
15   ;
16 }
17
18 INIT {
19   use lib 't/cdbi/testlib';
20   use Lazy;
21 }
22
23 is_deeply [ Lazy->columns('Primary') ],        [qw/this/],      "Pri";
24 is_deeply [ sort Lazy->columns('Essential') ], [qw/opop this/], "Essential";
25 is_deeply [ sort Lazy->columns('things') ],    [qw/that this/], "things";
26 is_deeply [ sort Lazy->columns('horizon') ],   [qw/eep orp/],   "horizon";
27 is_deeply [ sort Lazy->columns('vertical') ],  [qw/oop opop/],  "vertical";
28 is_deeply [ sort Lazy->columns('All') ], [qw/eep oop opop orp that this/], "All";
29
30 {
31   my @groups = Lazy->__grouper->groups_for(Lazy->find_column('this'));
32   is_deeply [ sort @groups ], [sort qw/things Essential Primary/], "this (@groups)";
33 }
34
35 {
36   my @groups = Lazy->__grouper->groups_for(Lazy->find_column('that'));
37   is_deeply \@groups, [qw/things/], "that (@groups)";
38 }
39
40 Lazy->create({ this => 1, that => 2, oop => 3, opop => 4, eep => 5 });
41
42 ok(my $obj = Lazy->retrieve(1), 'Retrieve by Primary');
43 ok($obj->_attribute_exists('this'),  "Gets primary");
44 ok($obj->_attribute_exists('opop'),  "Gets other essential");
45 ok(!$obj->_attribute_exists('that'), "But other things");
46 ok(!$obj->_attribute_exists('eep'),  " nor eep");
47 ok(!$obj->_attribute_exists('orp'),  " nor orp");
48 ok(!$obj->_attribute_exists('oop'),  " nor oop");
49
50 ok(my $val = $obj->eep, 'Fetch eep');
51 ok($obj->_attribute_exists('orp'),   'Gets orp too');
52 ok(!$obj->_attribute_exists('oop'),  'But still not oop');
53 ok(!$obj->_attribute_exists('that'), 'nor that');
54
55 {
56   Lazy->columns(All => qw/this that eep orp oop opop/);
57   ok(my $obj = Lazy->retrieve(1), 'Retrieve by Primary');
58   ok !$obj->_attribute_exists('oop'), " Don't have oop";
59   my $null = $obj->eep;
60   ok !$obj->_attribute_exists('oop'),
61     " Don't have oop - even after getting eep";
62 }
63
64 # Test contructor breaking.
65
66 eval {    # Need a hashref
67   Lazy->create(this => 10, that => 20, oop => 30, opop => 40, eep => 50);
68 };
69 ok($@, $@);
70
71 eval {    # False column
72   Lazy->create({ this => 10, that => 20, theother => 30 });
73 };
74 ok($@, $@);
75
76 eval {    # Multiple false columns
77   Lazy->create({ this => 10, that => 20, theother => 30, andanother => 40 });
78 };
79 ok($@, $@);
80
81
82 warning_like {
83     Lazy->columns( TEMP => qw(that) );
84 } qr/Declaring column that as TEMP but it already exists/;
85
86 # Test that create() and update() throws out columns that changed
87 {
88     my $l = Lazy->create({
89         this => 99,
90         that => 2,
91         oop  => 3,
92         opop => 4,
93     });
94
95     ok $l->db_Main->do(qq{
96         UPDATE @{[ $l->table ]}
97         SET    oop  = ?
98         WHERE  this = ?
99     }, undef, 87, $l->this);
100
101     is $l->oop, 87;
102
103     $l->oop(32);
104     $l->update;
105
106     ok $l->db_Main->do(qq{
107         UPDATE @{[ $l->table ]}
108         SET    oop  = ?
109         WHERE  this = ?
110     }, undef, 23, $l->this);
111
112     is $l->oop, 23;
113     
114     $l->delete;
115 }
116
117
118 # Now again for inflated values
119 SKIP: {
120     skip "Requires Date::Simple 3.03", 5 unless eval "use Date::Simple 3.03; 1; ";
121     Lazy->has_a(
122         orp     => 'Date::Simple',
123         inflate => sub { Date::Simple->new($_[0] . '-01-01') },
124         deflate => 'format'
125     );
126     
127     my $l = Lazy->create({
128         this => 89,
129         that => 2,
130         orp  => 1998,
131     });
132
133     ok $l->db_Main->do(qq{
134         UPDATE @{[ $l->table ]}
135         SET    orp  = ?
136         WHERE  this = ?
137     }, undef, 1987, $l->this);
138     
139     is $l->orp, '1987-01-01';
140
141     $l->orp(2007);
142     is $l->orp, '2007-01-01';   # make sure it's inflated
143     $l->update;
144     
145     ok $l->db_Main->do(qq{
146         UPDATE @{[ $l->table ]}
147         SET    orp  = ?
148         WHERE  this = ?
149     }, undef, 1942, $l->this);
150
151     is $l->orp, '1942-01-01';
152     
153     $l->delete;
154 }
155
156
157 # Test that a deleted object works
158 {
159     Lazy->search()->delete_all;
160     my $l = Lazy->create({
161         this => 99,
162         that => 2,
163         oop  => 3,
164         opop => 4,
165     });
166     
167     # Delete the object without it knowing.
168     Lazy->db_Main->do(qq[
169         DELETE
170         FROM   @{[ Lazy->table ]}
171         WHERE  this = 99
172     ]);
173     
174     $l->eep;
175     
176     # The problem was when an object had an inflated object
177     # loaded.  _flesh() would set _column_data to undef and
178     # get_column() would think nothing was there.
179     # I'm too lazy to set up the proper inflation test.
180     ok !exists $l->{_column_data}{orp};
181 }