use super::*;
use crate::Span;
use crate::arena::Arena;
use crate::item::Item;
fn sp() -> Span {
Span::new(0, 0)
}
fn key(name: &str) -> Key<'_> {
Key { name, span: sp() }
}
fn ival(i: i64) -> Item<'static> {
Item::integer_spanned(i as i128, sp())
}
#[test]
fn inner_insert_and_realloc() {
let arena = Arena::new();
let mut t = InnerTable::new();
assert!(t.is_empty());
assert_eq!(t.len(), 0);
t.insert_unique(key("k0"), ival(0), &arena);
assert_eq!(t.len(), 1);
assert_eq!(t.get("k0").unwrap().as_i64(), Some(0));
t.insert_unique(key("k1"), ival(1), &arena);
assert_eq!(t.len(), 2);
assert_eq!(t.get("k0").unwrap().as_i64(), Some(0));
assert_eq!(t.get("k1").unwrap().as_i64(), Some(1));
t.insert_unique(key("k2"), ival(2), &arena);
assert_eq!(t.len(), 3);
assert_eq!(t.get("k0").unwrap().as_i64(), Some(0));
assert_eq!(t.get("k1").unwrap().as_i64(), Some(1));
assert_eq!(t.get("k2").unwrap().as_i64(), Some(2));
t.insert_unique(key("k3"), ival(3), &arena);
t.insert_unique(key("k4"), ival(4), &arena);
assert_eq!(t.len(), 5);
assert!(!t.is_empty());
for i in 0..5 {
let name = format!("k{i}");
assert_eq!(t.get(&name).unwrap().as_i64(), Some(i));
}
}
#[test]
fn inner_get_and_mutate() {
let arena = Arena::new();
let mut t = InnerTable::new();
t.insert_unique(key("a"), ival(10), &arena);
t.insert_unique(key("b"), ival(20), &arena);
assert_eq!(t.get("a").unwrap().as_i64(), Some(10));
assert!(t.get("missing").is_none());
let (k, v) = t.get_entry("a").unwrap();
assert_eq!(k.name, "a");
assert_eq!(v.as_i64(), Some(10));
let v = t.get_mut("a").unwrap();
if let crate::item::ValueMut::Integer(i) = v.value_mut() {
*i = crate::Integer::from(99i64);
}
assert_eq!(t.get("a").unwrap().as_i64(), Some(99));
assert!(t.get_mut("missing").is_none());
assert!(t.contains_key("a"));
assert!(t.contains_key("b"));
assert!(!t.contains_key("missing"));
}
#[test]
fn inner_remove() {
let arena = Arena::new();
let mut t = InnerTable::new();
t.insert_unique(key("a"), ival(1), &arena);
let (_, v) = t.remove_entry("a").unwrap();
assert_eq!(v.as_i64(), Some(1));
assert!(t.is_empty());
let mut t = InnerTable::new();
t.insert_unique(key("a"), ival(1), &arena);
assert!(t.remove_entry("missing").is_none());
assert_eq!(t.len(), 1);
let mut t = InnerTable::new();
t.insert_unique(key("a"), ival(1), &arena);
t.insert_unique(key("b"), ival(2), &arena);
t.insert_unique(key("c"), ival(3), &arena);
let (_, v) = t.remove_entry("a").unwrap();
assert_eq!(v.as_i64(), Some(1));
assert_eq!(t.len(), 2);
let entries = t.entries();
assert_eq!(entries[0].0.name, "c"); assert_eq!(entries[1].0.name, "b");
let mut t = InnerTable::new();
t.insert_unique(key("a"), ival(1), &arena);
t.insert_unique(key("b"), ival(2), &arena);
t.insert_unique(key("c"), ival(3), &arena);
let (_, v) = t.remove_entry("b").unwrap();
assert_eq!(v.as_i64(), Some(2));
assert_eq!(t.len(), 2);
let entries = t.entries();
assert_eq!(entries[0].0.name, "a");
assert_eq!(entries[1].0.name, "c");
let mut t = InnerTable::new();
t.insert_unique(key("a"), ival(1), &arena);
t.insert_unique(key("b"), ival(2), &arena);
t.insert_unique(key("c"), ival(3), &arena);
let (_, v) = t.remove_entry("c").unwrap();
assert_eq!(v.as_i64(), Some(3));
assert_eq!(t.len(), 2);
let mut t = InnerTable::new();
t.insert_unique(key("mykey"), ival(42), &arena);
let (k, v) = t.remove_entry("mykey").unwrap();
assert_eq!(k.name, "mykey");
assert_eq!(v.as_i64(), Some(42));
assert!(t.is_empty());
}
#[test]
fn inner_iterators() {
let arena = Arena::new();
let mut t = InnerTable::new();
t.insert_unique(key("a"), ival(1), &arena);
t.insert_unique(key("b"), ival(2), &arena);
t.insert_unique(key("c"), ival(3), &arena);
let iter = IntoIter { table: t, index: 0 };
assert_eq!(iter.size_hint(), (3, Some(3)));
assert_eq!(iter.len(), 3);
let vals: Vec<_> = iter.collect();
assert_eq!(vals.len(), 3);
assert_eq!(vals[0].1.as_i64(), Some(1));
let mut t2 = InnerTable::new();
t2.insert_unique(key("x"), ival(10), &arena);
t2.insert_unique(key("y"), ival(20), &arena);
let mut iter = IntoIter {
table: t2,
index: 0,
};
assert_eq!(iter.size_hint(), (2, Some(2)));
iter.next();
assert_eq!(iter.size_hint(), (1, Some(1)));
}
fn make_table<'a>(arena: &'a Arena) -> Table<'a> {
let mut table = Table::new_spanned(Span::new(0, 100));
table.insert_unique(key("a"), ival(1), arena);
table.insert_unique(key("b"), ival(2), arena);
table.insert_unique(key("c"), ival(3), arena);
table
}
#[test]
fn table_access_and_mutation() {
let arena = Arena::new();
let mut table = make_table(&arena);
assert_eq!(table.len(), 3);
assert!(!table.is_empty());
assert_eq!(table.span(), Span::new(0, 100));
assert_eq!(table["a"].as_i64(), Some(1));
assert!(table.get("missing").is_none());
let (k, v) = table.get_key_value("b").unwrap();
assert_eq!(k.name, "b");
assert_eq!(v.as_i64(), Some(2));
assert!(table.get_key_value("missing").is_none());
let v = table.get_mut("a").unwrap();
if let crate::item::ValueMut::Integer(i) = v.value_mut() {
*i = crate::Integer::from(99i64);
}
assert_eq!(table["a"].as_i64(), Some(99));
assert!(table.get_mut("missing").is_none());
}
#[test]
fn table_iterators() {
let arena = Arena::new();
let table = make_table(&arena);
let mut count = 0;
for (k, v) in &table {
assert!(v.as_i64().is_some());
assert!(!k.name.is_empty());
count += 1;
}
assert_eq!(count, 3);
let mut table = make_table(&arena);
for (_, v) in &mut table {
if let crate::item::ValueMut::Integer(i) = v.value_mut() {
*i = crate::Integer::from(i.as_i128() + 100);
}
}
assert_eq!(table["a"].as_i64(), Some(101));
let table = make_table(&arena);
let vals: Vec<(Key<'_>, Item<'_>)> = table.into_iter().collect();
assert_eq!(vals.len(), 3);
}
#[test]
fn table_span_helpers() {
let mut table = Table::new_spanned(Span::new(10, 20));
assert_eq!(table.span_start(), 10);
table.set_span_start(50);
assert_eq!(table.span_start(), 50);
assert_eq!(table.span().start, 50);
table.set_span_end(100);
assert_eq!(table.span().end, 100);
table.extend_span_end(90); assert_eq!(table.span().end, 100);
table.extend_span_end(200); assert_eq!(table.span().end, 200);
let mut table = Table::new_spanned(Span::new(10, 20));
table.set_header_flag();
assert_eq!(table.span(), Span::new(10, 20));
}
#[test]
fn default_and_debug() {
let arena = Arena::new();
let table: Table<'_> = Table::default();
assert_eq!(table.len(), 0);
assert!(table.span().is_empty());
let mut table = Table::new_spanned(Span::new(0, 10));
table.insert_unique(key("y"), ival(99), &arena);
let debug = format!("{:?}", table);
assert!(debug.contains("y") || debug.contains("99"));
let table = make_table(&arena);
let entries = table.entries();
assert_eq!(entries.len(), 3);
assert_eq!(entries[0].0.name, "a");
}
#[test]
fn index_operator() {
let arena = Arena::new();
let table = make_table(&arena);
assert_eq!(table["a"].as_i64(), Some(1));
assert_eq!(table["b"].as_i64(), Some(2));
assert_eq!(table["c"].as_i64(), Some(3));
assert!(table["missing"].item().is_none());
assert!(table[""].item().is_none());
assert!(table["missing"]["nested"].item().is_none());
assert!(table["missing"][0].item().is_none());
let mut inner = InnerTable::new();
inner.insert_unique(key("x"), ival(42), &arena);
let mut outer = Table::new_spanned(Span::new(0, 50));
outer.insert_unique(key("nested"), Item::table(inner, Span::new(0, 20)), &arena);
assert_eq!(outer["nested"]["x"].as_i64(), Some(42));
assert!(outer["nested"]["y"].item().is_none());
let empty = Table::new();
assert!(empty["anything"].item().is_none());
}
#[test]
fn as_item_and_into_item() {
let arena = Arena::new();
let mut table = Table::new_spanned(Span::new(0, 50));
table.insert_unique(key("x"), ival(42), &arena);
table.insert_unique(key("y"), ival(99), &arena);
let item_ref = table.as_item();
assert_eq!(item_ref.span_unchecked(), Span::new(0, 50));
assert_eq!(item_ref.as_table().unwrap().len(), 2);
assert_eq!(
item_ref.as_table().unwrap().get("x").unwrap().as_i64(),
Some(42)
);
let table2 = make_table(&arena);
let item = table2.into_item();
assert_eq!(item.span_unchecked(), Span::new(0, 100));
assert_eq!(item.as_table().unwrap().len(), 3);
assert_eq!(*item.type_str(), "table");
}
#[test]
fn clone_in_basic() {
let arena = Arena::new();
let table = make_table(&arena);
let cloned = table.clone_in(&arena);
assert_eq!(cloned.len(), 3);
assert_eq!(cloned.span(), Span::new(0, 100));
assert_eq!(cloned["a"].as_i64(), Some(1));
assert_eq!(cloned["b"].as_i64(), Some(2));
assert_eq!(cloned["c"].as_i64(), Some(3));
}
#[test]
fn clone_in_empty() {
let arena = Arena::new();
let table = Table::new_spanned(Span::new(5, 10));
let cloned = table.clone_in(&arena);
assert!(cloned.is_empty());
assert_eq!(cloned.span(), Span::new(5, 10));
}
#[test]
fn clone_in_preserves_kind() {
let arena = Arena::new();
let mut table = Table::new_spanned(Span::new(0, 10));
table.insert_unique(key("k"), ival(1), &arena);
for kind in [
TableStyle::Implicit,
TableStyle::Dotted,
TableStyle::Header,
TableStyle::Inline,
] {
table.set_style(kind);
let cloned = table.clone_in(&arena);
assert_eq!(cloned.style(), kind);
assert_eq!(cloned["k"].as_i64(), Some(1));
}
}
#[test]
fn clone_in_nested_table() {
let arena = Arena::new();
let mut inner = InnerTable::new();
inner.insert_unique(key("x"), ival(42), &arena);
let mut outer = Table::new_spanned(Span::new(0, 50));
outer.insert_unique(key("nested"), Item::table(inner, Span::new(0, 20)), &arena);
outer.insert_unique(key("flat"), ival(7), &arena);
let cloned = outer.clone_in(&arena);
assert_eq!(cloned.len(), 2);
assert_eq!(cloned["nested"]["x"].as_i64(), Some(42));
assert_eq!(cloned["flat"].as_i64(), Some(7));
}
#[test]
fn clone_in_independent_of_source() {
let arena = Arena::new();
let mut table = make_table(&arena);
let cloned = table.clone_in(&arena);
if let Some(v) = table.get_mut("a") {
if let crate::item::ValueMut::Integer(i) = v.value_mut() {
*i = crate::Integer::from(999i64);
}
}
assert_eq!(cloned["a"].as_i64(), Some(1));
}