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}"
);
let qualified_null = "std.json.Value{ .null = {} }";
assert!(
out.contains(&format!(
"(result.object.get(\"data\").object.get(\"children\") orelse {qualified_null})"
)) || out.contains(&format!(".object.get(\"children\") orelse {qualified_null}")),
"a wire-optional key must be guarded with `orelse {qualified_null}` so a missing key \
renders the same as a present `null` value. A bare `orelse .null` compiles only where \
Zig can infer a result type, which a chained `.object.get(...)` access does not \
provide. 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 std.json.Value{ .null = {} }"),
"a field not marked wire-optional must not be guarded. Rendered:\n{out}"
);
}