#![allow(clippy::panic, clippy::unwrap_used, clippy::expect_used)]
use zerodds_types::assignability::{AssignabilityConfig, is_assignable};
use zerodds_types::from_ast::{Form, type_identifier};
use zerodds_xml_compose::compose_source;
const SOURCE: &str = r#"<dds>
<types>
<module name="Test">
<bitmask name="B_16" bitBound="16">
<flag name="B_FLAG_1" value="0"/>
<flag name="B_FLAG_2" value="1"/>
</bitmask>
<bitmask name="B_32" bitBound="32">
<flag name="B_FLAG_1" value="0"/>
<flag name="B_FLAG_2" value="1"/>
<flag name="B_FLAG_3" value="2"/>
</bitmask>
<union name="union_uint32" ><discriminator type="uint32" />
<case><caseDiscriminator value="2"/><member name="x1" type="int16"/></case>
<case><caseDiscriminator value="1"/><member name="x2" type="int32"/></case>
</union>
<union name="union_bitmask16" ><discriminator type="nonBasic" nonBasicTypeName="B_16"/>
<case><caseDiscriminator value="2"/><member name="x1" type="int16"/></case>
<case><caseDiscriminator value="1"/><member name="x2" type="int32"/></case>
</union>
<union name="union_bitmask32" ><discriminator type="nonBasic" nonBasicTypeName="B_32"/>
<case><caseDiscriminator value="2"/><member name="x1" type="int16"/></case>
<case><caseDiscriminator value="1"/><member name="x2" type="int32"/></case>
</union>
</module>
</types>
</dds>"#;
#[test]
fn a_bitmask_discriminator_matches_the_uint_of_its_bound() {
let composed = compose_source("unions_bitmask.xml", SOURCE);
assert!(!composed.failed(), "{:?}", composed.diagnostics);
let ast = &composed.ast;
let ti = |name: &str| {
let segments = ["Test", name].map(str::to_owned).to_vec();
let id = ast
.find_by_scoped_name(&zerodds_ast_core::ScopedName::absolute(segments))
.ok()
.and_then(zerodds_ast::AnyId::as_type)
.unwrap_or_else(|| panic!("the document declares {name}"));
type_identifier(ast, id, Form::Complete)
.unwrap_or_else(|e| panic!("{name} has an identifier: {e:?}"))
};
let uint32 = ti("union_uint32");
let bitmask32 = ti("union_bitmask32");
let bitmask16 = ti("union_bitmask16");
let registry = &composed.registry;
let cfg = AssignabilityConfig::default();
assert!(is_assignable(&uint32, &bitmask32, registry, &cfg).is_yes());
assert!(is_assignable(&bitmask32, &uint32, registry, &cfg).is_yes());
assert!(!is_assignable(&uint32, &bitmask16, registry, &cfg).is_yes());
assert!(!is_assignable(&bitmask16, &uint32, registry, &cfg).is_yes());
}