Use Class::Inspector->loaded() instead of ->can('can')
[catagits/Catalyst-Runtime.git] / lib / Catalyst / Test.pm
1 package Catalyst::Test;
2
3 use strict;
4 use warnings;
5
6 use Catalyst::Exception;
7 use Catalyst::Utils;
8 use Class::Inspector;
9 use UNIVERSAL::require;
10
11 =head1 NAME
12
13 Catalyst::Test - Test Catalyst Applications
14
15 =head1 SYNOPSIS
16
17     # Helper
18     script/test.pl
19
20     # Tests
21     use Catalyst::Test 'TestApp';
22     request('index.html');
23     get('index.html');
24
25     # Run tests against a remote server
26     CATALYST_SERVER='http://localhost:3000/' prove -r -l lib/ t/
27
28     # Tests with inline apps need to use Catalyst::Engine::Test
29     package TestApp;
30
31     use Catalyst;
32
33     sub foo : Global {
34             my ( $self, $c ) = @_;
35             $c->res->output('bar');
36     }
37
38     __PACKAGE__->setup();
39
40     package main;
41
42     use Test::More tests => 1;
43     use Catalyst::Test 'TestApp';
44
45     ok( get('/foo') =~ /bar/ );
46
47 =head1 DESCRIPTION
48
49 Test Catalyst Applications.
50
51 =head2 METHODS
52
53 =head2 get
54
55 Returns the content.
56
57     my $content = get('foo/bar?test=1');
58
59 =head2 request
60
61 Returns a C<HTTP::Response> object.
62
63     my $res = request('foo/bar?test=1');
64
65 =cut
66
67 sub import {
68     my $self  = shift;
69     my $class = shift;
70
71     my ( $get, $request );
72
73     if ( $ENV{CATALYST_SERVER} ) {
74         $request = sub { remote_request(@_) };
75         $get     = sub { remote_request(@_)->content };
76     }
77
78     else {
79         unless( Class::Inspector->loaded( $class ) ) {
80             $class->require;
81             die $@ if $@;
82         }
83         $class->import;
84
85         $request = sub { local_request( $class, @_ ) };
86         $get     = sub { local_request( $class, @_ )->content };
87     }
88
89     no strict 'refs';
90     my $caller = caller(0);
91     *{"$caller\::request"} = $request;
92     *{"$caller\::get"}     = $get;
93 }
94
95 =head2 local_request
96
97 =cut
98
99 sub local_request {
100     my $class = shift;
101
102     require HTTP::Request::AsCGI;
103
104     my $request = Catalyst::Utils::request( shift(@_) );
105     my $cgi     = HTTP::Request::AsCGI->new( $request, %ENV )->setup;
106
107     $class->handle_request;
108
109     return $cgi->restore->response;
110 }
111
112 my $agent;
113
114 =head2 remote_request
115
116 Do an actual remote request using LWP.
117
118 =cut
119
120 sub remote_request {
121
122     require LWP::UserAgent;
123
124     my $request = Catalyst::Utils::request( shift(@_) );
125     my $server  = URI->new( $ENV{CATALYST_SERVER} );
126
127     if ( $server->path =~ m|^(.+)?/$| ) {
128         $server->path("$1");    # need to be quoted
129     }
130
131     $request->uri->scheme( $server->scheme );
132     $request->uri->host( $server->host );
133     $request->uri->port( $server->port );
134     $request->uri->path( $server->path . $request->uri->path );
135
136     unless ($agent) {
137
138         $agent = LWP::UserAgent->new(
139             keep_alive   => 1,
140             max_redirect => 0,
141             timeout      => 60,
142         );
143
144         $agent->env_proxy;
145     }
146
147     return $agent->request($request);
148 }
149
150 =head1 SEE ALSO
151
152 L<Catalyst>.
153
154 =head1 AUTHOR
155
156 Sebastian Riedel, C<sri@cpan.org>
157
158 =head1 COPYRIGHT
159
160 This program is free software, you can redistribute it and/or modify it under
161 the same terms as Perl itself.
162
163 =cut
164
165 1;