Files
kebab/crates/kb-store-sqlite/tests/common/mod.rs
altair823 111f40ddf0 p1-6: kb-store-sqlite test suite (8 categories)
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.
2026-04-30 17:13:03 +00:00

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")
}
}