File Coverage

blib/lib/Plack/Test/Simple/Transaction.pm
Criterion Covered Total %
statement 51 87 58.6
branch 4 8 50.0
condition 3 41 7.3
subroutine 16 28 57.1
pod 14 14 100.0
total 88 178 49.4


line stmt bran cond sub pod time code
1             # ABSTRACT: PSGI Automated Application Testing Layer
2             package Plack::Test::Simple::Transaction;
3              
4 2     2   12 use utf8;
  2         4  
  2         16  
5              
6 2     2   66 use HTTP::Request;
  2         3  
  2         46  
7 2     2   11 use HTTP::Response;
  2         5  
  2         43  
8 2     2   10 use Moo;
  2         4  
  2         12  
9 2     2   3218 use Plack::Util;
  2         30692  
  2         267  
10 2     2   23 use URI;
  2         3  
  2         65  
11              
12 2     2   2075 use Plack::Test qw();
  2         1180  
  2         46  
13 2     2   13 use Test::More qw();
  2         4  
  2         42  
14              
15 2     2   2350 use Data::DPath qw(dpath);
  2         329630  
  2         17  
16 2     2   444 use JSON qw(decode_json);
  2         6  
  2         22  
17              
18             our $VERSION = '0.02'; # VERSION
19              
20             has data => (
21             is => 'rw',
22             lazy => 1,
23             builder => 1
24             );
25              
26             sub _build_data {
27 4     4   1188 my ($self) = @_;
28              
29 4 50       91 return {} unless $self->response->content;
30 4 50       152 return {} unless $self->response->header('Content-Type');
31 4 50       267 return {} unless $self->response->header('Content-Type') =~ /json/i;
32              
33             # only supporting JSON data currently !!!
34 4         250 return decode_json $self->response->decoded_content;
35             }
36              
37             has psgi => (
38             is => 'rw',
39             );
40              
41             has request => (
42             is => 'rw',
43             lazy => 1,
44             builder => 1
45             );
46              
47             sub _build_request {
48 0     0   0 return HTTP::Request->new(
49             uri => URI->new(scheme => 'http', host => 'localhost', path => '/')
50             )
51             }
52              
53             has response => (
54             is => 'rw',
55             lazy => 1,
56             builder => 1
57             );
58              
59             sub _build_response {
60 4     4   456 my $self = shift;
61 4         128 return $self->psgi->request($self->request);
62             }
63              
64             sub content_is {
65 0     0 1 0 my ($self, $value, $desc) = @_;
66 0   0     0 $desc ||= 'exact match for content';
67 0         0 return $self->_test_more(
68             'is', $self->response->decoded_content, $value, $desc
69             );
70             }
71              
72             sub content_isnt {
73 0     0 1 0 my ($self, $value, $desc) = @_;
74 0   0     0 $desc ||= 'not an exact match for content';
75 0         0 return $self->_test_more(
76             'isnt', $self->response->decoded_content, $value, $desc
77             );
78             }
79              
80             sub content_like {
81 0     0 1 0 my ($self, $regex, $desc) = @_;
82 0   0     0 $desc ||= 'content contains the expression specified';
83 0         0 return $self->_test_more(
84             'like', $self->response->decoded_content, $regex, $desc
85             );
86             }
87              
88             sub content_unlike {
89 0     0 1 0 my ($self, $regex, $desc) = @_;
90 0   0     0 $desc ||= 'content does not contain the expression specified';
91 0         0 return $self->_test_more(
92             'unlike', $self->response->decoded_content, $regex, $desc
93             );
94             }
95              
96             sub data_has {
97 0     0 1 0 my ($self, $path, $desc) = @_;
98 0   0     0 $desc ||= qq{has value for data path "$path"};
99 0         0 my $rs = [ dpath($path)->match($self->data) ];
100 0         0 return $self->_test_more(
101             'ok', $rs->[0], $desc
102             );
103             }
104              
105             sub data_hasnt {
106 0     0 1 0 my ($self, $path, $desc) = @_;
107 0   0     0 $desc ||= qq{has no value for data path "$path"};
108 0         0 my $rs = [ dpath($path)->match($self->data) ];
109 0         0 return $self->_test_more(
110             'ok', !$rs->[0], $desc
111             );
112             }
113              
114             sub data_is_deeply {
115 4     4 1 9 my $self = shift;
116 4 50       18 my ($path, $data) = ref $_[0] ? ('', shift) : (shift, shift);
117 4   50     9 $path ||= '/';
118 4   33     23 my $desc ||= qq{exact match for data path "$path"};
119 4         21 my $rs = [ dpath($path)->match($self->data) ];
120 4         1109 return $self->_test_more(
121             'is_deeply', $rs->[0], $data, $desc
122             );
123             }
124              
125             sub data_match {
126 4     4 1 36 goto &data_is_deeply;
127             }
128              
129             sub header_is {
130 0     0 1 0 my ($self, $name, $value, $desc) = @_;
131 0   0     0 $desc ||= "exact match for header $name with value " . ($value // '');
      0        
132 0         0 return $self->_test_more(
133             'is', $self->response->header($name), $value, $desc
134             );
135             }
136              
137             sub header_isnt {
138 0     0 1 0 my ($self, $name, $value, $desc) = @_;
139 0   0     0 $desc ||= "not an exact match for header $name with value " . ($value // '');
      0        
140 0         0 return $self->_test_more(
141             'isnt', $self->response->header($name), $value, $desc
142             );
143             }
144              
145             sub header_like {
146 0     0 1 0 my ($self, $name, $regex, $desc) = @_;
147 0   0     0 $desc ||= "header $name contains the expression specified";
148 0         0 return $self->_test_more(
149             'like', $self->response->header($name), $regex, $desc
150             );
151             }
152              
153             sub header_unlike {
154 0     0 1 0 my ($self, $name, $regex, $desc) = @_;
155 0   0     0 $desc ||= "header $name does not contain the expression specified";
156 0         0 return $self->_test_more(
157             'unlike', $self->response->header($name), $regex, $desc
158             );
159             }
160              
161             sub status_is {
162 4     4 1 11 my ($self, $code, $desc) = @_;
163 4   33     22 $desc ||= "status is $code";
164 4         76 return $self->_test_more(
165             'is', $self->response->code, $code, $desc
166             );
167             }
168              
169             sub status_isnt {
170 0     0 1 0 my ($self, $code, $desc) = @_;
171 0   0     0 $desc ||= "status is not $code";
172 0         0 return $self->_test_more(
173             'isnt', $self->response->code, $code, $desc
174             );
175             }
176              
177             sub _test_more {
178 8     8   5699 my ($self, $name, @args) = @_;
179              
180 8         17 local $Test::Builder::Level = $Test::Builder::Level + 2;
181 8         76 Test::More->can($name)->(@args);
182              
183 8         4647 return $self;
184             }
185              
186             1;
187              
188             __END__