#![cfg(any(
not(any(
feature = "parser_tests",
feature = "analyzer_tests",
feature = "codegen_tests",
feature = "interpreter_tests",
feature = "conformance_tests",
feature = "integration_tests",
)),
feature = "integration_tests",
))]
use std::fs;
use std::path::PathBuf;
use std::process::Command;
use tempfile::TempDir;
#[test]
#[cfg_attr(tarpaulin, ignore)]
fn test_library_compilation_creates_linkable_crate() {
let temp_dir = TempDir::new().unwrap();
let project_root = temp_dir.path();
let runtime_path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.parent()
.unwrap()
.join("windjammer")
.join("crates")
.join("windjammer-runtime");
let runtime_path_str = runtime_path.to_string_lossy().replace('\\', "/");
let wj_toml = format!(
r#"
[package]
name = "test-lib"
version = "0.1.0"
[dependencies]
windjammer-runtime = {{ path = "{}" }}
"#,
runtime_path_str
);
fs::write(project_root.join("wj.toml"), &wj_toml).unwrap();
let src = project_root.join("src");
fs::create_dir_all(&src).unwrap();
fs::write(
src.join("mod.wj"),
r#"
// Simple library module
pub fn hello() -> string {
"Hello from library!".to_string()
}
pub struct TestStruct {
pub value: int,
}
impl TestStruct {
pub fn new(value: int) -> TestStruct {
TestStruct { value }
}
}
"#,
)
.unwrap();
let lib_output = project_root.join("lib");
fs::create_dir_all(&lib_output).unwrap();
let cargo_toml = format!(
r#"[package]
name = "test-lib"
version = "0.1.0"
edition = "2021"
[dependencies]
windjammer-runtime = {{ path = "{}" }}
[lib]
name = "test_lib"
path = "lib.rs"
[workspace]
"#,
runtime_path_str
);
fs::write(lib_output.join("Cargo.toml"), cargo_toml).unwrap();
let lib_rs = r#"// Auto-generated lib.rs
pub mod mod_file;
// Re-export public items
pub use mod_file::hello;
pub use mod_file::TestStruct;
"#;
fs::write(lib_output.join("lib.rs"), lib_rs).unwrap();
let mod_rs = r#"// Generated from mod.wj
pub fn hello() -> String {
"Hello from library!".to_string()
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub struct TestStruct {
pub value: i64,
}
impl TestStruct {
pub fn new(value: i64) -> TestStruct {
TestStruct { value }
}
}
"#;
fs::write(lib_output.join("mod_file.rs"), mod_rs).unwrap();
let output = Command::new("cargo")
.arg("check")
.arg("--lib")
.current_dir(&lib_output)
.output();
match output {
Ok(result) => {
if !result.status.success() {
let stderr = String::from_utf8_lossy(&result.stderr);
panic!("Library compilation failed:\n{}", stderr);
}
}
Err(e) => {
panic!("Failed to run cargo check: {}", e);
}
}
let test_output = project_root.join("test");
fs::create_dir_all(&test_output).unwrap();
let test_code = r#"
use test_lib::{hello, TestStruct};
#[test]
#[cfg_attr(tarpaulin, ignore)]
fn test_library_import() {
let msg = hello();
assert_eq!(msg, "Hello from library!");
let obj = TestStruct::new(42);
assert_eq!(obj.value, 42);
}
"#;
fs::write(test_output.join("test.rs"), test_code).unwrap();
let lib_output_str = lib_output.to_string_lossy().replace('\\', "/");
let test_cargo_toml = format!(
r#"[package]
name = "test-tests"
version = "0.1.0"
edition = "2021"
[dependencies]
test-lib = {{ path = "{}" }}
[lib]
name = "test_tests"
path = "test.rs"
[workspace]
"#,
lib_output_str
);
fs::write(test_output.join("Cargo.toml"), test_cargo_toml).unwrap();
let test_result = Command::new("cargo")
.arg("test")
.current_dir(&test_output)
.output();
match test_result {
Ok(result) => {
if !result.status.success() {
let stderr = String::from_utf8_lossy(&result.stderr);
panic!("Test compilation/run failed:\n{}", stderr);
}
let stdout = String::from_utf8_lossy(&result.stdout);
assert!(
stdout.contains("test test_library_import ... ok"),
"Test should pass and import from library"
);
}
Err(e) => {
panic!("Failed to run cargo test: {}", e);
}
}
}
#[test]
#[cfg_attr(tarpaulin, ignore)]
fn test_library_needs_lib_rs_entry_point() {
let temp_dir = TempDir::new().unwrap();
let lib_output = temp_dir.path();
fs::create_dir_all(lib_output.join("game_loop")).unwrap();
fs::write(
lib_output.join("game_loop/game_loop.rs"),
"pub trait GameLoop {}",
)
.unwrap();
fs::write(
lib_output.join("game_loop/mod.rs"),
"pub mod game_loop;\npub use game_loop::*;",
)
.unwrap();
let lib_rs_content = r#"// Auto-generated library entry point
pub mod game_loop;
// Re-export for convenience
pub use game_loop::*;
"#;
fs::write(lib_output.join("lib.rs"), lib_rs_content).unwrap();
assert!(lib_output.join("lib.rs").exists(), "lib.rs should exist");
assert!(
lib_output.join("game_loop/mod.rs").exists(),
"module mod.rs should exist"
);
let lib_content = fs::read_to_string(lib_output.join("lib.rs")).unwrap();
assert!(
lib_content.contains("pub mod game_loop"),
"lib.rs should declare modules"
);
assert!(
lib_content.contains("pub use game_loop::*"),
"lib.rs should re-export"
);
}