114 / 114 lines covered (100.0%)
1use BDD::Behave::Colors;2use BDD::Behave::Failures;3use BDD::Behave::Formatter;45unit class BDD::Behave::Formatter::Tree does BDD::Behave::Formatter;67has Int $!indent = 0;8has Int $!failures-printed = 0;910method name(--> Str) { 'tree' }1112method print-indent {13 print ' ' x $!indent;14}1516method suite-loading(Str :$file) {17 say "\nLoading: $file";18}1920method suite-start($suite, Bool :$multi-file = False) {21 return unless $multi-file;22 say "\n" ~ light-blue($suite.file.basename);23}2425method group-start($group) {26 self.print-indent;27 say light-blue('⮑') ~ " " ~ yellow("'{$group.description}'");28 $!indent++;29}3031method group-end($group) {32 $!indent--;33}3435method group-around-skipped($group) {36 self.print-indent;37 say light-blue('⮑') ~ " " ~ light-blue('SKIPPED (around-all did not invoke continuation)');38}3940method example-start($example, Bool :$auto = False) {41 return if $auto;42 self.print-indent;43 say light-blue('⮑') ~ " " ~ yellow("'{$example.description}'");44}4546method example-auto-description($example, Str :$description) {47 self.print-indent;48 say light-blue('⮑') ~ " " ~ yellow("'{$description}'");49}5051method example-pass($example) {52 self.print-indent;53 say " " ~ light-blue('⮑') ~ " " ~ green('SUCCESS');54}5556method example-fail($example, :$failure-info) {57 self.print-indent;58 say " " ~ light-blue('⮑') ~ " " ~ red('FAILURE');59}6061method example-pending($example) {62 self.print-indent;63 say light-blue('⮑') ~ " " ~ yellow("'{$example.description}'");64 self.print-indent;65 say " " ~ light-blue('⮑') ~ " " ~ light-blue('PENDING');66}6768method example-skipped($example) {69 self.print-indent;70 say light-blue('⮑') ~ " " ~ yellow("'{$example.description}'");71 self.print-indent;72 say " " ~ light-blue('⮑') ~ " " ~ light-blue('SKIPPED');73}7475method example-around-skipped($example) {76 self.print-indent;77 say light-blue('⮑') ~ " " ~ yellow("'{$example.description}'");78 self.print-indent;79 say " " ~ light-blue('⮑') ~ " " ~ light-blue('SKIPPED (around-each did not invoke continuation)');80}8182method example-retry($example, Int :$attempt, Int :$max-attempts) {83 self.print-indent;84 say " " ~ light-blue('⮑') ~ " " ~ yellow("RETRY (attempt $attempt of $max-attempts)");85}8687method example-slow($example, Real :$threshold) {88 self.print-indent;89 say " " ~ light-blue('⮑') ~ " " ~ yellow(sprintf 'SLOW (%.3fs, threshold %.3fs)',90 $example.duration, $threshold);91}9293method run-summary(94 $result,95 Bool :$aborted = False,96 Int :$fail-fast = 0,97 Str :$order = 'defined',98 Int :$seed,99 Bool :$show-seed = False,100) {101 say '';102103 Failures.say(:from($!failures-printed));104 $!failures-printed = Failures.list.elems;105106 my $total-msg = "{$result.total} example" ~ ($result.total == 1 ?? '' !! 's');107 my $failed-msg = $result.failed > 0 ?? red("{$result.failed} failed") !! '';108 my $pending-msg = $result.pending > 0 ?? light-blue("{$result.pending} pending") !! '';109 my $skipped-msg = $result.skipped > 0 ?? light-blue("{$result.skipped} skipped") !! '';110 my $passed-msg = $result.passed > 0 ?? green("{$result.passed} passed") !! '';111112 my @parts = ($total-msg, $failed-msg, $pending-msg, $skipped-msg, $passed-msg).grep(*.so);113 say @parts.join(', ');114115 if $aborted {116 my $word = $fail-fast == 1 ?? 'failure' !! 'failures';117 say red("Aborted after $fail-fast $word (--fail-fast)");118 }119120 if $order eq 'random' && $seed.defined && ($show-seed || $result.failed > 0) {121 say "Randomized with seed $seed";122 }123}124125method profile-summary(@records, Int :$limit) {126 return unless $limit > 0;127 return unless @records.elems;128129 my @sorted = @records.sort({ -$^a<duration> });130 my @top = @sorted[0 ..^ ($limit min @sorted.elems)];131132 my $total = @top.map(*<duration>).sum;133 my $shown = @top.elems;134 say '';135 say "Top $shown slowest example" ~ ($shown == 1 ?? '' !! 's')136 ~ " ({sprintf '%.3f', $total}s total):";137138 for @top -> $rec {139 my $ex = $rec<example>;140 my $loc = $ex.defined ?? "{$ex.file}:{$ex.line}" !! '';141 say sprintf ' %.3fs %s', $rec<duration>, $rec<description>;142 say " $loc" if $loc.chars;143 }144}145146method retry-summary(@records) {147 return unless @records.elems;148 say '';149 my $word = @records.elems == 1 ?? 'example' !! 'examples';150 say yellow("Retried " ~ @records.elems ~ " $word:");151 for @records -> $rec {152 my $color = $rec.outcome eq 'pass' ?? &green !! &red;153 my $tag = $rec.outcome eq 'pass' ?? 'PASS' !! 'FAIL';154 my $word2 = $rec.attempts == 1 ?? 'attempt' !! 'attempts';155 say ' ' ~ $color("[$tag]") ~ ' ' ~ $rec.description156 ~ ' ' ~ yellow("({$rec.attempts}/{$rec.max-attempts} $word2)");157 say ' ' ~ $rec.location;158 }159}160161method benchmark-summary-section(162 @summaries, @regressions,163 Real :$threshold,164 Str :$format,165 IO::Path :$output,166 :$runner,167) {168 return unless @summaries.elems;169 my $rendered = $runner.render-benchmark-output(170 @summaries, @regressions,171 :$threshold, :$format,172 );173 if $output.defined {174 $output.spurt: $rendered ~ "\n";175 } else {176 say '';177 print $rendered;178 say '' unless $rendered.ends-with("\n");179 }180}181182method multi-file-overall(183 $result,184 Str :$order = 'defined',185 Int :$seed,186 Bool :$show-seed = False,187) {188 say "\n" ~ "=" x 60;189 say "Overall: {$result.total} example" ~ ($result.total == 1 ?? '' !! 's');190 say red(" {$result.failed} failed") if $result.failed > 0;191 say light-blue(" {$result.pending} pending") if $result.pending > 0;192 say light-blue(" {$result.skipped} skipped") if $result.skipped > 0;193 say green(" {$result.passed} passed") if $result.passed > 0;194 say "Randomized with seed $seed"195 if $order eq 'random' && $seed.defined && ($show-seed || $result.failed > 0);196}197198method multi-file-profile($runner, @records, Int :$limit) {199 self.profile-summary(@records, :$limit);200}201202method multi-file-benchmark(203 $runner,204 @summaries, @regressions,205 Real :$threshold,206 Str :$format,207 IO::Path :$output,208) {209 self.benchmark-summary-section(210 @summaries, @regressions,211 :$threshold, :$format, :$output, :$runner,212 );213}214215method load-errors(@errors) {216 return unless @errors.elems;217 say "\n" ~ red("Load errors ({@errors.elems}):");218 for @errors -> $err {219 say red(" ✗ ") ~ $err<file>;220 for $err<message>.lines -> $line {221 say " $line";222 }223 }224}