#![cfg(any(
not(any(
feature = "parser_tests",
feature = "analyzer_tests",
feature = "codegen_tests",
feature = "interpreter_tests",
feature = "conformance_tests",
feature = "integration_tests",
)),
feature = "codegen_tests",
))]
#[path = "common/test_utils.rs"]
mod test_utils;
use anyhow::Result;
use std::fs;
use std::process::Command;
#[test]
#[cfg_attr(tarpaulin, ignore)]
fn test_no_super_glob_when_explicit_glob_imports_present() -> Result<()> {
let timestamp = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_nanos();
let _tmp = tempfile::tempdir().unwrap();
let temp_dir = _tmp
.path()
.join(format!("wj_glob_ambiguity_test_{}", timestamp));
fs::create_dir_all(&temp_dir)?;
let gizmos_dir = temp_dir.join("src").join("gizmos");
fs::create_dir_all(&gizmos_dir)?;
fs::write(
gizmos_dir.join("transform_gizmo.wj"),
r#"
pub enum GizmoMode {
Translate,
Rotate,
Scale,
}
pub struct TransformGizmo {
pub mode: GizmoMode,
}
impl TransformGizmo {
pub fn new() -> TransformGizmo {
TransformGizmo { mode: GizmoMode::Translate }
}
}
"#,
)?;
fs::write(
gizmos_dir.join("mod.wj"),
r#"
pub mod transform_gizmo
pub use transform_gizmo::GizmoMode
pub use transform_gizmo::TransformGizmo
"#,
)?;
let panels_dir = temp_dir.join("src").join("panels");
fs::create_dir_all(&panels_dir)?;
fs::write(
panels_dir.join("scene_view.wj"),
r#"
pub enum GizmoMode {
Translate,
Rotate,
Scale,
}
pub struct SceneViewPanel {
pub mode: GizmoMode,
}
"#,
)?;
fs::write(
panels_dir.join("transform_gizmo_ui.wj"),
r#"
use crate::gizmos::*
pub struct GizmoPanel {
pub gizmo: TransformGizmo,
pub enabled: bool,
}
impl GizmoPanel {
pub fn new() -> GizmoPanel {
GizmoPanel {
gizmo: TransformGizmo::new(),
enabled: true,
}
}
pub fn set_mode(self, mode: GizmoMode) {
self.gizmo.mode = mode
}
}
"#,
)?;
fs::write(
panels_dir.join("mod.wj"),
r#"
pub mod scene_view
pub mod transform_gizmo_ui
pub use scene_view::GizmoMode
pub use scene_view::SceneViewPanel
"#,
)?;
fs::write(
temp_dir.join("wj.toml"),
r#"
[package]
name = "glob_ambiguity_test"
version = "0.1.0"
[dependencies]
"#,
)?;
let wj_compiler = test_utils::wj_binary();
let lib_output = temp_dir.join("lib");
fs::create_dir_all(&lib_output)?;
let output = Command::new(&wj_compiler)
.arg("build")
.arg("--no-cargo")
.arg(temp_dir.join("src"))
.arg("-o")
.arg(&lib_output)
.arg("--library")
.output()?;
let stderr = String::from_utf8_lossy(&output.stderr);
let stdout = String::from_utf8_lossy(&output.stdout);
let gizmo_ui_rs_path = lib_output.join("panels").join("transform_gizmo_ui.rs");
assert!(
gizmo_ui_rs_path.exists(),
"transform_gizmo_ui.rs should be generated at {:?}\nstdout: {}\nstderr: {}",
gizmo_ui_rs_path,
stdout,
stderr
);
let gizmo_ui_content = fs::read_to_string(&gizmo_ui_rs_path)?;
assert!(
gizmo_ui_content.contains("use crate::gizmos::*;"),
"Generated file should contain explicit glob import 'use crate::gizmos::*;'.\nGenerated:\n{}",
gizmo_ui_content
);
let has_super_glob = gizmo_ui_content.contains("use super::*;");
assert!(
!has_super_glob,
"When a file has explicit glob imports, `use super::*` should be suppressed to prevent \
E0659 ambiguity errors.\nGenerated transform_gizmo_ui.rs:\n{}",
gizmo_ui_content
);
Ok(())
}
#[test]
#[cfg_attr(tarpaulin, ignore)]
fn test_super_glob_still_added_without_explicit_glob_imports() -> Result<()> {
let timestamp = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_nanos();
let _tmp2 = tempfile::tempdir().unwrap();
let temp_dir = _tmp2
.path()
.join(format!("wj_super_glob_kept_test_{}", timestamp));
fs::create_dir_all(&temp_dir)?;
let quest_dir = temp_dir.join("src").join("quest");
fs::create_dir_all(&quest_dir)?;
fs::write(
quest_dir.join("types.wj"),
r#"
pub struct Quest {
pub name: string,
pub completed: bool,
}
impl Quest {
pub fn new(name: string) -> Quest {
Quest { name: name, completed: false }
}
}
"#,
)?;
fs::write(
quest_dir.join("manager.wj"),
r#"
pub struct QuestManager {
pub quests: Vec<Quest>,
}
impl QuestManager {
pub fn new() -> QuestManager {
QuestManager { quests: Vec::new() }
}
}
"#,
)?;
fs::write(
quest_dir.join("mod.wj"),
r#"
pub mod types
pub mod manager
pub use types::Quest
"#,
)?;
fs::write(
temp_dir.join("wj.toml"),
r#"
[package]
name = "super_glob_kept_test"
version = "0.1.0"
[dependencies]
"#,
)?;
let wj_compiler = test_utils::wj_binary();
let lib_output = temp_dir.join("lib");
fs::create_dir_all(&lib_output)?;
let output = Command::new(&wj_compiler)
.arg("build")
.arg("--no-cargo")
.arg(temp_dir.join("src"))
.arg("-o")
.arg(&lib_output)
.arg("--library")
.output()?;
let stderr = String::from_utf8_lossy(&output.stderr);
let stdout = String::from_utf8_lossy(&output.stdout);
let manager_rs_path = lib_output.join("quest").join("manager.rs");
assert!(
manager_rs_path.exists(),
"manager.rs should be generated at {:?}\nstdout: {}\nstderr: {}",
manager_rs_path,
stdout,
stderr
);
let manager_content = fs::read_to_string(&manager_rs_path)?;
let has_super_glob = manager_content.contains("use super::*;");
assert!(
has_super_glob,
"Files WITHOUT explicit glob imports should still get `use super::*` for sibling type access.\nGenerated manager.rs:\n{}",
manager_content
);
Ok(())
}