use proptest::prelude::*;
use sz_orm_core::Value;
proptest! {
#[test]
fn prop_i8_to_i64_roundtrip(v: i8) {
prop_assert_eq!(Value::I8(v).as_i64(), Some(v as i64));
}
#[test]
fn prop_i16_to_i64_roundtrip(v: i16) {
prop_assert_eq!(Value::I16(v).as_i64(), Some(v as i64));
}
#[test]
fn prop_i32_to_i64_roundtrip(v: i32) {
prop_assert_eq!(Value::I32(v).as_i64(), Some(v as i64));
}
#[test]
fn prop_i64_to_i64_roundtrip(v: i64) {
prop_assert_eq!(Value::I64(v).as_i64(), Some(v));
}
#[test]
fn prop_u8_to_i64_roundtrip(v: u8) {
prop_assert_eq!(Value::U8(v).as_i64(), Some(v as i64));
}
#[test]
fn prop_u16_to_i64_roundtrip(v: u16) {
prop_assert_eq!(Value::U16(v).as_i64(), Some(v as i64));
}
#[test]
fn prop_u32_to_i64_roundtrip(v: u32) {
prop_assert_eq!(Value::U32(v).as_i64(), Some(v as i64));
}
#[test]
fn prop_u64_to_i64_boundary(v: u64) {
let expected = i64::try_from(v).ok();
prop_assert_eq!(Value::U64(v).as_i64(), expected);
if v > i64::MAX as u64 {
prop_assert_eq!(Value::U64(v).as_i64(), None,
"U64 超过 i64::MAX 时必须返回 None,不静默截断");
}
}
#[test]
fn prop_f32_to_f64_roundtrip(v: f32) {
prop_assume!(v.is_finite());
prop_assert_eq!(Value::F32(v).as_f64(), Some(v as f64));
}
#[test]
fn prop_f64_to_f64_roundtrip(v: f64) {
prop_assume!(v.is_finite());
prop_assert_eq!(Value::F64(v).as_f64(), Some(v));
}
#[test]
fn prop_bool_roundtrip(b: bool) {
prop_assert_eq!(Value::Bool(b).as_bool(), Some(b));
}
#[test]
fn prop_string_as_str_roundtrip(s: String) {
let v = Value::String(s.clone());
prop_assert_eq!(v.as_str(), Some(s.as_str()));
}
#[test]
fn prop_to_param_sql_injection_defense(s: String) {
let param = Value::String(s).to_param().into_owned();
prop_assert!(
param.starts_with('\''),
"to_param 必须以 ' 开头,实际: {:?}",
param
);
prop_assert!(
param.ends_with('\''),
"to_param 必须以 ' 结尾,实际: {:?}",
param
);
let inner = ¶m[1..param.len() - 1];
let quote_count = inner.chars().filter(|&c| c == '\'').count();
prop_assert_eq!(
quote_count % 2,
0,
"to_param 内部 ' 数量必须为偶数(每个 ' 被转义为 ''),实际 {} 个",
quote_count
);
}
#[test]
fn prop_i64_to_f64_roundtrip_within_safe_range(
v in -(1i64 << 53)..(1i64 << 53)
) {
prop_assert_eq!(Value::I64(v).as_f64(), Some(v as f64));
}
#[test]
fn prop_value_from_i64_roundtrip(v: i64) {
let value: Value = v.into();
prop_assert_eq!(value.as_i64(), Some(v));
}
#[test]
fn prop_value_from_string_roundtrip(s: String) {
let value: Value = s.clone().into();
prop_assert_eq!(value.as_str(), Some(s.as_str()));
}
}