A number of equivalent-logic ::FC refactors
[dbsrgits/DBIx-Class.git] / t / row / filter_column.t
CommitLineData
956f4141 1use strict;
2use warnings;
3
4use Test::More;
c227b295 5use Test::Exception;
956f4141 6use lib qw(t/lib);
7use DBICTest;
cc2d2ead 8
85439e0c 9my $from_storage_ran = 0;
10my $to_storage_ran = 0;
cc2d2ead 11my $schema = DBICTest->init_schema();
c227b295 12DBICTest::Schema::Artist->load_components(qw(FilterColumn InflateColumn));
cc2d2ead 13DBICTest::Schema::Artist->filter_column(rank => {
85439e0c 14 filter_from_storage => sub { $from_storage_ran++; $_[1] * 2 },
15 filter_to_storage => sub { $to_storage_ran++; $_[1] / 2 },
cc2d2ead 16});
cc8ffd7b 17Class::C3->reinitialize() if DBIx::Class::_ENV_::OLD_MRO;
cc2d2ead 18
19my $artist = $schema->resultset('Artist')->create( { rank => 20 } );
20
21# this should be using the cursor directly, no inflation/processing of any sort
22my ($raw_db_rank) = $schema->resultset('Artist')
23 ->search ($artist->ident_condition)
24 ->get_column('rank')
25 ->_resultset
26 ->cursor
27 ->next;
28
29is ($raw_db_rank, 10, 'INSERT: correctly unfiltered on insertion');
30
31for my $reloaded (0, 1) {
32 my $test = $reloaded ? 'reloaded' : 'stored';
33 $artist->discard_changes if $reloaded;
34
35 is( $artist->rank , 20, "got $test filtered rank" );
36}
37
38$artist->update;
39$artist->discard_changes;
40is( $artist->rank , 20, "got filtered rank" );
41
42$artist->update ({ rank => 40 });
43($raw_db_rank) = $schema->resultset('Artist')
44 ->search ($artist->ident_condition)
45 ->get_column('rank')
46 ->_resultset
47 ->cursor
48 ->next;
49is ($raw_db_rank, 20, 'UPDATE: correctly unflitered on update');
50
51$artist->discard_changes;
52$artist->rank(40);
53ok( !$artist->is_column_changed('rank'), 'column is not dirty after setting the same value' );
54
8cfbd51c 55MC: {
56 my $cd = $schema->resultset('CD')->create({
57 artist => { rank => 20 },
58 title => 'fun time city!',
59 year => 'forevertime',
60 });
0f914ece 61 ($raw_db_rank) = $schema->resultset('Artist')
62 ->search ($cd->artist->ident_condition)
63 ->get_column('rank')
64 ->_resultset
65 ->cursor
66 ->next;
67
68 is $raw_db_rank, 10, 'artist rank gets correctly unfiltered w/ MC';
69 is $cd->artist->rank, 20, 'artist rank gets correctly filtered w/ MC';
8cfbd51c 70}
71
c227b295 72CACHE_TEST: {
73 my $expected_from = $from_storage_ran;
74 my $expected_to = $to_storage_ran;
75
76 # ensure we are creating a fresh obj
77 $artist = $schema->resultset('Artist')->single($artist->ident_condition);
78
79 is $from_storage_ran, $expected_from, 'from has not run yet';
80 is $to_storage_ran, $expected_to, 'to has not run yet';
81
82 $artist->rank;
83 cmp_ok (
84 $artist->get_filtered_column('rank'),
85 '!=',
86 $artist->get_column('rank'),
87 'filter/unfilter differ'
88 );
89 is $from_storage_ran, ++$expected_from, 'from ran once, therefor caches';
90 is $to_storage_ran, $expected_to, 'to did not run';
91
92 $artist->rank(6);
93 is $from_storage_ran, $expected_from, 'from did not run';
94 is $to_storage_ran, ++$expected_to, 'to ran once';
95
96 ok ($artist->is_column_changed ('rank'), 'Column marked as dirty');
97
98 $artist->rank;
c227b295 99 is $from_storage_ran, $expected_from, 'from did not run';
100 is $to_storage_ran, $expected_to, 'to did not run';
101
102 $artist->update;
103
104 $artist->set_column(rank => 3);
105 ok (! $artist->is_column_changed ('rank'), 'Column not marked as dirty on same set_column value');
106 is ($artist->rank, '6', 'Column set properly (cache blown)');
107 is $from_storage_ran, ++$expected_from, 'from ran once (set_column blew cache)';
108 is $to_storage_ran, $expected_to, 'to did not run';
109
110 $artist->rank(6);
111 ok (! $artist->is_column_changed ('rank'), 'Column not marked as dirty on same accessor-set value');
112 is ($artist->rank, '6', 'Column set properly');
113 is $from_storage_ran, $expected_from, 'from did not run';
dc6dadae 114 is $to_storage_ran, ++$expected_to, 'to did run once (call in to set_column)';
c227b295 115
116 $artist->store_column(rank => 4);
117 ok (! $artist->is_column_changed ('rank'), 'Column not marked as dirty on differing store_column value');
491c8ff9 118 is ($artist->rank, '8', 'Cache properly blown');
119 is $from_storage_ran, ++$expected_from, 'from did not run';
c227b295 120 is $to_storage_ran, $expected_to, 'to did not run';
121}
85439e0c 122
dc6dadae 123# test in-memory operations
124for my $artist_maker (
125 sub { $schema->resultset('Artist')->new({ rank => 42 }) },
126 sub { my $art = $schema->resultset('Artist')->new({}); $art->rank(42); $art },
127) {
128
129 my $expected_from = $from_storage_ran;
130 my $expected_to = $to_storage_ran;
131
132 my $artist = $artist_maker->();
133
134 is $from_storage_ran, $expected_from, 'from has not run yet';
135 is $to_storage_ran, $expected_to, 'to has not run yet';
136
137 ok( ! $artist->has_column_loaded('artistid'), 'pk not loaded' );
138 ok( $artist->has_column_loaded('rank'), 'Filtered column marked as loaded under new' );
139 is( $artist->rank, 42, 'Proper unfiltered value' );
140 is( $artist->get_column('rank'), 21, 'Proper filtered value' );
141}
142
c227b295 143IC_DIE: {
85aee309 144 throws_ok {
c227b295 145 DBICTest::Schema::Artist->inflate_column(rank =>
146 { inflate => sub {}, deflate => sub {} }
147 );
85aee309 148 } qr/InflateColumn can not be used on a column with a declared FilterColumn filter/, q(Can't inflate column after filter column);
c227b295 149
150 DBICTest::Schema::Artist->inflate_column(name =>
151 { inflate => sub {}, deflate => sub {} }
152 );
153
85aee309 154 throws_ok {
c227b295 155 DBICTest::Schema::Artist->filter_column(name => {
156 filter_to_storage => sub {},
157 filter_from_storage => sub {}
158 });
85aee309 159 } qr/FilterColumn can not be used on a column with a declared InflateColumn inflator/, q(Can't filter column after inflate column);
cde96798 160}
85439e0c 161
eec182b6 162# test when we do not set both filter_from_storage/filter_to_storage
163DBICTest::Schema::Artist->filter_column(rank => {
164 filter_to_storage => sub { $to_storage_ran++; $_[1] },
165});
cc8ffd7b 166Class::C3->reinitialize() if DBIx::Class::_ENV_::OLD_MRO;
eec182b6 167
168ASYMMETRIC_TO_TEST: {
169 # initialise value
170 $artist->rank(20);
171 $artist->update;
172
173 my $expected_from = $from_storage_ran;
174 my $expected_to = $to_storage_ran;
175
176 $artist->rank(10);
177 ok ($artist->is_column_changed ('rank'), 'Column marked as dirty on accessor-set value');
178 is ($artist->rank, '10', 'Column set properly');
179 is $from_storage_ran, $expected_from, 'from did not run';
180 is $to_storage_ran, ++$expected_to, 'to did run';
181
182 $artist->discard_changes;
183
184 is ($artist->rank, '20', 'Column set properly');
185 is $from_storage_ran, $expected_from, 'from did not run';
186 is $to_storage_ran, $expected_to, 'to did not run';
187}
188
189DBICTest::Schema::Artist->filter_column(rank => {
190 filter_from_storage => sub { $from_storage_ran++; $_[1] },
191});
cc8ffd7b 192Class::C3->reinitialize() if DBIx::Class::_ENV_::OLD_MRO;
eec182b6 193
194ASYMMETRIC_FROM_TEST: {
195 # initialise value
196 $artist->rank(23);
197 $artist->update;
198
199 my $expected_from = $from_storage_ran;
200 my $expected_to = $to_storage_ran;
201
202 $artist->rank(13);
203 ok ($artist->is_column_changed ('rank'), 'Column marked as dirty on accessor-set value');
204 is ($artist->rank, '13', 'Column set properly');
205 is $from_storage_ran, $expected_from, 'from did not run';
206 is $to_storage_ran, $expected_to, 'to did not run';
207
208 $artist->discard_changes;
209
210 is ($artist->rank, '23', 'Column set properly');
211 is $from_storage_ran, ++$expected_from, 'from did run';
212 is $to_storage_ran, $expected_to, 'to did not run';
213}
214
215throws_ok { DBICTest::Schema::Artist->filter_column( rank => {} ) }
216 qr/\QAn invocation of filter_column() must specify either a filter_from_storage or filter_to_storage/,
217 'Correctly throws exception for empty attributes'
218;
219
cc2d2ead 220done_testing;