use super::*;
#[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize)]
struct Sample {
name: String,
count: i64,
enabled: bool,
optional: Option<String>,
items: Vec<String>,
}
fn sample() -> Sample {
Sample {
name: "router".to_string(),
count: 42,
enabled: true,
optional: None,
items: vec!["one".to_string(), "two".to_string()],
}
}
#[test]
fn state_round_trips_through_links_notation() {
let encoded = encode(&sample()).expect("encode");
let decoded: Sample = decode(&encoded).expect("decode");
assert_eq!(decoded, sample());
}
#[test]
fn the_encoded_form_is_readable() {
let encoded = encode(&sample()).expect("encode");
assert!(encoded.contains("name \"router\""), "{encoded}");
assert!(encoded.contains("count 42"), "{encoded}");
assert!(encoded.contains("enabled true"), "{encoded}");
assert!(!encoded.contains("\"42\""), "{encoded}");
assert!(!encoded.contains("base64"), "{encoded}");
}
#[test]
fn json_written_by_an_earlier_release_still_loads() {
let json = serde_json::to_string(&sample()).expect("serialize");
let decoded: Sample = decode(&json).expect("JSON still decodes");
assert_eq!(decoded, sample());
}
#[test]
fn every_value_shape_converts_both_ways() {
let value = serde_json::json!({
"null": null,
"bool": false,
"int": -7,
"float": 1.5,
"string": "text",
"array": [1, "two", true],
"nested": {"inner": {"deep": 1}}
});
assert_eq!(from_lino(&to_lino(&value)), value);
}
#[test]
fn a_control_character_is_carried_without_base64ing_everything() {
let value = serde_json::json!({"plain": "readable", "raw": "a\u{0007}b"});
let encoded = lino_objects_codec::encode(&to_lino(&value));
assert!(encoded.contains("plain \"readable\""), "{encoded}");
let decoded = lino_objects_codec::decode(&encoded).expect("decode");
assert_eq!(from_lino(&decoded), value);
}
#[test]
fn a_links_document_is_not_misread_as_json() {
let encoded = encode(&sample()).expect("encode");
assert!(
encoded.trim_start().starts_with('('),
"links notation opens with a paren: {encoded}"
);
let decoded: Sample = decode(&encoded).expect("links notation decodes");
assert_eq!(decoded, sample());
}
#[test]
fn an_empty_collection_survives_both_encodings() {
let empty: Vec<Sample> = Vec::new();
let encoded = encode(&empty).expect("encode");
let decoded: Vec<Sample> = decode(&encoded).expect("decode");
assert!(decoded.is_empty(), "an empty list stays empty: {encoded}");
let decoded: Vec<Sample> = decode("[]").expect("decode JSON");
assert!(decoded.is_empty());
}
#[test]
fn a_vendor_document_survives_this_module_unchanged() {
let credential = serde_json::json!({
"claudeAiOauth": {
"accessToken": "sk-ant-oat01-example",
"refreshToken": "sk-ant-ort01-example",
"expiresAt": 4_102_444_800_000_i64,
"scopes": ["user:inference", "user:profile"],
}
});
let written = serde_json::to_string_pretty(&credential).expect("serialize");
let read: serde_json::Value = decode(&written).expect("a vendor file still decodes");
assert_eq!(read, credential, "a vendor document must not be reshaped");
let codex = serde_json::json!({
"OPENAI_API_KEY": null,
"tokens": {"id_token": "header.payload.signature", "account_id": "acct_1"},
"last_refresh": "2026-08-26T00:00:00Z",
});
let round_tripped: serde_json::Value =
decode(&serde_json::to_string(&codex).expect("serialize")).expect("decode");
assert_eq!(
round_tripped, codex,
"fields this crate does not model must survive untouched"
);
}