use assert_matches::assert_matches;
use crate::{
json::{self, ElemId},
test,
};
use super::DepthFirst;
#[test]
fn should_return_scalar_root_element() {
const JSON: &str = "101";
test::setup();
let elem = json::parse(JSON.into()).unwrap();
let mut walker = DepthFirst::new(&elem);
let elem_root = walker.next().unwrap();
assert_eq!(&elem, elem_root);
}
#[test]
fn should_return_compound_root_element() {
const JSON: &str = "{}";
test::setup();
let elem = json::parse(JSON.into()).unwrap();
let mut walker = DepthFirst::new(&elem);
let elem_root = walker.next().unwrap();
assert_eq!(&elem, elem_root);
}
#[test]
fn should_traverse_nested_objects() {
const JSON: &str = r#"{ "one": { "two": { "three": [101] }}}"#;
test::setup();
let elem = json::parse(JSON.into()).unwrap();
let mut walker = DepthFirst::new(&elem);
let elem_root = walker.next().unwrap();
assert_eq!(&elem, elem_root);
{
let elem_one = walker.next().unwrap();
assert!(elem_one.value().is_object());
{
let elem_two = walker.next().unwrap();
assert!(elem_two.value().is_object());
{
let elem_three = walker.next().unwrap();
assert!(elem_three.value().is_array());
{
let elem_four = walker.next().unwrap();
assert_matches!(elem_four.value().as_number().unwrap(), "101");
}
}
}
}
}
#[test]
fn iter_index_should_match_element_id_order() {
const JSON: &str = include_str!("../../../test_data/v211/every_field_set/cdr.json");
test::setup();
let elem = json::parse(JSON.into()).unwrap();
let walker = DepthFirst::new(&elem);
for (index, elem) in walker.enumerate() {
assert_eq!(elem.id().0, index);
}
}
#[test]
fn should_elem_map_from_element_iter() {
const JSON: &str = r#"{
"one": 1,
"two": ["a", "b", "c"],
"three": {
"d": 4,
"e": 5,
"f": 6
}
}"#;
test::setup();
let elem = json::parse(JSON.into()).unwrap();
let elem_list = ElementList::for_elem(&elem);
{
let root_id = ElemId::from(0);
assert_eq!(
elem_list.get(root_id).id(),
elem.id(),
"The root `Element` is always Id 0"
);
assert_eq!(elem.path(), "$");
{
let elem = elem_list.get(ElemId::from(1));
assert_eq!(elem.path(), "$.one");
assert_matches!(elem.value().as_number().unwrap(), "1");
}
{
let elem = elem_list.get(ElemId::from(2));
assert_eq!(elem.path(), "$.two");
let array = elem.value().as_array().unwrap();
let [arr_elem_0, arr_elem_1, arr_elem_2] =
array.iter().collect::<Vec<_>>().try_into().unwrap();
let elem = elem_list.get(ElemId::from(3));
assert_eq!(elem.id(), arr_elem_0.id());
assert_eq!(elem.path(), "$.two.0");
assert_matches!(elem.value().to_raw_str().unwrap().as_raw(), "a");
let elem = elem_list.get(ElemId::from(4));
assert_eq!(elem.id(), arr_elem_1.id());
assert_eq!(elem.path(), "$.two.1");
assert_matches!(elem.value().to_raw_str().unwrap().as_raw(), "b");
let elem = elem_list.get(ElemId::from(5));
assert_eq!(elem.id(), arr_elem_2.id());
assert_eq!(elem.path(), "$.two.2");
assert_matches!(elem.value().to_raw_str().unwrap().as_raw(), "c");
}
{
let elem = elem_list.get(ElemId::from(6));
assert_eq!(elem.path(), "$.three");
let fields = elem.value().as_object_fields().unwrap();
let [field_0, field_1, field_2] = fields.iter().collect::<Vec<_>>().try_into().unwrap();
let elem = elem_list.get(ElemId::from(7));
assert_eq!(elem.id(), field_0.id());
assert_eq!(elem.path(), "$.three.d");
assert_matches!(elem.value().as_number().unwrap(), "4");
let elem = elem_list.get(ElemId::from(8));
assert_eq!(elem.id(), field_1.id());
assert_eq!(elem.path(), "$.three.e");
assert_matches!(elem.value().as_number().unwrap(), "5");
let elem = elem_list.get(ElemId::from(9));
assert_eq!(elem.id(), field_2.id());
assert_eq!(elem.path(), "$.three.f");
assert_matches!(elem.value().as_number().unwrap(), "6");
}
}
}
struct ElementList<'a, 'buf>(Vec<&'a json::Element<'buf>>);
impl<'a, 'buf> ElementList<'a, 'buf> {
fn for_elem(root: &'a json::Element<'buf>) -> Self {
let walker = DepthFirst::new(root);
Self(walker.collect())
}
fn get(&self, id: ElemId) -> &json::Element<'buf> {
self.0.get(id.0).map(|e| &**e).unwrap()
}
}