Skip to content

Commit aa03ec1

Browse files
committed
Enable 'genhtml --show-details' in '--flat' and '--hierarchical' modes.
Fix bug that caused per-testcase summary to not be generated. Signed-off-by: Henry Cox <[email protected]>
1 parent 8446f29 commit aa03ec1

File tree

3 files changed

+125
-53
lines changed

3 files changed

+125
-53
lines changed

bin/genhtml

Lines changed: 55 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -4948,11 +4948,15 @@ sub new
49484948
my $worklist = $self->[$WORKLIST_IDX];
49494949
my $top_level_summary = $self->[0];
49504950
# no parent data for top-level
4951+
my $toplevelPerTestData =
4952+
($main::hierarchical || $main::flat) ? [{}, {}, {}] : undef;
49514953
$pending->{""} = [
49524954
['top',
4953-
[$top_level_summary, undef, $top_level_summary->name()]
4954-
, # summary, per-test data, name
4955-
['root'], ['root'],
4955+
[$top_level_summary, $toplevelPerTestData,
4956+
$top_level_summary->name()
4957+
],
4958+
['root'],
4959+
['root'],
49564960
[undef, undef]
49574961
],
49584962
{}
@@ -5146,17 +5150,16 @@ sub merge_one
51465150

51475151
sub compute_one
51485152
{
5149-
my ($type, $name, $summary, $parentSummary, $rel_dir, $base_dir, $trunc_dir)
5153+
my ($type, $name, $summary, $parentSummary, $perTestData,
5154+
$rel_dir, $base_dir, $trunc_dir)
51505155
= @_;
51515156

5152-
my $perTestData;
51535157
if ('file' eq $type) {
51545158
my ($testdata, $testfncdata, $testbrdata) =
51555159
main::process_file($summary, $parentSummary,
51565160
$trunc_dir, $rel_dir, $name);
51575161
$perTestData = [$testdata, $testfncdata, $testbrdata];
51585162
} elsif ('dir' eq $type) {
5159-
$perTestData = [{}, {}, {}];
51605163
# process the directory...
51615164
main::write_summary_pages($name, 1, # this is a directory,
51625165
$summary, $main::show_details,
@@ -5166,11 +5169,12 @@ sub compute_one
51665169
die("unexpected task")
51675170
unless 'top' eq $type;
51685171
# Create sorted pages
5169-
main::write_summary_pages(
5170-
$name, 0, # 0 == list directories
5171-
$summary,
5172-
0, # don't generate 'details' links for top-level report
5173-
".", "", undef, undef);
5172+
main::write_summary_pages($name, 0, # 0 == list directories
5173+
$summary,
5174+
# generate top-level 'details' in flat or hierarchical modes
5175+
$main::show_details &&
5176+
($main::flat || $main::hierarchical),
5177+
".", "", undef, $perTestData);
51745178
}
51755179
$summary->checkCoverageCriteria();
51765180
return $perTestData;
@@ -5295,9 +5299,10 @@ sub compute
52955299

52965300
eval {
52975301
$thisTestData =
5298-
compute_one($type, $name, $selfSummary,
5299-
$parentSummary, $rel_dir, $base_dir,
5300-
$trunc_dir);
5302+
compute_one($type, $name,
5303+
$selfSummary, $parentSummary,
5304+
$perTestData, $rel_dir,
5305+
$base_dir, $trunc_dir);
53015306

53025307
# clear the parent pointer that we hacked into place. Don't want that
53035308
# extra data returned by dumper.
@@ -5332,7 +5337,8 @@ sub compute
53325337
$lcovutil::profileData{child}{$name} = $childEnd - $childStart;
53335338
eval {
53345339
Storable::store(
5335-
[$perTestData,
5340+
[$thisTestData,
5341+
$parentPerTestData,
53365342
$selfSummary,
53375343
$criteria,
53385344
[$SourceFile::annotatedFiles - $annotateCount,
@@ -5356,9 +5362,9 @@ sub compute
53565362

53575363
my $thisTestData =
53585364
compute_one($type, $name, $selfSummary, $parentSummary,
5359-
$rel_dir, $base_dir, $trunc_dir);
5365+
$perTestData, $rel_dir, $base_dir, $trunc_dir);
53605366

5361-
$self->merge_one($perTestData, $name, $thisTestData,
5367+
$self->merge_one($parentPerTestData, $name, $thisTestData,
53625368
$selfSummary, $parentSummary, $parentPath);
53635369
my $end = Time::HiRes::gettimeofday();
53645370
$lcovutil::profileData{$type}{$name} = $end - $start;
@@ -5433,7 +5439,9 @@ sub merge_child($$$)
54335439
if -f $dumpfile;
54345440
if (defined($data)) {
54355441
eval {
5436-
my ($perTest, $summary, $criteria, $countData, $update) = @$data;
5442+
my ($perTest, $pPerTestData, $summary, $criteria, $countData,
5443+
$update)
5444+
= @$data;
54375445
die("unexpected restored count data")
54385446
if (($type eq 'file' && $countData->[1] != 1) ||
54395447
($type ne 'file' &&
@@ -6881,19 +6889,21 @@ sub get_relative_base_path($)
68816889

68826890
sub read_testfile($)
68836891
{
6892+
my $file = shift;
68846893
my %result;
68856894
my $test_name;
68866895
my $changed_testname;
68876896
local *TEST_HANDLE;
68886897

6889-
open(TEST_HANDLE, "<", $_[0]) or
6890-
die("cannot open $_[0]: $!\n");
6898+
open(TEST_HANDLE, "<", $file) or
6899+
die("cannot open $file]: $!\n");
68916900

68926901
while (<TEST_HANDLE>) {
68936902
chomp($_);
68946903
s/\r//g;
68956904
# Match lines beginning with TN:<whitespace(s)>
6896-
if (/^TN:\s+(.*?)\s*$/) {
6905+
next if /^#/; # skip comment
6906+
if (/^TN:\s*(.*?)\s*$/) {
68976907
# Store name for later use
68986908
$test_name = $1;
68996909
if ($test_name =~ s/\W/_/g) {
@@ -6902,10 +6912,12 @@ sub read_testfile($)
69026912
}
69036913

69046914
# Match lines beginning with TD:<whitespace(s)>
6905-
if (/^TD:\s+(.*?)\s*$/) {
6915+
if (/^TD:\s*(.*?)\s*$/) {
69066916
if (!defined($test_name)) {
6907-
die("Found test description without prior test name in $_[0]:$.\n"
6917+
lcovutil::ignorable_error($lcovutil::ERROR_FORMAT,
6918+
"\"$file\":$.: Found test description without prior test name."
69086919
);
6920+
next;
69096921
}
69106922
# Check for empty line
69116923
if ($1) {
@@ -6919,10 +6931,15 @@ sub read_testfile($)
69196931
}
69206932

69216933
close(TEST_HANDLE) or die("unable to close HTML file: $!\n");
6934+
if (!%result) {
6935+
lcovutil::ignorable_error($lcovutil::ERROR_EMPTY,
6936+
"no test descriptions found in '$file'.");
6937+
}
69226938

69236939
if ($changed_testname) {
69246940
lcovutil::ignorable_error($lcovutil::ERROR_FORMAT,
6925-
"invalid characters removed from testname in descriptions file $_[0]");
6941+
"invalid characters removed from testname in descriptions file '$file'."
6942+
);
69266943
}
69276944

69286945
return \%result;
@@ -8675,24 +8692,17 @@ END_OF_HTML
86758692
write_html($handle, " <td class=\"testPer\"></td>\n");
86768693
}
86778694
write_html($handle, " <td class=\"testPer\">$rate</td>\n");
8678-
if ($covtype != SummaryInfo::FUNCTION_DATA) {
8695+
write_html($handle, " <td class='testNum'>$found</td>\n");
8696+
if ($main::show_hitTotalCol) {
86798697
write_html($handle,
8680-
" <td class='testNum'>$found</td>\n");
8681-
if ($main::show_hitTotalCol) {
8682-
write_html($handle,
8683-
" <td class='testNum'>$hit</td>\n");
8684-
}
8685-
if ($main::show_tla) {
8686-
foreach my $tla (@{$activeTlaCols->{$covtype}}) {
8687-
my $count = $callback->count($tla);
8688-
$count = "" if 0 == $count;
8689-
write_html($handle,
8690-
" <td class=coverNumDflt>$count</td>\n");
8691-
}
8698+
" <td class='testNum'>$hit</td>\n");
8699+
}
8700+
if ($main::show_tla) {
8701+
foreach my $tla (@{$activeTlaCols->{$covtype}}) {
8702+
my $count = $callback->count($tla);
8703+
$count = "" if 0 == $count;
8704+
write_html($handle, " <td class=coverNumDflt>$count</td>\n");
86928705
}
8693-
} else {
8694-
write_html($handle,
8695-
" <td class=\"testNum\">$found&nbsp;/&nbsp;$hit</td>\n");
86968706
}
86978707
}
86988708
write_html($handle, " </tr>\n");
@@ -10685,7 +10695,11 @@ sub write_file_table(*$$$$$)
1068510695
# Determine HTML code for column headings
1068610696
my $hide = $HEAD_NO_DETAIL;
1068710697
my $show = $HEAD_NO_DETAIL;
10688-
if ($dirSummary->type() eq 'directory' && $show_details) {
10698+
if (($dirSummary->type() eq 'directory' ||
10699+
$main::flat ||
10700+
$main::hierarchical) &&
10701+
$show_details
10702+
) {
1068910703
# "detailed" if line coverage hash not empty
1069010704
my $detailed =
1069110705
defined($perTestcaseData) && scalar(%{$perTestcaseData->[0]});

man/genhtml.1

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -883,10 +883,23 @@ Generate detailed directory view.
883883

884884
When this option is enabled,
885885
.B genhtml
886-
generates two versions of each
887-
file view. One containing the standard information plus a link to a
888-
"detailed" version. The latter additionally contains information about
889-
which test case covered how many lines of each source file.
886+
generates two versions of each source file file entry in the corresponding summary table:
887+
.IP
888+
one containing the standard information plus a link to a
889+
"detailed" version, and
890+
.PP
891+
.IP
892+
a second which contains the number of coverpoints in the hit by each
893+
testcase.
894+
.br
895+
Note that missed coverpoints are not shown in the per-testcase table entry data.
896+
.PP
897+
898+
The corresponding summary table is found on the 'directory' page of the default 3-level genthm report, or on the top-level page of the 'flat' report (see
899+
.I genhtml \-\-flat ...
900+
), or on the parent directory page of the 'hierarchical' report (see
901+
.I genhtml \-\-hierarchical ...
902+
).
890903

891904
.RE
892905
.BI "\-b " baseline\-file\-pattern

tests/gendiffcov/simple/script.sh

Lines changed: 53 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,8 @@ DIFFCOV_OPTS="--function-coverage --branch-coverage --highlight --demangle-cpp -
128128
#DIFFCOV_OPTS="--function-coverage --branch-coverage --highlight --demangle-cpp --frame"
129129
#DIFFCOV_OPTS='--function-coverage --branch-coverage --highlight --demangle-cpp'
130130

131-
rm -f test.cpp *.gcno *.gcda a.out *.info *.info.gz diff.txt diff_r.txt diff_broken.txt *.log *.err *.json dumper* results.xlsx annotate.{cpp,exe} c d ./cover_db_py
132-
rm -rf ./baseline ./current ./differential* ./reverse ./diff_no_baseline ./no_baseline ./no_annotation ./no_owners differential_nobranch reverse_nobranch baseline-filter* noncode_differential* broken mismatchPath elidePath ./cover_db ./criteria ./mismatched ./navigation differential_prop proportion ./annotate ./current-* ./current_prefix* select select2 html_report
131+
rm -f test.cpp *.gcno *.gcda a.out *.info *.info.gz diff.txt diff_r.txt diff_broken.txt *.log *.err *.json dumper* results.xlsx annotate.{cpp,exe} c d ./cover_db_py names.data
132+
rm -rf ./baseline ./current ./differential* ./reverse ./diff_no_baseline ./no_baseline ./no_annotation ./no_owners differential_nobranch reverse_nobranch baseline-filter* noncode_differential* broken mismatchPath elidePath ./cover_db ./criteria ./mismatched ./navigation differential_prop proportion ./annotate ./current-* ./current_prefix* select select2 html_report ./usage ./errOut ./noNames
133133

134134
if [ "x$COVER" != 'x' ] && [ 0 != $LOCAL_COVERAGE ] ; then
135135
cover -delete -db $COVER_DB
@@ -377,22 +377,67 @@ if [ 0 != $? ] ; then
377377
fi
378378
fi
379379
380+
echo '' > names.data
381+
echo -o noNames $DIFFCOV_OPTS $IGNORE --show-details --description names.data current_name.info.gz
382+
$COVER $GENHTML_TOOL -o noNames $DIFFCOV_OPTS $IGNORE --show-details --description names.data current_name.info.gz
383+
if [ 0 == $? ] ; then
384+
echo "ERROR: expected fail due to missing descriptions - but passed"
385+
status=1
386+
if [ 0 == $KEEP_GOING ] ; then
387+
exit 1
388+
fi
389+
fi
390+
echo "TD: out of sequence" > names.data
391+
echo genhtml -o noNames $DIFFCOV_OPTS $IGNORE --show-details --description names.data current_name.info.gz
392+
$COVER $GENHTML_TOOL -o noNames $DIFFCOV_OPTS $IGNORE --show-details --description names.data current_name.info.gz
393+
if [ 0 == $? ] ; then
394+
echo "ERROR: expected fail due to invalid sequence - but passed"
395+
status=1
396+
if [ 0 == $KEEP_GOING ] ; then
397+
exit 1
398+
fi
399+
fi
400+
401+
380402
# check that vanilla, flat, hierarchical work with and without prefix
403+
cat > names.data <<EOF
404+
TN:myTest
405+
TD:faking some test data
406+
# test empty description
407+
TN:unusedTest
408+
TD:
409+
EOF
410+
381411
now=`date`
382412
for mode in '' '--flat' '--hierarchical' ; do
383-
echo genhtml $DIFFCOV_OPTS $mode --show-details current.info --output-directory ./current$mode $IGNORE
384-
$COVER $GENHTML_TOOL $mode $DIFFCOV_OPTS current.info --show-details --output-directory ./current$mode $IGNORE --current-date "$now"
413+
echo genhtml $DIFFCOV_OPTS $mode --show-details current_name.info.gz --output-directory ./current$mode $IGNORE --description names.data
414+
$COVER $GENHTML_TOOL $mode $DIFFCOV_OPTS current_name.info.gz --show-details --output-directory ./current$mode $IGNORE --current-date "$now" --description names.data
385415
if [ 0 != $? ] ; then
386416
echo "ERROR: genhtml current $mode failed"
387417
status=1
388418
if [ 0 == $KEEP_GOING ] ; then
389419
exit 1
390420
fi
391421
fi
422+
# verify that the 'details' link is there:
423+
# index.html file should refer to 'show details'
424+
if [ '' == "$mode" ] ; then
425+
FILE=./current/simple/index.html
426+
else
427+
FILE=./current$mode/index.html
428+
fi
429+
grep 'show details' $FILE
430+
if [ 0 != $? ] ; then
431+
echo "ERROR: no testcase 'details' link"
432+
status=1
433+
if [ 0 == $KEEP_GOING ] ; then
434+
exit 1
435+
fi
436+
fi
392437
393438
# run again with prefix
394-
echo genhtml $DIFFCOV_OPTS $mode --show-details current.info --output-directory ./current_prefix$mode $IGNORE --prefix `pwd`
395-
$COVER $GENHTML_TOOL $mode $DIFFCOV_OPTS current.info --show-details --output-directory ./current_prefix$mode $IGNORE --prefix `pwd` --current-date "$now"
439+
echo genhtml $DIFFCOV_OPTS $mode --show-details current_name.info.gz --output-directory ./current_prefix$mode $IGNORE --prefix `pwd` --description names.data
440+
$COVER $GENHTML_TOOL $mode $DIFFCOV_OPTS current_name.info.gz --show-details --output-directory ./current_prefix$mode $IGNORE --prefix `pwd` --current-date "$now" --description names.data
396441
if [ 0 != $? ] ; then
397442
echo "ERROR: genhtml current $mode --prefix failed"
398443
status=1
@@ -476,8 +521,8 @@ for opt in "" --dark-mode --flat ; do
476521
done
477522
478523
# check that this works with test names
479-
echo ${LCOV_HOME}/bin/genhtml $DIFFCOV_OPTS --baseline-file ./baseline_name.info.gz --diff-file diff.txt --annotate-script `pwd`/annotate.sh --show-owners all --show-noncode --ignore-errors source --simplified-colors -o differential_named ./current_name.info.gz $IGNORE
480-
$COVER ${GENHTML_TOOL} $DIFFCOV_OPTS --baseline-file ./baseline_name.info.gz --diff-file diff.txt --annotate-script `pwd`/annotate.sh --show-owners all --show-noncode --ignore-errors source --simplified-colors -o differential_named ./current_name.info.gz $GENHTML_PORT $IGNORE
524+
echo ${LCOV_HOME}/bin/genhtml $DIFFCOV_OPTS --baseline-file ./baseline_name.info.gz --diff-file diff.txt --annotate-script `pwd`/annotate.sh --show-owners all --show-noncode --ignore-errors source --simplified-colors -o differential_named ./current_name.info.gz $IGNORE --description names.data
525+
$COVER ${GENHTML_TOOL} $DIFFCOV_OPTS --baseline-file ./baseline_name.info.gz --diff-file diff.txt --annotate-script `pwd`/annotate.sh --show-owners all --show-noncode --ignore-errors source --simplified-colors -o differential_named ./current_name.info.gz $GENHTML_PORT $IGNORE --description names.data
481526
if [ 0 != $? ] ; then
482527
echo "ERROR: genhtml differential testname failed"
483528
status=1

0 commit comments

Comments
 (0)