File Coverage

blib/lib/Test/Kantan/Reporter/Spec.pm
Criterion Covered Total %
statement 118 177 66.6
branch 9 36 25.0
condition 3 14 21.4
subroutine 32 42 76.1
pod 0 17 0.0
total 162 286 56.6


line stmt bran cond sub pod time code
1             package Test::Kantan::Reporter::Spec;
2 3     3   2132 use strict;
  3         6  
  3         118  
3 3     3   16 use warnings;
  3         7  
  3         79  
4 3     3   23 use utf8;
  3         6  
  3         23  
5 3     3   113 use 5.010_001;
  3         10  
  3         128  
6 3     3   3496 use Term::ANSIColor ();
  3         25056  
  3         128  
7 3     3   3350 use IO::Handle;
  3         21565  
  3         148  
8              
9 3     3   22 use Moo;
  3         7  
  3         23  
10              
11             extends 'Test::Kantan::Reporter::Base';
12              
13             has messages => (is => 'ro', default => sub { +[] });
14             has message_groups => (is => 'ro', default => sub { +[] });
15             has message_stack => (is => 'ro', default => sub { +[] });
16              
17 3     3   1176 no Moo;
  3         5  
  3         14  
18              
19             our $UTF8;
20              
21 3     3   3089 use Scope::Guard;
  3         1218  
  3         3473  
22              
23             sub start {
24 3     3 0 6 my $self = shift;
25              
26 3         6 my $encoding = do {
27 3         2708 require Term::Encoding;
28 3         1788 Term::Encoding::get_encoding();
29             };
30              
31 3 50 33     4743 $UTF8 = ($encoding =~ /utf-?8/i && !$ENV{KANTAN_ASCII}) ? 1 : 0;
32              
33 3     3   2781 binmode *STDOUT, ":encoding(${encoding})";
  3         34  
  3         18  
  3         80  
34 3         42017 STDOUT->autoflush(1);
35              
36 3         181 $self->{root_suite} = $self->suite('');
37              
38 3         221 print "\n\n";
39             }
40              
41             sub colored {
42 0     0 0 0 my ($self, $color, $msg) = @_;
43 0 0       0 $self->color ? Term::ANSIColor::colored($color, $msg) : $msg;
44             }
45              
46             sub head_sp {
47 3     3 0 6 my ($self) = @_;
48 3         614 return ' ' x (2+($self->{level}-1)*2);
49             }
50              
51             sub suite {
52 6     6 0 15 my ($self, $title) = @_;
53              
54 6 100       28 if (length($title) > 0) {
55 3 100       181 print "\n" if $self->{level} <= 2;
56 3         12 printf "%s%s\n", $self->head_sp, $title;
57             }
58              
59 6         14 push @{$self->{message_stack}}, [];
  6         63  
60 6         15 push @{$self->{fail_stack}}, $self->state->fail_cnt;
  6         69  
61 6         13 push @{$self->{title}}, $title;
  6         19  
62 6         15 $self->{level}++;
63             return Scope::Guard->new(
64             sub {
65 5     5   43 my $orig_fail_cnt = pop @{$self->{fail_stack}};
  5         16  
66 5         9 my $messages = pop @{$self->{message_stack}};
  5         13  
67 5         10 my $titles = [@{$self->{title}}];
  5         17  
68 5 50 33     36 if ($orig_fail_cnt != $self->state->fail_cnt && @$messages) {
69 0         0 push @{$self->{message_groups}}, Test::Kantan::Reporter::Spec::MessageGroup->new(
  0         0  
70             titles => $titles,
71             messages => $messages,
72             );
73             }
74              
75 5         6 pop @{$self->{title}};
  5         10  
76              
77 5         98 --$self->{level};
78             }
79 6         65 );
80             }
81              
82             sub step {
83 0     0 0 0 my ($self, $title) = @_;
84              
85 0 0       0 if (length($title) > 0) {
86 0         0 printf "%s%s\n", $self->head_sp, $title;
87             }
88             }
89              
90             sub fail {
91 0     0 0 0 my ($self, %args) = @_;
92 0         0 $self->message(Test::Kantan::Reporter::Spec::Message::Fail->new(
93             reporter => $self,
94             %args
95             ));
96             }
97              
98             sub pass {
99 3     3 0 12 my ($self, %args) = @_;
100 3         55 $self->message(Test::Kantan::Reporter::Spec::Message::Pass->new(
101             reporter => $self,
102             %args
103             ));
104             }
105              
106             sub message {
107 4     4 0 4311 my ($self, $message) = @_;
108 4         7 push @{$self->{message_stack}->[-1]}, $message;
  4         35  
109             }
110              
111             sub exception {
112 0     0 0 0 my ($self, %args) = @_;
113 0         0 $self->message(Test::Kantan::Reporter::Spec::Message::Exception->new(
114             reporter => $self,
115             %args
116             ));
117             }
118              
119             sub diag {
120 1     1 0 4 my ($self, %args) = @_;
121              
122 1         12 $self->message(Test::Kantan::Reporter::Spec::Message::Diag->new(
123             reporter => $self,
124             %args
125             ));
126             }
127              
128             sub finalize {
129 2     2 0 6 my ($self, %args) = @_;
130              
131 2         13 delete $self->{root_suite};
132              
133 2 50 33     16 if (!$self->state->is_passing || $ENV{KANTAN_VERBOSE}) {
134 0 0       0 if (@{$self->{message_groups}}) {
  0         0  
135 0         0 printf "\n\n\n %s:\n", $self->colored(['red'], '(Diagnostic message)');
136 0         0 for my $message_group (@{$self->{message_groups}}) {
  0         0  
137             # Show group title
138             {
139 0         0 print "\n";
  0         0  
140 0         0 my $i=0;
141 0         0 my @titles = @{$message_group->titles};
  0         0  
142 0         0 shift @titles; # Remove root
143 0         0 for my $title (@titles) {
144 0 0       0 printf(" %s%s%s\n", (' ' x ($i++*2)),
145             $self->colored(['green'], $title),
146             $i==@titles ? ':' : ''
147             );
148             }
149             }
150              
151 0         0 for my $message (@{$message_group->messages}) {
  0         0  
152 0         0 my $str = $message->render();
153 0         0 $str =~ s/^/ /mg;
154 0         0 print "\n$str";
155             }
156             }
157             }
158             }
159              
160             # If Test::Builder was loaded...
161 2 50       28 if (Test::Builder->can('new')) {
162 0 0       0 if (!Test::Builder->new->is_passing) {
163             # Fail if Test::Builder was failed.
164 0         0 $self->state->failed;
165             }
166             }
167              
168 2 50       1642 printf "\n\n%sok\n", $self->state->fail_cnt ? 'not ' : '';
169 2         273 print "1..1\n";
170             }
171              
172              
173             package Test::Kantan::Reporter::Spec::MessageGroup;
174              
175 3     3   21 use Moo;
  3         7  
  3         18  
176              
177             has messages => (is => 'ro');
178             has titles => (is => 'ro');
179              
180 3     3   961 no Moo;
  3         6  
  3         14  
181              
182             package Test::Kantan::Reporter::Spec::Message::Base;
183 3     3   2264 use Test::Kantan::Util ();
  3         6  
  3         56  
184              
185 3     3   18 use Moo;
  3         4  
  3         14  
186              
187             has reporter => (
188             is => 'ro',
189             wek_ref => 1,
190             handles => [qw(colored cutoff)],
191             );
192              
193             has caller => ( is => 'ro' );
194              
195 3     3   880 no Moo;
  3         8  
  3         10  
196              
197             sub render_caller_pos {
198 0     0 0   my ($self) = @_;
199              
200 0   0       return sprintf(
201             " at %s line %s\n",
202             $self->colored(['yellow'], $self->caller->filename // '-'),
203             $self->colored(['yellow'], $self->caller->line)
204             );
205             }
206              
207             sub truncstr {
208 0     0 0   my ($self, $str, $cutoff) = @_;
209 0   0       return Test::Kantan::Util::truncstr($str, $cutoff // $self->reporter->cutoff);
210             }
211              
212             package Test::Kantan::Reporter::Spec::Message::Diag;
213              
214 3     3   1153 use Test::Kantan::Util qw(dump_data);
  3         4  
  3         179  
215              
216 3     3   16 use Moo;
  3         6  
  3         12  
217              
218             extends 'Test::Kantan::Reporter::Spec::Message::Base';
219              
220             has message => ( is => 'ro', required => 1 );
221             has caller => ( is => 'ro', required => 1 );
222             has cutoff => ( is => 'ro', required => 1 );
223              
224 3     3   1022 no Moo;
  3         6  
  3         14  
225              
226             sub render {
227 0     0 0   my ($self, $message) = @_;
228              
229 0           my @ret;
230              
231 0           my $msg = dump_data($self->message);
232 0           $msg =~ s/\n/\\n/g;
233 0 0         push @ret, $self->colored(['magenta'], $Test::Kantan::Reporter::Spec::UTF8 ? "\x{2668}\n" : "#\n");
234 0           push @ret, $self->colored(['magenta on_black'], $self->truncstr($msg, $self->cutoff)) . "\n";
235 0           push @ret, $self->render_caller_pos();
236 0           return join '', @ret;
237             }
238              
239              
240             package Test::Kantan::Reporter::Spec::Message::Fail;
241              
242 3     3   1193 use Moo;
  3         6  
  3         15  
243              
244             extends 'Test::Kantan::Reporter::Spec::Message::Base';
245              
246             has description => ( is => 'ro', required => 0 );
247             has diag => ( is => 'ro', required => 0 );
248             has caller => ( is => 'ro', required => 1 );
249              
250 3     3   942 no Moo;
  3         7  
  3         14  
251              
252             sub render {
253 0     0 0   my ($self) = @_;
254              
255 0           my @ret;
256 0 0         push @ret, sprintf(
257             "%s\n%s\n",
258             $self->colored(['red'], $Test::Kantan::Reporter::Spec::UTF8 ? "\x{2716}" : "x"),
259             $self->colored(['red on_black'], $self->caller->code)
260             );
261 0 0         if (defined $self->description) {
262 0           push @ret, sprintf("%s\n", $self->colored(['red on_black'], $self->description));
263             }
264 0 0         if (defined $self->diag) {
265 0           my $diag = $self->diag;
266 0           $diag =~ s/^/ /mg;
267 0           push @ret, sprintf("%s\n", $self->colored(['red on_black'], $diag));
268             }
269 0           push @ret, $self->render_caller_pos();
270 0           return join('', @ret);
271             }
272              
273              
274             package Test::Kantan::Reporter::Spec::Message::Exception;
275              
276 3     3   1327 use Moo;
  3         7  
  3         12  
277              
278             extends 'Test::Kantan::Reporter::Spec::Message::Base';
279              
280             has message => ( is => 'ro', required => 1 );
281              
282 3     3   949 no Moo;
  3         6  
  3         11  
283              
284             sub render {
285 0     0 0   my ($self) = @_;
286              
287 0           my $msg = $self->truncstr($self->message, 1024);
288 0 0         return join(
289             "\n",
290             $self->colored(['magenta on_black'], $Test::Kantan::Reporter::Spec::UTF8 ? "\x{2620}" : "orz"),
291             $msg,
292             );
293             }
294              
295              
296             package Test::Kantan::Reporter::Spec::Message::Pass;
297              
298 3     3   926 use Moo;
  3         6  
  3         14  
299              
300             extends 'Test::Kantan::Reporter::Spec::Message::Base';
301              
302             has caller => ( is => 'ro' );
303             has description => ( is => 'ro' );
304              
305 3     3   869 no Moo;
  3         6  
  3         10  
306              
307             sub render {
308 0     0 0   my ($self) = @_;
309 0 0         join('',
310             $self->colored(['green'], $Test::Kantan::Reporter::Spec::UTF8 ? "\x{2713}\n" : "o"),
311             $self->caller->code, "\n",
312             $self->render_caller_pos($self)
313             );
314             }
315              
316              
317             1;