File Coverage

blib/lib/Mojo/UserAgent/Mockable/Request/Compare.pm
Criterion Covered Total %
statement 103 108 95.3
branch 30 34 88.2
condition 5 6 83.3
subroutine 10 10 100.0
pod 1 1 100.0
total 149 159 93.7


line stmt bran cond sub pod time code
1 23     23   1940311 use 5.014;
  23         133  
2              
3             package Mojo::UserAgent::Mockable::Request::Compare;
4             $Mojo::UserAgent::Mockable::Request::Compare::VERSION = '1.58';
5             # VERSION
6              
7             # ABSTRACT: Helper class for Mojo::UserAgent::Mockable that compares two Mojo::Message::Request instances
8              
9              
10 23     23   158 use Carp;
  23         49  
  23         1662  
11 23     23   655 use Mojo::Base -base;
  23         188804  
  23         168  
12 23     23   5895 use Mojo::URL;
  23         15618  
  23         194  
13 23     23   3758 use Safe::Isa qw{$_isa};
  23         2688  
  23         14662  
14              
15             has compare_result => '';
16             has ignore_headers => sub { [] };
17             has ignore_body => '';
18             has ignore_userinfo => '';
19              
20             sub compare {
21 168     168 1 159274 my ($self, $r1, $r2) = @_;
22            
23 168 50       786 if (!$r1->$_isa('Mojo::Message::Request')) {
24 0         0 my $reftype = ref $r1;
25 0         0 croak qq{Cannot compare $reftype to Mojo::Message::Request};
26             }
27            
28 168 50       3796 if (!$r2->$_isa('Mojo::Message::Request')) {
29 0         0 my $reftype = ref $r2;
30 0         0 croak qq{Cannot compare Mojo::Message::Request to $reftype};
31             }
32              
33 168 100       2345 if ( $r1->method ne $r2->method ) {
34 1         12 $self->compare_result( sprintf q{Method mismatch: got '%s', expected '%s'}, $r1->method, $r2->method );
35 1         21 return 0;
36             }
37              
38 167 100       1850 if ( !$self->_compare_url( $r1->url, $r2->url ) ) {
39 83         460 return 0;
40             }
41              
42 84 100 100     378 if ( !$self->ignore_body && $r1->body ne $r2->body ) {
43 3         152 $self->compare_result('Body mismatch');
44 3         38 return 0;
45             }
46              
47 81 100       4931 if ($self->ignore_headers ne 'all') {
48 30         153 my $h1 = $r1->headers->to_hash;
49 30         3090 my $h2 = $r2->headers->to_hash;
50              
51 30         2289 for my $header (@{$self->ignore_headers}) {
  30         81  
52 10         59 delete $h1->{$header};
53 10         21 delete $h2->{$header};
54             }
55              
56 30 100       138 if (scalar keys %{$h1} ne scalar keys %{$h2}) {
  30         98  
  30         122  
57 2         8 $self->compare_result('Header count mismatch');
58 2         27 return 0;
59             }
60              
61 28         63 for my $header (keys %{$h1}) {
  28         90  
62 165 100       352 if (!defined $h2->{$header}) {
63 1         7 $self->compare_result(qq{Header "$header" mismatch: header not present in both requests.'});
64 1         15 return 0;
65             }
66              
67 164 100       415 if ($h1->{$header} ne $h2->{$header}) {
68 23     23   202 no warnings qw/uninitialized/;
  23         62  
  23         5791  
69 1         8 $self->compare_result(qq{Header "$header" mismatch: got '$h1->{$header}', expected '$h2->{$header}'});
70 1         14 return 0;
71             }
72             }
73             }
74              
75 77         651 $self->compare_result('');
76 77         715 return 1;
77             }
78              
79             sub _compare_url {
80 167     167   1449 my ($self, $u1, $u2) = @_;
81              
82 167 50       688 if (!ref $u1) {
83 0         0 $u1 = Mojo::URL->new($u1);
84             }
85 167         732 $u1 = $u1->to_abs;
86              
87 167 100       19505 if (!ref $u2) {
88 1         4 $u2 = Mojo::URL->new($u2);
89             }
90 167         667 $u2 = $u2->to_abs;
91              
92 23     23   213 no warnings qw/uninitialized/;
  23         49  
  23         11827  
93 167         15593 for my $key (qw/scheme userinfo host port fragment/) {
94 785         2428 my $ignore = sprintf 'ignore_%s', $key;
95 785 50 66     3445 next if $self->can($ignore) && $self->$ignore;
96              
97 785         3048 my $val1 = $u1->$key;
98 785         3568 my $val2 = $u2->$key;
99 785 100       3781 if ($val1 ne $val2) {
100 22         120 $self->compare_result(qq{URL $key mismatch: got "$val1", expected "$val2"});
101 22         249 return 0;
102             }
103             }
104            
105 145         501 my $p1 = Mojo::Path->new($u1->path);
106 145         3506 my $p2 = Mojo::Path->new($u2->path);
107 145 100       3293 if ($p1->to_string ne $p2->to_string) {
108 5         1282 my $val1 = $p1->to_string;
109 5         360 my $val2 = $p2->to_string;
110 5         404 $self->compare_result(qq{URL path mismatch: got "$val1", expected "$val2"});
111 5         78 return 0;
112             }
113              
114 140         29705 my $q1 = $u1->query->to_hash;
115 140         17664 my $q2 = $u2->query->to_hash;
116              
117 140 100       44996 if (scalar keys %{$q1} != scalar keys %{$q2}) {
  140         462  
  140         563  
118 2         4 my $count1 = scalar keys %{$q1};
  2         6  
119 2         5 my $count2 = scalar keys %{$q2};
  2         5  
120              
121 2         15 $self->compare_result(qq{URL query mismatch: parameter count mismatch: $count1 != $count2});
122 2         39 return 0;
123             }
124 138         305 for my $key (keys %{$q1}) {
  138         555  
125 598         1085 my $val1 = $q1->{$key};
126 598         1069 my $val2 = $q2->{$key};
127              
128 598 100       1286 if ( ref $val2 eq 'ARRAY' ){
129 1         3 $val1 = join(",", sort { $a cmp $b } @{$val1});
  1         9  
  1         10  
130 1         4 $val2 = join(",", sort { $a cmp $b } @{$val2});
  1         5  
  1         4  
131             }
132              
133 598 100       1788 if ($val1 ne $val2) {
134 54         485 $self->compare_result(qq{URL query mismatch: for key "$key", got "$val1", expected "$val2"});
135 54         1059 return 0;
136             }
137             }
138 23     23   185 use warnings qw/uninitialized/;
  23         49  
  23         2376  
139              
140 84         1050 return 1;
141             }
142              
143             1;
144              
145             __END__
146              
147             =pod
148              
149             =encoding UTF-8
150              
151             =head1 NAME
152              
153             Mojo::UserAgent::Mockable::Request::Compare - Helper class for Mojo::UserAgent::Mockable that compares two Mojo::Message::Request instances
154              
155             =head1 VERSION
156              
157             version 1.58
158              
159             =head1 ATTRIBUTES
160              
161             =head2 compare_result
162              
163             The result of the last compare operation. It is only populated when two requests B<do not> match.
164              
165             =head2 ignore_userinfo
166              
167             Set this to a true value to ignore a mismatch in the L<userinfo|Mojo::URL/userinfo> portion of a transaction URL.
168              
169             =head2 ignore_body
170              
171             Set this to a true value to ignore a mismatch in the bodies of the two compared transactions
172              
173             =head1 METHODS
174              
175             =head2 compare
176              
177             Compare two instances of L<Mojo::Message::Request>.
178              
179             =head1 AUTHOR
180              
181             Kit Peters <popefelix@gmail.com>
182              
183             =head1 COPYRIGHT AND LICENSE
184              
185             This software is copyright (c) 2021 by Kit Peters.
186              
187             This is free software; you can redistribute it and/or modify it under
188             the same terms as the Perl 5 programming language system itself.
189              
190             =cut