mod support;
use scryer_db::{ScryerDb, Symbol, SymbolReference};
use scryer_engine::IndexOptions;
use support::fixture::{index_dir, index_files};
async fn target_files(
db: &ScryerDb,
project: u64,
file: &str,
) -> anyhow::Result<Vec<(u32, String)>> {
use scryer_db::SourceFile;
let mut conn = db.lock().await;
let files = SourceFile::filter_by_project_id(project)
.exec(&mut *conn)
.await?;
let path = |id: u64| files.iter().find(|f| f.id == id).map(|f| f.path.clone());
let symbols = Symbol::filter_by_project_id(project)
.exec(&mut *conn)
.await?;
let mut out: Vec<(u32, String)> = SymbolReference::filter_by_project_id(project)
.exec(&mut *conn)
.await?
.into_iter()
.filter(|r| r.role == "call" && path(r.file_id).as_deref() == Some(file))
.filter_map(|r| {
let target = symbols.iter().find(|s| s.id == r.symbol_id)?;
Some((r.line_number, path(target.file_id)?))
})
.collect();
out.sort();
Ok(out)
}
#[tokio::test]
async fn calls_resolve_within_their_own_language() -> anyhow::Result<()> {
let (db, project) = index_files(
&[
("m.py", "def helper():\n return 1\n\n\ndef go():\n return helper()\n"),
(
"src/lib.rs",
"pub fn helper() -> u32 { 1 }\npub fn go() -> u32 { helper() }\n",
),
(
"z.ts",
"export function helper() { return 1; }\nexport function go() { return helper(); }\n",
),
],
IndexOptions::default(),
)
.await?;
assert_eq!(
target_files(&db, project, "m.py").await?,
[(6, "m.py".into())]
);
assert_eq!(
target_files(&db, project, "src/lib.rs").await?,
[(2, "src/lib.rs".into())]
);
assert_eq!(
target_files(&db, project, "z.ts").await?,
[(2, "z.ts".into())]
);
Ok(())
}
#[tokio::test]
async fn a_name_defined_only_in_another_language_is_unresolved() -> anyhow::Result<()> {
let dir = tempfile::tempdir()?;
std::fs::write(
dir.path().join("only.py"),
"def only_python():\n return 1\n",
)?;
std::fs::write(
dir.path().join("lib.rs"),
"pub fn go() { only_python(); }\n",
)?;
let db = ScryerDb::new_in_memory().await?;
let (project, report) = index_dir(&db, dir.path(), IndexOptions::default()).await?;
assert_eq!(report.unresolved_references, 1, "{report:?}");
assert!(target_files(&db, project, "lib.rs").await?.is_empty());
Ok(())
}