#---*- Makefile -*-------------------------------------------------------------
#$Author: antanas $
#$Date: 2021-08-02 16:56:30 +0300 (Mon, 02 Aug 2021) $
#$Revision: 8853 $
#$URL: svn+ssh://www.crystallography.net/home/coder/svn-repositories/cod-tools/tags/v3.8.0/makefiles/Makelocal-unit-test $
#------------------------------------------------------------------------------
#*
#  Runs unit tests for an individual module. Requires test driver script(s).
#  The makefile is also capable of creating test output files (*.out)
#  from test input files (*.inp), producing the list of tests that
#  did not pass and removing old test results.
#**

# The following variables should be predefined in the Makeconf file:
# ${TEST_MODULE}
#                   Full path to the module that is being tested.
# ${TEST_DEPEND}
#                   Additional dependencies that should be assembled
#                   before carrying out the tests (for example, *.so
#                   files that are generated by SWIG).
TEST_MODULE ?= ${notdir $(shell pwd)}.pm
TEST_DEPEND ?=

TEST_DIR = tests

SHELL = /bin/bash

.PRECIOUS: ${TEST_MODULE} ${TEST_DEPEND}
.PHONY: all tests alltests

all:

check tests alltests: test shtest

#------------------------------------------------------------------------------
# Tests that use the driver scripts:

SCRIPT_DIR = ${TEST_DIR}/scripts
INP_DIR    = ${TEST_DIR}/cases
OUTP_DIR   = ${TEST_DIR}/outputs

TEST_FILES = ${wildcard ${INP_DIR}/*.inp}
DIFF_FILES = ${TEST_FILES:${INP_DIR}/%.inp=${OUTP_DIR}/%.diff}
OUTP_FILES = ${TEST_FILES:${INP_DIR}/%.inp=${OUTP_DIR}/%.out}

.PHONY: test out outputs

test: ${sort ${DIFF_FILES}}

out outputs: ${OUTP_FILES}

${OUTP_DIR}/%.diff: ${INP_DIR}/%.inp ${INP_DIR}/%.opt ${TEST_MODULE} ${TEST_DEPEND}
	-@printf "%-30s " "$<:" ; \
	( ${SCRIPT_DIR}/$(shell echo $* | sed -e 's/_[0-9]*$$//') \
		$(shell grep -v '^#' ${word 2, $^}) \
		$< ) 2>&1 \
	| diff ${OUTP_DIR}/$*.out - \
		> $@ ; \
	if [ $$? = 0 ]; then echo "OK"; else echo "FAILED:"; cat $@; fi

${OUTP_DIR}/%.diff: ${INP_DIR}/%.inp ${TEST_MODULE} ${TEST_DEPEND}
	-@printf "%-30s " "$<:" ; \
	( ${SCRIPT_DIR}/$(shell echo $* | sed -e 's/_[0-9]*$$//') \
		$< ) 2>&1 \
	| diff ${OUTP_DIR}/$*.out - \
		> $@ ; \
	if [ $$? = 0 ]; then echo "OK"; else echo "FAILED:"; cat $@; fi

${OUTP_DIR}/%.out: ${INP_DIR}/%.inp ${INP_DIR}/%.opt ${TEST_MODULE} ${TEST_DEPEND}
	-@test -f $@ || echo "$@:"
	-@test -f $@ || \
	( ${SCRIPT_DIR}/$(shell echo $* | sed -e 's/_[0-9]*$$//') \
		$(shell grep -v '^#' ${word 2, $^}) \
		$< ) 2>&1 \
	| tee $@
	-@touch $@

${OUTP_DIR}/%.out: ${INP_DIR}/%.inp ${TEST_MODULE} ${TEST_DEPEND}
	-@test -f $@ || echo "$@:"
	-@test -f $@ || \
	( ${SCRIPT_DIR}/$(shell echo $* | sed -e 's/_[0-9]*$$//') \
		$< ) 2>&1 \
	| tee $@
	-@touch $@

#------------------------------------------------------------------------------
# Shell-driven tests:

SHELL_TSTDIR = ./${TEST_DIR}/shtests
SHELL_OUTDIR = ./${TEST_DIR}/shoutputs

SHELL_TESTS   = ${wildcard ${SHELL_TSTDIR}/*.sh}
SHELL_BASES   = ${notdir ${SHELL_TESTS}}
SHELL_OUTPUTS = ${addprefix ${SHELL_OUTDIR}/, ${SHELL_BASES:%.sh=%.out}}
SHELL_DIFFS   = ${addprefix ${SHELL_OUTDIR}/, ${SHELL_BASES:%.sh=%.diff}}

.PHONY: shtest shtests shout shoutputs

shtest shtests: ${sort ${SHELL_DIFFS}}

shout shoutputs: ${SHELL_OUTPUTS}

${SHELL_OUTDIR}/%.out: ${SHELL_TSTDIR}/%.sh ${TEST_MODULE} ${TEST_DEPEND}
	-@test -f $@ || echo "$@:"
	-@test -f $@ || $< ${TEST_MODULE} 2>&1 | tee $@
	-@touch $@

${SHELL_OUTDIR}/%.diff: ${SHELL_TSTDIR}/%.sh ${TEST_MODULE} ${TEST_DEPEND}
	-@printf "%-30s " "$*:" ; \
	$< ${TEST_MODULE} 2>&1 \
	| diff ${SHELL_OUTDIR}/$*.out - > $@ ; \
	if [ $$? = 0 ]; then echo "OK"; else echo "FAILED:"; cat $@; fi

#------------------------------------------------------------------------------
# Generate a list of tests that did not pass:

.PHONY: listdiff

listdiff: ${DIFF_FILES} ${SHELL_DIFFS}
	@find ${OUTP_DIR} ${SHELL_OUTDIR} -name \*.diff -size +0 \
	| sort -u | xargs --no-run-if-empty ls -l

#------------------------------------------------------------------------------
# Remove old tests results:

.PHONY: clean cleanAll distclean

clean cleanAll distclean: clean-YAPP-test

clean-YAPP-test:
	rm -f ${DIFF_FILES}
	rm -f ${SHELL_DIFFS}
