use super::*;
fn assert_roundtrip(input: &str) {
let encoded = encode_schema(input, None).expect("encoding failed");
let decoded = decode_schema(&encoded, false).expect("decoding failed");
let input_value: serde_json::Value =
serde_json::from_str(input).expect("input is not valid JSON");
let output_value: serde_json::Value =
serde_json::from_str(&decoded).expect("output is not valid JSON");
assert_eq!(
input_value, output_value,
"Round-trip mismatch:\nInput: {}\nOutput: {}",
input, decoded
);
}
fn assert_parse_error(input: &str) {
let result = encode_schema(input, None);
assert!(result.is_err(), "Expected parse error for input: {}", input);
}
#[test]
fn test_empty_object() {
let result = encode_schema(r#"{}"#, None);
if let Ok(encoded) = result {
let decoded = decode_schema(&encoded, false).expect("decode should work");
assert_eq!(decoded, "{}");
}
}
#[test]
fn test_empty_array() {
assert_parse_error(r#"[]"#);
}
#[test]
fn test_root_primitive_null() {
assert_parse_error(r#"null"#);
}
#[test]
fn test_root_primitive_true() {
assert_parse_error(r#"true"#);
}
#[test]
fn test_root_primitive_false() {
assert_parse_error(r#"false"#);
}
#[test]
fn test_root_primitive_number() {
assert_parse_error(r#"42"#);
}
#[test]
fn test_root_primitive_string() {
assert_parse_error(r#""hello""#);
}
#[test]
fn test_single_field_object() {
assert_roundtrip(r#"{"a":1}"#);
}
#[test]
fn test_single_row_array() {
let input = r#"[{"a":1}]"#;
let encoded = encode_schema(input, None).expect("encoding failed");
let decoded = decode_schema(&encoded, false).expect("decoding failed");
let expected = r#"{"a":1}"#;
let input_value: serde_json::Value = serde_json::from_str(expected).unwrap();
let output_value: serde_json::Value = serde_json::from_str(&decoded).unwrap();
assert_eq!(input_value, output_value, "Single-row arrays are unwrapped");
}
#[test]
fn test_deeply_nested_objects() {
let mut input = String::from(r#"{"a0":{"a1":{"a2":{"a3":{"a4":{"a5":{"a6":{"a7":{"a8":{"a9":"#);
input.push_str(r#"{"a10":{"a11":{"a12":{"a13":{"a14":{"a15":{"a16":{"a17":{"a18":{"a19":"#);
input.push_str(r#"{"a20":{"a21":{"a22":{"a23":{"a24":{"a25":{"a26":{"a27":{"a28":{"a29":"#);
input.push_str(r#"{"a30":{"a31":{"a32":{"a33":{"a34":{"a35":{"a36":{"a37":{"a38":{"a39":"#);
input.push_str(r#"{"a40":{"a41":{"a42":{"a43":{"a44":{"a45":{"a46":{"a47":{"a48":{"a49":"#);
input.push_str(r#"{"value":42}"#);
for _ in 0..50 {
input.push('}');
}
assert_roundtrip(&input);
}
#[test]
fn test_very_long_field_names() {
let long_name = "a".repeat(1024);
let input = format!(r#"{{"{}":1}}"#, long_name);
assert_roundtrip(&input);
}
#[test]
fn test_duplicate_keys_in_object() {
let input = r#"{"a":1,"a":2}"#;
let parsed: serde_json::Value = serde_json::from_str(input).unwrap();
assert_eq!(parsed["a"], 2);
assert_roundtrip(r#"{"a":2}"#);
}
#[test]
fn test_mixed_array_depths() {
let input = r#"{"shallow":[1,2],"deep":[[3,4],[5,6]],"deeper":[[[7,8]]]}"#;
let encoded = encode_schema(input, None).expect("encoding failed");
let decoded = decode_schema(&encoded, false).expect("decoding failed");
let expected = input;
let expected_value: serde_json::Value = serde_json::from_str(expected).unwrap();
let output_value: serde_json::Value = serde_json::from_str(&decoded).unwrap();
assert_eq!(
expected_value, output_value,
"Arrays should be properly reconstructed"
);
}
#[test]
fn test_many_fields() {
let mut fields = Vec::new();
for i in 0..100 {
fields.push(format!(r#""field{}": {}"#, i, i));
}
let input = format!("{{{}}}", fields.join(", "));
assert_roundtrip(&input);
}
#[test]
fn test_many_rows() {
let mut rows = Vec::new();
for i in 0..1000 {
rows.push(format!(r#"{{"id":{},"value":{}}}"#, i, i * 2));
}
let input = format!("[{}]", rows.join(","));
assert_roundtrip(&input);
}
#[test]
fn test_unicode_emoji_in_string() {
assert_roundtrip(r#"{"message":"Hello π World!"}"#);
}
#[test]
fn test_unicode_emoji_in_field_name() {
assert_roundtrip(r#"{"emoji_π":1}"#);
}
#[test]
fn test_unicode_cjk() {
assert_roundtrip(r#"{"δΈζ":"ζ΅θ―","ζ₯ζ¬θͺ":"γγΉγ","νκ΅μ΄":"μν"}"#);
}
#[test]
fn test_unicode_rtl() {
assert_roundtrip(r#"{"Ψ§ΩΨΉΨ±Ψ¨ΩΨ©":"Ω
Ψ±ΨΨ¨Ψ§"}"#);
}
#[test]
fn test_unicode_mixed() {
assert_roundtrip(r#"{"text":"HelloδΈηπΩ
Ψ±ΨΨ¨Ψ§"}"#);
}
#[test]
fn test_unicode_zero_width() {
assert_roundtrip(r#"{"zero\u200bwidth":"invisible\u200bspace"}"#);
}
#[test]
fn test_numeric_i64_max() {
let input = format!(r#"{{"value":{}}}"#, i64::MAX);
assert_roundtrip(&input);
}
#[test]
fn test_numeric_i64_min() {
let input = format!(r#"{{"value":{}}}"#, i64::MIN);
assert_roundtrip(&input);
}
#[test]
fn test_numeric_u64_max() {
let input = format!(r#"{{"value":{}}}"#, u64::MAX);
assert_roundtrip(&input);
}
#[test]
fn test_numeric_u64_zero() {
assert_roundtrip(r#"{"value":0}"#);
}
#[test]
fn test_numeric_f64_very_small() {
assert_roundtrip(r#"{"value":1.23456789e-308}"#);
}
#[test]
fn test_numeric_f64_very_large() {
assert_roundtrip(r#"{"value":1.23456789e308}"#);
}
#[test]
fn test_numeric_f64_many_decimals() {
assert_roundtrip(r#"{"value":3.141592653589793238462643383279}"#);
}
#[test]
fn test_numeric_f64_negative_zero() {
assert_roundtrip(r#"{"value":-0.0}"#);
}
#[test]
fn test_numeric_all_limits() {
let input = format!(
r#"{{"i64_max":{},"i64_min":{},"u64_max":{},"f64_small":1e-308,"f64_large":1e308}}"#,
i64::MAX,
i64::MIN,
u64::MAX
);
assert_roundtrip(&input);
}
#[test]
fn test_empty_string_value() {
assert_roundtrip(r#"{"name":""}"#);
}
#[test]
fn test_whitespace_only_string() {
assert_roundtrip(r#"{"spaces":" ","tabs":"\t\t\t"}"#);
}
#[test]
fn test_newlines_in_string() {
assert_roundtrip(r#"{"multiline":"line1\nline2\nline3"}"#);
}
#[test]
fn test_mixed_whitespace() {
assert_roundtrip(r#"{"text":" \t\n\r mixed \t\n "}"#);
}
#[test]
fn test_very_long_string_100kb() {
let long_string = "a".repeat(100 * 1024);
let input = format!(r#"{{"data":"{}"}}"#, long_string);
assert_roundtrip(&input);
}
#[test]
fn test_array_of_long_strings() {
let long_string = "test_".repeat(2000); let input = format!(
r#"[{{"a":"{}"}},{{"a":"{}"}},{{"a":"{}"}}]"#,
long_string, long_string, long_string
);
assert_roundtrip(&input);
}
#[test]
fn test_all_null_values() {
assert_roundtrip(r#"{"a":null,"b":null,"c":null}"#);
}
#[test]
fn test_sparse_array() {
let input = r#"[{"a":1},{"b":2},{"a":3,"b":4}]"#;
let encoded = encode_schema(input, None).expect("encoding failed");
let decoded = decode_schema(&encoded, false).expect("decoding failed");
let expected = r#"[{"a":1,"b":null},{"a":null,"b":2},{"a":3,"b":4}]"#;
let input_value: serde_json::Value = serde_json::from_str(expected).unwrap();
let output_value: serde_json::Value = serde_json::from_str(&decoded).unwrap();
assert_eq!(
input_value, output_value,
"Sparse arrays should be normalized with nulls"
);
}
#[test]
fn test_heterogeneous_types_in_array() {
let input = r#"[{"val":1},{"val":"string"},{"val":true}]"#;
let result = encode_schema(input, None);
if let Ok(encoded) = result {
let decode_result = decode_schema(&encoded, false);
if let Ok(decoded) = decode_result {
let output_value: serde_json::Value = serde_json::from_str(&decoded).unwrap();
assert_eq!(output_value.as_array().unwrap().len(), 3);
} else {
assert!(decode_result.is_err());
}
} else {
assert!(result.is_err());
}
}
#[test]
fn test_array_with_null_elements() {
let input = r#"{"items":[1,null,3,null,5]}"#;
let encoded = encode_schema(input, None).expect("encoding failed");
let decoded = decode_schema(&encoded, false).expect("decoding failed");
let expected = input;
let expected_value: serde_json::Value = serde_json::from_str(expected).unwrap();
let output_value: serde_json::Value = serde_json::from_str(&decoded).unwrap();
assert_eq!(
expected_value, output_value,
"Arrays are properly reconstructed with null preservation"
);
}
#[test]
fn test_nested_empty_arrays() {
let input = r#"{"outer":[],"nested":{"inner":[]}}"#;
let encoded = encode_schema(input, None).expect("encoding failed");
let decoded = decode_schema(&encoded, false).expect("decoding failed");
let expected_value: serde_json::Value = serde_json::from_str(input).unwrap();
let output_value: serde_json::Value = serde_json::from_str(&decoded).unwrap();
assert_eq!(
expected_value, output_value,
"Empty arrays should be preserved"
);
}
#[test]
fn test_boolean_edge_cases() {
assert_roundtrip(r#"[{"a":true,"b":false},{"a":false,"b":true},{"a":true,"b":true}]"#);
}
#[test]
fn test_mixed_number_types() {
let input = r#"{"integers":[1,2,3],"floats":[1.1,2.2,3.3],"mixed_int":42,"mixed_float":3.14}"#;
let encoded = encode_schema(input, None).expect("encoding failed");
let decoded = decode_schema(&encoded, false).expect("decoding failed");
let expected = input;
let expected_value: serde_json::Value = serde_json::from_str(expected).unwrap();
let output_value: serde_json::Value = serde_json::from_str(&decoded).unwrap();
assert_eq!(
expected_value, output_value,
"Arrays should be properly reconstructed"
);
}
#[test]
fn test_edge_cases_with_brotli() {
let test_cases = vec![
r#"{"emoji":"πππ"}"#,
r#"{"long":"aaaaaaaaaa","repeat":"bbbbbbbbbb"}"#,
r#"{"unicode":"δΈζΨ§ΩΨΉΨ±Ψ¨ΩΨ©π"}"#,
];
for input in test_cases {
let encoded = encode_schema(input, Some(SchemaCompressionAlgo::Brotli))
.expect("brotli encoding failed");
let decoded = decode_schema(&encoded, false).expect("brotli decoding failed");
let input_value: serde_json::Value = serde_json::from_str(input).unwrap();
let output_value: serde_json::Value = serde_json::from_str(&decoded).unwrap();
assert_eq!(input_value, output_value);
}
}
#[test]
fn test_edge_cases_with_lz4() {
let test_case_1 = r#"[{"id":1},{"id":2},{"id":3}]"#;
let test_case_2 = format!(r#"{{"value":{}}}"#, i64::MAX);
let test_case_3 = r#"{"data":"aaaaaaaaaaaaaaaaaaaaaaaaaaaa"}"#;
let test_cases = vec![test_case_1, &test_case_2, test_case_3];
for input in &test_cases {
let encoded =
encode_schema(input, Some(SchemaCompressionAlgo::Lz4)).expect("lz4 encoding failed");
let decoded = decode_schema(&encoded, false).expect("lz4 decoding failed");
let input_value: serde_json::Value = serde_json::from_str(input).unwrap();
let output_value: serde_json::Value = serde_json::from_str(&decoded).unwrap();
assert_eq!(input_value, output_value);
}
}
#[test]
fn test_edge_cases_with_zstd() {
let long_array = (0..100)
.map(|i| format!(r#"{{"id":{}}}"#, i))
.collect::<Vec<_>>()
.join(",");
let input = format!("[{}]", long_array);
let encoded =
encode_schema(&input, Some(SchemaCompressionAlgo::Zstd)).expect("zstd encoding failed");
let decoded = decode_schema(&encoded, false).expect("zstd decoding failed");
let input_value: serde_json::Value = serde_json::from_str(&input).unwrap();
let output_value: serde_json::Value = serde_json::from_str(&decoded).unwrap();
assert_eq!(input_value, output_value);
}
#[test]
fn test_invalid_json_syntax() {
let invalid_cases = vec![
r#"{"unclosed""#, r#"[1,2,3"#, r#"{"key":}"#, r#"{key:1}"#, r#"{'key':1}"#, r#"{"trailing":1,}"#, ];
for input in invalid_cases {
let result = encode_schema(input, None);
assert!(result.is_err(), "Expected error for: {}", input);
}
}
#[test]
fn test_array_of_primitives() {
assert_parse_error(r#"[1,2,3]"#);
assert_parse_error(r#"["a","b","c"]"#);
assert_parse_error(r#"[true,false,true]"#);
}
#[test]
fn test_mixed_array_objects_and_primitives() {
assert_parse_error(r#"[{"a":1},2,{"b":3}]"#);
}