#!/bin/sh
# Checks the per repository statistics page, which stays off until max-stats
# turns it on and then counts each author's commits over the last four
# periods, busiest first. A second config sets a finer max-stats so that what
# it takes out of the period selector is covered as well.
test_description='Check the statistics page'
. ./setup.sh
# The shared test config sets no max-stats, so this is what an untouched
# install does.
test_expect_success 'stats are off by default' '
cgit_url "foo/stats" >tmp &&
grep "^Status: 404" tmp &&
grep "
Stats are disabled
" tmp &&
cgit_ok_url "foo" >tmp &&
grep ">log" tmp &&
! grep ">stats" tmp
'
# A word that names no period leaves the page off rather than picking one.
test_expect_success 'a max-stats naming no period leaves stats off' '
cgitrc_repo badrc foo max-stats=decade &&
cgit_rc badrc "url=foo/stats/" >tmp &&
grep "^Status: 404" tmp &&
grep "
Stats are disabled
" tmp
'
# Asks for a stats page into tmp, and fails when the day turned during the
# request, since cgit reads the clock for itself and a new day can open a new
# period. The day read is left in now as year, month, day, ISO week and its
# year, for the caller to work out the labels from.
stats_today() {
now=$(date -u "+%Y %m %d W%V %G") &&
cgit_ok "$@" >tmp &&
test "$(date -u "+%Y %m %d W%V %G")" = "$now"
}
# The column labels of the stats table in tmp, one to a line.
period_labels() {
sed -n "s/^
Author<\/th>\(.*\)
Total<\/th><\/tr>$/\1/p" tmp |
sed -e "s/
//g" -e "s/<\/th>/;/g" | tr ";" "\n" | sed "/^$/d"
}
# Makes the given number of empty commits by the named author.
author_commits() {
i=0 &&
while test $i -lt $2
do
GIT_AUTHOR_NAME="$1" git commit --allow-empty -m "$1 $i" &&
i=$((i + 1)) || return 1
done
}
# The authors table counts only recent periods, so beside the 2005 commits of
# mkrepo the fixture has commits stamped now. Each author makes a different
# number of them, in the reverse of the order of their names, so the table
# has to sort by count. One of Gil's commits comes in through a merge, which
# counts for nobody. The walk releases each commit as it goes, which a commit
# read from a commit graph has to survive, so the fixture writes one.
test_expect_success 'set up a stats config' '
mkrepo repos/pulse 2 &&
(
cd repos/pulse &&
unset GIT_AUTHOR_DATE GIT_COMMITTER_DATE &&
git checkout -b side &&
author_commits "Gil Seven" 1 &&
git checkout - &&
echo ada >ada.txt &&
git add ada.txt &&
GIT_AUTHOR_NAME="Ada One" git commit -m "add ada.txt" &&
author_commits "Ben Two" 2 &&
author_commits "Cy Three" 3 &&
author_commits "Di Four" 4 &&
author_commits "Ed Five" 5 &&
author_commits "Flo Six" 6 &&
author_commits "Gil Seven" 6 &&
GIT_AUTHOR_NAME="Mo Merger" git merge --no-ff -m merge side &&
git commit-graph write --reachable
) &&
cgitrc_repo statsrc stat max-stats=year "repo.path=$PWD/repos/pulse/.git" &&
cgitrc_repo statmaxrc stat max-stats=month "repo.path=$PWD/repos/pulse/.git"
'
test_expect_success 'stats tab appears when enabled' '
cgit_ok statsrc "url=stat/" >tmp &&
grep ">stats" tmp
'
test_expect_success 'stats page renders the authors table' '
cgit_ok statsrc "url=stat/stats/" >tmp &&
grep "
Commits per author per week
" tmp
'
# Only the sums are compared, since a run that crosses into a new week moves
# the commits from one column to the next.
test_expect_success 'each author is counted and the busiest comes first' '
cgit_ok statsrc "url=stat/stats/" >tmp &&
sed -n "s/^
\([^<]*\)<\/td>.*
\([0-9]*\)<\/td><\/tr>$/\1 \2/p" tmp >actual &&
test_write_lines "Gil Seven 7" "Flo Six 6" "Ed Five 5" "Di Four 4" \
"Cy Three 3" "Ben Two 2" "Ada One 1" >expect &&
test_cmp expect actual &&
grep "^
Ada One
\(
[0-9]*
\)\{4\}
1
$" tmp &&
grep "^
Total
\(
[0-9]*
\)\{4\}
28
$" tmp
'
test_expect_success 'a merge counts for nobody' '
cgit_ok statsrc "url=stat/stats/" >tmp &&
grep "
Gil Seven
.*
7
" tmp &&
! grep ">Mo Merger<" tmp
'
test_expect_success 'the authors past the row count share one row' '
cgit_ok statsrc "url=stat/stats/&ofs=1" >tmp &&
sed -n "s/^
\([^<]*\)<\/td>.*
\([0-9]*\)<\/td><\/tr>$/\1 \2/p" tmp >actual &&
test_write_lines "Gil Seven 7" "Others (6) 21" >expect &&
test_cmp expect actual
'
# The table scrolls sideways on a narrow window with nothing in it a keyboard
# can reach, so the table itself takes focus, and the focus ring links have.
test_expect_success 'the authors table can take keyboard focus' '
cgit_ok statsrc "url=stat/stats/" >tmp &&
grep "
" tmp &&
sed -n "/^div#cgit a:focus-visible,$/,/^}/p" \
"$TEST_OUTPUT_DIRECTORY/../assets/cgit.css" >rule &&
grep "^div#cgit table.stats:focus-visible {$" rule &&
grep "^ outline: solid 2px var(--link);$" rule
'
test_expect_success 'stat options sit above the content' '
cgit_ok statsrc "url=stat/stats/" >tmp &&
tr -d "\n" Commits per author.*//" | grep "cgit-panel"
'
# Only Ada touched ada.txt, and in a commit inside the window.
test_expect_success 'stats below a path count that path alone' '
cgit_ok statsrc "url=stat/stats/ada.txt" >tmp &&
grep "