commit - faf55781ee6fb6fdcf94f474767adb31a8b78081
commit + 5b15eab651750b51fb7681d796d529d759170d84
blob - /dev/null
blob + d92a49c6cd415f96d377a1a25f7b99b21cb532c5 (mode 644)
--- /dev/null
+++ tests/fixtures/bad.ol
+fn main() {
+ let x: int = "hello";
+}
blob - /dev/null
blob + 89f385be9bb36adbe9e5f6f107768e17e42f2a0c (mode 644)
--- /dev/null
+++ tests/fixtures/countdown.ol
+fn main() {
+ for i in range(5) {
+ print(i);
+ }
+}
blob - /dev/null
blob + fedce3a8a57bb3c91ba27d7f16269bcc9540ded8 (mode 644)
--- /dev/null
+++ tests/fixtures/fizzbuzz.ol
+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
+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
+fn main() {
+ print(1 + 2);
+ print("hello " + "world");
+}
blob - /dev/null
blob + a4f175c4e32d5c1ba0f0a8753a0831e6e0728a75 (mode 644)
--- /dev/null
+++ tests/fixtures/math.ol
+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
+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
+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
+// 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"));
+}