#![cfg(feature = "code-intel-js")]
use std::fs;
use basemind::config::ConfigV1;
use basemind::path::RelPath;
use basemind::scanner::{ScanSource, scan, scan_paths};
use basemind::store::{Store, VIEW_WORKING};
fn helper_export_start(src: &str) -> u32 {
(src.find("function helper").unwrap() + "function ".len()) as u32
}
#[test]
fn scan_paths_restitches_unchanged_importer_when_dependency_export_moves() {
basemind::store::init_isolated_cache();
let dir = tempfile::tempdir().unwrap();
let root = dir.path();
let a_before = "export function helper() {\n return 1;\n}\n";
let b_src = "import { helper } from './a';\nexport function run() {\n return helper();\n}\n";
let a_abs = root.join("a.ts");
fs::write(&a_abs, a_before).unwrap();
fs::write(root.join("b.ts"), b_src).unwrap();
let mut store = Store::open(root, VIEW_WORKING).unwrap();
let cfg = ConfigV1::with_defaults();
scan(
root,
&mut store,
&cfg,
ScanSource::WorkingTree,
basemind::scanner::EmbedMode::Inline,
)
.unwrap();
if store.lookup("a.ts").is_none() || store.lookup("b.ts").is_none() {
eprintln!("typescript grammar unavailable in this environment — skipping cross-file assertions");
return;
}
let a = RelPath::from("a.ts");
let b = RelPath::from("b.ts");
let import_local_start = b_src.find("helper").unwrap() as u32;
let export_before = helper_export_start(a_before);
let baseline = basemind::query::resolved_references(&store, &a, export_before);
assert!(
baseline
.iter()
.any(|(p, s)| p.as_str() == Some("b.ts") && *s == import_local_start),
"full scan must link b.ts's import to the a.ts export at {export_before}; got {baseline:?}"
);
let a_after = "const pad = 0;\nexport function helper() {\n return pad + 2;\n}\n";
fs::write(&a_abs, a_after).unwrap();
scan_paths(root, &mut store, &cfg, &[a_abs], basemind::scanner::EmbedMode::Inline).unwrap();
let export_after = helper_export_start(a_after);
assert_ne!(
export_before, export_after,
"the edit must move the export name-site or the test proves nothing"
);
let after = basemind::query::resolved_references(&store, &a, export_after);
assert!(
after
.iter()
.any(|(p, s)| p.as_str() == Some("b.ts") && *s == import_local_start),
"scan_paths(a.ts, basemind::scanner::EmbedMode::Inline) must re-stitch b.ts's edge to the new a.ts export at {export_after}; got {after:?}"
);
let stale = basemind::query::resolved_references(&store, &a, export_before);
assert!(
!stale.iter().any(|(p, _)| p.as_str() == Some("b.ts")),
"the stale edge at the old export site must be purged; got {stale:?}"
);
assert_eq!(
basemind::query::definition_of(&store, &b, import_local_start),
Some((a.clone(), export_after)),
"cross-file goto-definition must follow the moved export after the incremental re-scan"
);
}