File Coverage

blib/lib/Test/Proto/Where.pm
Criterion Covered Total %
statement 29 29 100.0
branch 7 12 58.3
condition n/a
subroutine 8 8 100.0
pod 3 3 100.0
total 47 52 90.3


line stmt bran cond sub pod time code
1             package Test::Proto::Where;
2 2     2   34651 use strict;
  2         5  
  2         143  
3 2     2   210 use warnings;
  2         5  
  2         57  
4 2     2   2563 use Test::Proto::Common();
  2         7118  
  2         48  
5 2     2   17 use base 'Exporter';
  2         4  
  2         906  
6             our @EXPORT = qw(&test_subject &where &otherwise);
7              
8             =head1 NAME
9              
10             Test::Proto::Where - provide case switching using Test::Proto
11              
12             =head1 VERSION
13              
14             0.001
15              
16             =cut
17              
18             our $VERSION = '0.001';
19              
20             =head1 SYNOPSIS
21              
22             print test_subject {foo=>'bar'} =>
23             where [], sub{ 'Empty array' },
24             where pHash, sub{ 'A hash' },
25             otherwise sub { 'Something else' };
26              
27             Uses Test::Proto and its upgrading feature to implement a dispatch.
28              
29             Note: This module is presently B: it is a working proof of concept.
30              
31             =head1 SYNTAX
32              
33             =head3 test_subject
34              
35             Takes as its first argument a prototype, which must not be a list of bare array/hash. It then takes one or more where/otherwise statements, as described below. If it does not get the arguments it requires, it will C.
36              
37             If you are taking the first argument from a function or method call, you should use scalar to force scalar context, like this:
38              
39             test_subject scalar($obj->method) =>
40             where ...
41              
42             Note also that because test_subject takes where and otherwise as arugments, if you are enclosing the first argument in brackets you must enclose all the arguments in brackets, other wise perl will be confused and think you are only passing the first argument.
43              
44             =cut
45              
46             sub test_subject ($$) {
47 6     6 1 13 my $subject = shift;
48 6         9 my $where = shift;
49 6 50       19 die('Missing where') unless defined $where;
50 6 50       25 die('Expected where or otherwise') if ref $where ne 'Test::Proto::Where';
51 6         22 return $where->{run}->($subject);
52             }
53              
54             =head3 where
55              
56             C is followed by a test, then an instruction. If the test passes, the instruction is carried out and no other 'where' or 'otherwise' statements are executed.
57              
58             =cut
59              
60             sub where ($&;$) {
61 8     8 1 49 my $self = {
62             proto => shift,
63             code => shift,
64             type => 'where',
65             fallback => shift
66             };
67             $self->{run} = sub {
68 8     8   12 my $subject = shift;
69 8 100       37 return $self->{code}->($subject) if Test::Proto::Common::upgrade( $self->{proto} )->validate($subject);
70 3 50       35113 return unless defined $self->{fallback};
71 3 50       14 die('Expected where or otherwise') if ref $self->{fallback} ne 'Test::Proto::Where';
72 3         15 return $self->{fallback}->{run}->($subject);
73 8         40 };
74 8 50       27 die('where needs code') unless defined $self->{code};
75 8         37 bless $self, __PACKAGE__;
76             }
77              
78             =head3 otherwise
79              
80             C is followed an instruction. If no preceding where tests have passed, this instruction will be executed.
81              
82             =cut
83              
84             sub otherwise (&) {
85 4     4 1 19131 my $self = {
86             code => shift,
87             type => 'otherwise'
88             };
89 4         11 $self->{run} = $self->{code};
90 4         23 bless $self, __PACKAGE__;
91             }
92              
93             # test_subject scalar foo(), where pArray, {}, otherwise {};
94