#![cfg(all(feature = "wal2json", feature = "pg-walstream", feature = "maxwell"))]
extern crate alloc;
use alloc::string::String;
use alloc::vec::Vec;
use sqlite_diff_rs::maxwell::{Maxwell, MaxwellColumn};
use sqlite_diff_rs::pg_walstream::{ColumnValue, PgWalstream, PgWalstreamColumn};
use sqlite_diff_rs::wal2json::{Wal2Json, Wal2JsonColumn};
use sqlite_diff_rs::{JsonCanonicalDecoder, JsonVerbatimDecoder, TypeMap, Value, WireAdapter};
#[test]
fn json_verbatim_pg_walstream_text() {
let wire = "{\"k\": 1, \"nested\": [1, 2, 3]}";
let cv = ColumnValue::text(wire);
let got: Value<String, Vec<u8>> = PgWalstreamColumn {
column_name: "data",
oid: 114,
type_modifier: -1,
data: &cv,
}
.decoded_by(&JsonVerbatimDecoder)
.unwrap();
assert_eq!(got, Value::Text(String::from(wire)));
}
#[test]
fn json_verbatim_wal2json_object() {
let obj: serde_json::Value = serde_json::from_str("{\"k\": 1}").unwrap();
let got: Value<String, Vec<u8>> = Wal2JsonColumn {
column_name: "data",
pg_type_name: "json",
value: &obj,
}
.decoded_by(&JsonVerbatimDecoder)
.unwrap();
assert_eq!(got, Value::Text(String::from("{\"k\":1}")));
}
#[test]
fn json_verbatim_wal2json_string_pass_through() {
let s = serde_json::Value::String("{\"k\": 1}".into());
let got: Value<String, Vec<u8>> = Wal2JsonColumn {
column_name: "data",
pg_type_name: "json",
value: &s,
}
.decoded_by(&JsonVerbatimDecoder)
.unwrap();
assert_eq!(got, Value::Text(String::from("{\"k\": 1}")));
}
#[test]
fn json_verbatim_null_pass_through() {
let cv = ColumnValue::Null;
let got: Value<String, Vec<u8>> = PgWalstreamColumn {
column_name: "data",
oid: 114,
type_modifier: -1,
data: &cv,
}
.decoded_by(&JsonVerbatimDecoder)
.unwrap();
assert_eq!(got, Value::Null);
}
#[test]
fn json_canonical_sorts_keys() {
let unsorted: serde_json::Value = serde_json::from_str("{\"z\": 1, \"a\": 2}").unwrap();
let got: Value<String, Vec<u8>> = Wal2JsonColumn {
column_name: "data",
pg_type_name: "jsonb",
value: &unsorted,
}
.decoded_by(&JsonCanonicalDecoder)
.unwrap();
assert_eq!(got, Value::Text(String::from("{\"a\":2,\"z\":1}")));
}
#[test]
fn json_canonical_recurses_into_nested_objects() {
let src: serde_json::Value =
serde_json::from_str("{\"z\": {\"b\": 1, \"a\": 2}, \"a\": [3, 4]}").unwrap();
let got: Value<String, Vec<u8>> = Wal2JsonColumn {
column_name: "data",
pg_type_name: "jsonb",
value: &src,
}
.decoded_by(&JsonCanonicalDecoder)
.unwrap();
assert_eq!(
got,
Value::Text(String::from("{\"a\":[3,4],\"z\":{\"a\":2,\"b\":1}}"))
);
}
#[test]
fn json_canonical_string_source_reparses_and_sorts() {
let s = serde_json::Value::String("{\"z\":1,\"a\":2}".into());
let got: Value<String, Vec<u8>> = Wal2JsonColumn {
column_name: "data",
pg_type_name: "jsonb",
value: &s,
}
.decoded_by(&JsonCanonicalDecoder)
.unwrap();
assert_eq!(got, Value::Text(String::from("{\"a\":2,\"z\":1}")));
}
#[test]
fn json_discriminator_verbatim_vs_canonical_string_source() {
let raw = serde_json::Value::String("{\"z\":1,\"a\":2}".into());
let verbatim: Value<String, Vec<u8>> = Wal2JsonColumn {
column_name: "data",
pg_type_name: "jsonb",
value: &raw,
}
.decoded_by(&JsonVerbatimDecoder)
.unwrap();
let canonical: Value<String, Vec<u8>> = Wal2JsonColumn {
column_name: "data",
pg_type_name: "jsonb",
value: &raw,
}
.decoded_by(&JsonCanonicalDecoder)
.unwrap();
assert_eq!(verbatim, Value::Text(String::from("{\"z\":1,\"a\":2}")));
assert_eq!(canonical, Value::Text(String::from("{\"a\":2,\"z\":1}")));
assert_ne!(verbatim, canonical);
}
#[test]
fn defaults_route_json_types_verbatim() {
let pg: TypeMap<PgWalstream, String, Vec<u8>> = TypeMap::defaults();
let w2j: TypeMap<Wal2Json, String, Vec<u8>> = TypeMap::defaults();
let mx: TypeMap<Maxwell, String, Vec<u8>> = TypeMap::defaults();
let cv = ColumnValue::text("{\"k\": 1}");
let got = pg
.decode(PgWalstreamColumn {
column_name: "data",
oid: 114,
type_modifier: -1,
data: &cv,
})
.unwrap();
assert_eq!(got, Value::Text(String::from("{\"k\": 1}")));
let obj: serde_json::Value = serde_json::from_str("{\"k\": 1}").unwrap();
let got = w2j
.decode(Wal2JsonColumn {
column_name: "data",
pg_type_name: "json",
value: &obj,
})
.unwrap();
assert_eq!(got, Value::Text(String::from("{\"k\":1}")));
let s = serde_json::Value::String("{\"k\":1}".into());
let got = mx
.decode(MaxwellColumn {
column_name: "data",
mysql_type: Some("json"),
value: &s,
})
.unwrap();
assert_eq!(got, Value::Text(String::from("{\"k\":1}")));
}