File Coverage

blib/lib/Test2/Tools/URL.pm
Criterion Covered Total %
statement 110 111 99.1
branch 38 44 86.3
condition 15 18 83.3
subroutine 31 31 100.0
pod 8 8 100.0
total 202 212 95.2


line stmt bran cond sub pod time code
1             package Test2::Tools::URL;
2              
3 2     2   233896 use strict;
  2         11  
  2         60  
4 2     2   10 use warnings;
  2         4  
  2         46  
5 2     2   39 use 5.008001;
  2         6  
6 2     2   11 use Carp ();
  2         4  
  2         36  
7 2     2   11 use Test2::Compare ();
  2         5  
  2         45  
8 2     2   11 use Test2::Compare::Hash ();
  2         4  
  2         34  
9 2     2   13 use Test2::Compare::String ();
  2         4  
  2         54  
10 2     2   11 use Test2::Compare::Custom ();
  2         4  
  2         44  
11 2     2   11 use base qw( Exporter );
  2         5  
  2         1643  
12              
13             our @EXPORT = qw( url url_base url_component url_scheme url_host url_secure url_insecure url_mail_to );
14              
15             # ABSTRACT: Compare a URL in your Test2 test
16             our $VERSION = '0.06'; # VERSION
17              
18              
19             sub url (&)
20             {
21 46     46 1 312957 Test2::Compare::build('Test2::Tools::URL::Check', @_);
22             }
23              
24              
25             sub url_base ($)
26             {
27 3     3 1 2026 my($base) = @_;
28              
29 3         10 my $build = Test2::Compare::get_build();
30 3 100       16 if($build)
31 1         4 { $build->set_base($base) }
32             else
33 2         7 { Test2::Tools::URL::Check->set_global_base($base) }
34             }
35              
36              
37             sub url_component ($$)
38             {
39 52     52 1 1262 my($name, $expect, $lc, $check_name) = @_;
40              
41 52 100       145 $check_name = 1 unless defined $check_name;
42 52 100       101 if($check_name)
43             {
44 45 50       227 Carp::croak("$name is not a valid URL component")
45             unless $name =~ /^(?:scheme|authority|userinfo|hostport|host|port|path|query|fragment|user|password|media_type|data)$/;
46             }
47              
48 52 50       114 my $build = Test2::Compare::get_build()or Carp::croak("No current build!");
49 52         272 $build->add_component($name, $expect, $lc);
50             }
51              
52              
53             sub url_scheme ($)
54             {
55 2     2 1 98 unshift @_, 'scheme';
56 2         6 goto &url_component;
57             }
58              
59              
60             sub url_host ($)
61             {
62 2     2 1 136 @_ = ('host', $_[0], 1);
63 2         8 goto &url_component;
64             }
65              
66              
67             sub url_secure ()
68             {
69 2     2 1 99 my @caller = caller;
70             my $test = Test2::Compare::Custom->new(
71 2 100 66 2   107 code => sub { defined $_ && ( ref $_ || $_ ) ? 1 : 0 },
72 2         22 name => 'TRUE',
73             operator => 'TRUE()',
74             file => $caller[1],
75             lines => [$caller[2]],
76             );
77 2         72 @_ = ('secure', $test, undef, 0);
78 2         7 goto &url_component;
79             }
80              
81              
82             sub url_insecure ()
83             {
84 2     2 1 116 my @caller = caller;
85             my $test = Test2::Compare::Custom->new(
86 2 100   2   91 code => sub { my %p = @_; $p{got} ? 0 : $p{exists} },
  2         11  
87 2         18 name => 'FALSE',
88             operator => 'FALSE()',
89             file => $caller[1],
90             lines => [$caller[2]],
91             );
92 2         57 @_ = ('secure', $test, undef, 0);
93 2         8 goto &url_component;
94             }
95              
96              
97             sub url_mail_to ($)
98             {
99 3     3 1 212 @_ = ('to', $_[0], undef, 0);
100 3         10 goto &url_component;
101             }
102              
103             package Test2::Tools::URL::Check;
104              
105 2     2   18 use overload ();
  2         4  
  2         61  
106 2     2   1181 use URI 1.61;
  2         9446  
  2         60  
107 2     2   893 use URI::QueryParam;
  2         1560  
  2         82  
108 2     2   14 use Scalar::Util qw( blessed );
  2         10  
  2         133  
109 2     2   14 use base qw( Test2::Compare::Base );
  2         4  
  2         1409  
110              
111 30     30   12162 sub name { '' }
112              
113             my $global_base;
114              
115             sub _uri
116             {
117 78     78   132 my($self, $url) = @_;
118             $self->{base}
119             ? URI->new_abs("$url", $self->{base})
120 78 100       383 : $global_base
    100          
121             ? URI->new_abs("$url", $global_base)
122             : URI->new("$url");
123             }
124              
125             sub verify
126             {
127 46     46   8897 my($self, %params) = @_;
128 46         134 my($got, $exists) = @params{qw/ got exists /};
129              
130 46 50       115 return 0 unless $exists;
131 46 100       441 return 0 unless $got;
132 45 100 100     160 return 0 if ref($got) && !blessed($got);
133 41 100 100     105 return 0 if ref($got) && !overload::Method($got, '""');
134              
135 40         145 my $url = eval { $self->_uri($got) };
  40         87  
136 40 50       17615 return 0 if $@;
137 40 100       126 return 0 if ! $url->has_recognized_scheme;
138              
139 38         326 return 1;
140             }
141              
142             sub set_base
143             {
144 1     1   4 my($self, $base) = @_;
145 1         4 $self->{base} = $base;
146             }
147              
148             sub set_global_base
149             {
150 2     2   6 my($self, $base) = @_;
151 2         5 $global_base = $base;
152             }
153              
154             sub add_component
155             {
156 52     52   117 my($self, $name, $expect, $lc) = @_;
157 52         65 push @{ $self->{component} }, [ $name, $expect, $lc ];
  52         216  
158             }
159              
160             sub deltas
161             {
162 38     38   254 my($self, %args) = @_;
163 38         214 my($got, $convert, $seen) = @args{'got', 'convert', 'seen'};
164              
165 38         75 my $uri = $self->_uri($got);
166              
167 38         2725 my @deltas;
168              
169 38         55 foreach my $comp (@{ $self->{component} })
  38         101  
170             {
171 52         1189 my($name, $expect, $lc) = @$comp;
172              
173 52         82 my $method = $name;
174 52 100       127 $method = 'host_port' if $method eq 'hostport';
175 52 100       357 my $value = $uri->can($method) ? $uri->$method : undef;
176 52 100 100     1650 $value = lc $value if $lc && defined $value;
177 52         116 my $check = $convert->($expect);
178              
179 52 50 33     3836 if($^O eq 'MSWin32' && $method eq 'path')
180             {
181 0         0 $value =~ s{/([A-Z]:)}{$1};
182             }
183              
184 52 100 100     171 if($method eq 'query' && !$check->isa('Test2::Compare::String'))
185             {
186 6 100       28 if($check->isa('Test2::Compare::Hash'))
    50          
187             {
188 4         22 $value = $uri->query_form_hash;
189             }
190             elsif($check->isa('Test2::Compare::Array'))
191             {
192 2         7 $value = [ $uri->query_form ];
193             }
194             }
195              
196              
197 52         651 push @deltas => $check->run(
198             id => [ HASH => $name ],
199             convert => $convert,
200             seen => $seen,
201             exists => defined $value,
202             got => $value,
203             );
204             }
205              
206 38         4254 @deltas;
207             }
208              
209             1;
210              
211             __END__