test: add test for thread safety; remove mut for upsert and persist

This commit is contained in:
2025-10-29 12:17:33 +01:00
parent 6f6df06be2
commit a38b96a667
13 changed files with 23 additions and 32 deletions

View File

@@ -59,7 +59,7 @@ fn main() {
// Define the path for the SQLite database file.
let db_path = "./simple_product.sqlite3";
// Create a new `Catalog` instance with the specified database path.
let mut catalog = Catalog::new(db_path);
let catalog = Catalog::new(db_path);
// Initialize the catalog, which sets up the database.
catalog.init().unwrap();
// Create a new `Product` instance representing a laptop.

View File

@@ -18,7 +18,7 @@ impl Catalog {
/// removed from the in-memory catalog.
/// - All other entities that were successfully persisted (new or updated) have
/// their state changed to `EntityState::Loaded`.
pub fn persist(&mut self) -> result::Result<(), FailedTo> {
pub fn persist(&self) -> result::Result<(), FailedTo> {
let path = path::Path::new(&self.path);
self.on_items(|items| {
sqlite::persist::catalog(path, items).map_err(|_| FailedTo::PersistCatalog)?;

View File

@@ -18,7 +18,7 @@ impl Catalog {
/// # Arguments
///
/// * `object` - The object to insert or update, which must implement the `EAV` trait.
pub fn upsert(&mut self, object: impl EAV) -> Result<(), FailedTo> {
pub fn upsert(&self, object: impl EAV) -> Result<(), FailedTo> {
let mut entity = object.try_into().map_err(|_| FailedTo::ConvertObject)?;
self.on_items(|items| {
if items.contains_key(&entity.id) {

View File

@@ -4,7 +4,7 @@ mod tests {
#[test]
fn get_should_retrieve_and_convert_entity_by_id() {
// Should retrieve an entity by its ID and correctly convert it to the target type 'T'.
let mut catalog = Catalog::new("dummy.db");
let catalog = Catalog::new("dummy.db");
let item = Item {
id: "item-123".to_string(),
subclass: Some("subitem".to_string()),
@@ -21,7 +21,7 @@ mod tests {
#[test]
fn get_should_return_none_for_nonexistent_id() {
// Should return 'None' if the ID does not exist.
let mut catalog = Catalog::new("dummy.db");
let catalog = Catalog::new("dummy.db");
let item = Item {
id: "item-123".to_string(),
name: "Test Item".to_string(),

View File

@@ -11,7 +11,7 @@ mod tests {
std::fs::remove_file(path).unwrap();
}
// 1. 'init' -> 'insert' -> 'persist'
let mut catalog1 = Catalog::new(db_path);
let catalog1 = Catalog::new(db_path);
catalog1.init().unwrap();
let item_to_insert = Item {
id: "item-1".to_string(),
@@ -96,7 +96,7 @@ mod tests {
std::fs::remove_file(path).unwrap();
}
// 1. 'insert' -> 'persist'
let mut catalog1 = Catalog::new(db_path);
let catalog1 = Catalog::new(db_path);
catalog1.init().unwrap();
let item_to_delete = Item {
id: "item-to-delete".to_string(),
@@ -136,7 +136,7 @@ mod tests {
std::fs::remove_file(path).unwrap();
}
// 1. Initial setup
let mut catalog_setup = Catalog::new(db_path);
let catalog_setup = Catalog::new(db_path);
catalog_setup.init().unwrap();
let initial_item = Item {
id: "item-1".to_string(),

View File

@@ -4,7 +4,7 @@ mod tests {
#[test]
fn list_by_class_should_return_all_entities_of_class() {
// Should return an iterator with all entities of a specific class.
let mut catalog = Catalog::new("dummy.db");
let catalog = Catalog::new("dummy.db");
let item1 = Item {
id: "item-1".to_string(),
subclass: Some("subitem".to_string()),

View File

@@ -3,7 +3,7 @@ mod tests {
use crate::*;
#[test]
fn list_by_class_and_subclass_should_return_matching_entities() {
let mut catalog = Catalog::new("dummy.db");
let catalog = Catalog::new("dummy.db");
let item1 = Item {
id: "item-1".to_string(),
subclass: Some("electronics".to_string()),
@@ -35,7 +35,7 @@ mod tests {
}
#[test]
fn list_by_class_and_subclass_should_return_empty_if_no_match() {
let mut catalog = Catalog::new("dummy.db");
let catalog = Catalog::new("dummy.db");
let item1 = Item {
id: "item-1".to_string(),
subclass: Some("electronics".to_string()),

View File

@@ -11,7 +11,7 @@ mod tests {
std::fs::remove_file(path).unwrap();
}
// 1. Setup DB with a few items of the same class
let mut catalog1 = Catalog::new(db_path);
let catalog1 = Catalog::new(db_path);
catalog1.init().unwrap();
let item1 = Item {
id: "item-1".to_string(),
@@ -70,7 +70,7 @@ mod tests {
std::fs::remove_file(path).unwrap();
}
// 1. Persist an item to the database.
let mut catalog1 = Catalog::new(db_path);
let catalog1 = Catalog::new(db_path);
catalog1.init().unwrap();
let item_in_db = Item {
id: "item-1".to_string(),

View File

@@ -133,7 +133,7 @@ mod tests {
if path.exists() {
std::fs::remove_file(path).unwrap();
}
let mut catalog_setup = Catalog::new(db_path);
let catalog_setup = Catalog::new(db_path);
catalog_setup.init().unwrap();
let item_in_db = Item {
id: "item-1".to_string(),
@@ -1421,7 +1421,7 @@ mod tests {
if path.exists() {
std::fs::remove_file(path).unwrap();
}
let mut catalog_setup = Catalog::new(db_path);
let catalog_setup = Catalog::new(db_path);
catalog_setup.init().unwrap();
// Define a second struct with a different class
#[derive(Debug, Default, PartialEq, Clone)]

View File

@@ -11,7 +11,7 @@ mod tests {
std::fs::remove_file(path).unwrap();
}
// 1. Create a catalog, insert an item, and persist it to the DB.
let mut catalog1 = Catalog::new(db_path);
let catalog1 = Catalog::new(db_path);
catalog1.init().unwrap();
let item_to_persist = Item {
id: "item-1".to_string(),
@@ -66,7 +66,7 @@ mod tests {
std::fs::remove_file(path).unwrap();
}
// 1. Persist an item to the database.
let mut catalog1 = Catalog::new(db_path);
let catalog1 = Catalog::new(db_path);
catalog1.init().unwrap();
let item_in_db = Item {
id: "item-1".to_string(),

View File

@@ -11,7 +11,7 @@ mod tests {
std::fs::remove_file(path).unwrap();
}
// 1. Create catalog, insert an item, and persist
let mut catalog1 = Catalog::new(db_path);
let catalog1 = Catalog::new(db_path);
catalog1.init().unwrap();
let item1 = Item {
id: "item-1".to_string(),
@@ -77,7 +77,7 @@ mod tests {
std::fs::remove_file(path).unwrap();
}
// 1. Insert an entity and persist it.
let mut catalog1 = Catalog::new(db_path);
let catalog1 = Catalog::new(db_path);
catalog1.init().unwrap();
let original_item = Item {
id: "item-1".to_string(),
@@ -132,7 +132,7 @@ mod tests {
std::fs::remove_file(path).unwrap();
}
// 1. Setup: Pre-populate the database with some items.
let mut catalog_setup = Catalog::new(db_path);
let catalog_setup = Catalog::new(db_path);
catalog_setup.init().unwrap();
let item_to_update_original = Item {
id: "update-me".to_string(),
@@ -221,7 +221,7 @@ mod tests {
// Using a directory as a path should cause a failure.
let invalid_path = "target/test_dbs/a_directory_for_persist_fail";
std::fs::create_dir_all(invalid_path).unwrap();
let mut catalog = Catalog::new(invalid_path);
let catalog = Catalog::new(invalid_path);
let item = Item {
id: "item-1".to_string(),
name: "Test".to_string(),

View File

@@ -3,7 +3,6 @@ mod tests {
use crate::*;
use std::sync::*;
use std::thread;
#[test]
fn thread_safety_test() {
let db_path = "target/test_dbs/thread_safety_test.db";
@@ -12,10 +11,8 @@ mod tests {
std::fs::remove_file(path).unwrap();
}
std::fs::create_dir_all(path.parent().unwrap()).unwrap();
let catalog = Arc::new(Catalog::new(db_path));
catalog.init().unwrap();
let mut handles = vec![];
for i in 0..10 {
let catalog = Arc::clone(&catalog);
@@ -36,22 +33,16 @@ mod tests {
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
let total_items = catalog.with_items(|items| Ok(items.len())).unwrap();
assert_eq!(total_items, 1000);
catalog.persist().unwrap();
let mut new_catalog = Catalog::new(db_path);
new_catalog.load_by_class::<Item>().unwrap();
let total_items_after_load = new_catalog.with_items(|items| Ok(items.len())).unwrap();
assert_eq!(total_items_after_load, 1000);
std::fs::remove_file(path).unwrap();
}
}

View File

@@ -4,7 +4,7 @@ mod tests {
#[test]
fn upsert_should_add_single_entity_as_new() {
// 'upsert()': Should add a single entity to the 'items' map with 'EntityState::New'.
let mut catalog = Catalog::new("dummy.db");
let catalog = Catalog::new("dummy.db");
let item = Item {
id: "item-123".to_string(),
name: "Test Item".to_string(),
@@ -29,7 +29,7 @@ mod tests {
#[test]
fn upsert_should_overwrite_existing_entity() {
// 'upsert()': Should overwrite an existing entity with the same ID.
let mut catalog = Catalog::new("dummy.db");
let catalog = Catalog::new("dummy.db");
let item1 = Item {
id: "item-123".to_string(),
name: "First Item".to_string(),