File Coverage

blib/lib/Test/Story/File.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::File;
2 1     1   53111 use Moose;
  0            
  0            
3             use YAML qw(LoadFile);
4             use Test::Story::TestCase;
5             use Module::Load;
6             use Storable qw(dclone);
7              
8             has config => (
9             is => q{ro},
10             required => 1,
11             isa => q{HashRef}
12             );
13              
14             my %default_lazy = (
15             required => 1,
16             lazy => 1,
17             is => q{ro},
18             default => sub { die "need to override" },
19             );
20              
21             has filename => (
22             is => q{ro},
23             required => 1,
24             isa => q{Str}
25             );
26              
27             has file_root => (
28             %default_lazy,
29             isa => q{Str},
30             default => sub { return shift->config->{file_root} },
31             );
32              
33             has fixture_base => (
34             %default_lazy,
35             isa => q{Str},
36             default => sub { return shift->config->{fixture_base} },
37             );
38              
39             has verbose => (
40             %default_lazy,
41             isa => q{Int},
42             default => sub { return shift->config->{verbose} },
43             );
44              
45             has data => (
46             %default_lazy,
47             isa => q{ArrayRef},
48             default => sub {
49             my $self = shift;
50             my $content = [];
51             eval {
52             $content = [ LoadFile($self->filename) ];
53             };
54             if ($@) {
55             printf("# YAML syntax error while loading %s: %s\n", $self->filename, $@) if ($self->verbose);
56             }
57             return $content;
58             }
59             );
60              
61             has testcase_class => (
62             %default_lazy,
63             isa => q{Str},
64             default => "Test::Story::TestCase"
65             );
66              
67             has cases => (
68             %default_lazy,
69             isa => q{ArrayRef},
70             default => sub {
71             my $self = shift;
72             my @cases;
73             my $idx = 0;
74             my $filename = $self->filename;
75             foreach my $case (@{ $self->data }) {
76             next unless $case;
77             my $case = $self->testcase_class->new({
78             'data' => $case,
79             'index' => ++$idx,
80             'filename' => $filename,
81             'config' => dclone( $self->config ),
82             });
83             push @cases, $case if ($case->is_valid);
84             }
85             return \@cases;
86             }
87             );
88              
89             sub filtered_cases {
90             my $self = shift;
91             my ($id) = @_;
92              
93             my @cases = @{ $self->cases };
94             if (@{ $self->config->{'tags'}->{'include'} }) {
95             @cases = grep { $_->hasTags(@{ $self->config->{'tags'}->{'include'} }) } @cases;
96             }
97             if (@{ $self->config->{'tags'}->{'exclude'} }) {
98             my @filtered_cases = ();
99             CASE: foreach my $case (@cases) {
100             foreach my $tag (@{ $self->config->{'tags'}->{'exclude'} }) {
101             next CASE if ($case->hasTags($tag));
102             }
103             push @filtered_cases, $case;
104             }
105             @cases = @filtered_cases;
106             }
107             if ($id) {
108             @cases = grep { $_->id eq $id } @cases;
109             }
110             return \@cases;
111             }
112              
113             has fixture_class => (
114             %default_lazy,
115             isa => q{Str},
116             default => sub {
117             my $self = shift;
118             local @INC = @INC;
119             unless (grep $self->fixture_base, @INC) {
120             unshift @INC, $self->fixture_base;
121             }
122             my $filename = $self->filename;
123             my $root = $self->file_root;
124             $filename =~ s#^$root/?##;
125             $filename =~ s/\s+//g;
126             my @path = split('/', $filename);
127             pop @path; # take off the filename
128             unshift @path, split(/::/, $self->fixture_base);
129              
130             while ($#path > -1) {
131             my $class = join('::', @path);
132             print "# Attempting to load fixture class $class\n" if ($self->verbose > 2);
133             eval {
134             load($class);
135             };
136             unless ($@) {
137             return $class;
138             }
139             if ($@ !~ /^Can't locate /) {
140             warn "Error while loading fixture $class: $@\n";
141             }
142             pop @path;
143             }
144             die 'Cannot find a fixture class for "' . $self->filename . '"';
145             }
146             );
147              
148             sub BUILD {
149             my $self = shift;
150             my ($params) = @_;
151              
152             if (!-f $self->filename){
153             die 'Could not find a8n file "' . $self->filename . '"';
154             }
155             }
156              
157             # unimport moose functions and make immutable
158             no Moose;
159             __PACKAGE__->meta->make_immutable();
160             1;
161              
162             =pod
163              
164             =head1 NAME
165              
166             Test::Story::File - Storytest file object
167              
168             =head1 SYNOPSIS
169              
170             my $file = Test::Story::File->new({
171             filename => "cases/test1.tc",
172             file_root => $a8n->file_root,
173             fixture_base => $a8n->fixture_base,
174             });
175             $file->run_tests();
176              
177             =head1 DESCRIPTION
178              
179             This class is used to represent and run tests within individual storytest
180             files. For more information, please see L<Test::Story>.
181              
182             =head1 METHODS
183              
184             =head2 Accessors
185              
186             =over 4
187              
188             =item filename
189              
190             The filename that this object is supposed to represent.
191              
192             =item fixture_base
193              
194             See L<Test::Story/fixture_base>.
195              
196             =item file_root
197              
198             See L<Test::Story/file_root>.
199              
200             =item verbose
201              
202             See L<Test::Story/verbose>.
203              
204             =item testcase_class
205              
206             Used to set the class used to store testcases.
207              
208             Default: L<Test::Story::TestCase>
209              
210             =back
211              
212             =head2 Object Methods
213              
214             =over 4
215              
216             =item run_tests
217              
218             This iterates over each of the L</cases> and will create a
219             L<Test::FITesque::Test> test runner for test case. If you call this method
220             with a testcase ID, it will only run that one testcase.
221              
222             =item data
223              
224             Returns the raw datastructure of the YAML file.
225              
226             =item cases
227              
228             Returns objects representing each testcase within this test file. Unless
229             L</testcase_class> is overridden, this property returns instances of the
230             L<Test::Story::TestCase> class.
231              
232             =item fixture_class
233              
234             This locates the fixture class used to run testcases. The resulting class
235             is called whenever a test action needs to be run.
236              
237             If the L</filename> of this test is one or more sub-directories below the
238             L</file_root>, then it will append the directory name to the
239             L</fixture_base>, and will use it as part of the class name. It works its
240             way up the directory hierarchy until it finds a valid Perl class. If no
241             such classes can be found, it will use the value of L</fixture_base>.
242              
243             =back
244              
245             =head1 SEE ALSO
246              
247             L<Test::Story::TestCase>, L<Test::FITesque::Test>
248              
249             =head1 AUTHORS
250              
251             Michael Nachbaur E<lt>mike@nachbaur.comE<gt>,
252             Scott McWhirter E<lt>konobi@cpan.orgE<gt>
253              
254             =head1 LICENSE
255              
256             This library is free software; you can redistribute it and/or modify
257             it under the same terms as Perl itself, either Perl version 5.8.7 or,
258             at your option, any later version of Perl 5 you may have available.
259              
260             =head1 COPYRIGHT
261              
262             Copyright (C) 2008 Sophos, Plc.
263              
264             =cut