From ccafdd4cd34f0c3b8552fea8974d892b29bb2a9f Mon Sep 17 00:00:00 2001 From: Anton Bachin Date: Fri, 30 Aug 2019 22:18:41 +0300 Subject: [PATCH] New formatting for the summary report Resolves #243. --- src/report/report.ml | 2 + src/report/report_text.ml | 69 ++++++++++++++++++++++++ src/report/report_text.mli | 6 +-- test/unit/fixtures/report/reference.text | 4 +- 4 files changed, 76 insertions(+), 5 deletions(-) diff --git a/src/report/report.ml b/src/report/report.ml index 7d1d8396..7b49edce 100644 --- a/src/report/report.ml +++ b/src/report/report.ml @@ -583,6 +583,8 @@ let main () = search_in_path data points | `Csv, file -> generic_output file (Report_csv.make !Arguments.csv_separator) + | `Text, "-" -> + Report_text.output ~per_file:(not !Arguments.summary_only) data | `Text, file -> generic_output file (Report_text.make !Arguments.summary_only) | `Dump, file -> diff --git a/src/report/report_text.ml b/src/report/report_text.ml index 842fc9d3..f1cd61db 100644 --- a/src/report/report_text.ml +++ b/src/report/report_text.ml @@ -22,3 +22,72 @@ let make summary_only = "none" in Report_utils.(numbers s.visited s.total) ^ "\n" end + + + +let output ~per_file counts = + let stats = + Hashtbl.fold (fun file counts acc -> + let total = Array.length counts in + let visited = + Array.fold_left + (fun acc count -> if count > 0 then acc + 1 else acc) 0 counts + in + (file, visited, total)::acc) counts [] + in + + let percentage numerator denominator = + if denominator > 0 then + let p = + ((float_of_int numerator) *. 100.) /. (float_of_int denominator) in + Printf.sprintf "%.2f" p + else + "0.00" + in + + let second (_, v, _) = v in + let third (_, _, v) = v in + + let total projection = + stats + |> List.map projection + |> List.fold_left (+) 0 + in + let visited_total = total second in + let overall_total = total third in + + if per_file then begin + let digits i = + let rec loop bound count = + if bound > i then + count + else + loop (bound * 10) (count + 1) + in + loop 10 1 + in + let digits projection = + ("", visited_total, overall_total)::stats + |> List.map projection + |> List.map digits + |> List.fold_left max 1 + in + let visited_digits = digits second in + let total_digits = digits third in + + stats + |> List.sort (fun (file, _, _) (file', _, _) -> String.compare file file') + |> List.iter begin fun (name, visited, total) -> + Printf.printf "%6s %% %*i/%-*i %s\n" + (percentage visited total) + visited_digits visited + total_digits total + name + end; + + Printf.printf "%6s %% %i/%i Project coverage\n%!" + (percentage visited_total overall_total) visited_total overall_total + end + else + Printf.printf "Coverage: %i/%i (%s%%)\n%!" + visited_total overall_total (percentage visited_total overall_total) diff --git a/src/report/report_text.mli b/src/report/report_text.mli index 94597f5a..c6e664d7 100644 --- a/src/report/report_text.mli +++ b/src/report/report_text.mli @@ -4,9 +4,9 @@ -(** This module defines the output to bare text. *) - - val make : bool -> Report_generic.converter (** Returns a converter for bare text output, the passed boolean indicates whether only summary should be output. *) + +val output : per_file:bool -> (string, int array) Hashtbl.t -> unit +(** Writes a text summary report to STDOUT. *) diff --git a/test/unit/fixtures/report/reference.text b/test/unit/fixtures/report/reference.text index 221d86a7..ac40de69 100644 --- a/test/unit/fixtures/report/reference.text +++ b/test/unit/fixtures/report/reference.text @@ -1,2 +1,2 @@ -Coverage summary: 19/38 (50.00%) -File 'source.ml': 19/38 (50.00%) + 50.00 % 19/38 source.ml + 50.00 % 19/38 Project coverage