1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#![allow(missing_docs)]
//! Regression tests for Issue #81: panic!() and undefined functions return exit code 0
//!
//! Bug: panic!() and undefined function calls should return non-zero exit codes
//! Expected: Exit code 1 (or other non-zero)
//! Actual: Exit code 0 (success)
//!
//! GitHub Issue: <https://github.com/paiml/ruchy/issues/81>
//! Ticket: DEBUGGER-013
use predicates::prelude::*;
use std::io::Write;
use tempfile::NamedTempFile;
/// Test 1: panic!() should return non-zero exit code
#[test]
fn test_regression_081_panic_returns_nonzero_exit_code() {
let mut temp_file = NamedTempFile::new().unwrap();
writeln!(
temp_file,
r#"
fun main() {{
panic!("intentional crash");
}}
"#
)
.unwrap();
// RED TEST: This should FAIL (currently returns exit code 0)
assert_cmd::cargo::cargo_bin_cmd!("ruchy")
.arg("run")
.arg(temp_file.path())
.assert()
.failure() // Expect non-zero exit code
.stderr(predicate::str::contains("panic")); // Expect error message
}
/// Test 2: Undefined function call should return non-zero exit code
/// NOTE: Currently ignored - Ruchy treats undefined functions as valid (return Nil)
/// This requires language-level changes to add function existence checking
#[test]
#[ignore = "Language limitation: undefined functions return Nil instead of error"]
fn test_regression_081_undefined_function_returns_nonzero_exit_code() {
let mut temp_file = NamedTempFile::new().unwrap();
writeln!(
temp_file,
r"
fun main() {{
undefined_function_that_does_not_exist();
}}
"
)
.unwrap();
// RED TEST: This should FAIL (currently returns exit code 0)
assert_cmd::cargo::cargo_bin_cmd!("ruchy")
.arg("run")
.arg(temp_file.path())
.assert()
.failure() // Expect non-zero exit code
.stderr(predicate::str::contains("not found").or(predicate::str::contains("undefined")));
}
/// Test 3: Successful execution should return exit code 0
#[test]
fn test_regression_081_success_returns_zero_exit_code() {
let mut temp_file = NamedTempFile::new().unwrap();
writeln!(
temp_file,
r#"
fun main() {{
println("Hello World");
}}
"#
)
.unwrap();
// This should PASS (success case)
assert_cmd::cargo::cargo_bin_cmd!("ruchy")
.arg("run")
.arg(temp_file.path())
.assert()
.success() // Expect exit code 0
.stdout(predicate::str::contains("Hello World"));
}
/// Test 4: Runtime error (not panic) should return non-zero exit code
#[test]
fn test_regression_081_runtime_error_returns_nonzero_exit_code() {
let mut temp_file = NamedTempFile::new().unwrap();
writeln!(
temp_file,
r"
fun main() {{
let x = 1 / 0; // Division by zero
}}
"
)
.unwrap();
// RED TEST: This should FAIL (currently returns exit code 0)
assert_cmd::cargo::cargo_bin_cmd!("ruchy")
.arg("run")
.arg(temp_file.path())
.assert()
.failure() // Expect non-zero exit code
.stderr(predicate::str::contains("error").or(predicate::str::contains("Error")));
}