commit 5b15eab651750b51fb7681d796d529d759170d84 from: Murilo Ijanc date: Sun Apr 5 19:00:00 2026 UTC Add integration tests for v0.1 Test suite covering all language features: arithmetic, strings, variables, if/else, while, for/range, functions with implicit/explicit return, type mismatch errors, and all CLI subcommands (run, tokenize, parse, compile). 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' +// +// 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")); +}