#![cfg(feature = "notebook")]
#![allow(missing_docs)]
use assert_cmd::Command;
use predicates::prelude::*;
use std::fs;
use tempfile::TempDir;
fn ruchy_cmd() -> Command {
assert_cmd::cargo::cargo_bin_cmd!("ruchy")
}
fn create_temp_file(dir: &TempDir, name: &str, content: &str) -> std::path::PathBuf {
let path = dir.path().join(name);
fs::write(&path, content).expect("Failed to write temp file");
path
}
#[test]
fn cli_notebook_validate_file_exits_zero() {
let temp = TempDir::new().unwrap();
let file = create_temp_file(&temp, "simple.ruchy", "let x = 42\nprintln(x)\n");
ruchy_cmd().arg("notebook").arg(&file).assert().success(); }
#[test]
fn cli_notebook_validate_missing_file_exits_nonzero() {
ruchy_cmd()
.arg("notebook")
.arg("nonexistent_xyz.ruchy")
.assert()
.failure(); }
#[test]
fn cli_notebook_validate_syntax_error_exits_nonzero() {
let temp = TempDir::new().unwrap();
let file = create_temp_file(&temp, "invalid.ruchy", "let x = \n");
ruchy_cmd().arg("notebook").arg(&file).assert().failure(); }
#[test]
fn cli_notebook_validate_outputs_success_message() {
let temp = TempDir::new().unwrap();
let file = create_temp_file(&temp, "validate_test.ruchy", "let x = 42\n");
ruchy_cmd()
.arg("notebook")
.arg(&file)
.assert()
.success()
.stdout(
predicate::str::contains("valid")
.or(predicate::str::contains("Valid"))
.or(predicate::str::contains("success")),
);
}
#[test]
fn cli_notebook_custom_port() {
ruchy_cmd()
.arg("notebook")
.arg("--port")
.arg("9090")
.timeout(std::time::Duration::from_secs(2))
.assert(); }
#[test]
fn cli_notebook_invalid_port_format() {
ruchy_cmd()
.arg("notebook")
.arg("--port")
.arg("invalid")
.assert()
.failure(); }
#[test]
fn cli_notebook_port_out_of_range() {
ruchy_cmd()
.arg("notebook")
.arg("--port")
.arg("99999") .assert()
.failure(); }
#[test]
fn cli_notebook_custom_host() {
ruchy_cmd()
.arg("notebook")
.arg("--host")
.arg("0.0.0.0")
.timeout(std::time::Duration::from_secs(2))
.assert(); }
#[test]
fn cli_notebook_localhost_host() {
ruchy_cmd()
.arg("notebook")
.arg("--host")
.arg("localhost")
.timeout(std::time::Duration::from_secs(2))
.assert();
}
#[test]
#[ignore = "Opens browser - slow test, run in tier3-nightly"]
fn cli_notebook_open_browser_flag() {
ruchy_cmd()
.arg("notebook")
.arg("--open")
.timeout(std::time::Duration::from_secs(2))
.assert(); }
#[test]
fn cli_notebook_validate_with_port_option() {
let temp = TempDir::new().unwrap();
let file = create_temp_file(&temp, "port_test.ruchy", "let x = 42\n");
ruchy_cmd()
.arg("notebook")
.arg(&file)
.arg("--port")
.arg("9090")
.assert()
.success();
}
#[test]
fn cli_notebook_validate_with_host_option() {
let temp = TempDir::new().unwrap();
let file = create_temp_file(&temp, "host_test.ruchy", "let x = 42\n");
ruchy_cmd()
.arg("notebook")
.arg(&file)
.arg("--host")
.arg("localhost")
.assert()
.success();
}
#[test]
fn cli_notebook_missing_file_writes_stderr() {
ruchy_cmd()
.arg("notebook")
.arg("missing.ruchy")
.assert()
.failure()
.stderr(
predicate::str::contains("not found")
.or(predicate::str::contains("No such file"))
.or(predicate::str::contains("does not exist")),
);
}
#[test]
fn cli_notebook_syntax_error_writes_stderr() {
let temp = TempDir::new().unwrap();
let file = create_temp_file(&temp, "bad_syntax.ruchy", "fun f( { }\n");
ruchy_cmd()
.arg("notebook")
.arg(&file)
.assert()
.failure()
.stderr(predicate::str::is_empty().not()); }
#[test]
fn cli_notebook_empty_file_fails() {
let temp = TempDir::new().unwrap();
let file = create_temp_file(&temp, "empty.ruchy", "");
ruchy_cmd()
.arg("notebook")
.arg(&file)
.assert()
.failure()
.stderr(
predicate::str::contains("Unexpected end of input")
.or(predicate::str::contains("Parse error"))
.or(predicate::str::contains("Empty program")),
);
}
#[test]
fn cli_notebook_complex_program() {
let temp = TempDir::new().unwrap();
let file = create_temp_file(
&temp,
"complex.ruchy",
r"
fun factorial(n) {
if n <= 1 {
1
} else {
n * factorial(n - 1)
}
}
let result = factorial(5)
println(result)
",
);
ruchy_cmd().arg("notebook").arg(&file).assert().success();
}
#[test]
fn cli_notebook_notebook_with_cells() {
let temp = TempDir::new().unwrap();
let file = create_temp_file(
&temp,
"notebook_cells.ruchy",
r"
let x = 42
println(x)
let y = x * 2
println(y)
let z = y + x
println(z)
",
);
ruchy_cmd().arg("notebook").arg(&file).assert().success();
}
#[test]
fn cli_notebook_help_flag() {
ruchy_cmd()
.arg("notebook")
.arg("--help")
.assert()
.success()
.stdout(
predicate::str::contains("notebook")
.or(predicate::str::contains("Notebook"))
.or(predicate::str::contains("interactive")),
);
}
#[test]
fn cli_notebook_validate_with_functions() {
let temp = TempDir::new().unwrap();
let file = create_temp_file(
&temp,
"functions.ruchy",
r"
fun add(a, b) {
a + b
}
fun multiply(a, b) {
a * b
}
let result1 = add(5, 3)
let result2 = multiply(result1, 2)
println(result2)
",
);
ruchy_cmd().arg("notebook").arg(&file).assert().success();
}
#[test]
fn cli_notebook_validate_with_loops() {
let temp = TempDir::new().unwrap();
let file = create_temp_file(
&temp,
"loops.ruchy",
r"
for i in range(10) {
println(i)
}
let sum = 0
for i in range(5) {
sum = sum + i
}
println(sum)
",
);
ruchy_cmd().arg("notebook").arg(&file).assert().success();
}
#[test]
fn cli_notebook_validate_with_conditionals() {
let temp = TempDir::new().unwrap();
let file = create_temp_file(
&temp,
"conditionals.ruchy",
r#"
let x = 42
if x > 40 {
println("x is greater than 40")
} else {
println("x is not greater than 40")
}
let y = if x > 50 { 100 } else { 50 }
println(y)
"#,
);
ruchy_cmd().arg("notebook").arg(&file).assert().success();
}
#[test]
fn cli_notebook_validate_with_arrays() {
let temp = TempDir::new().unwrap();
let file = create_temp_file(
&temp,
"arrays.ruchy",
r"
let arr = [1, 2, 3, 4, 5]
for item in arr {
println(item)
}
let sum = 0
for i in range(5) {
sum = sum + arr[i]
}
println(sum)
",
);
ruchy_cmd().arg("notebook").arg(&file).assert().success();
}
#[test]
fn cli_notebook_validate_with_strings() {
let temp = TempDir::new().unwrap();
let file = create_temp_file(
&temp,
"strings.ruchy",
r#"
let greeting = "Hello"
let name = "World"
let message = greeting + " " + name
println(message)
let upper = message.to_uppercase()
println(upper)
"#,
);
ruchy_cmd().arg("notebook").arg(&file).assert().success();
}