use decy_core::transpile;
#[test]
fn falsify_class_to_struct_field_count_preserved() {
let cpp = r#"
extern "C" { void __m(); }
class Triple { public: int a; int b; int c; };
"#;
let rust = transpile(cpp).unwrap();
assert!(rust.contains("pub a: i32"), "Field a missing");
assert!(rust.contains("pub b: i32"), "Field b missing");
assert!(rust.contains("pub c: i32"), "Field c missing");
}
#[test]
fn falsify_constructor_maps_to_new() {
let cpp = r#"
extern "C" { void __m(); }
class Pair { public: int x; int y; Pair(int a, int b) : x(a), y(b) {} };
"#;
let rust = transpile(cpp).unwrap();
assert!(rust.contains("pub fn new(a: i32, b: i32) -> Self"), "Constructor not mapped to new()");
}
#[test]
fn falsify_destructor_maps_to_drop() {
let cpp = r#"
extern "C" { void __m(); }
class Res { public: int h; ~Res() {} };
"#;
let rust = transpile(cpp).unwrap();
assert!(rust.contains("impl Drop for Res"), "Destructor not mapped to Drop");
}
#[test]
fn falsify_no_destructor_no_drop() {
let cpp = r#"
extern "C" { void __m(); }
class Simple { public: int x; };
"#;
let rust = transpile(cpp).unwrap();
assert!(!rust.contains("impl Drop"), "Should not have Drop without destructor");
}
#[test]
fn falsify_namespace_to_mod() {
let cpp = r#"
extern "C" { void __m(); }
namespace utils { int helper(int x) { return x + 1; } }
"#;
let rust = transpile(cpp).unwrap();
assert!(rust.contains("pub mod utils"), "Namespace not mapped to mod");
assert!(rust.contains("fn helper("), "Function not inside mod");
}
#[test]
fn falsify_nested_namespace() {
let cpp = r#"
extern "C" { void __m(); }
namespace a { namespace b { int f() { return 1; } } }
"#;
let rust = transpile(cpp).unwrap();
assert!(rust.contains("pub mod a"), "Outer namespace missing");
assert!(rust.contains("pub mod b"), "Inner namespace missing");
}
#[test]
fn falsify_operator_plus_maps_to_add() {
let cpp = r#"
extern "C" { void __m(); }
class V { public: int x; V operator+(V o) { V r; return r; } };
"#;
let rust = transpile(cpp).unwrap();
assert!(rust.contains("impl std::ops::Add"), "operator+ not mapped to Add trait");
assert!(rust.contains("type Output"), "Missing Output associated type");
}
#[test]
fn falsify_operator_eq_maps_to_partial_eq() {
let cpp = r#"
extern "C" { void __m(); }
class P { public: int x; bool operator==(P o) { return x == o.x; } };
"#;
let rust = transpile(cpp).unwrap();
assert!(rust.contains("impl PartialEq for P"), "operator== not mapped to PartialEq");
}
#[test]
fn falsify_inheritance_embeds_base() {
let cpp = r#"
extern "C" { void __m(); }
class B { public: int id; };
class D : public B { public: int extra; };
"#;
let rust = transpile(cpp).unwrap();
assert!(rust.contains("base: B"), "Base class not embedded as field");
}
#[test]
fn falsify_inheritance_generates_deref() {
let cpp = r#"
extern "C" { void __m(); }
class B { public: int id; };
class D : public B { public: int extra; };
"#;
let rust = transpile(cpp).unwrap();
assert!(rust.contains("impl std::ops::Deref for D"), "Missing Deref impl");
assert!(rust.contains("type Target = B"), "Wrong Deref target");
}
#[test]
fn falsify_new_generates_box_new() {
let cpp = r#"
extern "C" { void __m(); }
class Obj { public: int v; Obj(int x) : v(x) {} ~Obj() {} };
void test() { Obj* o = new Obj(7); delete o; }
"#;
let rust = transpile(cpp).unwrap();
assert!(rust.contains("Box::new(Obj::new(7))"), "new not mapped to Box::new");
}
#[test]
fn falsify_delete_generates_drop() {
let cpp = r#"
extern "C" { void __m(); }
class Obj { public: int v; Obj(int x) : v(x) {} ~Obj() {} };
void test() { Obj* o = new Obj(7); delete o; }
"#;
let rust = transpile(cpp).unwrap();
assert!(rust.contains("drop(o)"), "delete not mapped to drop()");
}
#[test]
fn falsify_cuda_global_generates_extern_c() {
let cuda = r#"
__global__ void my_kernel(int* data, int n) {
int i = 0;
}
void host() { int x = 1; }
"#;
let rust = transpile(cuda).unwrap();
assert!(rust.contains("extern \"C\""), "Kernel should generate extern C");
assert!(rust.contains("fn my_kernel("), "Kernel name not preserved");
}
#[test]
fn falsify_cuda_host_transpiles_normally() {
let cuda = r#"
__global__ void k(int n) { int i = 0; }
void host_add(int a, int b) { int c = a + b; }
"#;
let rust = transpile(cuda).unwrap();
assert!(rust.contains("fn host_add("), "Host function should transpile normally");
let host_line_idx = rust.lines().position(|l| l.contains("fn host_add("));
let extern_line_idx = rust.lines().position(|l| l.contains("extern \"C\""));
if let (Some(host), Some(ext)) = (host_line_idx, extern_line_idx) {
assert!(host < ext || host > ext + 5, "host_add should not be inside extern C block");
}
}
#[test]
fn falsify_malloc_maps_to_box() {
let c = r#"
#include <stdlib.h>
int* create() {
int* p = (int*)malloc(sizeof(int));
*p = 42;
return p;
}
"#;
let rust = transpile(c).unwrap();
assert!(
rust.contains("Box::new") || rust.contains("vec!") || rust.contains("Vec::"),
"malloc not mapped to safe Rust allocation, got:\n{}",
rust
);
}
#[test]
fn falsify_implicit_this_maps_to_self() {
let cpp = r#"
extern "C" { void __m(); }
class C { public: int val; int get() { return val; } };
"#;
let rust = transpile(cpp).unwrap();
assert!(rust.contains("self.val"), "Implicit this.val should become self.val");
}
#[test]
fn falsify_no_copy_with_drop() {
let cpp = r#"
extern "C" { void __m(); }
class R { public: int h; R(int x) : h(x) {} ~R() {} };
"#;
let rust = transpile(cpp).unwrap();
assert!(!rust.contains("Copy"), "Should not derive Copy when Drop is implemented");
}
#[test]
fn falsify_no_conflicting_partial_eq() {
let cpp = r#"
extern "C" { void __m(); }
class P { public: int x; bool operator==(P o) { return x == o.x; } };
"#;
let rust = transpile(cpp).unwrap();
assert!(rust.contains("impl PartialEq"), "Should have PartialEq impl");
let derive_line = rust.lines().find(|l| l.contains("#[derive("));
if let Some(derive) = derive_line {
assert!(!derive.contains("PartialEq"), "Should NOT derive PartialEq when operator== exists");
}
}
#[test]
fn falsify_constructor_positional_fallback() {
let cpp = r#"
extern "C" { void __m(); }
class V { public: int x; int y; V(int a, int b) : x(a), y(b) {} };
"#;
let rust = transpile(cpp).unwrap();
assert!(rust.contains("x: a"), "Positional mapping x: a failed");
assert!(rust.contains("y: b"), "Positional mapping y: b failed");
}