File Coverage

blib/lib/Generic/Assertions.pm
Criterion Covered Total %
statement 91 94 96.8
branch 31 34 91.1
condition 5 5 100.0
subroutine 25 25 100.0
pod 1 2 50.0
total 153 160 95.6


line stmt bran cond sub pod time code
1 7     7   116077 use 5.006;
  7         16  
2 7     7   25 use strict;
  7         7  
  7         118  
3 7     7   30 use warnings;
  7         9  
  7         415  
4              
5             package Generic::Assertions;
6              
7             our $VERSION = '0.001002';
8              
9             # ABSTRACT: A Generic Assertion checking class
10              
11             our $AUTHORITY = 'cpan:KENTNL'; # AUTHORITY
12              
13 7     7   24 use Carp qw( croak carp );
  7         7  
  7         6579  
14              
15             sub new {
16 50     50 1 31965 my ( $class, @args ) = @_;
17 50 100 100     164 if ( @args % 2 == 1 and not ref $args[0] ) {
18 2         231 croak '->new() expects even number of arguments or a hash reference, got ' . scalar @args . ' argument(s)';
19             }
20 48         43 my $hash;
21 48 100       80 if ( ref $args[0] ) {
22 5         10 $hash = { args => $args[0] };
23             }
24             else {
25 43         101 $hash = { args => {@args} };
26             }
27 48         58 my $self = bless $hash, $class;
28 48         68 $self->BUILD;
29 43         82 return $self;
30             }
31              
32              
33              
34              
35              
36             sub BUILD {
37 48     48 0 49 my ($self) = @_;
38 48         66 my $tests = $self->_tests;
39 48         58 for my $test ( keys %{$tests} ) {
  48         89  
40 31 100       464 croak 'test ' . $test . ' must be a CodeRef' if not 'CODE' eq ref $tests->{$test};
41             }
42 45         70 my $handlers = $self->_handlers;
43 45         96 for my $handler ( keys %{$handlers} ) {
  45         81  
44 267 100       684 croak 'handler ' . $handler . ' must be a CodeRef' if not 'CODE' eq ref $handlers->{$handler};
45             }
46 43 50       82 croak 'input_transformer must be a CodeRef' if not 'CODE' eq ref $self->_input_transformer;
47 43         44 return;
48             }
49              
50             sub _args {
51 223     223   156 my ($self) = @_;
52 223 50       885 return $self->{args} if exists $self->{args};
53 0         0 return ( $self->{args} = {} );
54             }
55              
56             sub _tests {
57 76     76   56 my ( $self, ) = @_;
58 76 100       161 return $self->{tests} if exists $self->{tests};
59 48         43 my %tests;
60 48         37 for my $key ( grep { !/\A-/msx } keys %{ $self->_args } ) {
  47         161  
  48         70  
61 27         35 $tests{$key} = $self->_args->{$key};
62             }
63 48 100       62 return ( $self->{tests} = { %tests, %{ $self->_args->{'-tests'} || {} } } );
  48         57  
64             }
65              
66             sub _handlers {
67 83     83   77 my ( $self, ) = @_;
68 83 100       196 return $self->{handlers} if exists $self->{handlers};
69 45 100       34 return ( $self->{handlers} = { %{ $self->_handler_defaults }, %{ $self->_args->{'-handlers'} || {} } } );
  45         67  
  45         57  
70             }
71              
72             sub _handler_defaults {
73             return {
74             test => sub {
75 6     6   9 my ($status) = @_;
76 6         30 return $status;
77             },
78             log => sub {
79 6     6   8 my ( $status, $message, $name, @slurpy ) = @_;
80 6   100     704 carp sprintf 'Assertion < log %s > = %s : %s', $name, ( $status || '0' ), $message;
81 6         311 return $slurpy[0];
82             },
83             should => sub {
84 6     6   9 my ( $status, $message, $name, @slurpy ) = @_;
85 6 100       223 carp "Assertion < should $name > failed: $message" unless $status;
86 6         127 return $slurpy[0];
87             },
88             should_not => sub {
89 6     6   9 my ( $status, $message, $name, @slurpy ) = @_;
90 6 100       229 carp "Assertion < should_not $name > failed: $message" if $status;
91 6         132 return $slurpy[0];
92             },
93             must => sub {
94 6     6   9 my ( $status, $message, $name, @slurpy ) = @_;
95 6 100       225 croak "Assertion < must $name > failed: $message" unless $status;
96 3         7 return $slurpy[0];
97             },
98             must_not => sub {
99 6     6   38 my ( $status, $message, $name, @slurpy ) = @_;
100 6 100       225 croak "Assertion < must_not $name > failed: $message" if $status;
101 3         7 return $slurpy[0];
102             },
103 45     45   487 };
104             }
105              
106             sub _transform_input {
107 24     24   20 my ( $self, $name, @slurpy ) = @_;
108 24         28 return $self->_input_transformer->( $name, @slurpy );
109             }
110              
111             sub _input_transformer {
112 67     67   51 my ( $self, ) = @_;
113 67 100       198 return $self->{input_transformer} if exists $self->{input_transformer};
114 43 100       67 if ( exists $self->_args->{'-input_transformer'} ) {
115 12         11 return ( $self->{input_transformer} = $self->_args->{'-input_transformer'} );
116             }
117 31         44 return ( $self->{input_transformer} = $self->_input_transformer_default );
118             }
119              
120             sub _input_transformer_default {
121 12     12   8 return sub { shift; return @_ };
  12     31   21  
  31         159  
122             }
123              
124             # Dispatch the result of test name $test_name
125             sub _handle { ## no critic (Subroutines::ProhibitManyArgs)
126 36     36   162 my ( $self, $handler_name, $status_code, $message, $test_name, @slurpy ) = @_;
127 36         43 return $self->_handlers->{$handler_name}->( $status_code, $message, $test_name, @slurpy );
128             }
129              
130             # Perform $test_name and return its result
131             sub _test {
132 28     28   34 my ( $self, $test_name, @slurpy ) = @_;
133 28         55 my $tests = $self->_tests;
134 28 50       42 if ( not exists $tests->{$test_name} ) {
135 0         0 croak sprintf q[INVALID ASSERTION %s ( avail: %s )], $test_name, ( join q[,], keys %{$tests} );
  0         0  
136             }
137 28         54 return $tests->{$test_name}->(@slurpy);
138             }
139              
140             # Long form
141             # ->_assert( should => exist => path('./foo'))
142             # ->should( exist => path('./foo'))
143             sub _assert {
144 24     24   27 my ( $self, $handler_name, $test_name, @slurpy ) = @_;
145 24         30 my (@input) = $self->_transform_input( $test_name, @slurpy );
146 24         98 my ( $status, $message ) = $self->_test( $test_name, @input );
147 24         126 return $self->_handle( $handler_name, $status, $message, $test_name, @input );
148             }
149              
150             for my $handler (qw( should must should_not must_not test log )) {
151             my $code = sub {
152 24     24   275 my ( $self, $name, @slurpy ) = @_;
153 24         37 return $self->_assert( $handler, $name, @slurpy );
154             };
155             {
156             ## no critic (TestingAndDebugging::ProhibitNoStrict])
157 7     7   35 no strict 'refs';
  7         9  
  7         365  
158             *{ __PACKAGE__ . q[::] . $handler } = $code;
159             }
160             }
161              
162             1;
163              
164             __END__