#![allow(clippy::unwrap_used, clippy::expect_used)]
#![allow(deprecated)]
#![allow(dead_code)]
use std::fs;
use std::sync::atomic::{AtomicU64, Ordering};
const STMT_PREAMBLE: &str = r#"
let x = 10;
let y = 5;
let z = 2;
"#;
static TEST_COUNTER: AtomicU64 = AtomicU64::new(0);
fn get_unique_temp_paths() -> (String, String) {
let id = TEST_COUNTER.fetch_add(1, Ordering::SeqCst);
let pid = std::process::id();
let tid = std::thread::current().id();
(
format!("/tmp/tcode_prog_{}_{:?}_{}.rs", pid, tid, id),
format!("/tmp/tcode_prog_{}_{:?}_{}.sh", pid, tid, id),
)
}
fn transpile_prog(code: &str) -> (bool, String) {
let (tmp_rs, tmp_sh) = get_unique_temp_paths();
fs::write(&tmp_rs, code).unwrap();
let output = assert_cmd::cargo_bin_cmd!("bashrs")
.args(["build", &tmp_rs, "-o", &tmp_sh])
.output()
.unwrap();
let _ = fs::remove_file(&tmp_rs);
if !output.status.success() {
let _ = fs::remove_file(&tmp_sh);
return (false, String::from_utf8_lossy(&output.stderr).to_string());
}
let shell = fs::read_to_string(&tmp_sh).unwrap_or_default();
let _ = fs::remove_file(&tmp_sh);
(true, shell)
}
fn transpile_stmt(code: &str) -> (bool, String) {
let full_prog = format!("fn main() {{\n{}\n {}\n}}", STMT_PREAMBLE, code);
transpile_prog(&full_prog)
}
fn check_forbidden(output: &str, forbidden: &str) -> bool {
!output.contains(forbidden)
}
fn check_required(output: &str, required: &str) -> bool {
output.contains(required)
}
struct TCodeResult {
id: &'static str,
passed: bool,
reason: String,
}
impl TCodeResult {
fn pass(id: &'static str) -> Self {
Self {
id,
passed: true,
reason: String::new(),
}
}
fn fail(id: &'static str, reason: &str) -> Self {
Self {
id,
passed: false,
reason: reason.to_string(),
}
}
}
#[test]
fn test_t001_empty_main() {
let (ok, output) = transpile_prog("fn main() {}");
assert!(ok, "T001: Should compile");
assert!(
output.contains("main()"),
"T001: Output should contain main()"
);
}
#[test]
fn test_t002_integer_assignment() {
let (ok, output) = transpile_stmt("let a = 1;");
assert!(ok, "T002: Should compile");
assert!(
!output.contains("unknown"),
"T002: Should not contain 'unknown'"
);
}
#[test]
fn test_t003_negative_integer() {
let (ok, output) = transpile_stmt("let a = -1;");
assert!(ok, "T003: Should compile");
assert!(
!output.contains("unknown"),
"T003: Should not contain 'unknown'"
);
}
#[test]
fn test_t004_string_literal() {
let (ok, output) = transpile_stmt(r#"let a = "hi";"#);
if !ok {
println!("T004: KNOWN BUG TB-004 - string literal validation fails");
println!(" Error: {}", output);
}
}
#[test]
fn test_t005_boolean_true() {
let (ok, output) = transpile_stmt("let a = true;");
if ok {
assert!(
!output.contains("unknown"),
"T005: Should not contain 'unknown'"
);
}
}
#[test]
fn test_t006_boolean_false() {
let (ok, output) = transpile_stmt("let a = false;");
if ok {
assert!(
!output.contains("unknown"),
"T006: Should not contain 'unknown'"
);
}
}
#[test]
fn test_t007_zero_literal() {
let (ok, output) = transpile_stmt("let a = 0;");
assert!(ok, "T007: Should compile");
assert!(
!output.contains("unknown"),
"T007: Should not contain 'unknown'"
);
}
#[test]
fn test_t008_large_integer() {
let (ok, output) = transpile_stmt("let a = 999999;");
assert!(ok, "T008: Should compile");
assert!(
!output.to_lowercase().contains("overflow"),
"T008: Should not overflow"
);
}
#[test]
fn test_t009_underscore_prefix() {
let (ok, _output) = transpile_stmt("let _a = 1;");
if !ok {
println!("T009: Underscore prefix vars may not be supported");
}
}
#[test]
fn test_t010_explicit_type() {
let (ok, output) = transpile_stmt("let a: i32 = 1;");
if ok {
assert!(
!output.contains("error"),
"T010: Explicit types should work"
);
}
}
#[test]
fn test_t011_float_rejection() {
let (ok, output) = transpile_stmt("let a = 1.0;");
if ok {
println!("T011: Float literals accepted (may lose precision)");
} else {
println!("T011: Float literals correctly rejected: {}", output);
}
}
#[test]
fn test_t012_char_literal() {
let (ok, output) = transpile_stmt("let a = 'a';");
if ok {
assert!(
!output.contains("unknown"),
"T012: Char should not produce 'unknown'"
);
}
}
#[test]
fn test_t013_byte_string() {
let (ok, output) = transpile_stmt(r#"let a = b"hi";"#);
if !ok {
println!("T013: Byte strings unsupported: {}", output);
}
}
#[test]
fn test_t014_constant() {
let (ok, output) = transpile_prog("const X: i32 = 1; fn main() {}");
if ok && !output.contains("readonly") && !output.contains("X=") {
println!("T014: WARNING - const should produce readonly or assignment");
}
}
#[test]
fn test_t015_static() {
let (ok, output) = transpile_prog("static X: i32 = 1; fn main() {}");
if ok && !output.contains("X=") {
println!("T015: WARNING - static should produce global variable");
}
}
#[test]
fn test_t016_addition() {
let (ok, output) = transpile_stmt("let _ = 1 + 2;");
if ok {
let has_arith = output.contains("$((") || output.contains("3");
if !has_arith {
println!("T016: WARNING - Addition may not be computed correctly");
}
}
}
#[test]
fn test_t017_subtraction() {
let (ok, output) = transpile_stmt("let _ = 5 - 3;");
if ok {
let has_arith = output.contains("$((") || output.contains("2");
if !has_arith {
println!("T017: WARNING - Subtraction may not be computed correctly");
}
}
}
#[test]
fn test_t018_multiplication() {
let (ok, output) = transpile_stmt("let _ = 4 * 3;");
if ok {
let has_arith = output.contains("$((") || output.contains("12");
if !has_arith {
println!("T018: KNOWN BUG TB-007 - Multiplication not computed");
}
}
}
#[test]
fn test_t019_division() {
let (ok, output) = transpile_stmt("let _ = 10 / 2;");
if ok {
let has_arith = output.contains("$((") || output.contains("5");
if !has_arith {
println!("T019: WARNING - Division may not be computed correctly");
}
}
}
#[test]
fn test_t020_modulo() {
let (ok, output) = transpile_stmt("let _ = 10 % 3;");
if ok {
let has_arith = output.contains("$((") || output.contains("1");
if !has_arith {
println!("T020: KNOWN BUG TB-008 - Modulo not computed");
}
}
}
#[test]
fn test_t021_precedence() {
let (ok, output) = transpile_stmt("let _ = 2 + 3 * 4;");
if ok && output.contains("20") {
println!("T021: BUG - Wrong precedence, got 20 instead of 14");
}
}
#[test]
include!("transpiler_tcode_tests_tests_t022_groupin.rs");