#![allow(clippy::expect_used, clippy::unwrap_used, missing_docs)]
use std::fs;
use zerodds_build::Config;
const CROSS_MODULE: &str = "\
module common {
module util {
struct Location { double x; double y; double z; };
struct Orientation { double x; double y; double z; };
};
struct Robot {
::common::util::Location location;
::common::util::Orientation orientation;
};
};
";
#[test]
fn a_member_typed_from_another_module_reaches_the_generated_struct() {
let dir = tempfile::tempdir().expect("tempdir");
let idl = dir.path().join("Robot.idl");
fs::write(&idl, CROSS_MODULE).expect("write");
let out = dir.path().join("out");
fs::create_dir_all(&out).expect("out");
Config::new()
.out_dir(&out)
.emit_cargo_directives(false)
.compile(&[&idl])
.expect("compile");
let generated = fs::read_to_string(out.join("Robot.rs")).expect("read");
assert!(generated.contains("struct Robot"), "{generated}");
assert!(
generated.contains("location"),
"the member is in the struct: {generated}"
);
assert!(
generated.contains("orientation"),
"and so is the second one: {generated}"
);
assert!(
generated.contains("Location"),
"the type it names resolves: {generated}"
);
assert!(generated.contains("Orientation"), "{generated}");
}
#[test]
fn a_qualified_name_resolves_and_a_relative_one_is_the_known_gap() {
let dir = tempfile::tempdir().expect("tempdir");
let idl = dir.path().join("Spellings.idl");
fs::write(
&idl,
"module common {
module util { struct Location { double x; }; };
struct A { ::common::util::Location loc; };
struct B { common::util::Location loc; };
};",
)
.expect("write");
let out = dir.path().join("out");
fs::create_dir_all(&out).expect("out");
Config::new()
.out_dir(&out)
.emit_cargo_directives(false)
.compile(&[&idl])
.expect("compile");
let generated = fs::read_to_string(out.join("Spellings.rs")).expect("read");
assert!(
generated.matches("Location").count() >= 2,
"both qualified spellings resolve: {generated}"
);
let relative = dir.path().join("Relative.idl");
fs::write(
&relative,
"module common {
module util { struct Location { double x; }; };
struct C { util::Location loc; };
};",
)
.expect("write");
Config::new()
.out_dir(&out)
.emit_cargo_directives(false)
.compile(&[&relative])
.expect("§7.5 admits `util::Location` from inside `common`");
let relative_out = fs::read_to_string(out.join("Relative.rs")).expect("read");
assert!(
relative_out.contains("Location"),
"the member survives with its type, rather than the struct \
emitting without it: {relative_out}"
);
}
#[test]
fn a_name_that_resolves_to_nothing_fails_the_build() {
let dir = tempfile::tempdir().expect("tempdir");
let idl = dir.path().join("Missing.idl");
fs::write(&idl, "module m { struct S { ::nowhere::Absent gap; }; };").expect("write");
let out = dir.path().join("out");
fs::create_dir_all(&out).expect("out");
let result = Config::new()
.out_dir(&out)
.emit_cargo_directives(false)
.compile(&[&idl]);
assert!(
result.is_err(),
"a member typed by a name that names nothing must not compile"
);
}