use face_core::FaceError;
use face_core::input::items::{ItemsDetection, detect_items};
mod simple_shapes {
use super::*;
#[test]
fn top_level_array() {
let v = serde_json::json!([1, 2, 3]);
let det: ItemsDetection = detect_items(v).expect("top-level array detects");
assert_eq!(det.items.len(), 3);
assert_eq!(det.items[0], serde_json::json!(1));
assert_eq!(
det.items_path, ".",
"top-level array's items_path is the identity path `.`",
);
assert!(
det.meta.is_none(),
"top-level array carries no meta scalars; got {:?}",
det.meta,
);
}
#[test]
fn object_one_array_field() {
let v = serde_json::json!({"results": [1, 2, 3]});
let det = detect_items(v).expect("single array field detects");
assert_eq!(det.items.len(), 3);
assert_eq!(det.items_path, ".results");
}
#[test]
fn object_with_named_items_among_unnamed() {
let v = serde_json::json!({"items": [1], "extras": [2]});
let det = detect_items(v).expect("named candidate beats unnamed sibling");
assert_eq!(det.items, vec![serde_json::json!(1)]);
assert_eq!(det.items_path, ".items");
}
}
mod named_priority {
use super::*;
#[test]
fn items_beats_results() {
let v = serde_json::json!({"items": [1], "results": [2]});
let det = detect_items(v).expect("items beats results");
assert_eq!(det.items_path, ".items");
assert_eq!(det.items, vec![serde_json::json!(1)]);
}
#[test]
fn results_beats_data() {
let v = serde_json::json!({"results": [1], "data": [2]});
let det = detect_items(v).expect("results beats data");
assert_eq!(det.items_path, ".results");
assert_eq!(det.items, vec![serde_json::json!(1)]);
}
#[test]
fn last_candidate_picked_when_first_absent() {
let v = serde_json::json!({"scopes": [1], "anything": [2]});
let det = detect_items(v).expect("named scopes beats unnamed sibling");
assert_eq!(det.items_path, ".scopes");
assert_eq!(det.items, vec![serde_json::json!(1)]);
}
}
mod ambiguous {
use super::*;
#[test]
fn multiple_unnamed_arrays_errors() {
let v = serde_json::json!({"foo": [1], "bar": [2]});
let err = detect_items(v).expect_err("multiple unnamed arrays must error");
match &err {
FaceError::AmbiguousDetection { candidates, .. } => {
let fields: Vec<&str> = candidates.iter().map(|c| c.field.as_str()).collect();
assert!(
fields.iter().any(|f| *f == "foo" || *f == ".foo"),
"candidates must include foo (or .foo); got {fields:?}",
);
assert!(
fields.iter().any(|f| *f == "bar" || *f == ".bar"),
"candidates must include bar (or .bar); got {fields:?}",
);
}
other => panic!("expected FaceError::AmbiguousDetection, got {other:?} ({other})",),
}
}
}
mod scalar_inputs {
use super::*;
#[test]
fn scalar_string_errors() {
let v = serde_json::json!("hello");
let err = detect_items(v).expect_err("scalar string cannot host items");
match &err {
FaceError::InputParse { .. } => {}
other => panic!(
"expected FaceError::InputParse for scalar string root, got {other:?} ({other})",
),
}
}
#[test]
fn scalar_number_errors() {
let v = serde_json::json!(42);
let err = detect_items(v).expect_err("scalar number cannot host items");
match &err {
FaceError::InputParse { .. } => {}
other => panic!(
"expected FaceError::InputParse for scalar number root, got {other:?} ({other})",
),
}
}
}