diff --git a/example/missing_closing_paren.pl b/example/missing_closing_paren.pl new file mode 100644 index 0000000..f5fbdfc --- /dev/null +++ b/example/missing_closing_paren.pl @@ -0,0 +1,7 @@ +:- use_module(testing). + +test("test with unclosed paren", ( + true +% Missing closing paren here + +test("another test", true). diff --git a/example/passing_test.pl b/example/passing_test.pl new file mode 100644 index 0000000..988888f --- /dev/null +++ b/example/passing_test.pl @@ -0,0 +1,4 @@ +:- use_module(testing). + +test("passing test 1", true). +test("passing test 2", true). diff --git a/example/run_error_detection_tests.sh b/example/run_error_detection_tests.sh new file mode 100755 index 0000000..73c493d --- /dev/null +++ b/example/run_error_detection_tests.sh @@ -0,0 +1,81 @@ +#!/bin/bash + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" + +echo "==========================================" +echo "Testing Framework Error Detection Demo" +echo "==========================================" +echo + +# Test 1: Syntax Error File +echo "TEST 1: File with Syntax Error (Missing Period)" +echo "---" +echo "File: syntax_error_test.pl" +echo +scryer-prolog -f -g run_tests syntax_error_test.pl 2>&1 +EXIT_CODE=$? +echo "Exit code: $EXIT_CODE" +if [ "$EXIT_CODE" -eq 1 ]; then + echo "✓ PASS: Syntax error detected with exit code 1" +else + echo "✗ FAIL: Expected exit code 1, got $EXIT_CODE" +fi +echo + +# Test 2: Passing Tests +echo "TEST 2: Valid File with Passing Tests" +echo "---" +echo "File: passing_test.pl" +echo +scryer-prolog -f -g run_tests passing_test.pl 2>&1 +EXIT_CODE=$? +echo "Exit code: $EXIT_CODE" +if [ "$EXIT_CODE" -eq 0 ]; then + echo "✓ PASS: All tests passed with exit code 0" +else + echo "✗ FAIL: Expected exit code 0, got $EXIT_CODE" +fi +echo + +# Test 3: Mixed Pass/Fail Tests +echo "TEST 3: Valid File with Mixed Pass/Fail Tests" +echo "---" +echo "File: example.pl" +echo +scryer-prolog -f -g run_tests example.pl 2>&1 +EXIT_CODE=$? +echo "Exit code: $EXIT_CODE" +if [ "$EXIT_CODE" -eq 1 ]; then + echo "✓ PASS: Tests ran with failures detected, exit code 1" +else + echo "✗ FAIL: Expected exit code 1, got $EXIT_CODE" +fi +echo + +# Test 4: Another Syntax Error +echo "TEST 4: File with Syntax Error (Missing Closing Paren)" +echo "---" +echo "File: missing_closing_paren.pl" +echo +scryer-prolog -f -g run_tests missing_closing_paren.pl 2>&1 +EXIT_CODE=$? +echo "Exit code: $EXIT_CODE" +if [ "$EXIT_CODE" -eq 1 ]; then + echo "✓ PASS: Syntax error detected with exit code 1" +else + echo "✗ FAIL: Expected exit code 1, got $EXIT_CODE" +fi +echo + +echo "==========================================" +echo "Test Summary" +echo "==========================================" +echo +echo "The testing framework now:" +echo " • Detects when test files fail to load (syntax errors)" +echo " • Shows clear RED error messages" +echo " • Returns exit code 1 for file loading errors" +echo " • Returns exit code 0 when all tests pass" +echo " • Returns exit code 1 when any tests fail" +echo diff --git a/example/syntax_error_test.pl b/example/syntax_error_test.pl new file mode 100644 index 0000000..8b713f4 --- /dev/null +++ b/example/syntax_error_test.pl @@ -0,0 +1,8 @@ +:- use_module(testing). + +test("this should work", true). + +% Syntax error: missing period +test("this has syntax error", true) + +test("another test", false). diff --git a/testing.pl b/testing.pl index 77e6233..023f86d 100644 --- a/testing.pl +++ b/testing.pl @@ -75,6 +75,9 @@ After running, `run_tests/1` exits with a status code of 0 if all tests that were run succeeded and 1 otherwise. This makes it possible to check if tests pass inside scripts. + +If no tests are found in any of the searched modules, the framework will report an error in red text, +as this typically indicates a file loading failure (e.g., syntax error). The exit code will be set to 1. */ % SPDX-License-Identifier: Unlicense @@ -114,22 +117,40 @@ run_tests_opt(Modules, Color, Filter, Halt) :- maplist(module_mtests, Modules, MTests), - maplist( - [Color,Filter]+\(Module-Tests)^Succ^run_tests_module_opt(Module, Tests, Color, Filter, Succ), - MTests, - Successes - ), - ( all_succeeded(Successes) -> + collect_all_tests(MTests, AllTests), + ( AllTests == [] -> ( Halt == true -> - halt - ; true - ) - ; ( Halt == true -> + portray((ansi(Color, red), "\nERROR: No tests found. This may indicate a file loading error.", ansi(Color, reset), "\n")), halt(1) - ; false + ; ( + portray((ansi(Color, red), "\nERROR: No tests found. This may indicate a file loading error.", ansi(Color, reset), "\n")), + false + ) ) + ; ( + maplist( + [Color,Filter]+\(Module-Tests)^Succ^run_tests_module_opt(Module, Tests, Color, Filter, Succ), + MTests, + Successes + ), + ( all_succeeded(Successes) -> + ( Halt == true -> + halt + ; true + ) + ; ( Halt == true -> + halt(1) + ; false + ) + ) + ) ). +collect_all_tests([], []). +collect_all_tests([_-Tests|Rest], AllTests) :- + collect_all_tests(Rest, RestTests), + append(Tests, RestTests, AllTests). + module_tests(Module, Tests) :- catch( findall(