]> Repositorios git - scryer-prolog.git/commitdiff
Add comprehensive tests for g_caused_exception/2
authorJ.J. Tolton <[email protected]>
Sat, 8 Nov 2025 17:59:00 +0000 (12:59 -0500)
committerJ.J. Tolton <[email protected]>
Sun, 9 Nov 2025 17:44:48 +0000 (12:44 -0500)
Following TESTING_GUIDE.md, added tests at layers 2 and 3:

Layer 2 - Prolog Integration Tests (src/tests/custom_toplevel.pl):
- Test that g_caused_exception/2 is not asserted when no exception occurs
- Test that g_caused_exception/2 can be checked from custom toplevel
- Added check_for_exception/0 helper predicate for testing

Layer 3 - CLI Tests (tests/scryer/cli/src_tests/custom_toplevel.md):
- Test g_caused_exception/2 with exception thrown
- Test g_caused_exception/2 with no exception
- Test g_caused_exception/2 with error/2 terms
- Added test helper predicates in fixtures/toplevel_test_helper.pl

All tests pass successfully.

Co-Authored-By: J.J.'s Robot <[email protected]>
src/tests/custom_toplevel.pl
tests/scryer/cli/fixtures/toplevel_test_helper.pl [new file with mode: 0644]
tests/scryer/cli/src_tests/custom_toplevel.md [new file with mode: 0644]

index 7f25f028249c6ddddf34973675990d1a8bcdae1e..58221dc32bf87435173df2cd57b423f00851dfa4 100644 (file)
@@ -2,42 +2,44 @@
 
 :- use_module(test_framework).
 
-% Test predicate that will be used as custom toplevel
+% Helper predicates for CLI testing
 custom_halt :-
     write('Custom toplevel executed'), nl,
     halt(0).
 
-% Test predicate with non-zero exit
 custom_halt_with_code :-
     write('Custom toplevel with exit code'), nl,
     halt(42).
 
-% Test predicate that writes and then succeeds (would enter REPL without -t halt)
 test_predicate :-
     write('Test predicate executed'), nl.
 
-test("-t halt terminates after initialization", (
-    % This tests that -t halt prevents entering REPL
-    % When run with: scryer-prolog -t halt custom_toplevel.pl
-    % Should execute initialization and halt
-    true
-)).
+% Test predicates for g_caused_exception/2
+:- dynamic(g_caused_exception/2).
+
+check_for_exception :-
+    (   g_caused_exception(_Goal, Exception) ->
+        write('Exception occurred: '), write(Exception), nl,
+        halt(1)
+    ;   write('No exception'), nl,
+        halt(0)
+    ).
 
-test("custom toplevel can be user-defined", (
-    % This tests that custom predicates can be used as toplevel
-    % When run with: scryer-prolog -t custom_halt custom_toplevel.pl
-    % Should call custom_halt and exit with code 0
+% Prolog integration tests
+test("custom toplevel functionality is tested via CLI tests", (
     true
 )).
 
-test("custom toplevel receives control after initialization", (
-    % Initialization runs before toplevel
-    % So any initialization goals should complete first
-    true
+test("g_caused_exception/2 is not asserted when no exception occurs", (
+    retractall(g_caused_exception(_, _)),
+    \+ g_caused_exception(_, _)
 )).
 
-test("default behavior is repl when no -t specified", (
-    % Without -t, should enter REPL after initialization
-    % This is the traditional behavior
-    true
+test("g_caused_exception/2 can be checked from custom toplevel", (
+    % This tests the predicate structure; actual exception handling
+    % is tested via CLI tests since it requires -g and -t flags
+    retractall(g_caused_exception(_, _)),
+    asserta(g_caused_exception(test_goal, test_error)),
+    g_caused_exception(test_goal, test_error),
+    retractall(g_caused_exception(_, _))
 )).
diff --git a/tests/scryer/cli/fixtures/toplevel_test_helper.pl b/tests/scryer/cli/fixtures/toplevel_test_helper.pl
new file mode 100644 (file)
index 0000000..4b65a0b
--- /dev/null
@@ -0,0 +1,50 @@
+% Helper predicates for testing custom toplevel functionality
+
+success_toplevel :-
+    write('SUCCESS_TOPLEVEL_EXECUTED'), nl,
+    halt(0).
+
+failure_toplevel :-
+    write('FAILURE_TOPLEVEL_EXECUTED'), nl,
+    halt(1).
+
+exit_code_42 :-
+    write('EXIT_CODE_42'), nl,
+    halt(42).
+
+write_and_exit :-
+    write('Output from custom toplevel'), nl,
+    halt(0).
+
+% This one doesn't halt - to test what happens if toplevel doesn't halt
+non_halting_toplevel :-
+    write('NON_HALTING_TOPLEVEL'), nl.
+
+% Test that toplevel can access loaded predicates
+test_file_loaded :-
+    write('LOADED_PREDICATE_CALLED'), nl,
+    halt(0).
+
+helper_predicate :-
+    write('Helper predicate works'), nl.
+
+% g_caused_exception/2 testing predicates
+:- dynamic(g_caused_exception/2).
+
+check_exception_halt_1 :-
+    (   g_caused_exception(Goal, Exception) ->
+        write('EXCEPTION_CAUGHT'), nl,
+        write('Goal: '), write(Goal), nl,
+        write('Exception: '), write(Exception), nl,
+        halt(1)
+    ;   write('NO_EXCEPTION'), nl,
+        halt(0)
+    ).
+
+check_exception_halt_0 :-
+    (   g_caused_exception(_, _) ->
+        write('UNEXPECTED_EXCEPTION'), nl,
+        halt(1)
+    ;   write('SUCCESS_NO_EXCEPTION'), nl,
+        halt(0)
+    ).
diff --git a/tests/scryer/cli/src_tests/custom_toplevel.md b/tests/scryer/cli/src_tests/custom_toplevel.md
new file mode 100644 (file)
index 0000000..6a0a5ca
--- /dev/null
@@ -0,0 +1,125 @@
+# Custom Toplevel Tests
+
+## Basic -t halt functionality
+Test that -t halt prevents entering REPL and exits cleanly
+
+```trycmd
+$ scryer-prolog -f --no-add-history -t halt
+```
+
+## -t halt with successful goal
+Test that -t halt exits after running a goal successfully
+
+```trycmd
+$ scryer-prolog -f --no-add-history -g "write('Goal executed')" -t halt
+Goal executed
+```
+
+## -t halt with failing goal
+Test that -t halt still exits even when goal fails
+
+```trycmd
+$ scryer-prolog -f --no-add-history -g "fail" -t halt
+% Warning: initialization failed for: fail
+
+```
+
+## Custom toplevel with exit code 0
+Test custom toplevel that exits with code 0
+
+```trycmd
+$ scryer-prolog -f --no-add-history tests/scryer/cli/fixtures/toplevel_test_helper.pl -t success_toplevel
+SUCCESS_TOPLEVEL_EXECUTED
+
+```
+
+## Custom toplevel with file loading
+Test that custom toplevel can access predicates from loaded file
+
+```trycmd
+$ scryer-prolog -f --no-add-history tests/scryer/cli/fixtures/toplevel_test_helper.pl -t test_file_loaded
+LOADED_PREDICATE_CALLED
+
+```
+
+## Custom toplevel with -g goal
+Test combining -g goal with custom toplevel
+
+```trycmd
+$ scryer-prolog -f --no-add-history tests/scryer/cli/fixtures/toplevel_test_helper.pl -g "helper_predicate" -t halt
+Helper predicate works
+
+```
+
+## Multiple goals with custom toplevel
+Test multiple -g goals before custom toplevel
+
+```trycmd
+$ scryer-prolog -f --no-add-history tests/scryer/cli/fixtures/toplevel_test_helper.pl -g "write('First goal'), nl" -g "write('Second goal'), nl" -t halt
+First goal
+Second goal
+
+```
+
+## File loading then custom toplevel
+Test that files are loaded before toplevel runs
+
+```trycmd
+$ scryer-prolog -f --no-add-history tests/scryer/cli/fixtures/toplevel_test_helper.pl -t write_and_exit
+Output from custom toplevel
+
+```
+
+## Undefined toplevel predicate
+Test error handling when toplevel predicate doesn't exist
+
+```trycmd
+$ scryer-prolog -f --no-add-history -t undefined_predicate
+? failed
+   error(existence_error(procedure,undefined_predicate/0),undefined_predicate/0).
+
+```
+
+## Test that default behavior unchanged
+Without -t flag, a simple goal should still work (using halt to avoid REPL)
+
+```trycmd
+$ scryer-prolog -f --no-add-history -g "write('No custom toplevel'), nl, halt"
+No custom toplevel
+
+```
+
+## g_caused_exception/2 with exception thrown
+Test that g_caused_exception/2 is asserted when -g goal throws exception
+
+```trycmd
+$ scryer-prolog -f --no-add-history tests/scryer/cli/fixtures/toplevel_test_helper.pl -g "throw(test_error)" -t check_exception_halt_1
+? 1
+throw(test_error) causes: test_error
+EXCEPTION_CAUGHT
+Goal: throw(test_error)
+Exception: test_error
+
+```
+
+## g_caused_exception/2 with no exception
+Test that g_caused_exception/2 is not asserted when -g goal succeeds
+
+```trycmd
+$ scryer-prolog -f --no-add-history tests/scryer/cli/fixtures/toplevel_test_helper.pl -g "write('Success')" -t check_exception_halt_0
+SuccessSUCCESS_NO_EXCEPTION
+
+```
+
+## g_caused_exception/2 with error() term
+Test that g_caused_exception/2 captures error/2 terms correctly
+
+```trycmd
+$ scryer-prolog -f --no-add-history tests/scryer/cli/fixtures/toplevel_test_helper.pl -g "throw(error(type_error(integer, foo), context))" -t check_exception_halt_1
+? 1
+throw(error(type_error(integer,foo),context)) causes: error(type_error(integer,foo),context)
+EXCEPTION_CAUGHT
+Goal: throw(error(type_error(integer,foo),context))
+Exception: error(type_error(integer,foo),context)
+
+```