Mostly just write a fuckload of tests

This commit is contained in:
Ellie Huxtable 2023-06-01 22:13:17 +01:00
parent 1b242074da
commit 1443178c49
4 changed files with 105 additions and 11 deletions

View File

@ -543,6 +543,7 @@ mod test {
hostname: "test:host".to_string(),
session: "beepboopiamasession".to_string(),
cwd: "/home/ellie".to_string(),
host_id: "test-host".to_string(),
};
let results = db
@ -749,6 +750,7 @@ mod test {
hostname: "test:host".to_string(),
session: "beepboopiamasession".to_string(),
cwd: "/home/ellie".to_string(),
host_id: "test-host".to_string(),
};
let mut db = Sqlite::new("sqlite::memory:").await.unwrap();

View File

@ -91,13 +91,15 @@ impl Store for SqliteStore {
// TODO: batch inserts
let mut tx = self.pool.begin().await?;
Self::save_raw(&mut tx, &record).await?;
tx.commit().await?;
Ok(record)
}
async fn get(&self, id: String) -> Result<Record> {
async fn get(&self, id: &str) -> Result<Record> {
println!("querying {}", id);
let res = sqlx::query("select * from records where id = ?1")
.bind(id.as_str())
.bind(id)
.map(Self::query_row)
.fetch_one(&self.pool)
.await?;
@ -105,11 +107,11 @@ impl Store for SqliteStore {
Ok(res)
}
async fn len(&self, host: String, tag: String) -> Result<u64> {
async fn len(&self, host: &str, tag: &str) -> Result<u64> {
let res: (i64,) =
sqlx::query_as("select count(1) from records where host = ?1 and tag = ?2")
.bind(host.as_str())
.bind(tag.as_str())
.bind(host)
.bind(tag)
.fetch_one(&self.pool)
.await?;
@ -119,8 +121,21 @@ impl Store for SqliteStore {
#[cfg(test)]
mod tests {
use atuin_common::record::Record;
use crate::record::store::Store;
use super::SqliteStore;
fn test_record() -> Record {
Record::new(
String::from(atuin_common::utils::uuid_v7().simple().to_string()),
String::from("v1"),
String::from(atuin_common::utils::uuid_v7().simple().to_string()),
vec![0, 1, 2, 3],
)
}
#[tokio::test]
async fn create_db() {
let db = SqliteStore::new(":memory:").await;
@ -134,12 +149,72 @@ mod tests {
#[tokio::test]
async fn push_record() {
let db = SqliteStore::new(":memory:").await;
let db = SqliteStore::new(":memory:").await.unwrap();
let record = test_record();
let record = db.push(record).await;
assert!(
db.is_ok(),
"db could not be created, {:?}",
db.err().unwrap()
record.is_ok(),
"failed to insert record: {:?}",
record.unwrap_err()
);
}
#[tokio::test]
async fn get_record() {
let db = SqliteStore::new(":memory:").await.unwrap();
let record = test_record();
let record = db.push(record).await.unwrap();
let new_record = db.get(record.id.as_str()).await;
assert!(
new_record.is_ok(),
"failed to fetch record: {:?}",
new_record.unwrap_err()
);
assert_eq!(record, new_record.unwrap(), "records are not equal");
}
#[tokio::test]
async fn len() {
let db = SqliteStore::new(":memory:").await.unwrap();
let record = test_record();
let record = db.push(record).await.unwrap();
let len = db.len(record.host.as_str(), record.tag.as_str()).await;
assert!(
len.is_ok(),
"failed to get store len: {:?}",
len.unwrap_err()
);
assert_eq!(len.unwrap(), 1, "expected length of 1 after insert");
}
#[tokio::test]
async fn len_different_tags() {
let db = SqliteStore::new(":memory:").await.unwrap();
// these have different tags, so the len should be the same
// we model multiple stores within one database
// new store = new tag = independent length
let first = db.push(test_record()).await.unwrap();
let second = db.push(test_record()).await.unwrap();
let first_len = db
.len(first.host.as_str(), first.tag.as_str())
.await
.unwrap();
let second_len = db
.len(second.host.as_str(), second.tag.as_str())
.await
.unwrap();
assert_eq!(first_len, 1, "expected length of 1 after insert");
assert_eq!(second_len, 1, "expected length of 1 after insert");
}
}

View File

@ -10,6 +10,6 @@ use atuin_common::record::Record;
#[async_trait]
pub trait Store {
async fn push(&self, record: Record) -> Result<Record>;
async fn get(&self, id: String) -> Result<Record>;
async fn len(&self, host: String, tag: String) -> Result<u64>;
async fn get(&self, id: &str) -> Result<Record>;
async fn len(&self, host: &str, tag: &str) -> Result<u64>;
}

View File

@ -1,4 +1,5 @@
/// A single record stored inside of our local database
#[derive(Debug, Clone, PartialEq)]
pub struct Record {
pub id: String,
@ -15,3 +16,19 @@ pub struct Record {
/// Some data. This can be anything you wish to store. Use the tag field to know how to handle it.
pub data: Vec<u8>,
}
impl Record {
pub fn new(host: String, version: String, tag: String, data: Vec<u8>) -> Record {
let id = crate::utils::uuid_v7().as_simple().to_string();
let timestamp = chrono::Utc::now();
Record {
id,
host,
timestamp: timestamp.timestamp_nanos() as u64,
version,
tag,
data,
}
}
}