All 8 test categories from the task plan, plus a JobRepo subset:
migration — tests/migration.rs: fresh DB after run_migrations
exposes every required §5 table + index.
unit (copy) — tests/asset_writer.rs: copy mode writes file with
mode 0o644 + correct bytes.
unit (ref) — tests/asset_writer.rs: reference mode does not write
file; row records source path.
unit (cs) — tests/asset_writer.rs: tampered checksum returns a
Conflict-flavoured anyhow error.
unit (idem) — tests/idempotency.rs: same put_document twice → 1 row,
doc_version 1→2; tags re-derived.
unit (rb) — tests/idempotency.rs: put_blocks with FK violation
rolls back; pre-existing rows unchanged.
contract — tests/contract_roundtrip.rs: drives kb-parse-md +
kb-normalize + kb-chunk on
fixtures/markdown/code-and-table.md, persists, then
reloads via DocumentStore::get_document /
get_chunk and asserts byte-equal round-trip.
snapshot — tests/ingest_report_snapshot.rs +
snapshots/ingest_report.snapshot.json: pin the wire
JSON form of kb_core::IngestReport for an inline
fixture run.
jobs — tests/jobs.rs: create → progress → finish flow;
error message round-trip; list filters on status/kind.
Drops the unused `serde` direct dep from Cargo.toml; serde_json brings
its own. Dev-deps confirmed via `cargo tree -p kb-store-sqlite --depth 1`
to live only in the dev tree.
51 lines
1.5 KiB
Rust
51 lines
1.5 KiB
Rust
//! Shared test scaffolding: temp data_dir + freshly opened SqliteStore.
|
|
|
|
#![allow(dead_code)]
|
|
|
|
use std::path::PathBuf;
|
|
|
|
use kb_config::Config;
|
|
use rusqlite::Connection;
|
|
use tempfile::TempDir;
|
|
|
|
pub struct TestEnv {
|
|
pub temp: TempDir,
|
|
pub config: Config,
|
|
}
|
|
|
|
impl TestEnv {
|
|
pub fn new() -> Self {
|
|
Self::with_threshold(100)
|
|
}
|
|
|
|
/// Override the copy-threshold (useful for the reference-mode test
|
|
/// where we want a small file to land on the reference branch).
|
|
pub fn with_threshold(copy_threshold_mb: u64) -> Self {
|
|
let temp = tempfile::tempdir().expect("tempdir");
|
|
let mut config = Config::defaults();
|
|
config.storage.data_dir = temp.path().to_string_lossy().into_owned();
|
|
config.storage.copy_threshold_mb = copy_threshold_mb;
|
|
Self { temp, config }
|
|
}
|
|
|
|
pub fn config(&self) -> Config {
|
|
self.config.clone()
|
|
}
|
|
|
|
pub fn data_dir(&self) -> PathBuf {
|
|
self.temp.path().to_path_buf()
|
|
}
|
|
|
|
pub fn db_path(&self) -> PathBuf {
|
|
self.temp.path().join("kb.sqlite")
|
|
}
|
|
|
|
/// Open a side-channel rusqlite connection for direct SQL inspection.
|
|
/// The store-owned connection is held inside a Mutex; opening a fresh
|
|
/// one is the simplest way for tests to peek at row counts / pragmas.
|
|
pub fn with_conn<T>(&self, f: impl FnOnce(&Connection) -> rusqlite::Result<T>) -> T {
|
|
let conn = Connection::open(self.db_path()).expect("open side conn");
|
|
f(&conn).expect("with_conn closure")
|
|
}
|
|
}
|