J.J. Tolton [Sun, 9 Nov 2025 18:04:59 +0000 (13:04 -0500)]
Move -t and -g flags before filenames in tests
Per maintainer feedback, switches must come before files to follow
the convention: switches before files are Scryer-specific, switches
after files are application-specific.
J.J. Tolton [Sun, 9 Nov 2025 17:56:02 +0000 (12:56 -0500)]
Remove redundant unit test file
The custom_toplevel.pl unit tests were trivial and didn't actually test
the functionality. All real testing is done via comprehensive CLI tests
in tests/scryer/cli/src_tests/custom_toplevel.md
J.J. Tolton [Sun, 9 Nov 2025 17:16:02 +0000 (12:16 -0500)]
Move g_caused_exception/2 dynamic directive to toplevel.pl
- Add dynamic directive in toplevel.pl with other module-level directives
- Update test files to reference it as '':g_caused_exception/2
- Remove redundant dynamic directives from test files
- All tests passing
J.J. Tolton [Sat, 8 Nov 2025 17:59:00 +0000 (12:59 -0500)]
Add comprehensive tests for g_caused_exception/2
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
J.J. Tolton [Sat, 8 Nov 2025 17:43:46 +0000 (12:43 -0500)]
Add g_caused_exception/2 for custom toplevel error handling
When a goal throws an exception during initialization (-g flag), the
system now asserts g_caused_exception(Goal, Exception) in the user
module. This allows custom toplevels (-t flag) to check if an error
occurred and handle it appropriately.
Example usage:
scryer-prolog -g "throw(error)" -t check_error
Where check_error can be:
:- dynamic(g_caused_exception/2).
J.J. Tolton [Fri, 7 Nov 2025 00:39:21 +0000 (19:39 -0500)]
Fix bug where -t argument was processed as filename
Fixed issue where `scryer-prolog -t halt` would try to load "halt.pl"
as a file instead of just using halt as the custom toplevel.
The bug was caused by an extra clause `delegate_task([], []).` that
would return control to the calling context instead of continuing to
start_toplevel. This caused the argument processing in delegate_task
to continue and treat the already-consumed toplevel argument as a
filename.
Removing this clause ensures that delegate_task([], Goals0) always
proceeds to load initialization files and start the toplevel, fixing
the double-processing bug.
J.J. Tolton [Fri, 7 Nov 2025 00:12:09 +0000 (19:12 -0500)]
Add comprehensive tests for -t custom toplevel flag
- Create Prolog integration tests in src/tests/custom_toplevel.pl
- Add CLI test configuration in tests/scryer/cli/src_tests/custom_toplevel_tests.toml
- Tests verify:
* -t halt terminates after initialization
* Custom toplevels can be user-defined predicates
* Toplevel receives control after initialization completes
* Default behavior is REPL when no -t specified
- All tests pass successfully
Following TESTING_GUIDE.md three-layer testing approach:
- Layer 2: Prolog integration tests with test_framework
- Layer 3: CLI snapshot tests with .toml configuration
J.J. Tolton [Fri, 7 Nov 2025 00:02:30 +0000 (19:02 -0500)]
-t custom toplevel option
- Add -t FLAG to specify custom toplevel (arity 0 predicate)
- Default toplevel is 'repl' if -t is not specified
- Using `-t halt` achieves original goal of guaranteed termination
- Custom toplevels enable flexible exit strategies (e.g., server mode)
- Update help text to document -t flag
deref register to access stack variable for `directory_exists/1`
deref register to access stack variable for `directory_files/2`
deref register to access stack variable for `delete_directory/1`
deref register to access stack variable for `delete_file/1`
deref registers to access stack variable for `file_copy/2`
deref register to access stack variable for `file_exists/1`
deref register to access stack variable for `file_size/2`
deref register to access stack variable from `file_time` function
deref register to access stack variable for `make_directory/1`
deref register to access stack variable for `make_directory_path/1`
deref register to access stack variable for `path_canonical/2`
deref registers to access stack variables for `rename_file/2`
reproduce failing `directory_exists/1` with working directory passed as first argument
reproduce failing `delete_directory/1` with ./test directory passed as first argument
reproduce failing `file_size/1` with 2 bytes files passed as first argument
reproduce failing `file_exists/1` with existing file passed as first argument
reproduce failing `file_modification_time/1`, `file_access_time/1` and `file_creation_time/1` with existing file passed as first argument
reproduce failing `directory_files/2` with existing directory passed as first argument
reproduce failing `delete_file/1` with existing file passed as first argument
reproduce failing `make_directory/1` with non-existing directory passed as first argument
reproduce failing `make_directory_path/1` with non-existing path passed as first argument
reproduce failing `path_canonical/2` with non-canonical path passed as first argument
reproduce failing `rename_file/2` with existing file passed as first argument, target file as second arg
revised `directory_exists/1` test case
renamed test files, test directories
use `path_segments/2`, remove path separators
do not write file size to current output
revised `directory_files/2` test
revised `path_canonical/2` test
revised `file_exists/1` test
removed hardcoded expected size
extracted hardcoded directory argument
remove path prefix containing path separator
revised expected ls cmd exit code so that it is platform-agnostic