File Coverage

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