File Coverage

blib/lib/Test/WWW/Stub.pm
Criterion Covered Total %
statement 69 70 98.5
branch 9 10 90.0
condition 5 8 62.5
subroutine 25 26 96.1
pod 7 7 100.0
total 115 121 95.0


line stmt bran cond sub pod time code
1             package Test::WWW::Stub;
2 3     3   231489 use 5.010;
  3         19  
3 3     3   14 use strict;
  3         3  
  3         56  
4 3     3   13 use warnings;
  3         3  
  3         101  
5              
6             our $VERSION = "0.10";
7              
8 3     3   14 use Carp ();
  3         3  
  3         55  
9 3     3   1109 use Guard; # guard
  3         1146  
  3         130  
10 3     3   1078 use LWP::Protocol::PSGI;
  3         91175  
  3         92  
11 3     3   851 use Plack::Request;
  3         97420  
  3         78  
12 3     3   20 use Test::More ();
  3         7  
  3         46  
13 3     3   1350 use List::MoreUtils ();
  3         30177  
  3         75  
14 3     3   23 use URI;
  3         8  
  3         55  
15              
16 3     3   1111 use Test::WWW::Stub::Intercepter;
  3         6  
  3         2185  
17              
18             my $Intercepter = Test::WWW::Stub::Intercepter->new;
19             our @Requests;
20              
21             my $register_g;
22             my $app;
23 0     0   0 sub _app { $app; }
24              
25             $app = sub {
26             my ($env) = @_;
27             my $req = Plack::Request->new($env);
28              
29             push @Requests, $req;
30              
31             my $uri = _normalize_uri($req->uri);
32              
33             my $stubbed_res = $Intercepter->intercept($uri, $env, $req);
34             return $stubbed_res if $stubbed_res;
35              
36             my ($file, $line) = _trace_file_and_line();
37              
38             my $method = $req->method;
39             warn "Unexpected external access: $method $uri at $file line $line";
40              
41             return [ 499, [], [] ];
42             };
43              
44             sub import {
45 4   66 4   11131 $register_g //= LWP::Protocol::PSGI->register($app);
46             }
47              
48             sub register {
49 14     14 1 28647 my ($class, $uri_or_re, $app_or_res) = @_;
50 14   50     47 $app_or_res //= [200, [], []];
51              
52 14         53 my $handler = $Intercepter->register($uri_or_re, $app_or_res);
53             defined wantarray && return guard {
54 13     13   15831 $Intercepter->unregister($uri_or_re, $handler);
55 14 100       110 };
56             }
57              
58             sub last_request {
59 2 100   2 1 1745 return undef unless @Requests;
60 1         5 return $Requests[-1];
61             }
62              
63             sub last_request_for {
64 3     3 1 5772 my ($class, $method, $url) = @_;
65 3         7 my $reqs = { map { _request_signature($_) => $_ } @Requests };
  9         72  
66 3         40 my $signature = "$method $url";
67 3         11 return $reqs->{$signature};
68             }
69              
70             sub _request_signature {
71 9     9   11 my ($req) = @_;
72 9         19 my $normalized = _normalize_uri($req->uri);
73 9         23 return join ' ', $req->method, $normalized;
74             }
75              
76             # Don't use query part of URI for handler matching.
77             sub _normalize_uri {
78 40     40   8911 my ($uri) = @_;
79 40         99 my $cloned = $uri->clone;
80 40         275 $cloned->query(undef);
81 40         568 return $cloned;
82             }
83              
84 3     3 1 663 sub requests { @Requests }
85              
86             sub requested_ok {
87 3     3 1 9744 my ($class, $method, $url) = @_;
88 3         8 local $Test::Builder::Level = $Test::Builder::Level + 1;
89             Test::More::ok(
90             List::MoreUtils::any(sub {
91 5     5   37 my $req_url = _normalize_uri($_->uri);
92 5 100       42 $_->method eq $method && $req_url eq $url
93             }, @Requests),
94             "stubbed $method $url",
95 3 100       24 ) or Test::More::diag Test::More::explain [ map { $_->method . ' ' . $_->uri } @Requests ]
  4         1425  
96             }
97              
98             sub clear_requests {
99 3     3 1 7130 @Requests = ();
100             }
101              
102             sub _trace_file_and_line {
103 5     5   12 my $level = $Test::Builder::Level;
104 5         25 my (undef, $file, $line) = caller($level);
105             # assume "Actual" caller is test file named FOOBAR.t
106 5   66     44 while ($file && $file !~ m<\.t$>) {
107 40         233 (undef, $file, $line) = caller(++$level);
108             }
109 5         21 ($file, $line);
110             }
111              
112             sub unstub {
113 4 50   4 1 13401 Carp::croak 'guard is required' unless defined wantarray;
114 4         23 undef $register_g;
115             return guard {
116 4     4   754794 $register_g = LWP::Protocol::PSGI->register($app);
117             }
118 4         132 }
119              
120             1;
121             __END__