use noyalib::borrowed::{BorrowedValue, from_str_borrowed};
#[test]
fn null_parses_as_null() {
let v: BorrowedValue<'_> = from_str_borrowed("~").unwrap();
assert!(v.is_null());
assert_eq!(v.as_str(), None);
assert_eq!(v.as_i64(), None);
assert_eq!(v.as_bool(), None);
assert!(v.as_sequence().is_none());
assert!(v.as_mapping().is_none());
}
#[test]
fn string_scalar() {
let v: BorrowedValue<'_> = from_str_borrowed("hello").unwrap();
assert_eq!(v.as_str(), Some("hello"));
assert!(!v.is_null());
}
#[test]
fn integer_scalar() {
let v: BorrowedValue<'_> = from_str_borrowed("42").unwrap();
assert_eq!(v.as_i64(), Some(42));
}
#[test]
fn bool_scalar_true() {
let v: BorrowedValue<'_> = from_str_borrowed("true").unwrap();
assert_eq!(v.as_bool(), Some(true));
}
#[test]
fn bool_scalar_false() {
let v: BorrowedValue<'_> = from_str_borrowed("false").unwrap();
assert_eq!(v.as_bool(), Some(false));
}
#[test]
fn flow_sequence() {
let v: BorrowedValue<'_> = from_str_borrowed("[1, 2, 3]").unwrap();
let seq = v.as_sequence().expect("expected sequence");
assert_eq!(seq.len(), 3);
assert_eq!(seq[0].as_i64(), Some(1));
assert_eq!(seq[2].as_i64(), Some(3));
}
#[test]
fn block_sequence() {
let v: BorrowedValue<'_> = from_str_borrowed("- a\n- b\n- c\n").unwrap();
let seq = v.as_sequence().expect("seq");
assert_eq!(seq.len(), 3);
assert_eq!(seq[0].as_str(), Some("a"));
}
#[test]
fn flow_mapping() {
let v: BorrowedValue<'_> = from_str_borrowed("{a: 1, b: 2}").unwrap();
let m = v.as_mapping().expect("map");
assert_eq!(m.len(), 2);
assert_eq!(m.get("a").and_then(|v| v.as_i64()), Some(1));
assert_eq!(m.get("b").and_then(|v| v.as_i64()), Some(2));
}
#[test]
fn block_mapping() {
let v: BorrowedValue<'_> = from_str_borrowed("name: noyalib\nversion: 1\n").unwrap();
let m = v.as_mapping().expect("map");
assert_eq!(m.get("name").and_then(|v| v.as_str()), Some("noyalib"));
assert_eq!(m.get("version").and_then(|v| v.as_i64()), Some(1));
}
#[test]
fn nested_mapping_sequence() {
let yaml = "servers:\n - name: a\n port: 8080\n - name: b\n port: 9090\n";
let v: BorrowedValue<'_> = from_str_borrowed(yaml).unwrap();
let servers = v
.as_mapping()
.and_then(|m| m.get("servers"))
.and_then(|s| s.as_sequence())
.expect("sequence");
assert_eq!(servers.len(), 2);
assert_eq!(
servers[0]
.as_mapping()
.and_then(|m| m.get("name"))
.and_then(|v| v.as_str()),
Some("a")
);
assert_eq!(
servers[1]
.as_mapping()
.and_then(|m| m.get("port"))
.and_then(|v| v.as_i64()),
Some(9090)
);
}
#[test]
fn get_path_simple() {
let yaml = "config:\n host: db\n port: 5432\n";
let v: BorrowedValue<'_> = from_str_borrowed(yaml).unwrap();
let port = v.get_path("config.port").expect("path hit");
assert_eq!(port.as_i64(), Some(5432));
}
#[test]
fn get_path_missing_returns_none() {
let v: BorrowedValue<'_> = from_str_borrowed("a: 1\n").unwrap();
assert!(v.get_path("a.b.c").is_none());
}
#[test]
fn query_wildcard() {
let yaml = "items:\n - name: a\n v: 1\n - name: b\n v: 2\n";
let v: BorrowedValue<'_> = from_str_borrowed(yaml).unwrap();
let results = v.query("items[*].name");
assert_eq!(results.len(), 2);
assert_eq!(results[0].as_str(), Some("a"));
assert_eq!(results[1].as_str(), Some("b"));
}
#[test]
fn into_owned_preserves_structure() {
let yaml = "a:\n b: [1, 2, 3]\n c: hello\n";
let v: BorrowedValue<'_> = from_str_borrowed(yaml).unwrap();
let owned = v.into_owned();
let yaml_out = noyalib::to_string(&owned).unwrap();
let reparsed: noyalib::Value = noyalib::from_str(&yaml_out).unwrap();
assert_eq!(owned, reparsed);
}
#[test]
fn into_owned_scalar() {
let v: BorrowedValue<'_> = from_str_borrowed("42").unwrap();
let owned = v.into_owned();
assert_eq!(owned.as_i64(), Some(42));
}
#[test]
fn invalid_syntax_errors() {
let err = from_str_borrowed("a: [unclosed\nnext: v\n");
assert!(err.is_err());
}
#[test]
fn string_borrow_points_into_input() {
let yaml = String::from("hello world");
let v: BorrowedValue<'_> = from_str_borrowed(&yaml).unwrap();
let s = v.as_str().expect("string");
let yaml_ptr_range = yaml.as_ptr() as usize..(yaml.as_ptr() as usize + yaml.len());
assert!(yaml_ptr_range.contains(&(s.as_ptr() as usize)));
}