File Coverage

lib/Generic/Assertions.pm
Criterion Covered Total %
statement 92 95 96.8
branch 31 34 91.1
condition 5 5 100.0
subroutine 25 25 100.0
pod 1 2 50.0
total 154 161 95.6


line stmt bran cond sub pod time code
1 7     7   121559 use 5.006;
  7         21  
  7         242  
2 7     7   29 use strict;
  7         9  
  7         187  
3 7     7   35 use warnings;
  7         9  
  7         382  
4              
5             package Generic::Assertions;
6              
7             our $VERSION = '0.001001';
8              
9             # ABSTRACT: A Generic Assertion checking class
10              
11             our $AUTHORITY = 'cpan:KENTNL'; # AUTHORITY
12              
13 7     7   44 use Carp qw( croak carp );
  7         11  
  7         6719  
14              
15             sub new {
16 50     50 1 80421 my ( $class, @args ) = @_;
17 50 100 100     243 if ( @args % 2 == 1 and not ref $args[0] ) {
18 2         261 croak '->new() expects even number of arguments or a hash reference, got ' . scalar @args . ' argument(s)';
19             }
20 48         62 my $hash;
21 48 100       101 if ( ref $args[0] ) {
22 5         8 $hash = { args => $args[0] };
23             }
24             else {
25 43         139 $hash = { args => {@args} };
26             }
27 48         115 my $self = bless $hash, $class;
28 48         114 $self->BUILD;
29 43         108 return $self;
30             }
31              
32              
33              
34              
35              
36             sub BUILD {
37 48     48 0 55 my ($self) = @_;
38 48         99 my $tests = $self->_tests;
39 48         81 for my $test ( keys %{$tests} ) {
  48         93  
40 31 100       467 croak 'test ' . $test . ' must be a CodeRef' if not 'CODE' eq ref $tests->{$test};
41             }
42 45         104 my $handlers = $self->_handlers;
43 45         119 for my $handler ( keys %{$handlers} ) {
  45         119  
44 263 100       770 croak 'handler ' . $handler . ' must be a CodeRef' if not 'CODE' eq ref $handlers->{$handler};
45             }
46 43 50       117 croak 'input_transformer must be a CodeRef' if not 'CODE' eq ref $self->_input_transformer;
47 43         60 return;
48             }
49              
50             sub _args {
51 223     223   198 my ($self) = @_;
52 223 50       1259 return $self->{args} if exists $self->{args};
53 0         0 return ( $self->{args} = {} );
54             }
55              
56             sub _tests {
57 76     76   81 my ( $self, ) = @_;
58 76 100       229 return $self->{tests} if exists $self->{tests};
59 48         51 my %tests;
60 48         60 for my $key ( grep { !/\A-/msx } keys %{ $self->_args } ) {
  47         203  
  48         92  
61 27         59 $tests{$key} = $self->_args->{$key};
62             }
63 48 100       89 return ( $self->{tests} = { %tests, %{ $self->_args->{'-tests'} || {} } } );
  48         79  
64             }
65              
66             sub _handlers {
67 83     83   96 my ( $self, ) = @_;
68 83 100       247 return $self->{handlers} if exists $self->{handlers};
69 45 100       162 return ( $self->{handlers} = { %{ $self->_handler_defaults }, %{ $self->_args->{'-handlers'} || {} } } );
  45         76  
  45         78  
70             }
71              
72             sub _handler_defaults {
73             return {
74             test => sub {
75 6     6   10 my ($status) = @_;
76 6         41 return $status;
77             },
78             log => sub {
79 6     6   14 my ( $status, $message, $name, @slurpy ) = @_;
80 6   100     983 carp sprintf 'Assertion < log %s > = %s : %s', $name, ( $status || '0' ), $message;
81 6         384 return $slurpy[0];
82             },
83             should => sub {
84 6     6   9 my ( $status, $message, $name, @slurpy ) = @_;
85 6 100       361 carp "Assertion < should $name > failed: $message" unless $status;
86 6         197 return $slurpy[0];
87             },
88             should_not => sub {
89 6     6   12 my ( $status, $message, $name, @slurpy ) = @_;
90 6 100       423 carp "Assertion < should_not $name > failed: $message" if $status;
91 6         168 return $slurpy[0];
92             },
93             must => sub {
94 6     6   13 my ( $status, $message, $name, @slurpy ) = @_;
95 6 100       375 croak "Assertion < must $name > failed: $message" unless $status;
96 3         10 return $slurpy[0];
97             },
98             must_not => sub {
99 6     6   15 my ( $status, $message, $name, @slurpy ) = @_;
100 6 100       488 croak "Assertion < must_not $name > failed: $message" if $status;
101 3         14 return $slurpy[0];
102             },
103 45     45   710 };
104             }
105              
106             sub _transform_input {
107 24     24   36 my ( $self, $name, @slurpy ) = @_;
108 24         42 return $self->_input_transformer->( $name, @slurpy );
109             }
110              
111             sub _input_transformer {
112 67     67   68 my ( $self, ) = @_;
113 67 100       245 return $self->{input_transformer} if exists $self->{input_transformer};
114 43 100       84 if ( exists $self->_args->{'-input_transformer'} ) {
115 12         19 return ( $self->{input_transformer} = $self->_args->{'-input_transformer'} );
116             }
117 31         59 return ( $self->{input_transformer} = $self->_input_transformer_default );
118             }
119              
120             sub _input_transformer_default {
121 12     12   13 return sub { shift; return @_ };
  12     31   28  
  31         188  
122             }
123              
124             # Dispatch the result of test name $test_name
125             sub _handle { ## no critic (Subroutines::ProhibitManyArgs)
126 36     36   219 my ( $self, $handler_name, $status_code, $message, $test_name, @slurpy ) = @_;
127 36         65 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   55 my ( $self, $test_name, @slurpy ) = @_;
133 28         51 my $tests = $self->_tests;
134 28 50       65 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         78 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   43 my ( $self, $handler_name, $test_name, @slurpy ) = @_;
145 24         56 my (@input) = $self->_transform_input( $test_name, @slurpy );
146 24         182 my ( $status, $message ) = $self->_test( $test_name, @input );
147 24         215 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   449 my ( $self, $name, @slurpy ) = @_;
153 24         74 return $self->_assert( $handler, $name, @slurpy );
154             };
155             {
156             ## no critic (TestingAndDebugging::ProhibitNoStrict])
157 7     7   49 no strict 'refs';
  7         11  
  7         379  
158             *{ __PACKAGE__ . q[::] . $handler } = $code;
159             }
160             }
161              
162             1;
163              
164             __END__