#![cfg(feature = "deserialize")]
use armour_core::{
EnumType, Fields, KeyScheme, KeyType, ScalarTyp, SimpleEnumType, StructType, Typ,
};
#[test]
fn typ_primitive_roundtrip() {
let cases = [
Typ::Scalar(ScalarTyp::Bool),
Typ::Scalar(ScalarTyp::U8),
Typ::Scalar(ScalarTyp::U16),
Typ::Scalar(ScalarTyp::U32),
Typ::Scalar(ScalarTyp::U64),
Typ::Scalar(ScalarTyp::I32),
Typ::Scalar(ScalarTyp::I64),
Typ::Scalar(ScalarTyp::F32),
Typ::Scalar(ScalarTyp::F64),
Typ::Scalar(ScalarTyp::Str),
Typ::Scalar(ScalarTyp::Datetime),
Typ::Scalar(ScalarTyp::Timestamp),
Typ::Scalar(ScalarTyp::Decimal),
Typ::Scalar(ScalarTyp::Id32),
Typ::Scalar(ScalarTyp::Id64),
Typ::Scalar(ScalarTyp::Fuid),
Typ::Scalar(ScalarTyp::LowId),
Typ::Scalar(ScalarTyp::Bytes),
Typ::Scalar(ScalarTyp::Void),
Typ::Scalar(ScalarTyp::RustJson),
Typ::Scalar(ScalarTyp::JsonBytes),
Typ::Scalar(ScalarTyp::ArrayBytes(16)),
Typ::Array(4, &Typ::Scalar(ScalarTyp::U32)),
Typ::Vec(&Typ::Scalar(ScalarTyp::Str)),
Typ::Optional(&Typ::Scalar(ScalarTyp::U64)),
];
for t in cases {
let json = serde_json::to_string(&t).unwrap();
let back: Typ = serde_json::from_str(&json).unwrap();
assert_eq!(t, back, "failed round-trip for {t:?}; json = {json}");
}
}
#[test]
fn typ_struct_named_roundtrip() {
let original = Typ::Struct(StructType {
name: "User",
fields: Fields::Named(&[
("id", Typ::Scalar(ScalarTyp::Fuid)),
("name", Typ::Scalar(ScalarTyp::Str)),
]),
});
let json = serde_json::to_string(&original).unwrap();
let back: Typ = serde_json::from_str(&json).unwrap();
assert_eq!(original, back);
}
#[test]
fn typ_struct_unnamed_roundtrip() {
let original = Typ::Struct(StructType {
name: "Pair",
fields: Fields::Unnamed(&[Typ::Scalar(ScalarTyp::U32), Typ::Scalar(ScalarTyp::Str)]),
});
let json = serde_json::to_string(&original).unwrap();
let back: Typ = serde_json::from_str(&json).unwrap();
assert_eq!(original, back);
}
#[test]
fn typ_enum_roundtrip() {
let original = Typ::Enum(EnumType {
name: "Event",
variants: &[
(0, ("Created", Typ::Scalar(ScalarTyp::U64))),
(1, ("Deleted", Typ::Scalar(ScalarTyp::Void))),
],
});
let json = serde_json::to_string(&original).unwrap();
let back: Typ = serde_json::from_str(&json).unwrap();
assert_eq!(original, back);
}
#[test]
fn typ_simple_enum_roundtrip() {
let original = Typ::SimpleEnum(SimpleEnumType {
name: "Kind",
variants: &[(0, "Foo"), (1, "Bar")],
});
let json = serde_json::to_string(&original).unwrap();
let back: Typ = serde_json::from_str(&json).unwrap();
assert_eq!(original, back);
}
#[test]
fn key_scheme_typed_roundtrip() {
let s = KeyScheme::Typed(&[KeyType::U8, KeyType::Fuid]);
let json = serde_json::to_string(&s).unwrap();
let back: KeyScheme = serde_json::from_str(&json).unwrap();
assert_eq!(s, back);
}
#[test]
fn key_scheme_bytes_roundtrip() {
let s = KeyScheme::Bytes;
let json = serde_json::to_string(&s).unwrap();
let back: KeyScheme = serde_json::from_str(&json).unwrap();
assert_eq!(s, back);
}
#[test]
fn typ_enum_malformed_variant_key_returns_err() {
let json = r#"{"type":"Enum","data":{"name":"Event","variants":{"not-a-tag":["Created",{"type":"U64"}]}}}"#;
let err = serde_json::from_str::<Typ>(json).unwrap_err();
assert!(
err.to_string().contains("Enum variant key must be u8"),
"unexpected error: {err}"
);
}
#[test]
fn typ_simple_enum_wrong_value_type_returns_err() {
let json = r#"{"type":"SimpleEnum","data":{"name":"Kind","variants":{"0":42}}}"#;
let err = serde_json::from_str::<Typ>(json).unwrap_err();
assert!(
err.to_string()
.contains("SimpleEnum variant value must be string"),
"unexpected error: {err}"
);
}
#[test]
fn typ_enum_wrong_variant_shape_returns_err() {
let json = r#"{"type":"Enum","data":{"name":"Event","variants":{"0":"not-a-pair"}}}"#;
let err = serde_json::from_str::<Typ>(json).unwrap_err();
assert!(
err.to_string().contains("Enum variant value shape"),
"unexpected error: {err}"
);
}