use warnings;
use Test::More;
+use Test::Exception;
use lib qw(t/lib);
use DBICTest;
my $from_storage_ran = 0;
my $to_storage_ran = 0;
my $schema = DBICTest->init_schema();
-DBICTest::Schema::Artist->load_components('FilterColumn');
+DBICTest::Schema::Artist->load_components(qw(FilterColumn InflateColumn));
DBICTest::Schema::Artist->filter_column(rank => {
filter_from_storage => sub { $from_storage_ran++; $_[1] * 2 },
filter_to_storage => sub { $to_storage_ran++; $_[1] / 2 },
is $cd->artist->rank, 20, 'artist rank gets correctly filtered w/ MC';
}
-my $initial_from = $from_storage_ran;
-my $initial_to = $to_storage_ran;
+CACHE_TEST: {
+ my $expected_from = $from_storage_ran;
+ my $expected_to = $to_storage_ran;
+
+ # ensure we are creating a fresh obj
+ $artist = $schema->resultset('Artist')->single($artist->ident_condition);
+
+ is $from_storage_ran, $expected_from, 'from has not run yet';
+ is $to_storage_ran, $expected_to, 'to has not run yet';
+
+ $artist->rank;
+ cmp_ok (
+ $artist->get_filtered_column('rank'),
+ '!=',
+ $artist->get_column('rank'),
+ 'filter/unfilter differ'
+ );
+ is $from_storage_ran, ++$expected_from, 'from ran once, therefor caches';
+ is $to_storage_ran, $expected_to, 'to did not run';
+
+ $artist->rank(6);
+ is $from_storage_ran, $expected_from, 'from did not run';
+ is $to_storage_ran, ++$expected_to, 'to ran once';
+
+ ok ($artist->is_column_changed ('rank'), 'Column marked as dirty');
+
+ $artist->rank;
+ is $from_storage_ran, $expected_from, 'from did not run';
+ is $to_storage_ran, $expected_to, 'to did not run';
+
+ $artist->update;
+
+ $artist->set_column(rank => 3);
+ ok (! $artist->is_column_changed ('rank'), 'Column not marked as dirty on same set_column value');
+ is ($artist->rank, '6', 'Column set properly (cache blown)');
+ is $from_storage_ran, ++$expected_from, 'from ran once (set_column blew cache)';
+ is $to_storage_ran, $expected_to, 'to did not run';
+
+ $artist->rank(6);
+ ok (! $artist->is_column_changed ('rank'), 'Column not marked as dirty on same accessor-set value');
+ is ($artist->rank, '6', 'Column set properly');
+ is $from_storage_ran, $expected_from, 'from did not run';
+ is $to_storage_ran, $expected_to, 'to did not run';
+
+ $artist->store_column(rank => 4);
+ ok (! $artist->is_column_changed ('rank'), 'Column not marked as dirty on differing store_column value');
+ is ($artist->rank, '8', 'Cache properly blown');
+ is $from_storage_ran, ++$expected_from, 'from did not run';
+ is $to_storage_ran, $expected_to, 'to did not run';
+}
+
+IC_DIE: {
+ dies_ok {
+ DBICTest::Schema::Artist->inflate_column(rank =>
+ { inflate => sub {}, deflate => sub {} }
+ );
+ } q(Can't inflate column after filter column);
+
+ DBICTest::Schema::Artist->inflate_column(name =>
+ { inflate => sub {}, deflate => sub {} }
+ );
+
+ dies_ok {
+ DBICTest::Schema::Artist->filter_column(name => {
+ filter_to_storage => sub {},
+ filter_from_storage => sub {}
+ });
+ } q(Can't filter column after inflate column);
+}
+
+# test when we do not set both filter_from_storage/filter_to_storage
+DBICTest::Schema::Artist->filter_column(rank => {
+ filter_to_storage => sub { $to_storage_ran++; $_[1] },
+});
+Class::C3->reinitialize();
-# ensure we are creating a fresh obj
-$artist = $schema->resultset('Artist')->single($artist->ident_condition);
+ASYMMETRIC_TO_TEST: {
+ # initialise value
+ $artist->rank(20);
+ $artist->update;
-is $initial_from, $from_storage_ran, 'from has not run yet';
-is $initial_from, $from_storage_ran, 'to has not run yet';
+ my $expected_from = $from_storage_ran;
+ my $expected_to = $to_storage_ran;
-$artist->rank;
-$artist->get_filtered_column('rank');
-$artist->get_column('rank');
+ $artist->rank(10);
+ ok ($artist->is_column_changed ('rank'), 'Column marked as dirty on accessor-set value');
+ is ($artist->rank, '10', 'Column set properly');
+ is $from_storage_ran, $expected_from, 'from did not run';
+ is $to_storage_ran, ++$expected_to, 'to did run';
-is $from_storage_ran, $initial_from + 1, 'from ran once, therefor caches';
-is $to_storage_ran, $initial_to, 'to ran none';
-$initial_from = $from_storage_ran;
-$initial_to = $to_storage_ran;
+ $artist->discard_changes;
-$artist->rank(1);
+ is ($artist->rank, '20', 'Column set properly');
+ is $from_storage_ran, $expected_from, 'from did not run';
+ is $to_storage_ran, $expected_to, 'to did not run';
+}
-is $from_storage_ran, $initial_from, 'from ran none';
-is $to_storage_ran, $initial_to + 1, 'to ran once';
-$initial_from = $from_storage_ran;
-$initial_to = $to_storage_ran;
+DBICTest::Schema::Artist->filter_column(rank => {
+ filter_from_storage => sub { $from_storage_ran++; $_[1] },
+});
+Class::C3->reinitialize();
-$artist->rank;
+ASYMMETRIC_FROM_TEST: {
+ # initialise value
+ $artist->rank(23);
+ $artist->update;
-is $from_storage_ran, $initial_from + 1, 'from ran once';
-is $to_storage_ran, $initial_to, 'to ran none';
-$initial_from = $from_storage_ran;
-$initial_to = $to_storage_ran;
+ my $expected_from = $from_storage_ran;
+ my $expected_to = $to_storage_ran;
-$artist->rank;
+ $artist->rank(13);
+ ok ($artist->is_column_changed ('rank'), 'Column marked as dirty on accessor-set value');
+ is ($artist->rank, '13', 'Column set properly');
+ is $from_storage_ran, $expected_from, 'from did not run';
+ is $to_storage_ran, $expected_to, 'to did not run';
-is $from_storage_ran, $initial_from, 'from ran none';
-is $to_storage_ran, $initial_to, 'to ran none';
-$initial_from = $from_storage_ran;
-$initial_to = $to_storage_ran;
+ $artist->discard_changes;
-$artist->set_column(rank => 1);
-$artist->rank;
+ is ($artist->rank, '23', 'Column set properly');
+ is $from_storage_ran, ++$expected_from, 'from did run';
+ is $to_storage_ran, $expected_to, 'to did not run';
+}
-is $from_storage_ran, $initial_from + 1, 'from ran once (set column blows cache)';
-is $to_storage_ran, $initial_to, 'to ran none';
-$initial_from = $from_storage_ran;
-$initial_to = $to_storage_ran;
+throws_ok { DBICTest::Schema::Artist->filter_column( rank => {} ) }
+ qr/\QAn invocation of filter_column() must specify either a filter_from_storage or filter_to_storage/,
+ 'Correctly throws exception for empty attributes'
+;
done_testing;