use hegel::generators;
use noxu_bind::{
EntryBinding, IntBinding, LongBinding, SortedDoubleBinding,
SortedFloatBinding, StringBinding, TupleInput, TupleOutput,
};
use noxu_db::DatabaseEntry;
use noxu_bind::tuple::sort_key::SortKey;
#[hegel::test]
fn prop_int_binding_round_trip(tc: hegel::TestCase) {
let v = tc.draw(generators::integers::<i32>());
let binding = IntBinding::new();
let mut entry = DatabaseEntry::new();
binding.object_to_entry(&v, &mut entry).unwrap();
let result = binding.entry_to_object(&entry).unwrap();
assert_eq!(v, result);
}
#[hegel::test]
fn prop_long_binding_round_trip(tc: hegel::TestCase) {
let v = tc.draw(generators::integers::<i64>());
let binding = LongBinding::new();
let mut entry = DatabaseEntry::new();
binding.object_to_entry(&v, &mut entry).unwrap();
let result = binding.entry_to_object(&entry).unwrap();
assert_eq!(v, result);
}
#[hegel::test]
fn prop_string_binding_round_trip(tc: hegel::TestCase) {
let s = tc.draw(generators::from_regex(r"[^\x00]*").fullmatch(true));
let binding = StringBinding::new();
let mut entry = DatabaseEntry::new();
binding.object_to_entry(&s, &mut entry).unwrap();
let result = binding.entry_to_object(&entry).unwrap();
assert_eq!(s, result);
}
#[hegel::test]
fn prop_sorted_float_round_trip(tc: hegel::TestCase) {
let v = tc.draw(generators::floats::<f32>());
tc.assume(!v.is_nan());
let mut out = TupleOutput::new();
out.write_sorted_float(v);
let mut input = TupleInput::new(out.as_bytes());
let result = input.read_sorted_float().unwrap();
assert_eq!(v.to_bits(), result.to_bits());
}
#[hegel::test]
fn prop_sorted_double_round_trip(tc: hegel::TestCase) {
let v = tc.draw(generators::floats::<f64>());
tc.assume(!v.is_nan());
let mut out = TupleOutput::new();
out.write_sorted_double(v);
let mut input = TupleInput::new(out.as_bytes());
let result = input.read_sorted_double().unwrap();
assert_eq!(v.to_bits(), result.to_bits());
}
#[hegel::test]
fn prop_sorted_int_encoding_order(tc: hegel::TestCase) {
let a = tc.draw(generators::integers::<i32>());
let b = tc.draw(generators::integers::<i32>());
tc.assume(a < b);
let binding = IntBinding::new();
let mut entry_a = DatabaseEntry::new();
binding.object_to_entry(&a, &mut entry_a).unwrap();
let bytes_a = entry_a.data().to_vec();
let mut entry_b = DatabaseEntry::new();
binding.object_to_entry(&b, &mut entry_b).unwrap();
let bytes_b = entry_b.data().to_vec();
assert!(
bytes_a < bytes_b,
"encoded({a}) = {bytes_a:?} should be < encoded({b}) = {bytes_b:?}"
);
}
#[hegel::test]
fn prop_sorted_double_encoding_order(tc: hegel::TestCase) {
let a = tc.draw(generators::floats::<f64>());
let b = tc.draw(generators::floats::<f64>());
tc.assume(!a.is_nan() && !b.is_nan() && a < b);
let binding = SortedDoubleBinding::new();
let mut entry_a = DatabaseEntry::new();
binding.object_to_entry(&a, &mut entry_a).unwrap();
let bytes_a = entry_a.data().to_vec();
let mut entry_b = DatabaseEntry::new();
binding.object_to_entry(&b, &mut entry_b).unwrap();
let bytes_b = entry_b.data().to_vec();
assert!(
bytes_a < bytes_b,
"encoded({a}) = {bytes_a:?} should be < encoded({b}) = {bytes_b:?}"
);
}
#[hegel::test]
fn prop_sorted_float_encoding_order(tc: hegel::TestCase) {
let a = tc.draw(generators::floats::<f32>());
let b = tc.draw(generators::floats::<f32>());
tc.assume(!a.is_nan() && !b.is_nan() && a < b);
let binding = SortedFloatBinding::new();
let mut entry_a = DatabaseEntry::new();
binding.object_to_entry(&a, &mut entry_a).unwrap();
let bytes_a = entry_a.data().to_vec();
let mut entry_b = DatabaseEntry::new();
binding.object_to_entry(&b, &mut entry_b).unwrap();
let bytes_b = entry_b.data().to_vec();
assert!(
bytes_a < bytes_b,
"encoded({a}) = {bytes_a:?} should be < encoded({b}) = {bytes_b:?}"
);
}
#[hegel::test]
fn prop_tuple_i32_round_trip(tc: hegel::TestCase) {
let v = tc.draw(generators::integers::<i32>());
let mut out = TupleOutput::new();
out.write_i32(v);
let mut input = TupleInput::new(out.as_bytes());
let result = input.read_i32().unwrap();
assert_eq!(v, result);
}
#[hegel::test]
fn prop_tuple_i64_round_trip(tc: hegel::TestCase) {
let v = tc.draw(generators::integers::<i64>());
let mut out = TupleOutput::new();
out.write_i64(v);
let mut input = TupleInput::new(out.as_bytes());
let result = input.read_i64().unwrap();
assert_eq!(v, result);
}
#[hegel::test]
fn prop_packed_int_round_trip(tc: hegel::TestCase) {
let v = tc.draw(generators::integers::<i32>());
let mut out = TupleOutput::new();
out.write_packed_int(v);
let mut input = TupleInput::new(out.as_bytes());
let result = input.read_packed_int().unwrap();
assert_eq!(v, result);
}
#[hegel::test]
fn prop_packed_long_round_trip(tc: hegel::TestCase) {
let v = tc.draw(generators::integers::<i64>());
let mut out = TupleOutput::new();
out.write_packed_long(v);
let mut input = TupleInput::new(out.as_bytes());
let result = input.read_packed_long().unwrap();
assert_eq!(v, result);
}
#[hegel::test(test_cases = 256)]
fn prop_sort_key_u32_decode_then_encode(tc: hegel::TestCase) {
let v = tc.draw(generators::integers::<u32>());
let mut out = TupleOutput::new();
v.encode_sort_key(&mut out);
let bytes = out.into_vec();
let mut inp = TupleInput::new(&bytes);
let decoded = u32::decode_sort_key(&mut inp).unwrap();
assert_eq!(decoded, v);
let mut out2 = TupleOutput::new();
decoded.encode_sort_key(&mut out2);
assert_eq!(out2.into_vec(), bytes);
}
#[hegel::test(test_cases = 256)]
fn prop_sort_key_i64_decode_then_encode(tc: hegel::TestCase) {
let v = tc.draw(generators::integers::<i64>());
let mut out = TupleOutput::new();
v.encode_sort_key(&mut out);
let bytes = out.into_vec();
let mut inp = TupleInput::new(&bytes);
let decoded = i64::decode_sort_key(&mut inp).unwrap();
assert_eq!(decoded, v);
let mut out2 = TupleOutput::new();
decoded.encode_sort_key(&mut out2);
assert_eq!(out2.into_vec(), bytes);
}
#[hegel::test(test_cases = 256)]
fn prop_sort_key_i32_order_iff(tc: hegel::TestCase) {
let a = tc.draw(generators::integers::<i32>());
let b = tc.draw(generators::integers::<i32>());
let mut out_a = TupleOutput::new();
a.encode_sort_key(&mut out_a);
let mut out_b = TupleOutput::new();
b.encode_sort_key(&mut out_b);
let ba = out_a.into_vec();
let bb = out_b.into_vec();
assert_eq!(
a.cmp(&b),
ba.cmp(&bb),
"i32 sort-key ordering disagrees: a={a}, b={b}"
);
}
#[hegel::test(test_cases = 256)]
fn prop_sort_key_i16_order_iff(tc: hegel::TestCase) {
let a = tc.draw(generators::integers::<i16>());
let b = tc.draw(generators::integers::<i16>());
let mut out_a = TupleOutput::new();
a.encode_sort_key(&mut out_a);
let mut out_b = TupleOutput::new();
b.encode_sort_key(&mut out_b);
assert_eq!(a.cmp(&b), out_a.into_vec().cmp(&out_b.into_vec()));
}
#[hegel::test(test_cases = 256)]
fn prop_sort_key_bytes_roundtrip(tc: hegel::TestCase) {
let v = tc.draw(generators::binary().max_size(63));
let mut out = TupleOutput::new();
v.encode_sort_key(&mut out);
let bytes = out.into_vec();
let mut inp = TupleInput::new(&bytes);
let decoded = <Vec<u8>>::decode_sort_key(&mut inp).unwrap();
assert_eq!(&decoded, &v);
let mut out2 = TupleOutput::new();
decoded.encode_sort_key(&mut out2);
assert_eq!(out2.into_vec(), bytes);
}
#[hegel::test(test_cases = 256)]
fn prop_sort_key_bytes_order_preserving(tc: hegel::TestCase) {
let a = tc.draw(generators::binary().max_size(31));
let b = tc.draw(generators::binary().max_size(31));
let mut out_a = TupleOutput::new();
a.encode_sort_key(&mut out_a);
let mut out_b = TupleOutput::new();
b.encode_sort_key(&mut out_b);
assert_eq!(
a.cmp(&b),
out_a.into_vec().cmp(&out_b.into_vec()),
"Vec<u8> sort-key ordering disagrees"
);
}