From 24765e29635ce9179920b34ad053d173573bd3d5 Mon Sep 17 00:00:00 2001 From: Mathieu Barbin Date: Sat, 10 Feb 2024 12:23:58 +0100 Subject: [PATCH 1/3] Add --sort-by-stats flag to html reporter --- src/report/html.ml | 42 ++++++++++++++++++++++++++++++++++++++++-- src/report/html.mli | 1 + src/report/main.ml | 12 +++++++++--- 3 files changed, 50 insertions(+), 5 deletions(-) diff --git a/src/report/html.ml b/src/report/html.ml index 85dc053e..e9689e1b 100644 --- a/src/report/html.ml +++ b/src/report/html.ml @@ -31,7 +31,37 @@ type index_element = | File of index_file | Directory of (string * index_element list * (int * int)) -let output_html_index ~tree title theme filename files = +module Index_element : sig + type t = index_element + + val sort_by_stats : t list -> t list + + val flatten : t list -> t list +end = struct + type t = index_element + + let percentage = function + | File (_, _, stat) -> percentage stat + | Directory (_, _, stat) -> percentage stat + + let compare_by_stat e1 e2 = + compare (percentage e1, e1) (percentage e2, e2) + + let rec sort_by_stats files = + files + |> List.map (function + | (File _) as f -> f + | Directory (name, files, stats) -> Directory (name, sort_by_stats files, stats)) + |> List.sort compare_by_stat + + let rec flatten files = + files + |> List.concat_map (function + | (File _) as f -> [ f ] + | Directory (_, files, _) -> flatten files) +end + +let output_html_index ~tree ~sort_by_stats title theme filename files = Util.info "Writing index file..."; let add_stats (visited, total) (visited', total') = @@ -138,6 +168,13 @@ let output_html_index ~tree title theme filename files = let (files, stats) = collate files in + let files = + match sort_by_stats, tree with + | false, (false|true) -> files + | true, false -> files |> Index_element.flatten |> Index_element.sort_by_stats + | true, true -> files |> Index_element.sort_by_stats + in + let overall_coverage = Printf.sprintf "%.02f%%" (floor ((percentage stats) *. 100.) /. 100.) in write {| @@ -501,7 +538,7 @@ let output_string_to_separate_file content filename = let output ~to_directory ~title ~tab_size ~theme ~coverage_files ~coverage_paths - ~source_paths ~ignore_missing_files ~expect ~do_not_expect ~tree = + ~source_paths ~ignore_missing_files ~expect ~do_not_expect ~tree ~sort_by_stats = (* Read all the [.coverage] files and get per-source file visit counts. *) let coverage = @@ -535,6 +572,7 @@ let output (* Write the coverage report landing page. *) output_html_index ~tree + ~sort_by_stats title theme (Filename.concat to_directory "index.html") diff --git a/src/report/html.mli b/src/report/html.mli index aac2f4e8..b5d3c4d7 100644 --- a/src/report/html.mli +++ b/src/report/html.mli @@ -16,4 +16,5 @@ val output : expect:string list -> do_not_expect:string list -> tree:bool -> + sort_by_stats:bool -> unit diff --git a/src/report/main.ml b/src/report/main.ml index 4beec68b..7eed2761 100644 --- a/src/report/main.ml +++ b/src/report/main.ml @@ -179,17 +179,23 @@ let html = info ["tree"] ~doc: ("Generate collapsible directory tree with per-directory summaries.")) in + let sort_by_stats = + Arg.(value @@ flag @@ + info ["sort-by-stats"] ~doc: + ("Sort reported files by increasing values of coverage stats.")) + in let call_with_labels to_directory title tab_size theme coverage_files coverage_paths - source_paths ignore_missing_files expect do_not_expect tree = + source_paths ignore_missing_files expect do_not_expect tree sort_by_stats = Html.output ~to_directory ~title ~tab_size ~theme ~coverage_files ~coverage_paths - ~source_paths ~ignore_missing_files ~expect ~do_not_expect ~tree + ~source_paths ~ignore_missing_files ~expect ~do_not_expect ~tree ~sort_by_stats in Term.(const set_verbose $ verbose $ const call_with_labels $ to_directory $ title $ tab_size $ theme $ coverage_files 0 $ coverage_paths - $ source_paths $ ignore_missing_files $ expect $ do_not_expect $ tree), + $ source_paths $ ignore_missing_files $ expect $ do_not_expect $ tree + $ sort_by_stats), term_info "html" ~doc:"Generate HTML report locally." ~man:[ `S "USAGE EXAMPLE"; From 90f24a30b2d01ca3116ab6e803477d600670fafc Mon Sep 17 00:00:00 2001 From: Mathieu Barbin Date: Sat, 10 Feb 2024 12:26:55 +0100 Subject: [PATCH 2/3] Fix for older stdlib versions (List.concat_map requires >= 4.10) --- src/report/html.ml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/report/html.ml b/src/report/html.ml index e9689e1b..91ffc128 100644 --- a/src/report/html.ml +++ b/src/report/html.ml @@ -56,9 +56,10 @@ end = struct let rec flatten files = files - |> List.concat_map (function + |> List.map (function | (File _) as f -> [ f ] | Directory (_, files, _) -> flatten files) + |> List.concat end let output_html_index ~tree ~sort_by_stats title theme filename files = From feed6674e8424c68056e796fbcd4807879cbd3ed Mon Sep 17 00:00:00 2001 From: Anton Bachin Date: Mon, 12 Feb 2024 06:11:18 +0300 Subject: [PATCH 3/3] Nits --- src/report/html.ml | 28 ++++++++++++++-------------- src/report/main.ml | 8 +++++--- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/report/html.ml b/src/report/html.ml index 91ffc128..ebf70b92 100644 --- a/src/report/html.ml +++ b/src/report/html.ml @@ -31,15 +31,12 @@ type index_element = | File of index_file | Directory of (string * index_element list * (int * int)) -module Index_element : sig - type t = index_element - - val sort_by_stats : t list -> t list - - val flatten : t list -> t list -end = struct - type t = index_element - +module Index_element : +sig + val sort_by_stats : index_element list -> index_element list + val flatten : index_element list -> index_element list +end = +struct let percentage = function | File (_, _, stat) -> percentage stat | Directory (_, _, stat) -> percentage stat @@ -51,13 +48,14 @@ end = struct files |> List.map (function | (File _) as f -> f - | Directory (name, files, stats) -> Directory (name, sort_by_stats files, stats)) + | Directory (name, files, stats) -> + Directory (name, sort_by_stats files, stats)) |> List.sort compare_by_stat let rec flatten files = files |> List.map (function - | (File _) as f -> [ f ] + | (File _) as f -> [f] | Directory (_, files, _) -> flatten files) |> List.concat end @@ -171,8 +169,9 @@ let output_html_index ~tree ~sort_by_stats title theme filename files = let files = match sort_by_stats, tree with - | false, (false|true) -> files - | true, false -> files |> Index_element.flatten |> Index_element.sort_by_stats + | false, _ -> files + | true, false -> + files |> Index_element.flatten |> Index_element.sort_by_stats | true, true -> files |> Index_element.sort_by_stats in @@ -539,7 +538,8 @@ let output_string_to_separate_file content filename = let output ~to_directory ~title ~tab_size ~theme ~coverage_files ~coverage_paths - ~source_paths ~ignore_missing_files ~expect ~do_not_expect ~tree ~sort_by_stats = + ~source_paths ~ignore_missing_files ~expect ~do_not_expect ~tree + ~sort_by_stats = (* Read all the [.coverage] files and get per-source file visit counts. *) let coverage = diff --git a/src/report/main.ml b/src/report/main.ml index 7eed2761..9f4f7191 100644 --- a/src/report/main.ml +++ b/src/report/main.ml @@ -182,15 +182,17 @@ let html = let sort_by_stats = Arg.(value @@ flag @@ info ["sort-by-stats"] ~doc: - ("Sort reported files by increasing values of coverage stats.")) + ("Sort files in order of increasing coverage stats.")) in let call_with_labels to_directory title tab_size theme coverage_files coverage_paths - source_paths ignore_missing_files expect do_not_expect tree sort_by_stats = + source_paths ignore_missing_files expect do_not_expect tree + sort_by_stats = Html.output ~to_directory ~title ~tab_size ~theme ~coverage_files ~coverage_paths - ~source_paths ~ignore_missing_files ~expect ~do_not_expect ~tree ~sort_by_stats + ~source_paths ~ignore_missing_files ~expect ~do_not_expect ~tree + ~sort_by_stats in Term.(const set_verbose $ verbose $ const call_with_labels $ to_directory $ title $ tab_size $ theme $ coverage_files 0 $ coverage_paths