use std::collections::{HashMap, HashSet};
use super::assertions::render_assertion;
use crate::core::ir::{FieldDef, TypeDef, TypeRef};
use crate::e2e::field_access::FieldResolver;
use crate::e2e::fixture::Assertion;
fn children_field(ty: TypeRef) -> FieldDef {
FieldDef {
name: "children".to_string(),
ty,
..FieldDef::default()
}
}
fn table_ir() -> Vec<TypeDef> {
vec![TypeDef {
name: "ProcessResult".to_string(),
fields: vec![children_field(TypeRef::Vec(Box::new(TypeRef::Named(
"DataNode".to_string(),
))))],
..TypeDef::default()
}]
}
fn ir_anchored_resolver(type_defs: &[TypeDef], root_type: &str) -> FieldResolver {
FieldResolver::new(
&HashMap::new(),
&HashSet::new(),
&HashSet::new(),
&HashSet::new(),
&HashSet::new(),
)
.with_ir_collection_map(
FieldResolver::ir_collection_fields(type_defs),
Some(root_type.to_string()),
)
}
fn render_contains(field_resolver: &FieldResolver, field: &str, expected: &str) -> String {
let assertion = Assertion {
assertion_type: "contains".to_string(),
field: Some(field.to_string()),
value: Some(serde_json::json!(expected)),
..Default::default()
};
let mut out = String::new();
render_assertion(
&mut out,
&assertion,
"result",
"sample",
"sample",
false,
&[],
field_resolver,
false,
false,
false,
false,
false,
None,
);
out
}
#[test]
fn contains_on_an_undeclared_collection_field_is_classified_via_the_ir() {
let type_defs = table_ir();
let resolver = ir_anchored_resolver(&type_defs, "ProcessResult");
let out = render_contains(&resolver, "children", "Widget");
assert!(
out.contains(".iter().any("),
"an undeclared collection field must render the per-element scan, got:\n{out}"
);
assert!(
!out.contains(r##"result.children.contains(r#"Widget"#)"##),
"must not render the scalar .contains(&str) shape, which would not compile against \
Vec<DataNode>, got:\n{out}"
);
}
#[test]
fn a_same_named_string_field_on_an_unrelated_type_is_not_misclassified_as_a_collection() {
let type_defs = vec![TypeDef {
name: "OtherResult".to_string(),
fields: vec![children_field(TypeRef::String)],
..TypeDef::default()
}];
let resolver = ir_anchored_resolver(&type_defs, "OtherResult");
let out = render_contains(&resolver, "children", "Widget");
assert!(
out.contains(r##"result.children.contains(r#"Widget"#)"##),
"a plain string field's contains must keep using the scalar .contains(&str) shape, got:\n{out}"
);
}