use std::num::NonZeroU32;
use hashbrown::HashMap;
use versatile_data::*;
fn new_data(name: &str) -> Data {
let dir = std::env::temp_dir().join(format!("versatile-data-sort-{name}"));
let _ = std::fs::remove_dir_all(&dir);
Data::new(&dir, DataOption::default())
}
async fn insert(data: &mut Data, term_end: Term, fields: &[(&FieldName, &str)]) -> NonZeroU32 {
let fields: HashMap<FieldName, Vec<u8>> = fields
.iter()
.map(|(name, value)| ((*name).clone(), value.as_bytes().to_vec()))
.collect();
data.insert(Activity::Active, Term::Default, term_end, fields)
.await
}
#[test]
fn sort_by_last_updated_uses_last_updated() {
let mut data = new_data("last-updated");
let name = FieldName::new("name".into());
futures::executor::block_on(async {
let r1 = insert(&mut data, Term::Overwrite(300), &[(&name, "a")]).await;
std::thread::sleep(std::time::Duration::from_millis(1100));
let r2 = insert(&mut data, Term::Overwrite(200), &[(&name, "b")]).await;
std::thread::sleep(std::time::Duration::from_millis(1100));
let r3 = insert(&mut data, Term::Overwrite(100), &[(&name, "c")]).await;
let rows = data.all();
let asc = data.sort(&rows, &[Order::Asc(OrderKey::LastUpdated)]);
assert_eq!(asc, [r1, r2, r3]);
let desc = data.sort(&rows, &[Order::Desc(OrderKey::LastUpdated)]);
assert_eq!(desc, [r3, r2, r1]);
});
}
#[test]
fn sort_by_field_keeps_rows_without_the_field() {
let mut data = new_data("missing-field");
let name = FieldName::new("name".into());
let other = FieldName::new("other".into());
futures::executor::block_on(async {
let b = insert(&mut data, Term::Default, &[(&name, "b")]).await;
let none = insert(&mut data, Term::Default, &[(&other, "x")]).await;
let a = insert(&mut data, Term::Default, &[(&name, "a")]).await;
let rows = data.all();
let asc = data.sort(&rows, &[Order::Asc(OrderKey::Field(name.clone()))]);
assert_eq!(asc, [a, b, none]);
let desc = data.sort(&rows, &[Order::Desc(OrderKey::Field(name.clone()))]);
assert_eq!(desc, [b, a, none]);
});
}
#[test]
fn sub_sort_by_field_with_rows_without_the_field() {
let mut data = new_data("missing-sub-field");
let group = FieldName::new("group".into());
let name = FieldName::new("name".into());
futures::executor::block_on(async {
let none = insert(&mut data, Term::Default, &[(&group, "g")]).await;
let b = insert(&mut data, Term::Default, &[(&group, "g"), (&name, "b")]).await;
let a = insert(&mut data, Term::Default, &[(&group, "g"), (&name, "a")]).await;
let rows = data.all();
let sorted = data.sort(
&rows,
&[
Order::Asc(OrderKey::Field(group.clone())),
Order::Asc(OrderKey::Field(name.clone())),
],
);
assert_eq!(sorted, [a, b, none]);
});
}