File Coverage

blib/lib/Mojolicious/Command/swat.pm
Criterion Covered Total %
statement 9 57 15.7
branch 0 28 0.0
condition 0 8 0.0
subroutine 3 5 60.0
pod 1 1 100.0
total 13 99 13.1


line stmt bran cond sub pod time code
1             package Mojolicious::Command::swat;
2              
3             our $VERSION = '0.0.4';
4              
5 1     1   54900 use Mojo::Base 'Mojolicious::Command';
  1         3416313  
  1         5  
6              
7 1     1   29081336 use re 'regexp_pattern';
  1         2  
  1         199  
8 1     1   1038 use Getopt::Long qw(GetOptionsFromArray);
  1         9077  
  1         6  
9              
10             has description => 'Show available routes';
11             has usage => sub { shift->extract_usage };
12              
13             sub run {
14 0     0 1   my ($self, @args) = @_;
15              
16 0           GetOptionsFromArray \@args, 'f|force' => \my $force;
17              
18 0           my $rows = [];
19              
20 0           _walk($_, 0, $rows, 0) for @{$self->app->routes->children};
  0            
21              
22 0           ROUTE: for my $i (@$rows){
23              
24 0           my $http_method = $i->[1];
25 0           my $route = $i->[0];
26              
27 0 0         unless ($http_method=~/GET|POST/i){
28 0           print "sorry, swat does not support $http_method methods yet \n";
29 0           next ROUTE;
30             }
31              
32 0           my $filename = "swat/$route/";
33            
34 0 0 0       if (-e $filename and !$force){
35              
36 0           print "skip route $route - swat test already exist, use --force to override existed routes \n";
37 0           next ROUTE;
38              
39             }else{
40              
41 0           print "generate swat route for $route ... \n";
42 0           mkdir "swat/$route";
43              
44 0           print "generate swat data for $http_method $route ... \n";
45              
46 0           $filename.=lc($http_method); $filename.=".txt";
  0            
47 0 0         open(my $fh, '>', $filename) or die "Could not open file '$filename' $!";
48 0           print $fh "200 OK\n";
49 0           close $fh;
50             }
51              
52             }
53              
54              
55             }
56              
57             sub _walk {
58 0     0     my ($route, $depth, $rows, $verbose) = @_;
59              
60             # Pattern
61 0           my $prefix = '';
62 0 0         if (my $i = $depth * 2) { $prefix .= ' ' x $i . '+' }
  0            
63 0   0       push @$rows, my $row = [$prefix . ($route->pattern->unparsed || '/')];
64              
65             # Flags
66 0           my @flags;
67 0 0         push @flags, @{$route->over || []} ? 'C' : '.';
  0 0          
68 0 0         push @flags, (my $partial = $route->partial) ? 'D' : '.';
69 0 0         push @flags, $route->inline ? 'U' : '.';
70 0 0         push @flags, $route->is_websocket ? 'W' : '.';
71 0 0         push @$row, join('', @flags) if $verbose;
72              
73             # Methods
74 0           my $via = $route->via;
75 0 0         push @$row, !$via ? '*' : uc join ',', @$via;
76              
77             # Name
78 0           my $name = $route->name;
79 0 0         push @$row, $route->has_custom_name ? qq{"$name"} : $name;
80              
81             # Regex (verbose)
82 0           my $pattern = $route->pattern;
83 0   0       $pattern->match('/', $route->is_endpoint && !$partial);
84 0           my $regex = (regexp_pattern $pattern->regex)[0];
85 0           my $format = (regexp_pattern($pattern->format_regex))[0];
86 0 0         push @$row, $regex, $format ? $format : '' if $verbose;
    0          
87              
88 0           $depth++;
89 0           _walk($_, $depth, $rows, $verbose) for @{$route->children};
  0            
90 0           $depth--;
91             }
92              
93             1;
94              
95             =encoding utf8
96              
97              
98             =head1 NAME
99              
100             Mojolicious::Command::swat - Swat command
101              
102             =head1 SYNOPSIS
103              
104             Usage: APPLICATION swat [OPTIONS]
105              
106             Options:
107             -f, --force Override existed swat tests
108              
109             =head1 DESCRIPTION
110              
111             L generate L tests for mojo routes.
112              
113             This command walk through all available routes and generate a swat test for every one.
114             POST and GET http requests are only supported ( might be changed in the future ).
115              
116              
117             =head1 Hello World Example
118              
119              
120             =head2 install mojo
121              
122             sudo cpanm Mojolicious
123              
124             =head2 bootstrap a mojo application
125              
126             mkdir myapp
127             cd myapp
128             mojo generate lite_app myapp.pl
129              
130             =head2 define routes
131              
132              
133             $ nano myapp.pl
134              
135             #!/usr/bin/env perl
136             use Mojolicious::Lite;
137            
138             get '/' => sub {
139             my $c = shift;
140             $c->render(text => 'ROOT');
141             };
142            
143            
144             post '/hello' => sub {
145             my $c = shift;
146             $c->render(text => 'HELLO');
147             };
148            
149             get '/hello/world' => sub {
150             my $c = shift;
151             $c->render(text => 'HELLO WORLD');
152             };
153            
154             app->start;
155            
156              
157             $ ./myapp.pl routes
158             / GET
159             /hello POST hello
160             /hello/world GET helloworld
161              
162             =head1 install Mojolicious::Command::swat
163              
164             sudo cpanm Mojolicious::Command::swat
165              
166             =head2 bootstrap swat tests
167              
168             $ ./myapp.pl swat
169             generate swat route for / ...
170             generate swat data for GET / ...
171             generate swat route for /hello ...
172             generate swat data for POST /hello ...
173             generate swat route for /hello/world ...
174             generate swat data for GET /hello/world ...
175              
176              
177             =head2 specify routes checks
178              
179             This phase might be skipped as preliminary `200 OK` checks are already added on bootstrap phase. But you may define ones more.
180             For complete documentation on *how to write swat tests* please visit https://github.com/melezhik/swat
181              
182             $ echo ROOT >> swat/get.txt
183             $ echo HELLO >> swat/hello/post.txt
184             $ echo HELLO WORLD >> swat/hello/world/get.txt
185              
186              
187             =head2 start mojo application
188              
189             $ morbo ./myapp.pl
190             Server available at http://127.0.0.1:3000
191              
192             =head2 install swat
193              
194             sudo cpanm swat
195              
196             =head2 run swat tests
197              
198             $ swat ./swat/ http://127.0.0.1:3000
199             /home/vagrant/.swat/reports/http://127.0.0.1:3000/00.t ..............
200             # start swat for http://127.0.0.1:3000// | is swat package 0
201             # swat version v0.1.19 | debug 0 | try num 2 | ignore http errors 0
202             ok 1 - successful response from GET http://127.0.0.1:3000/
203             # data file: /home/vagrant/.swat/reports/http://127.0.0.1:3000///content.GET.txt
204             ok 2 - GET / returns 200 OK
205             ok 3 - GET / returns ROOT
206             1..3
207             ok
208             /home/vagrant/.swat/reports/http://127.0.0.1:3000/hello/00.post.t ...
209             # start swat for http://127.0.0.1:3000//hello | is swat package 0
210             # swat version v0.1.19 | debug 0 | try num 2 | ignore http errors 0
211             ok 1 - successful response from POST http://127.0.0.1:3000/hello
212             # data file: /home/vagrant/.swat/reports/http://127.0.0.1:3000//hello/content.POST.txt
213             ok 2 - POST /hello returns 200 OK
214             ok 3 - POST /hello returns HELLO
215             1..3
216             ok
217             /home/vagrant/.swat/reports/http://127.0.0.1:3000/hello/world/00.t ..
218             # start swat for http://127.0.0.1:3000//hello/world | is swat package 0
219             # swat version v0.1.19 | debug 0 | try num 2 | ignore http errors 0
220             ok 1 - successful response from GET http://127.0.0.1:3000/hello/world
221             # data file: /home/vagrant/.swat/reports/http://127.0.0.1:3000//hello/world/content.GET.txt
222             ok 2 - GET /hello/world returns 200 OK
223             ok 3 - GET /hello/world returns HELLO WORLD
224             1..3
225             ok
226             All tests successful.
227             Files=3, Tests=9, 0 wallclock secs ( 0.02 usr 0.00 sys + 0.02 cusr 0.00 csys = 0.04 CPU)
228             Result: PASS
229            
230              
231             =head1 SEE ALSO
232              
233             L, L, L, L
234              
235             =cut