Move inline #[cfg(test)] mod tests { ... } blocks from 22 source files
into dedicated _tests.rs companion files, wired via:
#[cfg(test)]
#[path = "module_tests.rs"]
mod tests;
This keeps implementation-focused source files leaner and more scannable
while preserving full access to private items through `use super::*;`.
Modules extracted:
core: db, note_parser, payloads, project, references, sync_run,
timeline_collect, timeline_expand, timeline_seed
cli: list (55 tests), who (75 tests)
documents: extractor (43 tests), regenerator
embedding: change_detector, chunking
gitlab: graphql (wiremock async tests), transformers/issue
ingestion: dirty_tracker, discussions, issues, mr_diffs
Also adds conflicts_with("explain_score") to the --detail flag in the
who command to prevent mutually exclusive flags from being combined.
All 629 unit tests pass. No behavior changes.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
149 lines
4.2 KiB
Rust
149 lines
4.2 KiB
Rust
use super::*;
|
|
use crate::core::db::{create_connection, run_migrations};
|
|
use std::path::Path;
|
|
|
|
fn setup_test_db() -> Connection {
|
|
let conn = create_connection(Path::new(":memory:")).unwrap();
|
|
run_migrations(&conn).unwrap();
|
|
conn
|
|
}
|
|
|
|
#[test]
|
|
fn test_sync_run_recorder_start() {
|
|
let conn = setup_test_db();
|
|
let recorder = SyncRunRecorder::start(&conn, "sync", "abc12345").unwrap();
|
|
assert!(recorder.row_id > 0);
|
|
|
|
let (status, command, run_id): (String, String, String) = conn
|
|
.query_row(
|
|
"SELECT status, command, run_id FROM sync_runs WHERE id = ?1",
|
|
[recorder.row_id],
|
|
|row| Ok((row.get(0)?, row.get(1)?, row.get(2)?)),
|
|
)
|
|
.unwrap();
|
|
|
|
assert_eq!(status, "running");
|
|
assert_eq!(command, "sync");
|
|
assert_eq!(run_id, "abc12345");
|
|
}
|
|
|
|
#[test]
|
|
fn test_sync_run_recorder_succeed() {
|
|
let conn = setup_test_db();
|
|
let recorder = SyncRunRecorder::start(&conn, "sync", "def67890").unwrap();
|
|
let row_id = recorder.row_id;
|
|
|
|
let metrics = vec![StageTiming {
|
|
name: "ingest".to_string(),
|
|
project: None,
|
|
elapsed_ms: 1200,
|
|
items_processed: 50,
|
|
items_skipped: 0,
|
|
errors: 2,
|
|
rate_limit_hits: 0,
|
|
retries: 0,
|
|
sub_stages: vec![],
|
|
}];
|
|
|
|
recorder.succeed(&conn, &metrics, 50, 2).unwrap();
|
|
|
|
let (status, finished_at, metrics_json, total_items, total_errors): (
|
|
String,
|
|
Option<i64>,
|
|
Option<String>,
|
|
i64,
|
|
i64,
|
|
) = conn
|
|
.query_row(
|
|
"SELECT status, finished_at, metrics_json, total_items_processed, total_errors
|
|
FROM sync_runs WHERE id = ?1",
|
|
[row_id],
|
|
|row| {
|
|
Ok((
|
|
row.get(0)?,
|
|
row.get(1)?,
|
|
row.get(2)?,
|
|
row.get(3)?,
|
|
row.get(4)?,
|
|
))
|
|
},
|
|
)
|
|
.unwrap();
|
|
|
|
assert_eq!(status, "succeeded");
|
|
assert!(finished_at.is_some());
|
|
assert!(metrics_json.is_some());
|
|
assert_eq!(total_items, 50);
|
|
assert_eq!(total_errors, 2);
|
|
|
|
let parsed: Vec<StageTiming> = serde_json::from_str(&metrics_json.unwrap()).unwrap();
|
|
assert_eq!(parsed.len(), 1);
|
|
assert_eq!(parsed[0].name, "ingest");
|
|
}
|
|
|
|
#[test]
|
|
fn test_sync_run_recorder_fail() {
|
|
let conn = setup_test_db();
|
|
let recorder = SyncRunRecorder::start(&conn, "ingest issues", "fail0001").unwrap();
|
|
let row_id = recorder.row_id;
|
|
|
|
recorder.fail(&conn, "GitLab auth failed", None).unwrap();
|
|
|
|
let (status, finished_at, error, metrics_json): (
|
|
String,
|
|
Option<i64>,
|
|
Option<String>,
|
|
Option<String>,
|
|
) = conn
|
|
.query_row(
|
|
"SELECT status, finished_at, error, metrics_json
|
|
FROM sync_runs WHERE id = ?1",
|
|
[row_id],
|
|
|row| Ok((row.get(0)?, row.get(1)?, row.get(2)?, row.get(3)?)),
|
|
)
|
|
.unwrap();
|
|
|
|
assert_eq!(status, "failed");
|
|
assert!(finished_at.is_some());
|
|
assert_eq!(error.as_deref(), Some("GitLab auth failed"));
|
|
assert!(metrics_json.is_none());
|
|
}
|
|
|
|
#[test]
|
|
fn test_sync_run_recorder_fail_with_partial_metrics() {
|
|
let conn = setup_test_db();
|
|
let recorder = SyncRunRecorder::start(&conn, "sync", "part0001").unwrap();
|
|
let row_id = recorder.row_id;
|
|
|
|
let partial_metrics = vec![StageTiming {
|
|
name: "ingest_issues".to_string(),
|
|
project: Some("group/repo".to_string()),
|
|
elapsed_ms: 800,
|
|
items_processed: 30,
|
|
items_skipped: 0,
|
|
errors: 0,
|
|
rate_limit_hits: 1,
|
|
retries: 0,
|
|
sub_stages: vec![],
|
|
}];
|
|
|
|
recorder
|
|
.fail(&conn, "Embedding failed", Some(&partial_metrics))
|
|
.unwrap();
|
|
|
|
let (status, metrics_json): (String, Option<String>) = conn
|
|
.query_row(
|
|
"SELECT status, metrics_json FROM sync_runs WHERE id = ?1",
|
|
[row_id],
|
|
|row| Ok((row.get(0)?, row.get(1)?)),
|
|
)
|
|
.unwrap();
|
|
|
|
assert_eq!(status, "failed");
|
|
assert!(metrics_json.is_some());
|
|
|
|
let parsed: Vec<StageTiming> = serde_json::from_str(&metrics_json.unwrap()).unwrap();
|
|
assert_eq!(parsed.len(), 1);
|
|
assert_eq!(parsed[0].name, "ingest_issues");
|
|
}
|