use super::*;
#[test]
fn parse_safety_attr() {
let parse_attr = |s: &str| parse_str::<SafetyAttr>(s);
let _: SafetyAttr = parse_attr("#[safety {}]").unwrap();
let attr = parse_attr("#[safety { SP }]").unwrap();
let sp = attr.args.property_reason().next().unwrap().0;
assert_eq!(sp.tag.name_type(), ("SP", None));
let attr = parse_attr("#[safety { hazard.Alias(p, q) }]").unwrap();
let sp = attr.args.property_reason().next().unwrap().0;
assert_eq!(sp.tag.name_type(), ("Alias", Some(TagType::Hazard)));
let args: Vec<_> = sp
.args
.iter()
.map(|arg| {
if let Expr::Path(path) = arg {
path.path.get_ident().unwrap().to_string()
} else {
unreachable!()
}
})
.collect();
assert_eq!(args, ["p", "q"]);
}
fn parse_args(s: &str) -> syn::Result<SafetyAttrArgs> {
parse_str::<SafetyAttrArgs>(s)
}
#[test]
fn parse_safety_args() {
_ = parse_args("SP").unwrap();
_ = parse_args("SP1, SP2").unwrap();
_ = parse_args("SP1; SP2").unwrap();
_ = parse_args(r#" SP1: "reason" "#).unwrap();
_ = parse_args(r#" SP1: "reason"; SP2: "reason" "#).unwrap();
_ = parse_args(r#" SP1: "reason", SP2: "reason" "#).unwrap_err();
_ = parse_args(r#" SP1, SP2: "reason" "#).unwrap();
_ = parse_args(r#" SP1, SP2: "reason"; SP3 "#).unwrap();
_ = parse_args(r#" SP3; SP1, SP2: "reason" "#).unwrap();
_ = parse_args(r#" SP3, SP4; SP1, SP2: "reason" "#).unwrap();
_ = parse_args(r#" SP3; SP1, SP2: "reason"; SP4 "#).unwrap();
_ = parse_args(r#" SP1, SP2: "reason"; SP3; "#).unwrap();
_ = parse_args(r#" SP1, SP2: "reason"; SP3, "#).unwrap();
_ = parse_args(r#" SP1(a) "#).unwrap();
_ = parse_args(r#" SP1(a, b) "#).unwrap();
_ = parse_args(r#" SP1(a, b, call()) "#).unwrap();
_ = parse_args(r#" SP1(a), SP2: "reason"; SP3 "#).unwrap();
_ = parse_args(r#" SP(a, b): "reason"; SP1, SP2: "reason"; SP3, SP4 "#).unwrap();
}
#[test]
fn parse_safety_complex_args() {
_ = parse_args(r#" hazard.Alias(p, q) "#).unwrap();
_ = parse_args(r#" hazard.Alias(A {a: self.a}, a::b(c![])) : "" "#).unwrap();
}
#[test]
fn new_single_sp() {
let name = "Tag";
let sp = PropertiesAndReason::new_single_sp(name);
assert_eq!(sp.tags.len(), 1, "{sp:#?} must have single property");
assert!(sp.tags[0].args.is_empty(), "{sp:#?} must have no arguments");
assert!(sp.tags[0].tag.typ.is_none());
assert_eq!(&*sp.tags[0].tag.name, name);
}
#[test]
fn parse_sp_str() {
let any = "any(Tag1, Tag2)";
let tag1 = "Tag1";
let tag2 = "Tag2";
let sp = PropertiesAndReason::parse_sp_str(any).unwrap();
assert_eq!(sp.tags.len(), 1, "{sp:#?} must have single property");
assert!(sp.tags[0].tag.typ.is_none());
assert_eq!(&*sp.tags[0].tag.name, ANY);
assert_eq!(&*sp.tags[0].args_as_string(), [tag1, tag2]);
let args = sp.tags[0]
.args_in_any_tag()
.unwrap_or_else(|| panic!("{sp:#?} must be any `any` SP with two args"));
assert_eq!(&*args[0].tags[0].tag.name, tag1);
assert_eq!(&*args[1].tags[0].tag.name, tag2);
}