more error handling and testing
[dbsrgits/DBIx-Class-ParameterizedJoinHack.git] / t / 00basic.t
index f24197b..348353e 100644 (file)
@@ -1,7 +1,8 @@
 use strict;
 use warnings;
 use lib 't/lib';
-use Test::More qw(no_plan);
+use Test::More;
+use Test::Fatal;
 use My::Schema;
 
 my $schema = My::Schema->connect('dbi:SQLite:dbname=:memory:');
@@ -27,14 +28,124 @@ $bob->create_related(assigned_tasks => {
     urgency => 30,
 });
 
-my $test_rs = $schema
-    ->resultset('Person')
-    ->search({ 'me.name' => { -like => 'Bob%' } });
+subtest 'has_many' => sub {
 
-is $test_rs->with_parameterized_join(
-    urgent_assigned_tasks => { urgency_threshold => 20 },
-)->count, 1, 'joined';
+    my $join_with_min = sub {
+        return shift->with_parameterized_join(
+            urgent_assigned_tasks => { urgency_threshold => $_[0] },
+        );
+    };
 
-is $test_rs->with_parameterized_join(
-    urgent_assigned_tasks => { urgency_threshold => 200 },
-)->count, 1, 'not joined';
+    my $join_with_range = sub {
+        return shift->with_parameterized_join(
+            tasks_in_urgency_range => {
+                min => $_[0],
+                max => $_[1],
+            },
+        );
+    };
+
+    my $search_count = sub {
+        return scalar shift->search(
+            { 'me.name' => { -like => 'Bob%' } },
+            {
+                '+select' => [{
+                    count => \[shift],
+                }],
+                '+as' => ['task_count'],
+            },
+        );
+    };
+    my $search = sub { $search_count->(shift, 'urgent_assigned_tasks.id') };
+
+    my $fetch_count = sub {
+        return shift->next->get_column('task_count');
+    };
+
+    subtest 'simple filter' => sub {
+        is $people->$join_with_min(19)->$search->$fetch_count,
+            2, 'filter min 19';
+        is $people->$join_with_min(29)->$search->$fetch_count,
+            1, 'filter min 29';
+        is $people->$join_with_min(39)->$search->$fetch_count,
+            0, 'filter min 39';
+    };
+
+    subtest 'multiple filters' => sub {
+        my $rs1 = $people->$join_with_min(19)->$search;
+        my $rs2 = $people->$join_with_min(29)->$search;
+        is $rs1->$fetch_count, 2, 'first';
+        is $rs2->$fetch_count, 1, 'second';
+    };
+
+    subtest 'overrides' => sub {
+        is $people
+            ->$join_with_min(19)
+            ->$join_with_min(29)
+            ->$search
+            ->$fetch_count,
+            1, 'overridden parameter';
+    };
+
+    subtest 'multi parameter' => sub {
+        my $search = sub {
+            $search_count->(shift, 'tasks_in_urgency_range.id');
+        };
+        is $people->$join_with_range(10, 30)->$search->$fetch_count,
+            3, 'full range';
+    };
+
+    subtest 'multi join' => sub {
+        is $people
+            ->$join_with_min(19)
+            ->$join_with_range(10, 30)
+            ->$search
+            ->$fetch_count,
+            2*3, 'full count';
+    };
+
+    subtest 'errors' => sub {
+        like exception {
+            $people->with_parameterized_join(urgent_assigned_tasks => {})
+                ->$search
+                ->$fetch_count;
+        }, qr{urgent_assigned_tasks.+urgency_threshold}, 'missing parameter';
+        like exception {
+            $people->with_parameterized_join(__invalid__ => {})
+                ->$search
+                ->$fetch_count;
+        }, qr{__invalid__}, 'unknown relation';
+        like exception {
+            $people->with_parameterized_join(undef, {});
+        }, qr{relation.+name}i, 'missing relation name';
+        like exception {
+            $people->with_parameterized_join(foo => []);
+        }, qr{parameters.+hash.+not.+ARRAY}i, 'invalid parameters';
+        like exception {
+            $people->with_parameterized_join(foo => 23);
+        }, qr{parameters.+hash.+not.+non-reference}i, 'non ref parameters';
+    };
+
+    subtest 'declaration errors' => sub {
+        my $errors = \%My::Schema::Result::Person::ERROR;
+        like delete $errors->{no_args}, qr{Missing.+relation.+name}i,
+            'no arguments';
+        like delete $errors->{no_source}, qr{Missing.+foreign.+source}i,
+            'no foreign source';
+        like delete $errors->{no_cond}, qr{Condition.+non-ref.+value}i,
+            'no condition';
+        like delete $errors->{invalid_cond}, qr{Condition.+SCALAR}i,
+            'invalid condition';
+        like delete $errors->{undef_args}, qr{Arguments.+array.+non-ref}i,
+            'undef args';
+        like delete $errors->{invalid_args}, qr{Arguments.+array.+SCALAR}i,
+            'invalid args';
+        like delete $errors->{undef_builder}, qr{builder.+code.+non-ref}i,
+            'undef builder';
+        like delete $errors->{invalid_builder}, qr{builder.+code.+ARRAY}i,
+            'invalid builder';
+        is_deeply $errors, {}, 'no more errors';
+    };
+};
+
+done_testing;