From fe9f5be23bd4a07151dba9e64a320ad6b81b7620 Mon Sep 17 00:00:00 2001 From: Akuli Date: Thu, 7 Dec 2023 17:48:15 +0200 Subject: [PATCH] add doctest script --- doctest.sh | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100755 doctest.sh diff --git a/doctest.sh b/doctest.sh new file mode 100755 index 00000000..7fd3cf2d --- /dev/null +++ b/doctest.sh @@ -0,0 +1,89 @@ +#!/usr/bin/env bash +# +# This file runs code snippets in doc/*.md files. + +set -e -o pipefail + +for arg in "$@"; do + if [[ "$arg" =~ ^- ]]; then + echo "Usage: $0 [doc/file1.md doc/file2.md ...]" >&2 + exit 2 + fi +done + +if [ $# == 0 ]; then + files=(doc/*.md) +else + files=("$@") +fi + +if [[ "$OS" =~ Windows ]]; then + source activate + mingw32-make + jou="$PWD/jou.exe" +else + make + jou="$PWD/jou" +fi + +function slice() +{ + local first_lineno="$1" + local last_lineno="$2" + local num_lines=$((last_lineno - first_lineno + 1)) + head -n $last_lineno | tail -n $num_lines +} + +function generate_expected_output() +{ + local joufile="$1" + + (grep -onH '# Warning: .*' "$joufile" || true) | sed -E s/'(.*):([0-9]*):# Warning: '/'compiler warning for file "test.jou", line \2: '/ + (grep -onH '# Error: .*' "$joufile" || true) | sed -E s/'(.*):([0-9]*):# Error: '/'compiler error in file "\1", line \2: '/ + (grep -oE '# Output:.*' "$joufile" || true) | sed -E s/'^# Output: ?'// +} + +rm -rf tmp/doctest +mkdir tmp/doctest + +for file in "${files[@]}"; do + echo "Extracting doctests from $file..." + mkdir tmp/doctest/"$(basename "$file")" + + for start_marker_lineno in $(grep -n '^```python$' "$file" | cut -d: -f1); do + outfile="tmp/doctest/$(basename "$file")/$((start_marker_lineno + 1)).jou" + awk -v n=$start_marker_lineno '(/^```$/ && line > n) { stop=1 } (++line > n && !stop) { print }' "$file" > "$outfile" + + # Do not test if there is no expected output/errors + if [ -z "$(generate_expected_output "$outfile")" ]; then + rm "$outfile" + fi + done +done + +ntotal=$(ls -1 tmp/doctest/*/*.jou | wc -l) +if [ $ntotal == 0 ]; then + echo "*** Error: no doctests found ***" >&2 + exit 1 +fi +echo "Running $ntotal doctests..." +nfail=0 + +cd tmp/doctest +for file in */*.jou; do + echo "${file%.*}" | tr '/' ':' # foo.md/123.jou --> foo.md:123 + cp "$file" test.jou + if diff --text -u --color=always <(generate_expected_output test.jou | tr -d '\r') <( "$jou" test.jou 2>&1 || true | tr -d '\r'); then + echo " ok" + else + ((nfail++)) || true + fi +done + +echo "" +echo "" + +echo "$((ntotal-nfail)) succeeded, $nfail failed" +if [ $nfail != 0 ]; then + exit 1 +fi