Commit Diff


commit - faf55781ee6fb6fdcf94f474767adb31a8b78081
commit + 5b15eab651750b51fb7681d796d529d759170d84
blob - /dev/null
blob + d92a49c6cd415f96d377a1a25f7b99b21cb532c5 (mode 644)
--- /dev/null
+++ tests/fixtures/bad.ol
@@ -0,0 +1,3 @@
+fn main() {
+    let x: int = "hello";
+}
blob - /dev/null
blob + 89f385be9bb36adbe9e5f6f107768e17e42f2a0c (mode 644)
--- /dev/null
+++ tests/fixtures/countdown.ol
@@ -0,0 +1,5 @@
+fn main() {
+    for i in range(5) {
+        print(i);
+    }
+}
blob - /dev/null
blob + fedce3a8a57bb3c91ba27d7f16269bcc9540ded8 (mode 644)
--- /dev/null
+++ tests/fixtures/fizzbuzz.ol
@@ -0,0 +1,15 @@
+fn main() {
+    let mut i = 1;
+    while i <= 20 {
+        if i % 15 == 0 {
+            print("FizzBuzz");
+        } else if i % 3 == 0 {
+            print("Fizz");
+        } else if i % 5 == 0 {
+            print("Buzz");
+        } else {
+            print(i);
+        }
+        i = i + 1;
+    }
+}
blob - /dev/null
blob + efc7b22660682b4343cd68fa3ee92731f6db35bb (mode 644)
--- /dev/null
+++ tests/fixtures/functions.ol
@@ -0,0 +1,15 @@
+fn add(a: int, b: int) -> int {
+    a + b
+}
+
+fn abs(x: int) -> int {
+    if x < 0 {
+        return -x;
+    }
+    x
+}
+
+fn main() {
+    print(add(3, 4));
+    print(abs(-42));
+}
blob - /dev/null
blob + c45c1a96fb17af371a179244e078f266715ca1a5 (mode 644)
--- /dev/null
+++ tests/fixtures/hello.ol
@@ -0,0 +1,4 @@
+fn main() {
+    print(1 + 2);
+    print("hello " + "world");
+}
blob - /dev/null
blob + a4f175c4e32d5c1ba0f0a8753a0831e6e0728a75 (mode 644)
--- /dev/null
+++ tests/fixtures/math.ol
@@ -0,0 +1,8 @@
+fn main() {
+    print(10 - 3);
+    print(6 * 7);
+    print(100 / 4);
+    print(17 % 5);
+    print(-42);
+    print(3.14 + 1.0);
+}
blob - /dev/null
blob + 7cf7a37a29d2477887cdce21cc8ea0cfca318025 (mode 644)
--- /dev/null
+++ tests/fixtures/sum.ol
@@ -0,0 +1,7 @@
+fn main() {
+    let mut total = 0;
+    for i in range(10) {
+        total = total + i;
+    }
+    print(total);
+}
blob - /dev/null
blob + fa74548d811a7448b1c35a4d158c6ee355547619 (mode 644)
--- /dev/null
+++ tests/fixtures/vars.ol
@@ -0,0 +1,6 @@
+fn main() {
+    let x: int = 10;
+    let mut y = 20;
+    y = y + x;
+    print(y);
+}
blob - /dev/null
blob + 697677b148b0b37500fbf2808c35b1ecce153768 (mode 644)
--- /dev/null
+++ tests/integration.rs
@@ -0,0 +1,164 @@
+// vim: set tw=79 cc=80 ts=4 sw=4 sts=4 et :
+//
+// Copyright (c) 2025-2026 Murilo Ijanc' <murilo@ijanc.org>
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+//
+
+use std::process::Command;
+
+fn run_ol(args: &[&str]) -> (String, String, bool) {
+    let output = Command::new(env!("CARGO_BIN_EXE_ol"))
+        .args(args)
+        .output()
+        .expect("failed to run ol");
+
+    let stdout =
+        String::from_utf8_lossy(&output.stdout)
+            .to_string();
+    let stderr =
+        String::from_utf8_lossy(&output.stderr)
+            .to_string();
+
+    (stdout, stderr, output.status.success())
+}
+
+fn fixture(name: &str) -> String {
+    format!("tests/fixtures/{name}")
+}
+
+// --- run tests ---
+
+#[test]
+fn test_hello() {
+    let (stdout, _, ok) =
+        run_ol(&["run", &fixture("hello.ol")]);
+    assert!(ok);
+    assert_eq!(stdout, "3\nhello world\n");
+}
+
+#[test]
+fn test_math() {
+    let (stdout, _, ok) =
+        run_ol(&["run", &fixture("math.ol")]);
+    assert!(ok);
+    let lines: Vec<&str> =
+        stdout.trim().lines().collect();
+    assert_eq!(lines[0], "7");
+    assert_eq!(lines[1], "42");
+    assert_eq!(lines[2], "25");
+    assert_eq!(lines[3], "2");
+    assert_eq!(lines[4], "-42");
+    assert!(lines[5].starts_with("4.14"));
+}
+
+#[test]
+fn test_vars() {
+    let (stdout, _, ok) =
+        run_ol(&["run", &fixture("vars.ol")]);
+    assert!(ok);
+    assert_eq!(stdout.trim(), "30");
+}
+
+#[test]
+fn test_fizzbuzz() {
+    let (stdout, _, ok) =
+        run_ol(&["run", &fixture("fizzbuzz.ol")]);
+    assert!(ok);
+    let lines: Vec<&str> =
+        stdout.trim().lines().collect();
+    assert_eq!(lines.len(), 20);
+    assert_eq!(lines[0], "1");
+    assert_eq!(lines[1], "2");
+    assert_eq!(lines[2], "Fizz");
+    assert_eq!(lines[3], "4");
+    assert_eq!(lines[4], "Buzz");
+    assert_eq!(lines[14], "FizzBuzz");
+    assert_eq!(lines[19], "Buzz");
+}
+
+#[test]
+fn test_functions() {
+    let (stdout, _, ok) =
+        run_ol(&["run", &fixture("functions.ol")]);
+    assert!(ok);
+    assert_eq!(stdout, "7\n42\n");
+}
+
+#[test]
+fn test_countdown() {
+    let (stdout, _, ok) =
+        run_ol(&["run", &fixture("countdown.ol")]);
+    assert!(ok);
+    assert_eq!(stdout, "0\n1\n2\n3\n4\n");
+}
+
+#[test]
+fn test_sum() {
+    let (stdout, _, ok) =
+        run_ol(&["run", &fixture("sum.ol")]);
+    assert!(ok);
+    assert_eq!(stdout.trim(), "45");
+}
+
+// --- error tests ---
+
+#[test]
+fn test_type_mismatch() {
+    let (_, stderr, ok) =
+        run_ol(&["run", &fixture("bad.ol")]);
+    assert!(!ok);
+    assert!(stderr.contains("type mismatch"));
+    assert!(stderr.contains("expected int"));
+    assert!(stderr.contains("found str"));
+    assert!(stderr.contains("bad.ol:2:"));
+}
+
+// --- tokenize tests ---
+
+#[test]
+fn test_tokenize() {
+    let (stdout, _, ok) =
+        run_ol(&["tokenize", &fixture("hello.ol")]);
+    assert!(ok);
+    assert!(stdout.contains("Fn"));
+    assert!(stdout.contains("Ident(\"main\")"));
+    assert!(stdout.contains("Print"));
+    assert!(stdout.contains("Eof"));
+}
+
+// --- compile tests ---
+
+#[test]
+fn test_compile() {
+    let (stdout, _, ok) =
+        run_ol(&["compile", &fixture("hello.ol")]);
+    assert!(ok);
+    assert!(stdout.contains("== main =="));
+    assert!(stdout.contains("Constant"));
+    assert!(stdout.contains("Add"));
+    assert!(stdout.contains("Print"));
+    assert!(stdout.contains("Return"));
+}
+
+// --- parse tests ---
+
+#[test]
+fn test_parse() {
+    let (stdout, _, ok) =
+        run_ol(&["parse", &fixture("hello.ol")]);
+    assert!(ok);
+    assert!(stdout.contains("Program"));
+    assert!(stdout.contains("FnDecl"));
+    assert!(stdout.contains("main"));
+}