"nodrop",
]
+[[package]]
+name = "assert_cmd"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f2475b58cd94eb4f70159f4fd8844ba3b807532fe3131b3373fae060bbe30396"
+dependencies = [
+ "bstr",
+ "doc-comment",
+ "predicates",
+ "predicates-core",
+ "predicates-tree",
+ "wait-timeout",
+]
+
[[package]]
name = "autocfg"
version = "0.1.7"
"byte-tools",
]
+[[package]]
+name = "bstr"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a40b47ad93e1a5404e6c18dec46b628214fee441c70f4ab5d6942142cc268a3d"
+dependencies = [
+ "lazy_static",
+ "memchr",
+ "regex-automata",
+]
+
[[package]]
name = "bumpalo"
version = "3.6.0"
"subtle",
]
+[[package]]
+name = "difference"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
+
[[package]]
name = "digest"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc9f8914dcb99891bdfee82536bbff8d9aa612b0dbe83872afbc66902bdec0b9"
+[[package]]
+name = "doc-comment"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
+
[[package]]
name = "downcast"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
+[[package]]
+name = "predicates"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eeb433456c1a57cc93554dea3ce40b4c19c4057e41c55d4a0f3d84ea71c325aa"
+dependencies = [
+ "difference",
+ "predicates-core",
+]
+
+[[package]]
+name = "predicates-core"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "57e35a3326b75e49aa85f5dc6ec15b41108cf5aee58eabb1f274dd18b73c2451"
+
+[[package]]
+name = "predicates-tree"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "15f553275e5721409451eb85e15fd9a860a6e5ab4496eb215987502b5f5391f2"
+dependencies = [
+ "predicates-core",
+ "treeline",
+]
+
[[package]]
name = "proc-macro-hack"
version = "0.5.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d813022b2e00774a48eaf43caaa3c20b45f040ba8cbf398e2e8911a06668dbe6"
+[[package]]
+name = "regex-automata"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4"
+dependencies = [
+ "byteorder",
+]
+
[[package]]
name = "remove_dir_all"
version = "0.5.3"
name = "scryer-prolog"
version = "0.8.128"
dependencies = [
+ "assert_cmd",
"base64",
"blake2",
"chrono",
"num-rug-adapter",
"openssl",
"ordered-float",
+ "predicates-core",
"prolog_parser",
"ref_thread_local",
"ring",
"winapi 0.3.9",
]
+[[package]]
+name = "treeline"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a7f741b240f1a48843f9b8e0444fb55fb2a4ff67293b50a9179dfd5ea67f8d41"
+
[[package]]
name = "typenum"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
+[[package]]
+name = "wait-timeout"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6"
+dependencies = [
+ "libc",
+]
+
[[package]]
name = "wasi"
version = "0.10.2+wasi-snapshot-preview1"
base64 = "0.12.3"
sodiumoxide = "0.2.6"
slice-deque = "0.3.0"
+
+[dev-dependencies]
+assert_cmd = "1.0.3"
+predicates-core = "1.0.2"
--- /dev/null
+:- use_module(library(debug)).
+:- use_module(library(format)).
+
+missing_dot :- write('Not "." at the end of the line'), nl
+
+:- initialize(missing_dot).
\ No newline at end of file
+++ /dev/null
-/// Loads the file and if some expected output is given checks that it matches
-fn test_file(file: &str, expected: Option<&[u8]>) {
- use scryer_prolog::*;
-
- let input = machine::Stream::from("");
- let output = machine::Stream::from(String::new());
-
- let mut wam = machine::Machine::new(input, output.clone());
-
- wam.load_file(
- file.into(),
- machine::Stream::from(
- std::fs::read_to_string(AsRef::<std::path::Path>::as_ref(file)).unwrap(),
- ),
- );
-
- if let Some(expected) = expected {
- let output = output.bytes().unwrap();
- assert_eq!(output.as_slice(), expected);
- }
-}
-
-#[test]
-fn builtins() {
- test_file("src/tests/builtins.pl", Some(b""));
-}
-
-#[test]
-fn call_with_inference_limit() {
- test_file("src/tests/call_with_inference_limit.pl", Some(b""));
-}
-
-#[test]
-fn facts() {
- test_file("src/tests/facts.pl", Some(b""));
-}
-
-#[test]
-fn hello_world() {
- test_file(
- "src/tests/hello_world.pl",
- Some("Hello World!\n".as_bytes()),
- );
-}
-
-#[test]
-fn predicates() {
- test_file("src/tests/predicates.pl", Some(b""));
-}
-
-#[test]
-fn rules() {
- test_file("src/tests/rules.pl", Some(b""));
-}
-
-#[test]
-#[ignore] // ignored as this does not appear to terminate
-fn setup_call_cleanup() {
- test_file("src/tests/setup_call_cleanup.pl", Some(b""));
-}
-
-#[test]
-#[ignore] // ignored as this does not terminate
-fn clpz() {
- test_file("src/tests/clpz/test_clpz.pl", Some(b""));
-}
--- /dev/null
+use assert_cmd::Command;
+use std::ffi::OsStr;
+
+pub(crate) trait Expectable {
+ #[track_caller]
+ fn assert_eq(self, other: &[u8]);
+}
+
+impl Expectable for &str {
+ #[track_caller]
+ fn assert_eq(self, other: &[u8]) {
+ if let Ok(other_str) = std::str::from_utf8(other) {
+ assert_eq!(other_str, self)
+ } else {
+ // should always fail as other is not valid utf-8 but self is
+ // just for consistent assert error message
+ assert_eq!(other, self.as_bytes())
+ }
+ }
+}
+
+impl Expectable for &[u8] {
+ #[track_caller]
+ fn assert_eq(self, other: &[u8]) {
+ assert_eq!(other, self)
+ }
+}
+
+/// Tests whether the file can be successfully loaded
+/// and produces the expected output during it
+pub(crate) fn load_module_test<T: Expectable>(file: &str, expected: T) {
+ use scryer_prolog::*;
+
+ let input = machine::Stream::from("");
+ let output = machine::Stream::from(String::new());
+
+ let mut wam = machine::Machine::new(input, output.clone());
+
+ wam.load_file(
+ file.into(),
+ machine::Stream::from(
+ std::fs::read_to_string(AsRef::<std::path::Path>::as_ref(file)).unwrap(),
+ ),
+ );
+
+ let output = output.bytes().unwrap();
+ expected.assert_eq(output.as_slice());
+}
+
+pub const SCRYER_PROLOG: &str = "scryer-prolog";
+
+pub fn run_top_level_test_no_args<
+ S: Into<Vec<u8>>,
+ O: assert_cmd::assert::IntoOutputPredicate<P>,
+ P: predicates_core::Predicate<[u8]>,
+>(
+ stdin: S,
+ expected_stdout: O,
+) {
+ run_top_level_test_with_args::<&[&str], _, _, _, _>(&[], stdin, expected_stdout)
+}
+
+/// Test whether scryr-prolog
+/// produces the expected output when called with the supplied
+/// arguments and fed the supplied input
+pub fn run_top_level_test_with_args<
+ A: IntoIterator<Item = AS>,
+ S: Into<Vec<u8>>,
+ O: assert_cmd::assert::IntoOutputPredicate<P>,
+ AS: AsRef<OsStr>,
+ P: predicates_core::Predicate<[u8]>,
+>(
+ args: A,
+ stdin: S,
+ expected_stdout: O,
+) {
+ Command::cargo_bin(SCRYER_PROLOG)
+ .unwrap()
+ .args(args)
+ .write_stdin(stdin)
+ .assert()
+ .stdout(expected_stdout.into_output())
+ .success();
+}
--- /dev/null
+mod helper;
+
+mod src_tests;
--- /dev/null
+use crate::helper::{load_module_test, run_top_level_test_with_args};
+
+#[test]
+fn builtins() {
+ load_module_test("src/tests/builtins.pl", "");
+}
+
+#[test]
+fn call_with_inference_limit() {
+ load_module_test("src/tests/call_with_inference_limit.pl", "");
+}
+
+#[test]
+fn facts() {
+ load_module_test("src/tests/facts.pl", "");
+}
+
+#[test]
+fn hello_world() {
+ load_module_test("src/tests/hello_world.pl", "Hello World!\n");
+}
+
+#[test]
+fn syntax_error() {
+ load_module_test(
+ "tests-pl/syntax_error.pl",
+ "caught: error(syntax_error(incomplete_reduction),read_term/3:5)\n",
+ );
+}
+
+#[test]
+fn predicates() {
+ load_module_test("src/tests/predicates.pl", "");
+}
+
+#[test]
+fn rules() {
+ load_module_test("src/tests/rules.pl", "");
+}
+
+#[test]
+fn setup_call_cleanup_load() {
+ load_module_test("src/tests/setup_call_cleanup.pl", "caught: unthrown\n");
+}
+
+#[test]
+fn setup_call_cleanup_process() {
+ run_top_level_test_with_args(
+ &["src/tests/setup_call_cleanup.pl"],
+ "",
+ "caught: unthrown\n",
+ );
+}
+
+#[test]
+#[ignore] // ignored as this does not terminate
+fn clpz_load() {
+ load_module_test("src/tests/clpz/test_clpz.pl", "");
+}