#![cfg(feature = "std")]
use graphitesql::{Connection, Value};
fn one(c: &Connection, sql: &str) -> Value {
c.query(sql).unwrap().rows[0][0].clone()
}
fn text(c: &Connection, sql: &str) -> String {
match one(c, sql) {
Value::Text(s) => s,
v => panic!("not text: {v:?}"),
}
}
#[test]
fn json_text_keeps_the_source_number_form() {
let c = Connection::open_memory().unwrap();
assert_eq!(text(&c, "SELECT json('1e2')"), "1e2");
assert_eq!(text(&c, "SELECT json('1E10')"), "1E10");
assert_eq!(text(&c, "SELECT json('-0.0')"), "-0.0");
assert_eq!(
text(&c, "SELECT json('[1e2, 1.50, 100, 2.0, 1.5e3]')"),
"[1e2,1.50,100,2.0,1.5e3]"
);
assert_eq!(
text(&c, "SELECT json('{\"a\":1e2,\"b\":2.50}')"),
r#"{"a":1e2,"b":2.50}"#
);
assert_eq!(text(&c, "SELECT json_array(1.5, 2.0)"), "[1.5,2.0]");
}
#[test]
fn json_text_keeps_overflowing_number_text() {
let c = Connection::open_memory().unwrap();
assert_eq!(text(&c, "SELECT json('1e1000')"), "1e1000");
assert_eq!(text(&c, "SELECT json('-1e1000')"), "-1e1000");
assert_eq!(text(&c, "SELECT json('9.9e999')"), "9.9e999");
assert_eq!(text(&c, "SELECT json('[1e1000]')"), "[1e1000]");
assert_eq!(text(&c, "SELECT json('{\"x\":1e1000}')"), r#"{"x":1e1000}"#);
assert_eq!(text(&c, "SELECT json('9e999')"), "9e999");
assert_eq!(
one(&c, "SELECT json_extract('[1e1000]', '$[0]')"),
Value::Real(f64::INFINITY)
);
}
#[test]
fn leading_zero_integer_is_malformed() {
let c = Connection::open_memory().unwrap();
for bad in ["00", "007", "000", "00.5", "-00", "-01", "[01]", "[1,00]"] {
assert!(
c.query(&format!("SELECT json('{bad}')")).is_err(),
"expected {bad} to be malformed JSON"
);
}
assert_eq!(text(&c, "SELECT json('0')"), "0");
assert_eq!(text(&c, "SELECT json('0.5')"), "0.5");
assert_eq!(text(&c, "SELECT json('0e1')"), "0e1");
assert_eq!(text(&c, "SELECT json('[0,1,2]')"), "[0,1,2]");
}
#[test]
fn json5_dot_form_keeps_its_shape_with_minimal_zero() {
let c = Connection::open_memory().unwrap();
assert_eq!(text(&c, "SELECT json('1.e5')"), "1.0e5");
assert_eq!(text(&c, "SELECT json('.5e2')"), "0.5e2");
assert_eq!(text(&c, "SELECT json('10.e2')"), "10.0e2");
assert_eq!(text(&c, "SELECT json('1.E5')"), "1.0E5");
assert_eq!(text(&c, "SELECT json('1.e5000')"), "1.0e5000");
assert_eq!(text(&c, "SELECT json('5.')"), "5.0");
assert_eq!(text(&c, "SELECT json('-.5')"), "-0.5");
assert_eq!(text(&c, "SELECT json('1.5e3')"), "1.5e3");
assert_eq!(text(&c, "SELECT json(jsonb('1.e5'))"), "1.0e5");
}
#[test]
fn extracted_scalar_is_the_canonical_value() {
let c = Connection::open_memory().unwrap();
assert_eq!(
one(&c, "SELECT json_extract('[1e2]', '$[0]')"),
Value::Real(100.0)
);
assert_eq!(
one(&c, "SELECT json_extract('{\"a\":1.50}', '$.a')"),
Value::Real(1.5)
);
}
#[test]
fn jsonb_round_trip_preserves_number_text() {
let c = Connection::open_memory().unwrap();
assert_eq!(text(&c, "SELECT json(jsonb('[1e2,2.50]'))"), "[1e2,2.50]");
assert_eq!(text(&c, "SELECT hex(jsonb('1e10'))"), "4531653130");
}