#!/bin/sh

# dh_octave_check: Automate checking of Octave-Forge Debian packages
# This file is part of the dh-octave Debian package and was also part
# of the deprecated octave-pkg-dev package.

# Copyright (c) 2018  Rafael Laboissière <rafael@laboissiere.net>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.

: <<=cut

=encoding utf8

=head1 NAME

dh_octave_check - automatically run an Octave-Forge package test suite

=head1 SYNOPSIS

B<dh_octave_check>

=head1 DESCRIPTION

B<dh_octave_check> performs the automated tests present in both F<*.m>
and F<*.cc> files in the current directory, which should be the top-level
source directory of an Octave add-on package.  It also runs the
script F<debian/check.m>, if it exists.

=head1 SEE ALSO

L<debhelper(7)>, L<dh(1)>, L<dh_octave_substvar(1)>, L<dh_octave_clean(1)>,
L<dh_octave_version(1)>, L<dh_octave_changelogs(1)>

This program is meant to be used together with debhelper for Debian
packages derived from Octave-Forge packages.

=head1 AUTHOR

Rafael Laboissière <rafael@debian.org>

=cut

# Set the octave executable and the octave options, when the
# corresponding variables are absent from the environment.
: ${octave:=octave-cli}
: ${octave_options:="--no-history --silent --no-init-file --no-window-system"}

[ -e PKG_ADD ] && mv PKG_ADD PKG_ADD.bak

echo Checking package...

unit_test_regex='^%!\(assert\|test\|error\|fail\|xtest\|warning\)'

# Extract tests from installed m files
tmp_script=$(tempfile)
tmp_results=$(tempfile)
cat >$tmp_script <<EOF
fid = fopen ("$tmp_results", "w");
disp ('Checking m files ...');
addpath (genpath (sprintf ('%s/debian', pwd ())));
[usr_pkg, sys_pkg] = pkg ('list');
for i = 1 : length (sys_pkg)
    pkg ('load', sys_pkg {1, i}.name);
endfor
EOF
excluded_files_expr=$(for i in $DH_OCTAVE_EXCLUDE_TEST ; do
                          echo " -a ! -name $i " ;
                      done)
for f in $(find inst/ -name \*.m $excluded_files_expr | grep -v /private/) ; do
    if grep -q "$unit_test_regex" $f ; then
        stem=$(echo $f | sed 's:[^@]*/::;s/\.m$//')
        cat >>$tmp_script <<EOF
disp ("[$stem]");
[npass, ntest, nxfail, nskip] = test ("$stem",
                                      ifelse (strcmp ("$DH_OCTAVE_TEST_OPT", ""),
                                              "verbose", "$DH_OCTAVE_TEST_OPT"));
printf ("%d test%s, %d passed, %d known failure%s, %d skipped\n",
        ntest, ifelse (ntest > 1, "s", ""), npass, nxfail,
        ifelse (nxfail > 1, "s", ""), nskip);
fprintf (fid, "%s %d %d %d %d\n", "$stem", ntest, npass, nxfail, nskip);
EOF
    fi
done

# Extract tests from .cc files - these are not installed, but the
# compiled .oct files are.
# We search for the tests in the .cc files, but invoke the .oct files;
# this means we must add generate a loadpath starting at the current
# directory and source PKG_ADD files (they might add autoload()
# directives)

# We deactivate the warning about relative paths used for the PKG_ADD file.
cat >>$tmp_script <<EOF
disp ('Checking CC files ...');
addpath (genpath (pwd (), '.pc'));
[usr_pkg, sys_pkg] = pkg ('list');
for i = 1 : length (sys_pkg);
    pkg ('load', sys_pkg {1, i}.name);
endfor
warning ('off', 'Octave:autoload-relative-file-name');
EOF
if [ -f PKG_ADD ] ; then
    echo "source('PKG_ADD');" >> $tmp_script
fi
if [ -f PKG_ADD.bak ] ; then
    echo "source('PKG_ADD.bak');" >> $tmp_script
fi
if [ -d src ] ; then
    for f in $(find src/ -name \*.cc $excluded_files_expr) ; do
        if grep -q "$unit_test_regex" $f ; then
            f=${f##*/}
            cat >>$tmp_script <<EOF
disp ("[$f]");
[npass, ntest, nxfail, nskip] = test ("$f",
                                      ifelse (strcmp ("$DH_OCTAVE_TEST_OPT", ""),
                                              "verbose", "$DH_OCTAVE_TEST_OPT"));
printf ("%d test%s, %d passed, %d known failure%s, %d skipped\n",
        ntest, ifelse (ntest > 1, "s", ""), npass, nxfail,
        ifelse (nxfail > 1, "s", ""), nskip);
fprintf (fid, "%s %d %d %d %d\n", "$f", ntest, npass, nxfail, nskip);
EOF
        fi
    done
fi

if [ -f debian/check.m ] ; then
    cat >>$tmp_script <<EOF
disp ("Run tests in debian/check.m");
try
    source ("debian/check.m");
    fprintf (fid, "debian/check.m 1 1 0 0\n");
catch
    fprintf (fid, "debian/check.m 1 0 1 0\n");
end_try_catch
fclose (fid);
EOF
fi

eval $DH_OCTAVE_TEST_ENV $octave $octave_options $tmp_script
rm -f $tmp_script

if [ -e PKG_ADD.bak ] ; then
    mv PKG_ADD.bak PKG_ADD
fi

ntest=0
npass=0
nxfail=0
nskip=0
while read f1 f2 f3 f4 f5 ; do
    ntest=$((ntest + f2))
    npass=$((npass + f3))
    nxfail=$((nxfail + f4))
    nskip=$((nskip + f5))
done < $tmp_results
rm -f $tmp_results
echo "Summary: $ntest tests, $npass passed, $nxfail known failures, $nskip skipped"
if [ "$ntest" -gt $((npass + nxfail + nskip)) ] ; then
    exit 1
fi
