use super::{nth_attribute_is_present, StepListItems};
#[test]
fn nth_attribute_present_and_non_null_is_true() {
let entity = b"#40=IFCBUILDINGSTOREY('guid',$,'Level 1',$,$,#18,#39,$,.ELEMENT.,0.);";
assert!(nth_attribute_is_present(entity, 0));
assert!(nth_attribute_is_present(entity, 6));
}
#[test]
fn nth_attribute_dollar_is_false() {
let entity = b"#40=IFCBUILDINGSTOREY('guid',$,'Level 1',$,$,#18,$,$,.ELEMENT.,0.);";
assert!(!nth_attribute_is_present(entity, 6));
assert!(!nth_attribute_is_present(entity, 1));
}
#[test]
fn nth_attribute_past_the_end_is_false() {
let entity = b"#1=IFCWALL('guid',$,'Wall');";
assert!(!nth_attribute_is_present(entity, 10));
}
#[test]
fn nth_attribute_empty_value_is_false() {
let entity = b"#1=IFCFOO('a',,'c');";
assert!(!nth_attribute_is_present(entity, 1));
assert!(nth_attribute_is_present(entity, 0));
assert!(nth_attribute_is_present(entity, 2));
}
#[test]
fn nth_attribute_nested_parens_are_not_top_level_commas() {
let entity = b"#30=IFCPOLYLOOP((#20,#21,#22),$);";
assert!(nth_attribute_is_present(entity, 0));
assert!(!nth_attribute_is_present(entity, 1));
assert!(!nth_attribute_is_present(entity, 2));
}
#[test]
fn nth_attribute_quoted_comma_and_paren_are_not_top_level() {
let entity =
b"#40=IFCBUILDINGSTOREY('guid',$,'Level 1, west (annex)',$);";
assert!(nth_attribute_is_present(entity, 0)); assert!(!nth_attribute_is_present(entity, 1)); assert!(nth_attribute_is_present(entity, 2)); assert!(!nth_attribute_is_present(entity, 3)); assert!(!nth_attribute_is_present(entity, 4));
}
#[test]
fn nth_attribute_escaped_quote_stays_inside_the_string() {
let entity = b"#1=IFCWALL('guid',$,'quo''te',$);";
assert!(nth_attribute_is_present(entity, 2)); assert!(!nth_attribute_is_present(entity, 3)); assert!(!nth_attribute_is_present(entity, 4));
}
#[test]
fn nth_attribute_no_open_paren_is_false() {
assert!(!nth_attribute_is_present(b"#1=IFCWALL;", 0));
}
#[test]
fn nth_attribute_no_close_paren_is_false() {
assert!(!nth_attribute_is_present(b"#1=IFCWALL('guid'", 0));
}
#[test]
fn nth_attribute_reversed_boundary_is_false() {
assert!(!nth_attribute_is_present(b")(", 0));
assert!(!nth_attribute_is_present(b"garbage)stuff(more", 0));
}
#[test]
fn treats_a_comment_before_dollar_as_still_null() {
let content = "#1=IFCWALL(/* c1 */ $);";
assert!(!nth_attribute_is_present(content.as_bytes(), 0));
}
#[test]
fn treats_a_comment_before_a_value_as_non_null() {
let content = "#1=IFCWALL(/* c1 */ 'a');";
assert!(nth_attribute_is_present(content.as_bytes(), 0));
}
#[test]
fn comma_inside_a_comment_does_not_split_attributes() {
let content = "#1=IFCWALL('a', /* x, y */ $);";
assert!(!nth_attribute_is_present(content.as_bytes(), 1));
}
#[test]
fn dollar_inside_a_comment_is_comment_text() {
let content = "#1=IFCWALL(/* was $ */ 'a');";
assert!(nth_attribute_is_present(content.as_bytes(), 0));
}
#[test]
fn dollar_inside_a_comment_before_a_real_null_attribute() {
let content = "#1=IFCWALL(/* was $ */ $);";
assert!(!nth_attribute_is_present(content.as_bytes(), 0));
}
#[test]
fn comment_free_records_unchanged() {
let content = "#1=IFCWALL('a',$,5);";
assert!(nth_attribute_is_present(content.as_bytes(), 0));
assert!(!nth_attribute_is_present(content.as_bytes(), 1));
assert!(nth_attribute_is_present(content.as_bytes(), 2));
}
#[test]
fn a_comment_before_the_argument_list_does_not_open_it() {
let commented = b"#1=IFCWALL /* (was IFCSLAB) */ ($,'a');";
let plain = b"#1=IFCWALL($,'a');";
for index in 0..3 {
assert_eq!(
nth_attribute_is_present(commented, index),
nth_attribute_is_present(plain, index),
"attribute {index} must read the same with and without the comment"
);
}
assert!(!nth_attribute_is_present(commented, 0));
assert!(nth_attribute_is_present(commented, 1));
}
#[test]
fn a_comment_in_the_record_head_is_trivia() {
let record = b"#1 /* (a) */ = /* (b) */ IFCWALL($,'a');";
assert!(!nth_attribute_is_present(record, 0));
assert!(nth_attribute_is_present(record, 1));
}
#[test]
fn every_step_whitespace_byte_is_trimmed_around_a_value() {
for ws in ["\t", "\x0b", "\x0c", " ", "\r\n"] {
let record = format!("#1=IFCWALL({ws}${ws},{ws}'a'{ws});");
assert!(
!nth_attribute_is_present(record.as_bytes(), 0),
"a `$` padded with {ws:?} is still the null token"
);
assert!(
nth_attribute_is_present(record.as_bytes(), 1),
"a value padded with {ws:?} is still a value"
);
assert!(!nth_attribute_is_present(record.as_bytes(), 2));
}
}
#[test]
fn a_comment_inside_the_argument_list_is_trivia_for_every_slot() {
assert!(!nth_attribute_is_present(b"#1=IFCWALL('a', /* x, y */ $);", 2));
let storey =
b"#40=IFCBUILDINGSTOREY('guid',$,/* 'Level 1', */ $,$,$,#18,#39,$,.ELEMENT.,0.);";
assert!(nth_attribute_is_present(storey, 6));
assert!(!nth_attribute_is_present(storey, 7));
}
#[test]
fn an_unterminated_comment_or_string_settles_nothing() {
assert!(!nth_attribute_is_present(b"#1=IFCWALL(/* open 'a');", 0));
assert!(!nth_attribute_is_present(b"#1=IFCWALL('a', /* open $);", 1));
assert!(!nth_attribute_is_present(b"#1=IFCWALL('open,$);", 0));
assert!(!nth_attribute_is_present(b"#1=IFCWALL('a',$,'open);", 0));
}
fn items(record: &[u8]) -> (Vec<&[u8]>, bool) {
let mut items = StepListItems::of_record(record).expect("the list opens");
let collected = items.by_ref().collect();
(collected, items.closed())
}
#[test]
fn issue_4687_list_items_are_trimmed_of_comments_and_split_outside_them() {
let (attributes, closed) =
items(b"#1=IFCWALL( 'a,(b' /* it's, ) */ , /* x */ (#2, /* y, */ #3) ,$);");
assert_eq!(attributes, [&b"'a,(b'"[..], b"(#2, /* y, */ #3)", b"$"]);
assert!(closed);
let nested: Vec<&[u8]> = StepListItems::of_list(attributes[1]).unwrap().collect();
assert_eq!(nested, [&b"#2"[..], b"#3"]);
}
#[test]
fn issue_4687_list_items_empty_lists_slots_and_unclosed_input() {
assert_eq!(items(b"#1=X();"), (vec![], true));
assert_eq!(items(b"#1=X( /* none */ );"), (vec![], true));
assert_eq!(items(b"#1=X(,);"), (vec![&b""[..], b""], true));
assert_eq!(items(b"#1=X('a',$"), (vec![&b"'a'"[..]], false));
assert_eq!(items(b"#1=X('a',/* open"), (vec![&b"'a'"[..]], false));
assert!(StepListItems::of_list(b"$").is_none());
}