Play nicer with lower-level methods
[dbsrgits/DBIx-Class.git] / t / row / filter_column.t
1 use strict;
2 use warnings;
3
4 use Test::More;
5 use lib qw(t/lib);
6 use DBICTest;
7
8 my $from_storage_ran = 0;
9 my $to_storage_ran = 0;
10 my $schema = DBICTest->init_schema();
11 DBICTest::Schema::Artist->load_components('FilterColumn');
12 DBICTest::Schema::Artist->filter_column(rank => {
13   filter_from_storage => sub { $from_storage_ran++; $_[1] * 2 },
14   filter_to_storage   => sub { $to_storage_ran++; $_[1] / 2 },
15 });
16 Class::C3->reinitialize();
17
18 my $artist = $schema->resultset('Artist')->create( { rank => 20 } );
19
20 # this should be using the cursor directly, no inflation/processing of any sort
21 my ($raw_db_rank) = $schema->resultset('Artist')
22                              ->search ($artist->ident_condition)
23                                ->get_column('rank')
24                                 ->_resultset
25                                  ->cursor
26                                   ->next;
27
28 is ($raw_db_rank, 10, 'INSERT: correctly unfiltered on insertion');
29
30 for my $reloaded (0, 1) {
31   my $test = $reloaded ? 'reloaded' : 'stored';
32   $artist->discard_changes if $reloaded;
33
34   is( $artist->rank , 20, "got $test filtered rank" );
35 }
36
37 $artist->update;
38 $artist->discard_changes;
39 is( $artist->rank , 20, "got filtered rank" );
40
41 $artist->update ({ rank => 40 });
42 ($raw_db_rank) = $schema->resultset('Artist')
43                              ->search ($artist->ident_condition)
44                                ->get_column('rank')
45                                 ->_resultset
46                                  ->cursor
47                                   ->next;
48 is ($raw_db_rank, 20, 'UPDATE: correctly unflitered on update');
49
50 $artist->discard_changes;
51 $artist->rank(40);
52 ok( !$artist->is_column_changed('rank'), 'column is not dirty after setting the same value' );
53
54 MC: {
55    my $cd = $schema->resultset('CD')->create({
56       artist => { rank => 20 },
57       title => 'fun time city!',
58       year => 'forevertime',
59    });
60    ($raw_db_rank) = $schema->resultset('Artist')
61                                 ->search ($cd->artist->ident_condition)
62                                   ->get_column('rank')
63                                    ->_resultset
64                                     ->cursor
65                                      ->next;
66
67    is $raw_db_rank, 10, 'artist rank gets correctly unfiltered w/ MC';
68    is $cd->artist->rank, 20, 'artist rank gets correctly filtered w/ MC';
69 }
70
71 my $expected_from = $from_storage_ran;
72 my $expected_to   = $to_storage_ran;
73
74 # ensure we are creating a fresh obj
75 $artist = $schema->resultset('Artist')->single($artist->ident_condition);
76
77 is $from_storage_ran, $expected_from, 'from has not run yet';
78 is $to_storage_ran, $expected_to, 'to has not run yet';
79
80 $artist->rank;
81 cmp_ok (
82   $artist->get_filtered_column('rank'),
83     '!=',
84   $artist->get_column('rank'),
85   'filter/unfilter differ'
86 );
87 is $from_storage_ran, ++$expected_from, 'from ran once, therefor caches';
88 is $to_storage_ran, $expected_to,  'to did not run';
89
90 $artist->rank(6);
91 is $from_storage_ran, $expected_from, 'from did not run';
92 is $to_storage_ran, ++$expected_to,  'to ran once';
93
94 ok ($artist->is_column_changed ('rank'), 'Column marked as dirty');
95
96 $artist->rank;
97 is $from_storage_ran, ++$expected_from, 'from ran once';
98 is $to_storage_ran, $expected_to,  'to did not run';
99
100 $artist->rank;
101 is $from_storage_ran, $expected_from, 'from did not run';
102 is $to_storage_ran, $expected_to,  'to did not run';
103
104 $artist->update;
105
106 $artist->set_column(rank => 3);
107 ok (! $artist->is_column_changed ('rank'), 'Column not marked as dirty on same set_column value');
108 is ($artist->rank, '6', 'Column set properly (cache blown)');
109 is $from_storage_ran, ++$expected_from, 'from ran once (set_column blew cache)';
110 is $to_storage_ran, $expected_to,  'to did not run';
111
112 $artist->rank(6);
113 ok (! $artist->is_column_changed ('rank'), 'Column not marked as dirty on same accessor-set value');
114 is ($artist->rank, '6', 'Column set properly');
115 is $from_storage_ran, $expected_from, 'from did not run';
116 is $to_storage_ran, $expected_to,  'to did not run';
117
118 $artist->store_column(rank => 4);
119 ok (! $artist->is_column_changed ('rank'), 'Column not marked as dirty on differing store_column value');
120 is ($artist->rank, '6', 'Filtered column still contains old value (cache not blown)');
121 is $from_storage_ran, $expected_from, 'from did not run';
122 is $to_storage_ran, $expected_to,  'to did not run';
123
124 $artist->set_column(rank => 4);
125 TODO: {
126   local $TODO = 'There seems to be no way around that much wizardry... which is ok';
127   ok ($artist->is_column_changed ('rank'), 'Column marked as dirty on out-of-sync set_column value');
128 }
129 is ($artist->rank, '8', 'Column set properly (cache blown)');
130 is $from_storage_ran, ++$expected_from, 'from ran once (set_column blew cache)';
131 is $to_storage_ran, $expected_to,  'to did not run';
132
133 done_testing;