mod common;
use common::{js::run_js, parse_json_result, write_range_to_hb, Result};
use futures_lite::{Stream, StreamExt};
use hyperbee::{
traverse::{KeyDataResult, TraverseConfig},
Hyperbee,
};
async fn collect(stream: impl Stream<Item = KeyDataResult>) -> Result<Vec<Vec<u8>>> {
let stream_res = stream.collect::<Vec<KeyDataResult>>().await;
Ok(stream_res.into_iter().map(|x| x.unwrap().key).collect())
}
#[tokio::test]
async fn hello_world() -> Result<()> {
let storage_dir = tempfile::tempdir()?;
let storage_dir_path = format!("{}", storage_dir.path().display());
let hb = Hyperbee::from_storage_dir(&storage_dir).await?;
let key = b"hello";
let value = b"world";
hb.put(key, Some(b"world")).await?;
let res = hb.get(b"hello").await?;
assert_eq!(res, Some((1u64, Some(value.to_vec()))));
let output = run_js(
&storage_dir_path,
"
const r = await hb.get('hello');
write(r.value.toString());",
)?;
assert_eq!(output.stdout, b"world");
Ok(())
}
#[tokio::test]
async fn zero_to_one_hundred() -> Result<()> {
let storage_dir = tempfile::tempdir()?;
let storage_dir_path = format!("{}", storage_dir.path().display());
let hb = Hyperbee::from_storage_dir(&storage_dir).await?;
let keys = write_range_to_hb!(&hb);
let output = run_js(
&storage_dir_path,
"
const out = [];
for (let i = 0; i < 100; i++) {
out.push(
(await hb.get(String(i))).value.toString()
);
}
write(JSON.stringify(out));
",
)?;
let res = parse_json_result(&output)?;
assert_eq!(res, keys);
Ok(())
}
#[tokio::test]
async fn stream_in_same_order() -> Result<()> {
let storage_dir = tempfile::tempdir()?;
let storage_dir_path = format!("{}", storage_dir.path().display());
let hb = Hyperbee::from_storage_dir(&storage_dir).await?;
let _ = write_range_to_hb!(&hb);
let rust_res: Vec<Vec<u8>> = collect(hb.traverse(Default::default()).await?).await?;
let output = run_js(
&storage_dir_path,
"
const out = [];
for await (const x of hb.createReadStream()) {
out.push(x.value.toString())
}
write(JSON.stringify(out));
",
)?;
let js_res = parse_json_result(&output)?;
assert_eq!(js_res, rust_res);
Ok(())
}
#[tokio::test]
async fn sub_database() -> Result<()> {
let storage_dir = tempfile::tempdir()?;
let storage_dir_path = format!("{}", storage_dir.path().display());
let hb = Hyperbee::from_storage_dir(&storage_dir).await?;
let pref = b"pref";
let sub = hb.sub(pref, Default::default());
let _ = write_range_to_hb!(&sub);
let traverse_config = TraverseConfig::default();
let rust_res: Vec<Vec<u8>> = collect(sub.traverse(&traverse_config).await?).await?;
let output = run_js(
&storage_dir_path,
"
const out = [];
const sub = hb.sub('pref');
for await (const x of sub.createReadStream()) {
out.push(x.value.toString())
}
write(JSON.stringify(out));
",
)?;
let js_res = parse_json_result(&output)?;
assert_eq!(js_res, rust_res);
Ok(())
}