use super::assertions::render_json_assertion;
use crate::e2e::field_access::FieldResolver;
use crate::e2e::fixture::Assertion;
use std::collections::{HashMap, HashSet};
fn resolver_with_wire_optional(field: &str) -> FieldResolver {
let wire_optional: HashSet<String> = [field.to_string()].into_iter().collect();
FieldResolver::new(
&HashMap::new(),
&HashSet::new(),
&HashSet::new(),
&HashSet::new(),
&HashSet::new(),
)
.with_wire_optional_fields(wire_optional)
}
fn empty_resolver() -> FieldResolver {
FieldResolver::new(
&HashMap::new(),
&HashSet::new(),
&HashSet::new(),
&HashSet::new(),
&HashSet::new(),
)
}
fn is_empty_assertion(field: &str) -> Assertion {
Assertion {
assertion_type: "is_empty".to_string(),
field: Some(field.to_string()),
..Assertion::default()
}
}
#[test]
fn wire_optional_leaf_key_is_not_force_unwrapped() {
let resolver = resolver_with_wire_optional("children");
let assertion = is_empty_assertion("data.children");
let mut out = String::new();
render_json_assertion(&mut out, &assertion, "result", &resolver, false);
assert!(
!out.contains(".object.get(\"children\").?"),
"a wire-optional key must not be force-unwrapped with `.?`, which panics when serde \
omitted the key entirely. Rendered:\n{out}"
);
assert!(
out.contains("(result.object.get(\"data\").object.get(\"children\") orelse .null)")
|| out.contains(".object.get(\"children\") orelse .null"),
"a wire-optional key must be guarded with `orelse .null` so a missing key renders the \
same as a present `null` value. Rendered:\n{out}"
);
}
#[test]
fn non_wire_optional_leaf_key_keeps_force_unwrap() {
let resolver = empty_resolver();
let assertion = is_empty_assertion("data.children");
let mut out = String::new();
render_json_assertion(&mut out, &assertion, "result", &resolver, false);
assert!(
out.contains(".object.get(\"children\").?"),
"a field not marked wire-optional must keep the plain `.?` accessor. Rendered:\n{out}"
);
assert!(
!out.contains("orelse .null"),
"a field not marked wire-optional must not be guarded. Rendered:\n{out}"
);
}