#![cfg(feature = "std")]
use graphitesql::{Connection, Value};
fn one(c: &Connection, sql: &str) -> Value {
c.query(sql).unwrap().rows[0][0].clone()
}
fn hex(c: &Connection, sql: &str) -> String {
match one(c, &format!("SELECT hex({sql})")) {
Value::Text(s) => s,
v => panic!("hex not text: {v:?}"),
}
}
#[test]
fn jsonb_encoding_matches_sqlite_bytes() {
let c = Connection::open_memory().unwrap();
assert_eq!(hex(&c, "jsonb('null')"), "00");
assert_eq!(hex(&c, "jsonb('42')"), "233432"); assert_eq!(hex(&c, "jsonb('\"hi\"')"), "276869"); assert_eq!(hex(&c, "jsonb('[1,2,3]')"), "6B133113321333");
assert_eq!(hex(&c, "jsonb('{\"a\":1}')"), "4C17611331");
assert_eq!(hex(&c, "jsonb_array(1,2,3)"), hex(&c, "jsonb('[1,2,3]')"));
}
#[test]
fn json_functions_accept_jsonb_input() {
let c = Connection::open_memory().unwrap();
assert_eq!(
one(&c, "SELECT json(jsonb('{\"a\":1,\"b\":[2,3]}'))"),
Value::Text(r#"{"a":1,"b":[2,3]}"#.into())
);
assert_eq!(
one(
&c,
"SELECT json_extract(jsonb('{\"a\":10,\"b\":[20,30]}'), '$.b[1]')"
),
Value::Integer(30)
);
assert_eq!(
one(&c, "SELECT json_type(jsonb('[1,2,3]'))"),
Value::Text("array".into())
);
assert_eq!(
one(&c, "SELECT json_array_length(jsonb('[1,2,3,4]'))"),
Value::Integer(4)
);
}
#[test]
fn jsonb_functions_return_blobs_and_compose() {
let c = Connection::open_memory().unwrap();
assert!(matches!(one(&c, "SELECT jsonb('[1]')"), Value::Blob(_)));
assert!(matches!(
one(&c, "SELECT jsonb_extract(jsonb('{\"a\":[1,2]}'), '$.a')"),
Value::Blob(_)
));
assert_eq!(
one(&c, "SELECT jsonb_extract(jsonb('{\"a\":5}'), '$.a')"),
Value::Integer(5)
);
assert_eq!(
one(
&c,
"SELECT json(jsonb_object('a', 1, 'b', jsonb_array(2, 3)))"
),
Value::Text(r#"{"a":1,"b":[2,3]}"#.into())
);
assert_eq!(
one(
&c,
"SELECT json_extract(jsonb_set('{\"a\":1}', '$.b', jsonb('[7,8]')), '$.b[1]')"
),
Value::Integer(8)
);
assert!(c.query("SELECT json_array(x'4142')").is_err());
}
#[test]
fn jsonb_mutators_and_aggregates() {
let mut c = Connection::open_memory().unwrap();
assert_eq!(
one(&c, "SELECT json(jsonb_remove('{\"a\":1,\"b\":2}', '$.a'))"),
Value::Text(r#"{"b":2}"#.into())
);
assert_eq!(
one(&c, "SELECT json(jsonb_patch('{\"a\":1}', '{\"b\":2}'))"),
Value::Text(r#"{"a":1,"b":2}"#.into())
);
c.execute("CREATE TABLE t(x)").unwrap();
c.execute("INSERT INTO t VALUES (1),(2),(3)").unwrap();
assert_eq!(
one(&c, "SELECT json(jsonb_group_array(x)) FROM t"),
Value::Text("[1,2,3]".into())
);
assert!(matches!(
one(&c, "SELECT jsonb_group_array(x) FROM t"),
Value::Blob(_)
));
}
#[test]
fn json5_number_forms_use_int5_float5_tags() {
let c = Connection::open_memory().unwrap();
assert_eq!(hex(&c, "jsonb('.5')"), "262E35"); assert_eq!(hex(&c, "jsonb('5.')"), "26352E"); assert_eq!(hex(&c, "jsonb('-.5')"), "362D2E35");
assert_eq!(hex(&c, "jsonb('0xFF')"), "4430784646"); assert_eq!(hex(&c, "jsonb('0x10')"), "4430783130");
assert_eq!(hex(&c, "jsonb('1.5e3')"), "55312E356533");
assert_eq!(hex(&c, "jsonb('1.50')"), "45312E3530");
assert_eq!(hex(&c, "jsonb('+5')"), "1335"); assert_eq!(hex(&c, "jsonb('+0.5')"), "35302E35");
assert_eq!(
one(&c, "SELECT json(jsonb('.5'))"),
Value::Text("0.5".into())
);
assert_eq!(
one(&c, "SELECT json(jsonb('0xFF'))"),
Value::Text("255".into())
);
assert_eq!(
one(&c, "SELECT json(jsonb('5.'))"),
Value::Text("5.0".into())
);
assert_eq!(
one(&c, "SELECT json(jsonb('1.50'))"),
Value::Text("1.50".into())
);
}