mod common;
use std::path::Path;
use common::{make_temp_root, write_file};
use unity_solution_generator::{
BuildConfig, BuildPlatform, GenerateOptions, Lockfile, RefCategory, SolutionGenerator,
xml::deterministic_guid,
};
const GR: &str = "tpl";
#[test]
fn guid_pinning_table() {
for (name, expected) in [
("Lib", &*deterministic_guid("Lib")),
("Assembly-CSharp", &*deterministic_guid("Assembly-CSharp")),
("Assembly-CSharp-Editor", &*deterministic_guid("Assembly-CSharp-Editor")),
] {
let actual = deterministic_guid(name);
assert_eq!(
actual, *expected,
"GUID for {} drifted from {} to {}",
name, expected, actual
);
}
let cases: &[(&str, &str)] = &[
("Lib", "{00000000-0B88-041C-24EC-8619B87F02CC}"),
("Foo", "{00000000-0B87-EB69-F2BB-95199C92E1D7}"),
("Assembly-CSharp", "{BC802F6F-F258-0B13-9024-7747C527DB7B}"),
("Assembly-CSharp-Editor", "{97E07C5E-6C9E-3B67-26CD-B0ED29BA73D3}"),
];
for (name, expected) in cases {
let actual = deterministic_guid(name);
if actual != *expected {
panic!(
"GUID pin drift: deterministic_guid({:?}) = {:?}, expected {:?}.\n\
If this change is intentional, update the table in regression.rs.",
name, actual, expected
);
}
}
}
fn lockfile_for_fixture() -> Lockfile {
let mut lf = Lockfile::empty("6000.2.7f2", "/test/unity");
lf.refs
.entry(RefCategory::Engine)
.or_default()
.push(unity_solution_generator::DllRef::new(
"UnityEngine",
"$(UnityPath)/Unity.app/Contents/Managed/UnityEngine/UnityEngine.dll",
));
lf.defines.push("UNITY_6000".into());
lf
}
fn write_fixture(root: &Path) {
write_file(root, "Assets/Foo/Foo.asmdef", r#"{"name":"Foo","references":[]}"#);
write_file(root, "Assets/Foo/Foo.cs", "class Foo {}\n");
write_file(
root,
"Assets/IOSOnly/IOSOnly.asmdef",
r#"{"name":"IOSOnly","includePlatforms":["iOS"]}"#,
);
write_file(root, "Assets/IOSOnly/IOSOnly.cs", "class IOSOnly {}\n");
write_file(
root,
"Assets/Bar/Bar.asmdef",
r#"{"name":"Bar","includePlatforms":["Editor"]}"#,
);
write_file(root, "Assets/Bar/Bar.cs", "class Bar {}\n");
write_file(
root,
"Assets/Baz/Baz.asmdef",
r#"{"name":"Baz","defineConstraints":["UNITY_INCLUDE_TESTS"]}"#,
);
write_file(root, "Assets/Baz/Baz.cs", "class Baz {}\n");
}
fn opts(root: &Path, platform: BuildPlatform, cfg: BuildConfig) -> GenerateOptions {
GenerateOptions::new(root.to_string_lossy().into_owned(), platform)
.with_generator_root(GR)
.with_build_config(cfg)
}
#[test]
fn ios_editor_includes_all_four_asmdefs() {
let tmp = make_temp_root();
let root = tmp.path();
write_fixture(root);
let result = SolutionGenerator::new()
.generate_from_lockfile(
&opts(root, BuildPlatform::Ios, BuildConfig::Editor),
&lockfile_for_fixture(),
)
.unwrap();
let names: Vec<String> = result
.variant_csprojs
.iter()
.filter_map(|p| Path::new(p).file_stem().map(|s| s.to_string_lossy().into_owned()))
.collect();
for expected in ["Foo", "IOSOnly", "Bar", "Baz"] {
assert!(
names.iter().any(|n| n == expected),
"ios-editor missing {}: got {:?}",
expected,
names
);
}
}
#[test]
fn ios_prod_excludes_editor_only() {
let tmp = make_temp_root();
let root = tmp.path();
write_fixture(root);
let result = SolutionGenerator::new()
.generate_from_lockfile(
&opts(root, BuildPlatform::Ios, BuildConfig::Prod),
&lockfile_for_fixture(),
)
.unwrap();
let names: Vec<String> = result
.variant_csprojs
.iter()
.filter_map(|p| Path::new(p).file_stem().map(|s| s.to_string_lossy().into_owned()))
.collect();
assert!(names.iter().any(|n| n == "Foo"), "Foo (runtime) should be included");
assert!(names.iter().any(|n| n == "IOSOnly"), "IOSOnly should match ios platform");
assert!(
!names.iter().any(|n| n == "Bar"),
"Bar (editor-only) should NOT be in prod variant"
);
assert!(
!names.iter().any(|n| n == "Baz"),
"Baz (test) should NOT be in prod variant"
);
}
#[test]
fn android_prod_excludes_ios_only() {
let tmp = make_temp_root();
let root = tmp.path();
write_fixture(root);
let result = SolutionGenerator::new()
.generate_from_lockfile(
&opts(root, BuildPlatform::Android, BuildConfig::Prod),
&lockfile_for_fixture(),
)
.unwrap();
let names: Vec<String> = result
.variant_csprojs
.iter()
.filter_map(|p| Path::new(p).file_stem().map(|s| s.to_string_lossy().into_owned()))
.collect();
assert!(names.iter().any(|n| n == "Foo"));
assert!(
!names.iter().any(|n| n == "IOSOnly"),
"iOS-only asmdef should NOT be in android-prod"
);
assert!(!names.iter().any(|n| n == "Bar"));
}