File Coverage

blib/lib/Test/A8N/TestCase.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             package Test::A8N::TestCase;
2 1     1   30564 use warnings;
  1         4  
  1         33  
3 1     1   7 use strict;
  1         2  
  1         34  
4              
5             # NB: Moose also enforces 'strict' and warnings;
6 1     1   1438 use Moose;
  0            
  0            
7             use Storable qw(dclone);
8             use YAML::Syck;
9             use File::Spec::Functions;
10              
11             sub BUILD {
12             my $self = shift;
13             my @configs = ();
14             foreach my $file (@{ $self->configuration }) {
15             $file = catfile($self->config->{file_root}, $file);
16             if (!-f $file) {
17             die sprintf(
18             q{Can't load configuration file "%s" for testcase "%s" in file "%s"; no such file.},
19             $file, $self->name, $self->filename
20             );
21             }
22             push @configs, %{ LoadFile($file) };
23             }
24             push @configs, %{ dclone($self->config) };
25             my %config = @configs;
26             foreach my $key (keys %config) {
27             $self->config->{$key} = $config{$key};
28             }
29             }
30              
31             has config => (
32             is => q{ro},
33             required => 1,
34             isa => q{HashRef}
35             );
36              
37             my %default_lazy = (
38             required => 1,
39             lazy => 1,
40             is => q{ro},
41             default => sub { die "need to override" },
42             );
43              
44             has data => (
45             is => q{ro},
46             required => 1,
47             isa => q{HashRef}
48             );
49              
50             has filename => (
51             is => q{ro},
52             required => 1,
53             isa => q{Str}
54             );
55              
56             has index => (
57             is => q{ro},
58             required => 1,
59             isa => q{Int}
60             );
61              
62             has id => (
63             %default_lazy,
64             isa => q{Str},
65             default => sub {
66             my $self = shift;
67             if (exists $self->data->{ID}) {
68             return $self->data->{ID};
69             } else {
70             my $id = $self->name;
71             $id =~ s/ /_/g;
72             return lc($id);
73             }
74             }
75             );
76              
77             has name => (
78             %default_lazy,
79             isa => q{Str},
80             default => sub {
81             my $self = shift;
82             return $self->data->{NAME};
83             }
84             );
85              
86             has summary => (
87             %default_lazy,
88             isa => q{Str},
89             default => sub {
90             my $self = shift;
91             return $self->data->{SUMMARY};
92             }
93             );
94              
95             has tags => (
96             %default_lazy,
97             isa => q{ArrayRef},
98             default => sub {
99             my $self = shift;
100             if (ref $self->data->{TAGS} eq 'ARRAY') {
101             return [@{ $self->data->{TAGS} }];
102             }
103             return [];
104             }
105             );
106              
107             sub hasTags {
108             my $self = shift;
109             my $truth = 1;
110             foreach my $tag (@_) {
111             #warn "Inspecting tag $tag against " . join(", ", @{ $self->tags }) . "\n";
112             $truth = 0 unless (grep {$_ eq $tag} @{ $self->tags });
113             }
114             #warn "Returning truth $truth\n";
115             return $truth;
116             }
117              
118             has configuration => (
119             %default_lazy,
120             isa => q{ArrayRef},
121             default => sub {
122             my $self = shift;
123             if (ref $self->data->{CONFIGURATION} eq 'ARRAY') {
124             return [@{ $self->data->{CONFIGURATION} }];
125             }
126             return [];
127             }
128             );
129              
130             has instructions => (
131             %default_lazy,
132             isa => q{ArrayRef},
133             default => sub {
134             my $self = shift;
135             if (ref $self->data->{INSTRUCTIONS} eq 'ARRAY') {
136             return [@{ $self->data->{INSTRUCTIONS} }];
137             }
138             return [];
139             }
140             );
141              
142             has expected => (
143             %default_lazy,
144             isa => q{ArrayRef},
145             default => sub {
146             my $self = shift;
147             if (ref $self->data->{EXPECTED} eq 'ARRAY') {
148             return [@{ $self->data->{EXPECTED} }];
149             }
150             return [];
151             }
152             );
153              
154             has preconditions => (
155             %default_lazy,
156             isa => q{ArrayRef},
157             default => sub {
158             my $self = shift;
159             if (ref $self->data->{PRECONDITIONS} eq 'ARRAY') {
160             return [@{ $self->data->{PRECONDITIONS} }];
161             }
162             return [];
163             }
164             );
165              
166             has postconditions => (
167             %default_lazy,
168             isa => q{ArrayRef},
169             default => sub {
170             my $self = shift;
171             if (ref $self->data->{POSTCONDITIONS} eq 'ARRAY') {
172             return [@{ $self->data->{POSTCONDITIONS} }];
173             }
174             return [];
175             }
176             );
177              
178             has is_valid => (
179             %default_lazy,
180             isa => q{Bool},
181             default => sub {
182             my $self = shift;
183             my $length = @{ $self->test_data };
184             return $length > 0;
185             }
186             );
187              
188             has test_data => (
189             %default_lazy,
190             isa => q{ArrayRef},
191             default => sub {
192             my $self = shift;
193             return $self->parse_data([
194             @{ $self->preconditions },
195             @{ $self->instructions },
196             @{ $self->postconditions },
197             ]);
198             }
199             );
200              
201             sub parse_data {
202             my $self = shift;
203             my ($data) = @_;
204             my @tests = ();
205             foreach my $test (@$data) {
206             # Handle single-string tests
207             if (!ref($test)) {
208             push @tests, [$test];
209             }
210              
211             # Handle hash tests
212             elsif (ref($test) eq 'HASH') {
213             my ($name) = keys %$test;
214             my ($value) = $test->{$name};
215             push @tests, [$name, $value];
216             }
217              
218             else {
219             die "Unable to parse structure of type '".ref($test)."'";
220             }
221             }
222             return \@tests;
223             }
224              
225             # unimport moose functions and make immutable
226             no Moose;
227             __PACKAGE__->meta->make_immutable();
228             1;
229              
230             =pod
231              
232             =head1 NAME
233              
234             Test::A8N::TestCase - Storytest testcase object
235              
236             =head1 SYNOPSIS
237              
238             my $tc = Test::A8N::TestCase->new({
239             data => [ ... ],
240             index => ++$idx,
241             filename => "cases/test1.tc",
242             });
243              
244             =head1 DESCRIPTION
245              
246             This represents an individual testcase within a test file. It encapsulates
247             the logic around parsing test instructions, sorting them and processing
248             their arguments in such a way that they are readable by
249             L<Test::FITesque::Test>.
250              
251             =head1 METHODS
252              
253             =head2 Data Accessors
254              
255             =over 4
256              
257             =item id
258              
259             Returns the C<ID> property from the testcase data. If none is supplied, it
260             generates an ID from the testcase L</name> property.
261              
262             =item name
263              
264             Returns the C<NAME> property from the testcase data.
265              
266             =item summary
267              
268             Returns the C<SUMMARY> property from the testcase data.
269              
270             =item tags
271              
272             Returns an array of the C<TAGS> list from the testcase data. An example of
273             the expected syntax is:
274              
275             TAGS:
276             - clustering
277             - smoke
278              
279             =item expected
280              
281             Returns an array of the C<EXPECTED> list from the testcase data.
282              
283             =item configuration
284              
285             Returns an array of the C<CONFIGURATION> list from the testcase data. This
286             can be used by fixtures to load additional configuration that may be needed
287             to run your test.
288              
289             =item preconditions
290              
291             Returns an array of the C<PRECONDITIONS> list, used by L</test_data> to
292             compose a list of fixture calls.
293              
294             =item postconditions
295              
296             Returns an array of the C<POSTCONDITIONS> list, used by L</test_data> to
297             compose a list of fixture calls.
298              
299             =item instructions
300              
301             Returns an array of the C<INSTRUCTIONS> list, used by L</test_data> to
302             compose a list of fixture calls.
303              
304             =back
305              
306             =head2 Object Methods
307              
308             =over 4
309              
310             =item data
311              
312             Returns the raw datastructure of the YAML file.
313              
314             =item test_data
315              
316             Assembles the results from L</preconditions>, L</instructions>, and
317             L</postconditions> and, using L</parse_data>, returns a data structure that
318             L<Test::FITesque::Test> can process.
319              
320             =item parse_data
321              
322             Scrubs the arguments to test statements into a format that
323             L<Test::FITesque::Test> can process.
324              
325             =back
326              
327             =head1 SEE ALSO
328              
329             L<Test::A8N::File>
330              
331             =head1 AUTHORS
332              
333             Michael Nachbaur E<lt>mike@nachbaur.comE<gt>,
334             Scott McWhirter E<lt>konobi@cpan.orgE<gt>
335              
336             =head1 LICENSE
337              
338             This library is free software; you can redistribute it and/or modify
339             it under the same terms as Perl itself, either Perl version 5.8.7 or,
340             at your option, any later version of Perl 5 you may have available.
341              
342             =head1 COPYRIGHT
343              
344             Copyright (C) 2008 Sophos, Plc.
345              
346             =cut