/
50_stackable.t
178 lines (135 loc) · 4.78 KB
/
50_stackable.t
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
#!/usr/bin/perl -w
# vim: ts=2 sw=2 filetype=perl expandtab
# Exercises Filter::Stack (and friends) without the rest of POE.
use strict;
use lib qw(./mylib ../mylib);
sub POE::Kernel::ASSERT_DEFAULT () { 1 }
BEGIN {
package POE::Kernel;
use constant TRACE_DEFAULT => exists($INC{'Devel/Cover.pm'});
}
use Test::More tests => 29;
use_ok('POE::Filter::Stackable');
use_ok('POE::Filter::Grep');
use_ok('POE::Filter::Map');
use_ok('POE::Filter::RecordBlock');
use_ok('POE::Filter::Line');
# Create a filter stack to test.
my $filter_stack = POE::Filter::Stackable->new(
Filters => [
POE::Filter::Line->new( Literal => "!" ),
# The next Map filter translates Put data from RecordBlock
# (arrayrefs) into scalars for Line. On the Get side, it just
# wraps parens around whatever Line returns.
POE::Filter::Map->new(
Put => sub { @$_ }, # scalarify puts
Get => sub { "((($_)))" }, # transform gets
),
POE::Filter::Grep->new(
Put => sub { 1 }, # always put
Get => sub { /1/ }, # only get /1/
),
# RecordBlock puts arrayrefs. They pass through Grep->Put
# without change. RecordBlock receives whatever-- lines in this
# case, but only ones that match /1/ from Grep->Get.
POE::Filter::RecordBlock->new( BlockSize => 2 ),
]
);
ok(defined($filter_stack), "filter stack created");
my $block = $filter_stack->get( [ "test one (1)!test two (2)!" ] );
ok(!@$block, "partial get returned nothing");
my $pending = $filter_stack->get_pending();
is_deeply(
$pending, [ "(((test one (1))))" ],
"filter stack has correct get_pending"
);
$block = $filter_stack->get( [ "test three (3)!test four (100)!" ] );
is_deeply(
$block, [ [ "(((test one (1))))", "(((test four (100))))" ] ],
"filter stack returned correct data"
);
# Make a copy of the block. Bad things happen when both blocks have
# the same reference because we're passing by reference a lot.
my $stream = $filter_stack->put( [ $block, $block ] );
is_deeply(
$stream,
[
"(((test one (1))))!", "(((test four (100))))!",
"(((test one (1))))!", "(((test four (100))))!",
],
"filter stack serialized correct data"
);
# Test some of the discrete stackable filters by themselves.
my @test_list = (1, 1, 2, 3, 5);
# Map
my $map = POE::Filter::Map->new( Code => sub { "((($_)))" } );
$map->get_one_start( [ @test_list ] );
my $map_pending = join '', @{$map->get_pending()};
ok($map_pending eq "11235", "map filter's parser buffer verifies");
foreach my $compare (@test_list) {
my $next = $map->get_one();
is_deeply(
$next, [ "((($compare)))" ],
"map filter get_one() returns ((($compare)))"
);
}
my $map_next = $map->get_one();
ok(!@$map_next, "nothing left to get from map filter");
### Go back and test more of Stackable.
{
my @filters_should_be = qw(
POE::Filter::Line POE::Filter::Map POE::Filter::Grep
POE::Filter::RecordBlock
);
my @filters_are = $filter_stack->filter_types();
is_deeply(\@filters_are, \@filters_should_be,
"filter types stacked correctly");
}
# test pushing and popping
{
my @filters_strlist = map { "$_" } $filter_stack->filters();
my $filter_pop = $filter_stack->pop();
ok(
ref($filter_pop) eq "POE::Filter::RecordBlock",
"popped the correct filter"
);
my $filter_shift = $filter_stack->shift();
ok(
ref($filter_shift) eq 'POE::Filter::Line',
"shifted the correct filter"
);
$filter_stack->push( $filter_pop );
$filter_stack->unshift( $filter_shift );
my @filters_strlist_end = map { "$_" } $filter_stack->filters();
is_deeply(\@filters_strlist_end, \@filters_strlist,
"repushed, reshifted filters are in original order");
}
# push error checking
{
my @filters_strlist = map { "$_" } $filter_stack->filters();
eval { $filter_stack->push(undef) };
ok(!!$@, "undef is not a filter");
eval { $filter_stack->push(['i am not a filter']) };
ok(!!$@, "bare references are not filters");
eval { $filter_stack->push(bless(['i am not a filter'], "foo$$")) };
ok(!!$@, "random blessed references are not filters");
# not blessed into a package that ISA POE::Filter
eval { $filter_stack->push(123, "two not-filter things") };
ok(!!$@, "multiple non-filters are not filters");
my @filters_strlist_end = map { "$_" } $filter_stack->filters();
is_deeply(\@filters_strlist_end, \@filters_strlist,
"filters unchanged despite errors");
}
# test cloning
{
my @filters_strlist = map { "$_" } $filter_stack->filters();
my @filter_types = $filter_stack->filter_types();
my $new_stack = $filter_stack->clone();
isnt("$new_stack", "$filter_stack", "cloned stack is different");
isnt(join('---', @filters_strlist),
join('---', $new_stack->filters()),
"filters are different");
is_deeply(\@filter_types, [$new_stack->filter_types()],
"but types are the same");
}
exit 0;