#![allow(clippy::unwrap_used)]
use iqdb_types::{
DistanceMetric, Filter, Hit, IqdbError, Metadata, SearchParams, Value, Vector, VectorId,
VectorRef,
};
#[test]
fn value_float_nan_breaks_reflexive_equality_by_design() {
let nan = Value::Float(f64::NAN);
assert_ne!(nan, Value::Float(f64::NAN));
}
#[test]
fn value_variants_of_different_kinds_are_never_equal() {
assert_ne!(Value::Int(1), Value::Float(1.0));
assert_ne!(Value::Bool(true), Value::Int(1));
assert_ne!(Value::Null, Value::Bool(false));
assert_ne!(Value::String("1".to_string()), Value::Int(1));
}
#[test]
fn metadata_collect_keeps_the_last_value_for_a_duplicate_key() {
let meta: Metadata = [
("k".to_string(), Value::Int(1)),
("k".to_string(), Value::Int(2)),
]
.into_iter()
.collect();
assert_eq!(meta.len(), 1);
assert_eq!(meta.get("k"), Some(&Value::Int(2)));
}
#[test]
fn metadata_default_is_empty_and_queryable() {
let m = Metadata::default();
assert!(m.is_empty());
assert_eq!(m.len(), 0);
assert_eq!(m.get("anything"), None);
assert_eq!(m.iter().count(), 0);
}
#[test]
fn vector_handles_single_and_large_dimensions() {
let one = Vector::new(vec![0.0]).unwrap();
assert_eq!(one.dim(), 1);
assert!(!one.is_empty());
let big: Vec<f32> = (0..4096).map(|i| i as f32).collect();
let v = Vector::new(big.clone()).unwrap();
assert_eq!(v.dim(), 4096);
assert_eq!(v.into_inner(), big); }
#[test]
fn vector_accepts_finite_extremes_and_subnormals() {
assert!(Vector::new(vec![f32::MIN, -0.0, 0.0, f32::MAX]).is_ok());
assert!(Vector::new(vec![f32::MIN_POSITIVE / 2.0]).is_ok()); }
#[test]
fn vector_ref_permits_an_empty_view() {
let empty: [f32; 0] = [];
let r = VectorRef::from(&empty[..]);
assert!(r.is_empty());
assert_eq!(r.dim(), 0);
}
#[test]
fn vector_id_single_byte_and_max_u64_render() {
assert_eq!(VectorId::try_from(vec![0xff]).unwrap().to_string(), "ff");
assert_eq!(VectorId::from(u64::MAX).to_string(), u64::MAX.to_string());
}
#[test]
fn empty_filter_combinators_construct_the_expected_shape() {
assert_eq!(Filter::and(vec![]), Filter::And(vec![]));
assert_eq!(Filter::or(vec![]), Filter::Or(vec![]));
}
#[test]
fn search_params_tier1_leaves_optionals_unset() {
let p = SearchParams::new(0, DistanceMetric::Hamming);
assert_eq!(p.k, 0); assert_eq!(p.ef, None);
assert!(p.filter.is_none());
}
#[test]
fn hit_distance_may_be_negative_or_zero() {
assert_eq!(Hit::new(VectorId::from(1u64), -3.5).distance, -3.5);
assert_eq!(Hit::new(VectorId::from(2u64), 0.0).distance, 0.0);
}
#[test]
fn error_is_copy_and_equatable_with_struct_fields() {
let e = IqdbError::ResourceLimitExceeded {
kind: "total_vectors",
max: 10,
found: 11,
};
let copy = e; assert_eq!(e, copy);
assert_ne!(IqdbError::NotFound, IqdbError::Duplicate);
}
#[cfg(feature = "serde")]
#[test]
fn vector_ref_serializes_as_its_slice() {
let data = [1.0_f32, 2.0, 3.0];
let json = serde_json::to_string(&VectorRef::from(&data[..])).unwrap();
assert_eq!(json, "[1.0,2.0,3.0]");
}
#[cfg(feature = "serde")]
#[test]
fn serde_round_trips_null_and_empty_metadata() {
let null = serde_json::to_string(&Value::Null).unwrap();
assert_eq!(serde_json::from_str::<Value>(&null).unwrap(), Value::Null);
let empty = Metadata::default();
let json = serde_json::to_string(&empty).unwrap();
assert_eq!(json, "{}");
assert_eq!(serde_json::from_str::<Metadata>(&json).unwrap(), empty);
}