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