File Coverage

blib/lib/Test/Routine/AutoClear.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1             package Test::Routine::AutoClear;
2             {
3             $Test::Routine::AutoClear::VERSION = '0.004';
4             }
5             # ABSTRACT: Enables autoclearing attrs in Test::Routines
6 2     2   4206 use Test::Routine ();
  0            
  0            
7             use Moose::Exporter;
8              
9             use Test::Routine::Meta::Builder;
10              
11              
12             Moose::Exporter->setup_import_methods(
13             with_meta => [qw{has}],
14             as_is => [qw{builder}],
15             also => 'Test::Routine',
16             );
17              
18             sub init_meta {
19             my($class, %arg) = @_;
20              
21             my $meta = Moose::Role->init_meta(%arg);
22             my $role = $arg{for_class};
23             Moose::Util::apply_all_roles($role, 'Test::Routine::DoesAutoClear');
24              
25             return $meta;
26             }
27              
28             sub has {
29             my($meta, $name, %options) = @_;
30              
31             if (delete $options{autoclear}) {
32             push @{$options{traits}}, 'AutoClear'
33             }
34              
35             $meta->add_attribute(
36             $name,
37             %options,
38             );
39             }
40              
41             sub builder (&) {
42             my $builder = shift;
43             bless $builder, 'Test::Routine::Meta::Builder';
44             }
45              
46             1;
47              
48             __END__
49              
50             =pod
51              
52             =head1 NAME
53              
54             Test::Routine::AutoClear - Enables autoclearing attrs in Test::Routines
55              
56             =head1 VERSION
57              
58             version 0.004
59              
60             =head1 SYNOPSIS
61              
62             use Test::Routine::AutoClear;
63             use Test::More;
64             use File::Tempdir;
65              
66             has _tempdir => (
67             is => 'ro',
68             isa => 'Int',
69             builder => '_build_tempdir',
70             lazy => 1,
71             autoclear => 1,
72             handles => {
73             tempdir => 'name',
74             },
75             );
76              
77             sub _build_tempdir {
78             File::Tempdir->new();
79             }
80              
81             And now all the tests that use a tempdir in your test routine will get a
82             fresh Tempdir
83              
84             =head1 DESCRIPTION
85              
86             When I'm writing tests with L<Test::Routine> I find myself writing code like
87             this all the time:
88              
89             has counter => (
90             is => ro,
91             lazy => 1,
92             default => 0
93             lazy => 1,
94             clearer => 'reset_counter',
95             );
96              
97             after run_test => sub {
98             shift->reset_counter;
99             };
100              
101             And after about the first time, I got bored of doing this. So I started to fix
102             it, and here's my first cut.
103              
104             L<Test::Routine::AutoClear> addresses this by adding a new C<autoclear> key to
105             the C<has> arguments. If you set C<autoclear> to a true value on an attribute
106             then, after each test is run, all the autoclearing attributes will be reset.
107              
108             =head2 Clearing logic
109              
110             Consider the following Test::Routine:
111              
112             use Test::More;
113             use Test::Routine::AutoClear;
114             use Test::Routine::Util;
115              
116             has some_attrib => (
117             is => 'ro',
118             default => 10,
119             lazy => 1,
120             autoclear => 1,
121             clearer => 'reset_attrib',
122             );
123              
124             test "This should be invariant" => sub {
125             my $self = shift;
126             my $attrib = $self->attrib;
127             $self->reset_attrib;
128             is $self->attrib, $attrib;
129             };
130              
131             run_me "Test defaults";
132             run_me "Test initialising", { attrib => 20 };
133             done_testing;
134              
135             It seems to me that, in a perfect world at least, that test should pass. Which
136             it does. Huzzah!
137              
138             =head2 Passing a builder
139              
140             So... you're writing a Moose object and you want the default value to be an
141             empty arrayref. You'll have noticed that you can't write:
142              
143             has queue => (
144             is => 'ro',
145             default => [],
146             );
147              
148             Moose will complain vigorously. And rightly so. If you were to do:
149              
150             run_me "Something", { queue => [qw(something)] }
151              
152             you would rapidly discover E<why> Moose complains. So what's a poor tester to
153             do?
154              
155             Why, take advantage of the very lovely and worthwhile C<builder> helper and
156             write this:
157              
158             run_me "This works", { queue => builder { [] } };
159              
160             and Test::Routine::AutoClear will pretend that you _actually_ declared queue
161             like so:
162              
163             has queue => (
164             is => 'ro',
165             default => sub { [] },
166             );
167              
168             NB: The builder routine you passed in is called just like a Moose builder
169             method, so you get to look at the instance you're building the value
170             for. However, right now, this builder is _not_ called lazily, so there's no
171             guarantee that attributes that you may depend on have been intialized
172             yet. Expect this to be fixed in a future version.
173              
174             =head1 BUGS
175              
176             Lots. Including, but not limited to:
177              
178             =over 4
179              
180             =item *
181              
182             The interface is still very fluid. I make no promises about interface
183             stability.
184              
185             =item *
186              
187             I'm pretty sure that if you end up mixing in multiple roles that use
188             this role then you'll end up clearing your attributes lots of times.
189              
190             =back
191              
192             =head1 SEE ALSO
193              
194             =over 4
195              
196             =item *
197              
198             L<Test::Routine>
199              
200             =back
201              
202             =head1 AUTHOR
203              
204             Piers Cawley <pdcawley@bofh.org.uk>
205              
206             =head1 COPYRIGHT AND LICENSE
207              
208             This software is copyright (c) 2012 by Piers Cawley.
209              
210             This is free software; you can redistribute it and/or modify it under
211             the same terms as the Perl 5 programming language system itself.
212              
213             =cut