Skip to content

Commit

Permalink
Rewrite the test runner in python
Browse files Browse the repository at this point in the history
Show details after failed tests, and a final summary.

Display all available information for failed tests (not only in travis).

Stop removing the last line. The header pollutes the diff, but the
last line does’t change often.
Also, testing it makes sense in interactive mode.

Move the smoke test into its own directory.
  • Loading branch information
asarhaddon committed Feb 23, 2023
1 parent 05fc5a5 commit b38f027
Show file tree
Hide file tree
Showing 11 changed files with 140 additions and 109 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ $(generated_sources): %: %.in Makefile
.PHONY: test

test: all
cd test && ./run-tests.sh
./test/run

# This Makefile does not support parallelism (but gprbuild does).
.NOTPARALLEL:
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,11 @@ Build-time Dependencies

* GPRBuild
* gnat
* python3 (for tests)

On a Debian-like system, you can install these roughly as follows:

$ apt-get install gprbuild gnat
$ apt-get install gprbuild gnat python3

GNAT versions before 4.9 are believed to link against a buggy runtime on
64-bit platforms, so should be avoided.
Expand Down
1 change: 1 addition & 0 deletions test/01_aeneid/expected.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36285,3 +36285,4 @@ recedo, recedere, recessi, recessus V (3rd) [XXXAX]
recede, go back, withdraw, ebb; retreat; retire; move/keep/pass/slip away;


=>Blank exits =>
1 change: 1 addition & 0 deletions test/02_ius/expected.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ nullus, nulla, nullum (gen -ius) ADJ [XXXAX]
no; none, not any; (PRONominal ADJ)


=>Blank exits =>
1 change: 1 addition & 0 deletions test/03_qualdupes/expected.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ ludius, ludi(i) N (2nd) M [XDXEO] uncommon
dancer; stage performer;


=>Blank exits =>
File renamed without changes.
8 changes: 0 additions & 8 deletions test/ignore-top-and-tail

This file was deleted.

133 changes: 133 additions & 0 deletions test/run
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
#!/usr/bin/python3

"""Test Whitaker's words."""

import glob
import os.path
import shutil
import subprocess
import sys
import tempfile

testdir = os.path.abspath(os.path.dirname(sys.argv[0]))

prog = os.path.join(testdir, '..', 'bin', 'words')
datadir = os.path.join(testdir, '..')
for arg_index in range(1, len(sys.argv)):
arg = sys.argv[arg_index]
if arg.startswith('--prog='):
prog = arg[7:]
elif arg.startswith('--datadir='):
datadir = arg[10:]
else:
print(sys.argv[0], ': unknown argument:', arg)
sys.exit(1)


def check(test: str) -> bool:
"""The test name is a subdirectory in testdir.
If args.txt exists, each line is a command line arguments.
If input.txt exists, its content is passed on standard input.
The standard output must match expected.txt, except that
* trailing whitespaces are ignored,
* the first 18 lines are ignored in interactive mode (if input.txt
exists) because it contains a header, no latin.
"""

# Required to test file inclusion.
os.chdir(os.path.join(testdir, test))

args = [prog]
args_path = 'args.txt'
if os.path.exists(args_path):
with open(args_path, encoding='utf-8') as args_fd:
args.extend(line.rstrip() for line in args_fd)

input_path = 'input.txt'
if os.path.exists(input_path):
with open(input_path, 'rb') as input_fd:
input_bytes = input_fd.read()
else:
input_bytes = b''

words = subprocess.run(args, input=input_bytes,
capture_output=True, check=False)

result = True

if words.returncode != 0:
print(f'Test {test}: return code: {words.returncode}')
result = False

if words.stderr != b'':
print(f'-- Begin of standard error of {test}')
print(words.stderr.decode('utf-8'))
print(f'-- End of standard error of {test}')
result = False

expected_path = 'expected.txt'
got = words.stdout
if input_bytes != b'':
# Skip the interactive mode header.
got = b'\n'.join(got.split(b'\n')[18:])
diff_args = ('diff', '-uZ', expected_path, '-')
# This writes the differences on standard output, if any.
diff = subprocess.run(diff_args, input=got, check=False)
if diff.returncode != 0:
print()
print()
print(f'-- Begin of raw standard output of {test}')
print(words.stdout.decode('utf-8'))
print(f'-- End of raw standard output of {test} (diff above)')
print()
print()
result = False

print('Test', test, ':', ('FAIL', 'PASS')[result])
return result


def run_some_tests() -> dict[str, bool]:
"""
Create a temporary datadir with the test configuration, mostly
in order to select some non-interactive input options. The other
files required at run time are copied from HOWTO.txt.
"""

results: dict[str, bool] = {}

with tempfile.TemporaryDirectory() as temp_dir:
os.environ['WHITAKERS_WORDS_DATADIR'] = temp_dir

shutil.copy(os.path.join(testdir, 'WORD.MDV'), temp_dir)
for data_file in ('INFLECTS.SEC', 'ADDONS.LAT', 'UNIQUES.LAT',
'DICTFILE.GEN', 'STEMFILE.GEN', 'INDXFILE.GEN',
'EWDSFILE.GEN'):
shutil.copy(os.path.join(datadir, data_file), temp_dir)

# If the initial smoke test fails, don't waste time on other
# tests, and just let the whole thing crash.
results['smoke'] = check('smoke')
if results['smoke']:
for test in glob.glob('[0-9][0-9]_*', root_dir=testdir):
results[test] = check(test)

return results


def show(results: dict[str, bool]) -> None:
"""Display a final summary."""
if all(results.values()):
print('All tests passed')
else:
print('Some tests failed:')
for test, result in results.items():
if not result:
print(' ', test)
sys.exit(1)


show(run_some_tests())
99 changes: 0 additions & 99 deletions test/run-tests.sh

This file was deleted.

1 change: 1 addition & 0 deletions test/smoke/args.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
rem acu tetigisti
File renamed without changes.

0 comments on commit b38f027

Please sign in to comment.