File Coverage

blib/lib/HTTP/WebTest/Plugin.pm
Criterion Covered Total %
statement 147 151 97.3
branch 48 64 75.0
condition 7 13 53.8
subroutine 21 22 95.4
pod 17 17 100.0
total 240 267 89.8


line stmt bran cond sub pod time code
1             # $Id: Plugin.pm,v 1.14 2003/03/02 11:52:10 m_ilya Exp $
2              
3             package HTTP::WebTest::Plugin;
4              
5             =head1 NAME
6              
7             HTTP::WebTest::Plugin - Base class for HTTP::WebTest plugins.
8              
9             =head1 SYNOPSIS
10              
11             Not applicable.
12              
13             =head1 DESCRIPTION
14              
15             L plugin classes can inherit from this class.
16             It provides some useful helper methods.
17              
18             =head1 METHODS
19              
20             =cut
21              
22 21     21   124 use strict;
  21         40  
  21         853  
23              
24 21     21   12084 use HTTP::WebTest::TestResult;
  21         56  
  21         572  
25 21     21   129 use HTTP::WebTest::Utils qw(make_access_method);
  21         120  
  21         39649  
26              
27             =head2 new ($webtest)
28              
29             Constructor.
30              
31             =head3 Returns
32              
33             A new plugin object that will be used by
34             L object C<$webtest>.
35              
36             =cut
37              
38             sub new {
39 692     692 1 2316 my $proto = shift;
40 692   33     3312 my $class = ref($proto) || $proto;
41              
42 692         2133 my $self = bless {}, $class;
43              
44 692         2994 my $webtest = shift;
45              
46 692         2962 $self->webtest($webtest);
47              
48 692         2666 return $self;
49             };
50              
51             =head2 webtest ()
52              
53             =head3 Returns
54              
55             An L object that uses this plugin.
56              
57             =cut
58              
59             *webtest = make_access_method('WEBTEST');
60              
61             =head2 global_test_param ($param, $optional_default)
62              
63             =head3 Returns
64              
65             If global test parameter C<$param> is not defined, returns
66             C<$optional_default> or C if there is no default.
67              
68             If the global test parameter C<$param> is defined, returns it's value.
69              
70             =cut
71              
72             sub global_test_param {
73 2760     2760 1 4205 my $self = shift;
74 2760         3465 my $param = shift;
75 2760         4060 my $default = shift;
76              
77 2760         9534 my $value = $self->webtest->global_test_param($param);
78              
79 2760 100       11860 my $ret = defined $value ? $value : $default;
80              
81 2760         11344 return $self->_canonic_value($ret);
82             }
83              
84             =head2 test_param ($param, $optional_default)
85              
86             =head3 Returns
87              
88             If latest test parameter C<$param> is not defined, returns
89             C<$optional_default> or C if there is no default.
90              
91             If latest test parameter C<$param> is defined returns it's value.
92              
93             =cut
94              
95             sub test_param {
96 11532     11532 1 16057 my $self = shift;
97 11532         29977 my $param = shift;
98 11532         18212 my $default = shift;
99              
100 11532         49365 my $global_value = $self->webtest->global_test_param($param);
101              
102 11532         21461 my $value;
103 11532 100       39976 if(defined $self->webtest->current_test) {
104 11525         41845 $value = $self->webtest->current_test->param($param);
105 11525 100       38711 $value = defined $value ? $value : $global_value;
106             } else {
107 7         11 $value = $global_value;
108             }
109              
110 11532 100       23813 my $ret = defined $value ? $value : $default;
111              
112 11532         37547 return $self->_canonic_value($ret);
113             }
114              
115             =head2 global_yesno_test_param ($param, $optional_default)
116              
117             =head3 Returns
118              
119             If the global test parameter C<$param> is not defined, returns
120             C<$optional_default> or false if no default exists.
121              
122             If the global test parameter C<$param> is defined, returns true if latest
123             test parameter C<$param> is C, false otherwise.
124              
125             =cut
126              
127             sub global_yesno_test_param {
128 350     350 1 940 my $self = shift;
129 350         652 my $param = shift;
130 350   50     1706 my $default = shift || 0;
131              
132 350         3257 my $value = $self->global_test_param($param);
133              
134 350 100       2983 return $default unless defined $value;
135 51         395 return $value =~ /^yes$/i;
136             }
137              
138             =head2 yesno_test_param ($param, $optional_default)
139              
140             =head3 Returns
141              
142             If latest test parameter C<$param> is not defined returns
143             C<$optional_default> or false if it is not defined also.
144              
145             If latest test parameter C<$param> is defined returns true if latest
146             test parameter C<$param> is C. False otherwise.
147              
148             =cut
149              
150             sub yesno_test_param {
151 1479     1479 1 3893 my $self = shift;
152 1479         2172 my $param = shift;
153 1479   100     8088 my $default = shift || 0;
154              
155 1479         3323 my $value = $self->test_param($param);
156              
157 1479 100       7528 return $default unless defined $value;
158 39         261 return $value =~ /^yes$/i;
159             }
160              
161             # reference on hash that caches return value of subroutine calls
162             *_sub_cache = make_access_method('_SUB_CACHE', sub { {} });
163              
164             # searches passed data structure for code references and replaces them
165             # with value returned by referenced subs
166             sub _canonic_value {
167 16450     16450   23105 my $self = shift;
168 16450         25205 my $value = shift;
169              
170 16450 100       55858 if(ref($value) eq 'CODE') {
171             # check if value is in cache; value returned from subroutine
172             # is cached so we don't evaluate test parameter value more
173             # than one time
174 34 100       59 unless(${$self->_sub_cache}{$value}) {
  34         507  
175 21         78 ${$self->_sub_cache}{$value} = $value->($self->webtest);
  21         1675  
176             }
177              
178 34         103 $value = ${$self->_sub_cache}{$value};
  34         103  
179             }
180              
181 16450 100       57877 if(ref($value) eq 'ARRAY') {
    50          
182 1212         4847 $value = [ map $self->_canonic_value($_), @$value ];
183             } elsif(ref($value) eq 'HASH') {
184 0         0 for my $key (keys %$value) {
185 0         0 $value->{$key} = $self->_canonic_value($value->{$key});
186             }
187             }
188              
189 16450         97059 return $value;
190             }
191              
192             =head2 test_result ($ok, $comment)
193              
194             Factory method that creates test result object.
195              
196             =head3 Returns
197              
198             A L object.
199              
200             =cut
201              
202             sub test_result {
203 373     373 1 1223 my $self = shift;
204 373         618 my $ok = shift;
205 373         640 my $comment = shift;
206              
207 373         2970 my $result = HTTP::WebTest::TestResult->new;
208 373         1733 $result->ok($ok);
209 373         1386 $result->comment($comment);
210              
211 373         2489 return $result;
212             }
213              
214             # helper method used by validate_params and by global_validate_params
215             # to validate values of test parameters
216             sub _validate_params {
217 2331     2331   18484 my $self = shift;
218 2331         8214 my %params = @_;
219              
220 2331         21854 my %param_types = grep $_ =~ /\S/, split /\s+/, $self->param_types;
221              
222 2331         31662 while(my($param, $value) = each %params) {
223 7184 100       56707 next unless defined $value;
224              
225 960         2148 my $type = $param_types{$param};
226 960 50       2692 die "HTTP::WebTest: unknown test parameter '$param'"
227             unless defined $type;
228              
229 960         3146 $self->validate_value($param, $value, $type);
230             }
231             }
232              
233             =head2 validate_params (@params)
234              
235             Checks test parameters in C<@params>. Throws exception if any
236             of them are invalid.
237              
238             =cut
239              
240             sub validate_params {
241 1394     1394 1 2547 my $self = shift;
242 1394         5189 my @params = @_;
243              
244 1394         2798 my %params = ();
245 1394         4215 for my $param (@params) {
246 5804         15577 $params{$param} = $self->test_param($param);
247             }
248              
249 1394         8413 $self->_validate_params(%params);
250             }
251              
252             =head2 global_validate_params (@params)
253              
254             Checks global test parameters in C<@params>. Throws exception
255             if any of them are invalid.
256              
257             =cut
258              
259             sub global_validate_params {
260 937     937 1 1936 my $self = shift;
261 937         2125 my @params = @_;
262              
263 937         1886 my %params = ();
264 937         1730 for my $param (@params) {
265 1380         6820 $params{$param} = $self->global_test_param($param);
266             }
267              
268 937         9712 $self->_validate_params(%params);
269             }
270              
271             =head2 validate_value($param, $value, $type)
272              
273             Checks if C<$value> of test parameter C<$param> has type <$type>.
274              
275             =head3 Exceptions
276              
277             Dies if check is not successful.
278              
279             =cut
280              
281             sub validate_value {
282 988     988 1 1446 my $self = shift;
283 988         1446 my $param = shift;
284 988         1415 my $value = shift;
285 988         1418 my $type = shift;
286              
287             # parse param type specification
288 988         6875 my($method, $args) = $type =~ /^ (\w+) (?: \( (.*?) \) )? $/x;
289 988 50       2711 die "HTTP::WebTest: bad type specification '$type'"
290             unless defined $method;
291 988         2323 $method = 'check_' . $method;
292              
293             # get additional arguments for type validation sub
294 988 100       11584 $args = '' unless defined $args;
295 988         111525 my @args = eval " ( $args ) ";
296 988 50       4402 die "HTTP::WebTest: can't eval args '$args': $@"
297             if $@;
298              
299 988         12889 $self->$method($param, $self->_canonic_value($value), @args);
300             }
301              
302             =head2 param_types ()
303              
304             This method should be redefined in the subclasses. Returns information
305             about test parameters that are supported by plugin. Used to validate
306             tests.
307              
308             =head3 Returns
309              
310             A string that looks like:
311              
312             'param1 type1
313             param2 type2
314             param3 type3(optional,args)
315             param4 type4'
316              
317             =cut
318              
319 0     0 1 0 sub param_types { '' }
320              
321             =head2 check_anything ($value)
322              
323             Method that checks whether test parameter value is of C
324             type.
325              
326             This is NOOP operation. It always succeed.
327              
328             =cut
329              
330 13     13 1 146 sub check_anything { 1 }
331              
332             =head2 check_list ($param, $value, @optional_spec)
333              
334             Method that checks whether test parameter value is of C
335             type. That is it is a reference on an array.
336              
337             Optional list C<@optional_spec> can define specification on allowed
338             elements of list. It can be either
339              
340             ('TYPE_1', 'TYPE_2', ..., 'TYPE_N')
341              
342             or
343              
344             ('TYPE_1', 'TYPE_2', ..., 'TYPE_M', '...')
345              
346             First specification requires list value of test parameter to contain
347             C elements. First element of list should be of should C
348             type, second element of list should of C type, ..., N-th
349             element of list should be of C type.
350              
351             Second specification requires list value of test parameter to contain
352             at least C elements. First element of list should be of should
353             C type, second element of list should of C type, ...,
354             M-th element of list should be of C type, all following
355             elements should be of C type.
356              
357             =head3 Exceptions
358              
359             Dies if checks is not successful.
360              
361             =cut
362              
363             sub check_list {
364 167     167 1 755 my $self = shift;
365 167         695 my $param = shift;
366 167         621 my $value = shift;
367 167         417 my @spec = @_;
368              
369 167 50       672 die "HTTP::WebTest: parameter '$param' is not a list"
370             unless ref($value) eq 'ARRAY';
371              
372 167 100       1815 return unless @spec;
373              
374 13         31 my @list = @$value;
375 13         39 my $prev_type = undef;
376 13         73 for my $i (0 .. @list - 1) {
377 20         31 my $type = shift @spec;
378              
379 20 50       49 die "HTTP::WebTest: too many elements in list parameter '$param'"
380             unless defined $type;
381              
382 20 100       49 if($type eq '...') {
383 1         2 $type = $prev_type;
384 1         3 push @spec, '...';
385             }
386              
387 20         34 my $elem = $list[$i];
388              
389 20         84 $self->validate_value("$param\[$i]", $elem, $type);
390              
391 20         50 $prev_type = $type;
392             }
393              
394 13 100 66     76 shift @spec if defined $spec[0] and $spec[0] eq '...';
395              
396 13 50       106 die "HTTP::WebTest: too few elements in list parameter '$param'"
397             if @spec;
398             }
399              
400             =head2 check_scalar ($param, $value, $optional_regexp)
401              
402             Method that checks whether test parameter value is of C
403             type (that is it is usual Perl scalar and is not a reference).
404              
405             If C<$optional_regexp> is specified also checks value of parameter
406             using this regual expression.
407              
408             =head3 Exceptions
409              
410             Dies if check is not successful.
411              
412             =cut
413              
414             sub check_scalar {
415 391     391 1 830 my $self = shift;
416 391         601 my $param = shift;
417 391         629 my $value = shift;
418 391         840 my $optional_regexp = shift;
419              
420 391 100       3050 die "HTTP::WebTest: parameter '$param' is not a scalar"
421             unless not ref($value);
422              
423 228 100       3227 return unless defined $optional_regexp;
424              
425 23 50       782 die "HTTP::WebTest: parameter '$param' doesn't match regexp '$optional_regexp'"
426             unless $value =~ /$optional_regexp/i;
427             }
428              
429             =head2 check_stringref ($param, $value)
430              
431             Method that checks whether test parameter value is of C
432             type (that is it is a reference on scalar).
433              
434             =head3 Exceptions
435              
436             Dies if check is not successful.
437              
438             =cut
439              
440             sub check_stringref {
441 417     417 1 574 my $self = shift;
442 417         544 my $param = shift;
443 417         717 my $value = shift;
444              
445 417 50       5655 die "HTTP::WebTest: parameter '$param' is not a scalar reference"
446             unless ref($value) eq 'SCALAR';
447             }
448              
449             =head2 check_uri ($param, $value)
450              
451             Method that checks whether test parameter value is of C
452             type (that is it either scalar or L object).
453              
454             =head3 Exceptions
455              
456             Dies if check is not successful.
457              
458             =cut
459              
460             sub check_uri {
461 177     177 1 318 my $self = shift;
462 177         322 my $param = shift;
463 177         323 my $value = shift;
464              
465 177         369 my $ok = 1;
466 177         310 eval { $self->check_scalar($param, $value) };
  177         880  
467 177 100       593 if($@) {
468 163 50 33     1633 $ok = 0
469             unless defined ref($value) and UNIVERSAL::isa($value, 'URI');
470             }
471              
472 177 50       1304 die "HTTP::WebTest: parameter '$param' is not a URI"
473             unless $ok;
474             }
475              
476             =head2 check_hashlist ($param, $value)
477              
478             Method that checks whether test parameter value is of C
479             type (that is it is either a hash reference or an array reference
480             that points to array containing even number of elements).
481              
482             =head3 Exceptions
483              
484             Dies if check is not successful.
485              
486             =cut
487              
488             sub check_hashlist {
489 23     23 1 49 my $self = shift;
490 23         59 my $param = shift;
491 23         44 my $value = shift;
492              
493 23         41 my $ok = 1;
494 23         59 eval { $self->check_list($param, $value) };
  23         101  
495 23 50       72 if($@) {
496 0 0       0 $ok = 0
497             unless ref($value) eq 'HASH';
498             } else {
499 23 50       238 $ok = 0
500             unless (@$value % 2) == 0;
501             }
502              
503 23 50       198 die "HTTP::WebTest: parameter '$param' is neither a hash nor a list with even number of elements"
504             unless $ok;
505             }
506              
507             =head2 check_yesno ($param, $value)
508              
509             Same as
510              
511             check_scalar($param, $value, '^(?:yes|no)$');
512              
513             =cut
514              
515             sub check_yesno {
516 94     94 1 231 my $self = shift;
517 94         219 my $param = shift;
518 94         169 my $value = shift;
519              
520 94         316 check_scalar($param, $value, '^(?:yes|no)$');
521             }
522              
523             =head1 COPYRIGHT
524              
525             Copyright (c) 2001-2003 Ilya Martynov. All rights reserved.
526              
527             This program is free software; you can redistribute it and/or modify
528             it under the same terms as Perl itself.
529              
530             =head1 SEE ALSO
531              
532             L
533              
534             L
535              
536             L
537              
538             L
539              
540             =cut
541              
542             1;