File Coverage

blib/lib/Outhentic.pm
Criterion Covered Total %
statement 18 208 8.6
branch 0 112 0.0
condition n/a
subroutine 6 16 37.5
pod n/a
total 24 336 7.1


line stmt bran cond sub pod time code
1             package Outhentic;
2              
3             our $VERSION = '0.0.3';
4              
5             1;
6              
7             package main;
8              
9 1     1   24573 use strict;
  1         2  
  1         29  
10 1     1   5 use Test::More;
  1         2  
  1         6  
11 1     1   1209 use Data::Dumper;
  1         10162  
  1         66  
12 1     1   1170 use File::Temp qw/ tempfile /;
  1         23685  
  1         63  
13 1     1   519 use Outhentic::Story;
  1         3  
  1         1821  
14              
15             $| = 1;
16              
17             sub execute_cmd {
18 0     0     my $cmd = shift;
19 0 0         diag("execute cmd: $cmd") if debug_mod2();
20 0           (system($cmd) == 0);
21             }
22              
23             sub run_story_file {
24              
25 0 0   0     return get_prop('stdout') if defined get_prop('stdout');
26              
27 0           my ($fh, $content_file) = tempfile( DIR => get_prop('test_root_dir') );
28              
29 0 0         if (get_prop('my_stdout')){
30              
31 0           ok(1,"stdout is already set");
32              
33 0 0         open F, ">", $content_file or die $!;
34 0           print F get_prop('my_stdout');
35 0           close F;
36 0           ok(1, "stdout saved to $content_file");
37              
38             }else{
39              
40 0           my $story_file = get_prop('story_file');
41              
42 0           my $st = execute_cmd("perl $story_file 1>$content_file 2>&1 && test -f $content_file");
43              
44 0 0         if ($st) {
    0          
45 0           ok(1, "perl $story_file succeeded");
46             }elsif(ignore_story_err()){
47 0           ok(1, "perl $story_file failed, still continue due to ignore_story_err enabled");
48             }else{
49 0           ok(0, "perl $story_file succeeded");
50 0 0         open CNT, $content_file or die $!;
51 0           my $rdata = join "", ;
52 0           close CNT;
53 0           diag("perl $story_file \n===>\n$rdata");
54             }
55              
56 0           ok(1,"stdout saved to $content_file");
57              
58             }
59              
60 0 0         open F, $content_file or die $!;
61 0           my $cont = '';
62 0           $cont.= $_ while ;
63 0           close F;
64              
65 0           set_prop( stdout => $cont );
66              
67 0           my $debug_bytes = get_prop('debug_bytes');
68              
69 0 0         diag `head -c $debug_bytes $content_file` if debug_mod2();
70              
71 0           return get_prop('stdout');
72             }
73              
74             sub populate_context {
75              
76 0 0   0     return if context_populated();
77              
78 0           my $data = shift;
79 0           my $i = 0;
80              
81 0           my $context = [];
82              
83 0           for my $l ( split /\n/, $data ){
84 0           chomp $l;
85 0           $i++;
86 0 0         $l=":blank_line" unless $l=~/\S/;
87 0           push @$context, [$l, $i];
88             }
89              
90 0           set_prop('context',$context);
91 0           set_prop('context_local',$context);
92              
93 0 0         diag("context populated") if debug_mod2();
94              
95 0           set_prop(context_populated => 1);
96              
97             }
98              
99             sub check_line {
100              
101 0     0     my $pattern = shift;
102 0           my $check_type = shift;
103 0           my $message = shift;
104 0           my $status = 0;
105              
106              
107 0           reset_captures();
108 0           my @captures;
109              
110 0           populate_context( run_story_file() );
111              
112 0 0         diag("lookup $pattern ...") if debug_mod2();
113              
114 0           my @context = @{get_prop('context')};
  0            
115 0           my @context_local = @{get_prop('context_local')};
  0            
116 0           my @context_new = ();
117              
118 0 0         if ($check_type eq 'default'){
    0          
119 0           for my $c (@context_local){
120 0           my $ln = $c->[0]; my $next_i = $c->[1];
  0            
121 0 0         if ( index($ln,$pattern) != -1){
122 0           $status = 1;
123 0           push @context_new, $context[$next_i];
124             }
125             }
126             }elsif($check_type eq 'regexp'){
127 0           for my $c (@context_local){
128 0           my $re = qr/$pattern/;
129 0           my $ln = $c->[0]; my $next_i = $c->[1];
  0            
130              
131 0           my @foo = ($ln =~ /$re/g);
132              
133 0 0         if (scalar @foo){
134 0           push @captures, [@foo];
135 0           $status = 1;
136 0           push @context_new, $context[$next_i];
137             }
138             }
139             }else {
140 0           die "unknown check_type: $check_type";
141             }
142              
143 0           ok($status,$message);
144              
145              
146 0 0         if (debug_mod2()){
147 0           my $k=0;
148 0           for my $ce (@captures){
149 0           $k++;
150 0           diag "captured item N $k";
151 0           for my $c (@{$ce}){
  0            
152 0           diag("\tcaptures: $c");
153             }
154             }
155             }
156              
157 0           set_prop( captures => [ @captures ] );
158              
159 0 0         if (in_block_mode()){
160 0           set_prop( context_local => [@context_new] );
161             }
162              
163             return
164              
165 0           }
166              
167              
168             sub header {
169              
170 0 0   0     if (debug_mod12()) {
171              
172 0           my $project = get_prop('project_root_dir');
173 0           my $story = get_prop('story');
174 0           my $story_type = get_prop('story_type');
175 0           my $story_file = get_prop('story_file');
176 0           my $debug = get_prop('debug');
177 0           my $ignore_story_err = ignore_story_err();
178              
179 0           ok(1, "project: $project");
180 0           ok(1, "story: $story");
181 0           ok(1, "story_type: $story_type");
182 0           ok(1, "debug: $debug");
183 0           ok(1, "ignore story errors: $ignore_story_err");
184             }
185             }
186              
187             sub generate_asserts {
188              
189 0     0     my $filepath_or_array_ref = shift;
190 0           my $write_header = shift;
191              
192 0 0         header() if $write_header;
193              
194 0           my @ents;
195             my @ents_ok;
196 0           my $ent_type;
197              
198 0 0         if ( ref($filepath_or_array_ref) eq 'ARRAY') {
199 0           @ents = @$filepath_or_array_ref
200             }else{
201 0 0         return unless $filepath_or_array_ref;
202 0 0         open my $fh, $filepath_or_array_ref or die $!;
203 0           while (my $l = <$fh>){
204 0           push @ents, $l
205             }
206 0           close $fh;
207             }
208              
209              
210              
211 0           ENTRY: for my $l (@ents){
212              
213 0           chomp $l;
214 0 0         diag $l if runner_debug();
215              
216 0 0         next ENTRY unless $l =~ /\S/; # skip blank lines
217              
218 0 0         if ($l=~ /^\s*#(.*)/) { # skip comments
219 0           next ENTRY;
220             }
221              
222 0 0         if ($l=~ /^\s*begin:\s*$/) { # begin: block marker
223 0 0         diag("begin: block") if debug_mod2();
224 0           set_block_mode();
225 0           next ENTRY;
226             }
227 0 0         if ($l=~ /^\s*end:\s*$/) { # end: block marker
228 0           unset_block_mode();
229 0           populate_context( run_story_file() );
230 0 0         diag("end: block") if debug_mod2();
231 0           set_prop( context_populated => 0); # flush current context
232 0           next ENTRY;
233             }
234              
235 0 0         if ($l=~/^\s*code:\s*(.*)/){
    0          
    0          
    0          
236 0 0         die "unterminated entity found: $ents_ok[-1]" if defined($ent_type);
237 0           my $code = $1;
238 0 0         if ($code=~s/\\\s*$//){
239 0           push @ents_ok, $code;
240 0           $ent_type = 'code';
241 0           next ENTRY; # this is multiline, hold this until last line \ found
242             }else{
243 0           undef $ent_type;
244 0           handle_code($code);
245             }
246             }elsif($l=~/^\s*generator:\s*(.*)/){
247 0 0         die "unterminated entity found: $ents_ok[-1]" if defined($ent_type);
248 0           my $code = $1;
249 0 0         if ($code=~s/\\\s*$//){
250 0           push @ents_ok, $code;
251 0           $ent_type = 'generator';
252 0           next ENTRY; # this is multiline, hold this until last line \ found
253             }else{
254 0           undef $ent_type;
255 0           handle_generator($code);
256             }
257              
258             }elsif($l=~/^\s*regexp:\s*(.*)/){
259 0 0         die "unterminated entity found: $ents_ok[-1]" if defined($ent_type);
260 0           my $re=$1;
261 0           undef $ent_type;
262 0           handle_regexp($re);
263             }elsif(defined($ent_type)){
264 0 0         if ($l=~s/\\\s*$//) {
265 0           push @ents_ok, $l;
266 0           next ENTRY; # this is multiline, hold this until last line \ found
267             }else {
268              
269 1     1   6 no strict 'refs';
  1         1  
  1         708  
270 0           my $name = "handle_"; $name.=$ent_type;
  0            
271 0           push @ents_ok, $l;
272 0           &$name(\@ents_ok);
273              
274 0           undef $ent_type;
275 0           @ents_ok = ();
276              
277             }
278             }else{
279 0           s{#.*}[], s{\s+$}[], s{^\s+}[] for $l;
280 0           undef $ent_type;
281 0           handle_plain($l);
282             }
283             }
284              
285 0 0         die "unterminated entity found: $ents_ok[-1]" if defined($ent_type);
286              
287             }
288              
289             sub handle_code {
290              
291 0     0     my $code = shift;
292              
293 0 0         unless (ref $code){
294 0           eval $code;
295 0 0         die "code entry eval perl error, code:$code , error: $@" if $@;
296 0 0         diag "handle_code OK. $code" if runner_debug();
297             } else {
298 0           my $code_to_eval = join "\n", @$code;
299 0           eval $code_to_eval;
300 0 0         die "code entry eval error, code:$code_to_eval , error: $@" if $@;
301 0 0         diag "handle_code OK. multiline. $code_to_eval" if runner_debug();
302             }
303              
304             }
305              
306             sub handle_generator {
307              
308 0     0     my $code = shift;
309 0 0         unless (ref $code){
310 0           my $arr_ref = eval $code;
311 0 0         die "generator entry eval error, code:$code , error: $@" if $@;
312 0 0         diag "handle_generator OK. $code" if runner_debug();
313 0           generate_asserts($arr_ref,0);
314             } else {
315 0           my $code_to_eval = join "\n", @$code;
316 0           my $arr_ref = eval $code_to_eval;
317 0 0         die "generator entry eval error, code:$code_to_eval , error: $@" if $@;
318 0 0         diag "handle_generator OK. multiline. $code_to_eval" if runner_debug();
319 0           generate_asserts($arr_ref,0);
320             }
321              
322             }
323              
324             sub handle_regexp {
325              
326 0     0     my $re = shift;
327              
328 0           my $story = get_prop('story');
329              
330 0 0         my $message = in_block_mode() ? "$story stdout matches the | $re" : "$story stdout matches the $re";
331 0           check_line($re, 'regexp', $message);
332 0 0         diag "handle_regexp OK. $re" if runner_debug();
333              
334             }
335              
336             sub handle_plain {
337              
338 0     0     my $l = shift;
339              
340 0           my $story = get_prop('story');
341              
342 0 0         my $message = in_block_mode() ? "$story stdout has | $l" : "$story stdout has $l";
343 0           check_line($l, 'default', $message);
344 0 0         diag "handle_plain OK. $l" if runner_debug();
345             }
346              
347              
348             1;
349              
350              
351             __END__