#![cfg(test)]
#![allow(warnings)]
#![allow(clippy::assertions_on_constants)]
#![allow(clippy::unreadable_literal)]
#![allow(clippy::unwrap_used)]
#![allow(
clippy::expect_used,
clippy::print_stdout,
clippy::uninlined_format_args,
clippy::needless_borrows_for_generic_args,
clippy::items_after_statements,
dropping_references
)]
use std::io::Write;
use std::process::{Command, Stdio};
#[test]
fn test_repl_e2e_qualified_function_call() {
let input = "std::fs::read_file(\"test.txt\")";
let mut child = Command::new("cargo")
.args(&["run", "--bin", "ruchy", "repl"])
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.expect("Failed to start ruchy repl");
let stdin = child.stdin.as_mut().expect("Failed to open stdin");
writeln!(stdin, "{}", input).expect("Failed to write to stdin");
drop(stdin);
let output = child.wait_with_output().expect("Failed to read output");
println!("=== REPL E2E DEBUG ===");
println!("Exit code: {}", output.status.code().unwrap_or(-1));
println!("Stdout: {}", String::from_utf8_lossy(&output.stdout));
println!("Stderr: {}", String::from_utf8_lossy(&output.stderr));
let stderr = String::from_utf8_lossy(&output.stderr);
let parse_failed = stderr.contains("Failed to parse input");
let runtime_failed = stderr.contains("Unknown static method") || stderr.contains("Error:");
println!("Parse failed: {}", parse_failed);
println!("Runtime failed: {}", runtime_failed);
assert!(
!parse_failed,
"PARSING should succeed for qualified function calls"
);
if runtime_failed {
println!("EXPECTED: Runtime failure for unknown method (not a parser issue)");
}
}
#[test]
fn test_repl_e2e_two_segment_vs_three_segment() {
let test_cases = vec![
("Result::Ok(42)", true), ("fs::read_file(\"test\")", true), ("std::fs::read_file(\"test\")", true), ("a::b::c::function()", true), ("std::collections::HashMap::new()", true), ];
for (input, should_parse_successfully) in test_cases {
println!("Testing: {}", input);
let mut child = Command::new("cargo")
.args(&["run", "--bin", "ruchy", "repl"])
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.expect("Failed to start ruchy repl");
let stdin = child.stdin.as_mut().expect("Failed to open stdin");
writeln!(stdin, "{}", input).expect("Failed to write to stdin");
drop(stdin);
let output = child.wait_with_output().expect("Failed to read output");
let stderr = String::from_utf8_lossy(&output.stderr);
let stdout = String::from_utf8_lossy(&output.stdout);
let parsing_failed = stderr.contains("Failed to parse input")
|| stderr.contains("Unexpected token")
|| stderr.contains("Expected");
if should_parse_successfully {
assert!(
!parsing_failed,
"Input '{}' should parse successfully but failed with: {}",
input, stderr
);
if stdout.contains("Error") || stderr.contains("Unknown") {
println!("✓ '{}' parsed correctly (runtime error expected)", input);
}
}
}
}
#[test]
fn test_repl_binary_vs_unit_test_parity() {
let input = "std::fs::read_file(\"test.txt\")";
use ruchy::frontend::parser::Parser;
let mut parser = Parser::new(input);
let unit_result = parser.parse();
assert!(unit_result.is_ok(), "Unit test parsing must work");
let mut child = Command::new("cargo")
.args(&["run", "--bin", "ruchy", "repl"])
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.expect("Failed to start ruchy repl");
let stdin = child.stdin.as_mut().expect("Failed to open stdin");
writeln!(stdin, "{}", input).expect("Failed to write to stdin");
drop(stdin);
let output = child.wait_with_output().expect("Failed to read output");
let stderr = String::from_utf8_lossy(&output.stderr);
let repl_parsing_failed =
stderr.contains("Failed to parse input") || stderr.contains("Unexpected token");
if repl_parsing_failed {
panic!("REPL parsing failed for '{}': {}", input, stderr);
}
}