//! Cross-checks the two paths [`plan-runner`] exposes for materializing //! input tables: the pure [`build_tables`] path and the [`Storage`]-routed //! [`build_tables_via_storage`] path. Same fixture, same plan, must agree //! row-for-row. //! //! This is the visible proof of the layer boundary: any new `Storage` //! backend (LMDB, fjall, geomerge) keeps this test honest by re-running it //! with a different `S`. use plan_runner::{build_tables, build_tables_via_storage, execute, parse_plan, run_json}; use storage::MemoryStorage; use storage::value::Value; const FIXTURE: &str = include_str!("../fixtures/three_atom_chain.json"); #[test] fn storage_backed_execution_matches_pure_path() { let plan = parse_plan(FIXTURE).expect("parse plan"); let pure_tables = build_tables(&plan).expect("build_tables"); let pure = execute(&pure_tables, &plan.query).expect("pure execute"); let mut storage = MemoryStorage::default(); let storage_tables = build_tables_via_storage(&plan, &mut storage).expect("build_tables_via_storage"); let via_storage = execute(&storage_tables, &plan.query).expect("storage execute"); assert_eq!(pure.columns, via_storage.columns); // Scan order between MemoryStorage and the direct-from-JSON path isn't // required to match; compare rows as a multiset. `Value` is not `Ord` // (it carries `RowId` and `String`), so use a Debug-derived sort key. assert_eq!(sorted_rows(&pure.rows), sorted_rows(&via_storage.rows)); } #[test] fn storage_backed_execution_matches_run_json_oracle() { let plan = parse_plan(FIXTURE).expect("parse plan"); let oracle = run_json(FIXTURE).expect("run_json"); let mut storage = MemoryStorage::default(); let tables = build_tables_via_storage(&plan, &mut storage).expect("build_tables_via_storage"); let via_storage = execute(&tables, &plan.query).expect("storage execute"); assert_eq!(oracle.columns, via_storage.columns); assert_eq!(sorted_rows(&oracle.rows), sorted_rows(&via_storage.rows)); } fn sorted_rows(rows: &[Vec]) -> Vec { let mut keys: Vec = rows.iter().map(|r| format!("{r:?}")).collect(); keys.sort(); keys }