mod common;
use common::sqry_bin;
use assert_cmd::Command;
use std::fs;
use std::io;
use std::path::{Path, PathBuf};
use tempfile::TempDir;
fn sqry_cmd() -> Command {
let path = sqry_bin();
Command::new(path)
}
fn index_project(path: &Path) {
sqry_cmd().arg("index").arg(path).assert().success();
}
fn copy_fixture_dir(relative: &str) -> TempDir {
let binding = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
let root = binding.parent().expect("workspace root");
let source = root.join(relative);
assert!(
source.exists(),
"fixture directory {} not found",
source.display()
);
let temp = TempDir::new().expect("create temp dir");
copy_dir_all(&source, temp.path()).expect("copy fixture into temp dir");
temp
}
fn copy_dir_all(src: &Path, dst: &Path) -> io::Result<()> {
fs::create_dir_all(dst)?;
for entry in fs::read_dir(src)? {
let entry = entry?;
let ty = entry.file_type()?;
let dest_path = dst.join(entry.file_name());
if ty.is_dir() {
copy_dir_all(&entry.path(), &dest_path)?;
} else if ty.is_file() {
fs::copy(entry.path(), dest_path)?;
}
}
Ok(())
}
#[test]
fn dart_graph_builder_extracts_widget_classes_and_functions() {
let project = copy_fixture_dir("tests/fixtures/flutter_widgets");
index_project(project.path());
let output = sqry_cmd()
.arg("graph")
.arg("--path")
.arg(project.path())
.arg("--format")
.arg("json")
.arg("stats")
.arg("--by-language")
.output()
.expect("run sqry graph stats");
assert!(
output.status.success(),
"graph stats command failed: {}",
String::from_utf8_lossy(&output.stderr)
);
let stats: serde_json::Value =
serde_json::from_slice(&output.stdout).expect("stats output should be valid JSON");
let language_summary = stats["nodes_by_language"]
.as_object()
.expect("nodes_by_language map missing");
assert!(
language_summary
.keys()
.any(|lang| lang.eq("Dart") || lang.eq("DART")),
"expected Dart nodes in language summary, got {language_summary:?}"
);
let dart_count = language_summary
.get("Dart")
.or_else(|| language_summary.get("DART"))
.and_then(serde_json::Value::as_u64)
.unwrap_or(0);
assert!(
dart_count >= 3,
"expected at least 3 Dart nodes (classes), got {dart_count}"
);
}
#[test]
fn dart_widget_hierarchy_includes_inherited_widget_access() {
let project = copy_fixture_dir("tests/fixtures/flutter_widgets");
index_project(project.path());
let output = sqry_cmd()
.arg("graph")
.arg("--path")
.arg(project.path())
.arg("--format")
.arg("text")
.arg("dependency-tree")
.arg("AppShell")
.output()
.expect("run sqry graph dependency-tree");
let stdout = String::from_utf8_lossy(&output.stdout);
let stderr = String::from_utf8_lossy(&output.stderr);
let completed_ok = output.status.success()
|| stderr.contains("not found")
|| stderr.contains("No dependencies")
|| stderr.contains("Graph command failed");
assert!(
completed_ok,
"Expected command to complete (with or without finding dependencies). stdout:\n{stdout}\nstderr:\n{stderr}"
);
if output.status.success() && !stdout.is_empty() {
let _has_registry = stdout.contains("ChannelRegistry");
let _has_inherited = stdout.contains("InheritedWidget");
}
}