File Coverage

inc/Test/Base.pm
Criterion Covered Total %
statement 267 384 69.5
branch 77 202 38.1
condition 22 83 26.5
subroutine 47 63 74.6
pod 0 29 0.0
total 413 761 54.2


line stmt bran cond sub pod time code
1             package Test::Base;
2             our $VERSION = '0.89';
3              
4 40     40   221760 use Spiffy -Base;
  40         92  
  40         164  
5 40     40   2121 use Spiffy ':XXX';
  40     40   1823  
  40     40   2782  
  40         3532  
  40         1696  
  40         2669  
  40         3450  
  40         85  
  40         3454  
6              
7             my $HAS_PROVIDER;
8             BEGIN {
9 40     40   1960 $HAS_PROVIDER = eval "require Test::Builder::Provider; 1";
10              
11 40 50       266 if ($HAS_PROVIDER) {
12 0         0 Test::Builder::Provider->import('provides');
13             }
14             else {
15 40     40   1894 *provides = sub { 1 };
  40         79  
16             }
17             }
18              
19              
20             my @test_more_exports;
21             BEGIN {
22 40     40   1082 @test_more_exports = qw(
23             ok isnt like unlike is_deeply cmp_ok
24             skip todo_skip pass fail
25             eq_array eq_hash eq_set
26             plan can_ok isa_ok diag
27             use_ok
28             $TODO
29             );
30             }
31              
32 40     40   25885 use Test::More import => \@test_more_exports;
  40         2601255  
  40         416  
33 40     40   10711 use Carp;
  40         108  
  40         17978  
34              
35             our @EXPORT = (@test_more_exports, qw(
36             is no_diff
37              
38             blocks next_block first_block
39             delimiters spec_file spec_string
40             filters filters_delay filter_arguments
41             run run_compare run_is run_is_deeply run_like run_unlike
42             skip_all_unless_require is_deep run_is_deep
43             WWW XXX YYY ZZZ
44             tie_output no_diag_on_only
45              
46             find_my_self default_object
47              
48             croak carp cluck confess
49             ));
50              
51             field '_spec_file';
52             field '_spec_string';
53             field _filters => [qw(norm trim)];
54             field _filters_map => {};
55             field spec =>
56             -init => '$self->_spec_init';
57             field block_list =>
58             -init => '$self->_block_list_init';
59             field _next_list => [];
60             field block_delim =>
61             -init => '$self->block_delim_default';
62             field data_delim =>
63             -init => '$self->data_delim_default';
64             field _filters_delay => 0;
65             field _no_diag_on_only => 0;
66              
67             field block_delim_default => '===';
68             field data_delim_default => '---';
69              
70             my $default_class;
71             my $default_object;
72             my $reserved_section_names = {};
73              
74 199     199 0 347 sub default_object {
75 199   66     1088 $default_object ||= $default_class->new;
76 199         329 return $default_object;
77             }
78              
79             my $import_called = 0;
80             sub import() {
81 80     80   1259 $import_called = 1;
82 80 100       580 my $class = (grep /^-base$/i, @_)
83             ? scalar(caller)
84             : $_[0];
85 80 100       247 if (not defined $default_class) {
86 40         87 $default_class = $class;
87             }
88             # else {
89             # croak "Can't use $class after using $default_class"
90             # unless $default_class->isa($class);
91             # }
92              
93 80 100       338 unless (grep /^-base$/i, @_) {
94 40         97 my @args;
95 40         159 for (my $ii = 1; $ii <= $#_; ++$ii) {
96 72 50       194 if ($_[$ii] eq '-package') {
97 0         0 ++$ii;
98             } else {
99 72         222 push @args, $_[$ii];
100             }
101             }
102 40 100       359 Test::More->import(import => \@test_more_exports, @args)
103             if @args;
104             }
105              
106 80         31591 _strict_warnings();
107 80         1647 goto &Spiffy::import;
108             }
109              
110             # Wrap Test::Builder::plan
111             my $plan_code = \&Test::Builder::plan;
112             my $Have_Plan = 0;
113             {
114 40     40   368 no warnings 'redefine';
  40         122  
  40         169010  
115             *Test::Builder::plan = sub {
116 40     40   18968 $Have_Plan = 1;
117 40         199 goto &$plan_code;
118             };
119             }
120              
121             my $DIED = 0;
122             $SIG{__DIE__} = sub { $DIED = 1; die @_ };
123              
124 28     28 0 42 sub block_class { $self->find_class('Block') }
  28         64  
125 155     155 0 230 sub filter_class { $self->find_class('Filter') }
  155         251  
126              
127 183     183 0 202 sub find_class {
128 183         212 my $suffix = shift;
129 183         349 my $class = ref($self) . "::$suffix";
130 183 100       543 return $class if $class->can('new');
131 28         72 $class = __PACKAGE__ . "::$suffix";
132 28 50       135 return $class if $class->can('new');
133 0         0 eval "require $class";
134 0 0       0 return $class if $class->can('new');
135 0         0 die "Can't find a class for $suffix";
136             }
137              
138 42     42 0 86 sub check_late {
139 42 50       160 if ($self->{block_list}) {
140 0         0 my $caller = (caller(1))[3];
141 0         0 $caller =~ s/.*:://;
142 0         0 croak "Too late to call $caller()"
143             }
144             }
145              
146             sub find_my_self() {
147 205 100   205 0 2706 my $self = ref($_[0]) eq $default_class
148             ? splice(@_, 0, 1)
149             : default_object();
150 205         745 return $self, @_;
151             }
152              
153             sub blocks() {
154 2     2 0 23 (my ($self), @_) = find_my_self(@_);
155              
156 2 50       8 croak "Invalid arguments passed to 'blocks'"
157             if @_ > 1;
158 2 50 33     9 croak sprintf("'%s' is invalid argument to blocks()", shift(@_))
159             if @_ && $_[0] !~ /^[a-zA-Z]\w*$/;
160              
161 2         34 my $blocks = $self->block_list;
162              
163 2   50     12 my $section_name = shift || '';
164             my @blocks = $section_name
165 2 50       10 ? (grep { exists $_->{$section_name} } @$blocks)
  0         0  
166             : (@$blocks);
167              
168 2 50       6 return scalar(@blocks) unless wantarray;
169              
170 2 50       34 return (@blocks) if $self->_filters_delay;
171              
172 2         6 for my $block (@blocks) {
173 6 50       69 $block->run_filters
174             unless $block->is_filtered;
175             }
176              
177 2         8 return (@blocks);
178             }
179              
180             sub next_block() {
181 0     0 0 0 (my ($self), @_) = find_my_self(@_);
182 0         0 my $list = $self->_next_list;
183 0 0       0 if (@$list == 0) {
184 0         0 $list = [@{$self->block_list}, undef];
  0         0  
185 0         0 $self->_next_list($list);
186             }
187 0         0 my $block = shift @$list;
188 0 0 0     0 if (defined $block and not $block->is_filtered) {
189 0         0 $block->run_filters;
190             }
191 0         0 return $block;
192             }
193              
194             sub first_block() {
195 0     0 0 0 (my ($self), @_) = find_my_self(@_);
196 0         0 $self->_next_list([]);
197 0         0 $self->next_block;
198             }
199              
200             sub filters_delay() {
201 0     0 0 0 (my ($self), @_) = find_my_self(@_);
202 0 0       0 $self->_filters_delay(defined $_[0] ? shift : 1);
203             }
204              
205             sub no_diag_on_only() {
206 0     0 0 0 (my ($self), @_) = find_my_self(@_);
207 0 0       0 $self->_no_diag_on_only(defined $_[0] ? shift : 1);
208             }
209              
210             sub delimiters() {
211 40     40 0 229 (my ($self), @_) = find_my_self(@_);
212 40         260 $self->check_late;
213 40         90 my ($block_delimiter, $data_delimiter) = @_;
214 40   33     132 $block_delimiter ||= $self->block_delim_default;
215 40   33     295 $data_delimiter ||= $self->data_delim_default;
216 40         896 $self->block_delim($block_delimiter);
217 40         640 $self->data_delim($data_delimiter);
218 40         98 return $self;
219             }
220              
221             sub spec_file() {
222 2     2 0 192 (my ($self), @_) = find_my_self(@_);
223 2         12 $self->check_late;
224 2         39 $self->_spec_file(shift);
225 2         5 return $self;
226             }
227              
228             sub spec_string() {
229 0     0 0 0 (my ($self), @_) = find_my_self(@_);
230 0         0 $self->check_late;
231 0         0 $self->_spec_string(shift);
232 0         0 return $self;
233             }
234              
235             sub filters() {
236 4     4 0 961 (my ($self), @_) = find_my_self(@_);
237 4 50       20 if (ref($_[0]) eq 'HASH') {
238 4         78 $self->_filters_map(shift);
239             }
240             else {
241 0         0 my $filters = $self->_filters;
242 0         0 push @$filters, @_;
243             }
244 4         14 return $self;
245             }
246              
247             sub filter_arguments() {
248 0     0 0 0 $Test::Base::Filter::arguments;
249             }
250              
251 0     0 0 0 sub have_text_diff {
252 0 0 0     0 eval { require Text::Diff; 1 } &&
  0         0  
  0         0  
253             $Text::Diff::VERSION >= 0.35 &&
254             $Algorithm::Diff::VERSION >= 1.15;
255             }
256              
257             provides 'is';
258             sub is($$;$) {
259 143     143 0 85375 (my ($self), @_) = find_my_self(@_);
260 143         351 my ($actual, $expected, $name) = @_;
261 143 50       570 local $Test::Builder::Level = $Test::Builder::Level + 1 unless $HAS_PROVIDER;
262 143 50 33     606 if ($ENV{TEST_SHOW_NO_DIFFS} or
      33        
      0        
      0        
      0        
263             not defined $actual or
264             not defined $expected or
265             $actual eq $expected or
266             not($self->have_text_diff) or
267             $expected !~ /\n./s
268             ) {
269 143         437 Test::More::is($actual, $expected, $name);
270             }
271             else {
272 0 0       0 $name = '' unless defined $name;
273 0         0 ok $actual eq $expected, $name;
274 0         0 diag Text::Diff::diff(\$expected, \$actual);
275             }
276             }
277              
278             sub run(&;$) {
279 2     2 0 99 (my ($self), @_) = find_my_self(@_);
280 2         5 my $callback = shift;
281 2         6 for my $block (@{$self->block_list}) {
  2         36  
282 12 50       8051 $block->run_filters unless $block->is_filtered;
283 12         18 &{$callback}($block);
  12         26  
284             }
285             }
286              
287             my $name_error = "Can't determine section names";
288 2     2   4 sub _section_names {
289 2 50       50 return unless defined $self->spec;
290 2 50       12 return @_ if @_ == 2;
291 0 0       0 my $block = $self->first_block
292             or croak $name_error;
293             my @names = grep {
294 0         0 $_ !~ /^(ONLY|LAST|SKIP)$/;
295 0 0       0 } @{$block->{_section_order}[0] || []};
  0         0  
296 0 0       0 croak "$name_error. Need two sections in first block"
297             unless @names == 2;
298 0         0 return @names;
299             }
300              
301 2     2   4 sub _assert_plan {
302 2 50       6 plan('no_plan') unless $Have_Plan;
303             }
304              
305 40     40   72350 sub END {
306 40 0 33     1182 run_compare() unless $Have_Plan or $DIED or not $import_called;
      33        
307             }
308              
309             sub run_compare() {
310 0     0 0 0 (my ($self), @_) = find_my_self(@_);
311 0 0       0 return unless defined $self->spec;
312 0         0 $self->_assert_plan;
313 0         0 my ($x, $y) = $self->_section_names(@_);
314 0         0 local $Test::Builder::Level = $Test::Builder::Level + 1;
315 0         0 for my $block (@{$self->block_list}) {
  0         0  
316 0 0 0     0 next unless exists($block->{$x}) and exists($block->{$y});
317 0 0       0 $block->run_filters unless $block->is_filtered;
318 0 0       0 if (ref $block->$x) {
    0          
319 0 0       0 is_deeply($block->$x, $block->$y,
320             $block->name ? $block->name : ());
321             }
322             elsif (ref $block->$y eq 'Regexp') {
323 0 0       0 my $regexp = ref $y ? $y : $block->$y;
324 0 0       0 like($block->$x, $regexp, $block->name ? $block->name : ());
325             }
326             else {
327 0 0       0 is($block->$x, $block->$y, $block->name ? $block->name : ());
328             }
329             }
330             }
331              
332             sub run_is() {
333 1     1 0 5 (my ($self), @_) = find_my_self(@_);
334 1         5 $self->_assert_plan;
335 1         6 my ($x, $y) = $self->_section_names(@_);
336 1         4 local $Test::Builder::Level = $Test::Builder::Level + 1;
337 1         1 for my $block (@{$self->block_list}) {
  1         21  
338 5 100 66     1958 next unless exists($block->{$x}) and exists($block->{$y});
339 4 50       102 $block->run_filters unless $block->is_filtered;
340 4 50       9 is($block->$x, $block->$y,
341             $block->name ? $block->name : ()
342             );
343             }
344             }
345              
346             sub run_is_deeply() {
347 1     1 0 7 (my ($self), @_) = find_my_self(@_);
348 1         8 $self->_assert_plan;
349 1         6 my ($x, $y) = $self->_section_names(@_);
350 1         2 for my $block (@{$self->block_list}) {
  1         22  
351 5 50 33     4239 next unless exists($block->{$x}) and exists($block->{$y});
352 5 50       80 $block->run_filters unless $block->is_filtered;
353 5 50       12 is_deeply($block->$x, $block->$y,
354             $block->name ? $block->name : ()
355             );
356             }
357             }
358              
359             sub run_like() {
360 0     0 0 0 (my ($self), @_) = find_my_self(@_);
361 0         0 $self->_assert_plan;
362 0         0 my ($x, $y) = $self->_section_names(@_);
363 0         0 for my $block (@{$self->block_list}) {
  0         0  
364 0 0 0     0 next unless exists($block->{$x}) and defined($y);
365 0 0       0 $block->run_filters unless $block->is_filtered;
366 0 0       0 my $regexp = ref $y ? $y : $block->$y;
367 0 0       0 like($block->$x, $regexp,
368             $block->name ? $block->name : ()
369             );
370             }
371             }
372              
373             sub run_unlike() {
374 0     0 0 0 (my ($self), @_) = find_my_self(@_);
375 0         0 $self->_assert_plan;
376 0         0 my ($x, $y) = $self->_section_names(@_);
377 0         0 for my $block (@{$self->block_list}) {
  0         0  
378 0 0 0     0 next unless exists($block->{$x}) and defined($y);
379 0 0       0 $block->run_filters unless $block->is_filtered;
380 0 0       0 my $regexp = ref $y ? $y : $block->$y;
381 0 0       0 unlike($block->$x, $regexp,
382             $block->name ? $block->name : ()
383             );
384             }
385             }
386              
387             sub skip_all_unless_require() {
388 0     0 0 0 (my ($self), @_) = find_my_self(@_);
389 0         0 my $module = shift;
390 0 0       0 eval "require $module; 1"
391             or Test::More::plan(
392             skip_all => "$module failed to load"
393             );
394             }
395              
396             sub is_deep() {
397 0     0 0 0 (my ($self), @_) = find_my_self(@_);
398 0         0 require Test::Deep;
399 0         0 Test::Deep::cmp_deeply(@_);
400             }
401              
402             sub run_is_deep() {
403 0     0 0 0 (my ($self), @_) = find_my_self(@_);
404 0         0 $self->_assert_plan;
405 0         0 my ($x, $y) = $self->_section_names(@_);
406 0         0 for my $block (@{$self->block_list}) {
  0         0  
407 0 0 0     0 next unless exists($block->{$x}) and exists($block->{$y});
408 0 0       0 $block->run_filters unless $block->is_filtered;
409 0 0       0 is_deep($block->$x, $block->$y,
410             $block->name ? $block->name : ()
411             );
412             }
413             }
414              
415 6     6   14 sub _pre_eval {
416 6         12 my $spec = shift;
417 6 50       18 return unless defined $spec;
418 6 50       33 return $spec unless $spec =~
419             s/\A\s*<<<(.*?)>>>\s*$//sm;
420 0         0 my $eval_code = $1;
421 0         0 eval "package main; $eval_code";
422 0 0       0 croak $@ if $@;
423 0         0 return $spec;
424             }
425              
426 6     6   17 sub _block_list_init {
427 6         78 my $spec = $self->spec;
428 6 50       22 return [] unless defined $spec;
429 6         63 $spec = $self->_pre_eval($spec);
430 6         96 my $cd = $self->block_delim;
431 6         720 my @hunks = ($spec =~ /^(\Q${cd}\E.*?(?=^\Q${cd}\E|\z))/msg);
432 6         47 my $blocks = $self->_choose_blocks(@hunks);
433 6         173 $self->block_list($blocks); # Need to set early for possible filter use
434 6         13 my $seq = 1;
435 6         19 for my $block (@$blocks) {
436 28         315 $block->blocks_object($self);
437 28         275 $block->seq_num($seq++);
438             }
439 6         47 return $blocks;
440             }
441              
442 6     6   17 sub _choose_blocks {
443 6         12 my $blocks = [];
444 6         22 for my $hunk (@_) {
445 28         66 my $block = $self->_make_block($hunk);
446 28 50       67 if (exists $block->{ONLY}) {
447 0 0       0 diag "I found ONLY: maybe you're debugging?"
448             unless $self->_no_diag_on_only;
449 0         0 return [$block];
450             }
451 28 50       51 next if exists $block->{SKIP};
452 28         46 push @$blocks, $block;
453 28 50       66 if (exists $block->{LAST}) {
454 0         0 return $blocks;
455             }
456             }
457 6         16 return $blocks;
458             }
459              
460 66     66   80 sub _check_reserved {
461 66         82 my $id = shift;
462             croak "'$id' is a reserved name. Use something else.\n"
463 66 50 33     247 if $reserved_section_names->{$id} or
464             $id =~ /^_/;
465             }
466              
467 28     28   39 sub _make_block {
468 28         49 my $hunk = shift;
469 28         452 my $cd = $self->block_delim;
470 28         300 my $dd = $self->data_delim;
471 28         77 my $block = $self->block_class->new;
472 28 50       352 $hunk =~ s/\A\Q${cd}\E[ \t]*(.*)\s+// or die;
473 28         87 my $name = $1;
474 28         396 my @parts = split /^\Q${dd}\E +\(?(\w+)\)? *(.*)?\n/m, $hunk;
475 28         69 my $description = shift @parts;
476 28   50     119 $description ||= '';
477 28 50       71 unless ($description =~ /\S/) {
478 28         41 $description = $name;
479             }
480 28         171 $description =~ s/\s*\z//;
481 28         81 $block->set_value(description => $description);
482              
483 28         46 my $section_map = {};
484 28         60 my $section_order = [];
485 28         60 while (@parts) {
486 66         155 my ($type, $filters, $value) = splice(@parts, 0, 3);
487 66         150 $self->_check_reserved($type);
488 66 50       120 $value = '' unless defined $value;
489 66 50       93 $filters = '' unless defined $filters;
490 66 50       109 if ($filters =~ /:(\s|\z)/) {
491 0 0       0 croak "Extra lines not allowed in '$type' section"
492             if $value =~ /\S/;
493 0         0 ($filters, $value) = split /\s*:(?:\s+|\z)/, $filters, 2;
494 0 0       0 $value = '' unless defined $value;
495 0         0 $value =~ s/^\s*(.*?)\s*$/$1/;
496             }
497 66         191 $section_map->{$type} = {
498             filters => $filters,
499             };
500 66         117 push @$section_order, $type;
501 66         115 $block->set_value($type, $value);
502             }
503 28         72 $block->set_value(name => $name);
504 28         60 $block->set_value(_section_map => $section_map);
505 28         69 $block->set_value(_section_order => $section_order);
506 28         132 return $block;
507             }
508              
509 6     6   14 sub _spec_init {
510 6 50       84 return $self->_spec_string
511             if $self->_spec_string;
512 6         24 local $/;
513 6         18 my $spec;
514 6 100       87 if (my $spec_file = $self->_spec_file) {
515 2 50       88 open FILE, $spec_file or die $!;
516 2         80 $spec = ;
517 2         25 close FILE;
518             }
519             else {
520 4         20 require Scalar::Util;
521 4         20 my $handle = Scalar::Util::openhandle( \*main::DATA );
522 4 50       13 if ($handle) {
523 4         88 $spec = <$handle>;
524             }
525             }
526 6         54 return $spec;
527             }
528              
529             sub _strict_warnings() {
530 80     80   416 require Filter::Util::Call;
531 80         148 my $done = 0;
532             Filter::Util::Call::filter_add(
533             sub {
534 156 100   156   65023 return 0 if $done;
535 80         179 my ($data, $end) = ('', '');
536 80         908 while (my $status = Filter::Util::Call::filter_read()) {
537 4987 50       7216 return $status if $status < 0;
538 4987 100       6887 if (/^__(?:END|DATA)__\r?$/) {
539 4         10 $end = $_;
540 4         329 last;
541             }
542 4983         5458 $data .= $_;
543 4983         10604 $_ = '';
544             }
545 80         649 $_ = "use strict;use warnings;$data$end";
546 80         1957 $done = 1;
547             }
548 80         580 );
549             }
550              
551             sub tie_output() {
552 0     0 0 0 my $handle = shift;
553 0 0       0 die "No buffer to tie" unless @_;
554 0         0 tie *$handle, 'Test::Base::Handle', $_[0];
555             }
556              
557 40     40 0 497 sub no_diff {
558 40         529 $ENV{TEST_SHOW_NO_DIFFS} = 1;
559             }
560              
561             package Test::Base::Handle;
562              
563             sub TIEHANDLE() {
564 0     0   0 my $class = shift;
565 0         0 bless \ $_[0], $class;
566             }
567              
568 0     0   0 sub PRINT {
569 0         0 $$self .= $_ for @_;
570             }
571              
572             #===============================================================================
573             # Test::Base::Block
574             #
575             # This is the default class for accessing a Test::Base block object.
576             #===============================================================================
577             package Test::Base::Block;
578             our @ISA = qw(Spiffy);
579              
580             our @EXPORT = qw(block_accessor);
581              
582 5     5   93 sub AUTOLOAD {
583 5         9 return;
584             }
585              
586             sub block_accessor() {
587 107     107   163 my $accessor = shift;
588 40     40   393 no strict 'refs';
  40         101  
  40         8187  
589 107 50       526 return if defined &$accessor;
590             *$accessor = sub {
591 246     246   17165 my $self = shift;
592 246 50       465 if (@_) {
593 0         0 Carp::croak "Not allowed to set values for '$accessor'";
594             }
595 246 50       251 my @list = @{$self->{$accessor} || []};
  246         702  
596             return wantarray
597 246 100       1284 ? (@list)
598             : $list[0];
599 107         674 };
600             }
601              
602             block_accessor 'name';
603             block_accessor 'description';
604             Spiffy::field 'seq_num';
605             Spiffy::field 'is_filtered';
606             Spiffy::field 'blocks_object';
607             Spiffy::field 'original_values' => {};
608              
609 342     342   384 sub set_value {
610 40     40   340 no strict 'refs';
  40         114  
  40         8888  
611 342         398 my $accessor = shift;
612 342 100       803 block_accessor $accessor
613             unless defined &$accessor;
614 342         1095 $self->{$accessor} = [@_];
615             }
616              
617 27     27   44 sub run_filters {
618 27         60 my $map = $self->_section_map;
619 27         75 my $order = $self->_section_order;
620 27 50       309 Carp::croak "Attempt to filter a block twice"
621             if $self->is_filtered;
622 27         58 for my $type (@$order) {
623 64         128 my $filters = $map->{$type}{filters};
624 64         159 my @value = $self->$type;
625 64         763 $self->original_values->{$type} = $value[0];
626 64         151 for my $filter ($self->_get_filters($type, $filters)) {
627 164 50       338 $Test::Base::Filter::arguments =
628             $filter =~ s/=(.*)$// ? $1 : undef;
629 164         296 my $function = "main::$filter";
630 40     40   340 no strict 'refs';
  40         109  
  40         22861  
631 164 100       583 if (defined &$function) {
632 9 50 33     65 local $_ =
633             (@value == 1 and not defined($value[0])) ? undef :
634             join '', @value;
635 9         16 my $old = $_;
636 9         25 @value = &$function(@value);
637 9 50 33     984 if (not(@value) or
      33        
      33        
638             @value == 1 and defined($value[0]) and $value[0] =~ /\A(\d+|)\z/
639             ) {
640 0 0 0     0 if ($value[0] && $_ eq $old) {
641 0         0 Test::Base::diag("Filters returning numbers are supposed to do munging \$_: your filter '$function' apparently doesn't.");
642             }
643 0         0 @value = ($_);
644             }
645             }
646             else {
647 155         1680 my $filter_object = $self->blocks_object->filter_class->new;
648 155 50       283 die "Can't find a function or method for '$filter' filter\n"
649             unless $filter_object->can($filter);
650 155         1673 $filter_object->current_block($self);
651 155         426 @value = $filter_object->$filter(@value);
652             }
653             # Set the value after each filter since other filters may be
654             # introspecting.
655 164         564 $self->set_value($type, @value);
656             }
657             }
658 27         310 $self->is_filtered(1);
659             }
660              
661 64     64   87 sub _get_filters {
662 64         87 my $type = shift;
663 64   50     196 my $string = shift || '';
664 64         264 $string =~ s/\s*(.*?)\s*/$1/;
665 64         101 my @filters = ();
666 64   100     613 my $map_filters = $self->blocks_object->_filters_map->{$type} || [];
667 64 100       164 $map_filters = [ $map_filters ] unless ref $map_filters;
668 64         87 my @append = ();
669 64         77 for (
670 64         582 @{$self->blocks_object->_filters},
671             @$map_filters,
672             split(/\s+/, $string),
673             ) {
674 164         197 my $filter = $_;
675 164 50       278 last unless length $filter;
676 164 50       316 if ($filter =~ s/^-//) {
    50          
677 0         0 @filters = grep { $_ ne $filter } @filters;
  0         0  
678             }
679             elsif ($filter =~ s/^\+//) {
680 0         0 push @append, $filter;
681             }
682             else {
683 164         298 push @filters, $filter;
684             }
685             }
686 64         167 return @filters, @append;
687             }
688              
689             {
690             %$reserved_section_names = map {
691             ($_, 1);
692             } keys(%Test::Base::Block::), qw( new DESTROY );
693             }
694              
695             1;