#![allow(dead_code)]
use assert_cmd::Command;
use serde_json::Value;
use tempfile::TempDir;
pub fn sgr_cmd() -> Command {
let mock_dir = common::mock_llm_path();
let mut c = Command::cargo_bin("sqlite-graphrag").expect("sqlite-graphrag binary not found");
c.env("PATH", common::prepend_path(&mock_dir));
c
}
#[path = "../common/mod.rs"]
pub mod common;
pub struct Env {
pub tmp: TempDir,
}
impl Env {
pub fn new() -> Self {
let tmp = TempDir::new().expect("TempDir::new failed");
Self { tmp }
}
pub fn cmd(&self) -> Command {
let mut c = sgr_cmd();
common::wire_assert_cmd(&self.tmp, &mut c, "test.sqlite");
c.arg("--skip-memory-guard");
c
}
pub fn init(&self) {
self.cmd().arg("init").assert().success();
}
pub fn remember_simple(&self, name: &str) -> Value {
let output = self
.cmd()
.args([
"remember",
"--name",
name,
"--type",
"project",
"--description",
"descricao-contrato",
"--namespace",
"global",
"--body",
"corpo-de-teste-schema-contract",
])
.output()
.expect("remember failed to run");
assert!(
output.status.success(),
"remember returned an error: {:?}\nstdout: {}",
output.status.code(),
String::from_utf8_lossy(&output.stdout)
);
serde_json::from_slice(&output.stdout).expect("remember stdout is not valid JSON")
}
pub fn remember_with_entities(&self, name: &str) -> (String, String) {
let ent_a = format!("Ent{}Alpha", name.replace('-', ""));
let ent_b = format!("Ent{}Beta", name.replace('-', ""));
let entities_path = self.tmp.path().join(format!("{name}_ents.json"));
let json_ents = format!(
r#"[{{"name":"{ent_a}","entity_type":"concept"}},{{"name":"{ent_b}","entity_type":"concept"}}]"#
);
std::fs::write(&entities_path, &json_ents).expect("writing the entities file failed");
let output = self
.cmd()
.args([
"--llm-backend",
"none",
"remember",
"--name",
name,
"--type",
"project",
"--description",
"descricao-entidades",
"--body",
"corpo-com-entidades-para-schema",
"--entities-file",
entities_path
.to_str()
.expect("entities path is not valid UTF-8"),
])
.output()
.expect("remember with entities failed to run");
assert!(
output.status.success(),
"remember with entities returned an error: {:?}",
output.status.code()
);
(ent_a, ent_b)
}
pub fn parse_stdout(output: &std::process::Output, cmd: &str) -> Value {
serde_json::from_slice(&output.stdout).unwrap_or_else(|e| {
panic!(
"[{cmd}] stdout is not valid JSON: {e}\nraw stdout: {:?}",
String::from_utf8_lossy(&output.stdout)
)
})
}
}
pub const AGENT_SURFACE_SCHEMA: &str = include_str!("../../docs/schemas/agent-surface.schema.json");
const AGENT_SURFACE_URI: &str =
"https://github.com/danilo-aguiar-br/sqlite-graphrag/schemas/agent-surface.schema.json";
pub fn validate_schema(cmd: &str, schema_str: &str, instance: &Value) {
let schema: Value =
serde_json::from_str(schema_str).unwrap_or_else(|e| panic!("[{cmd}] invalid schema: {e}"));
let shared: Value = serde_json::from_str(AGENT_SURFACE_SCHEMA)
.unwrap_or_else(|e| panic!("[{cmd}] agent-surface.schema.json is invalid: {e}"));
let resource = jsonschema::Resource::from_contents(shared)
.unwrap_or_else(|e| panic!("[{cmd}] agent-surface is not a valid resource: {e}"));
let validator = jsonschema::options()
.with_resource(AGENT_SURFACE_URI, resource)
.build(&schema)
.unwrap_or_else(|e| panic!("[{cmd}] failed to compile the schema: {e}"));
let violations: Vec<String> = validator
.iter_errors(instance)
.map(|e| format!(" - path={} kind={:?}", e.instance_path, e.kind))
.collect();
assert!(
violations.is_empty(),
"[{cmd}] {n} schema violation(s):\n{list}\ninstance: {inst}",
n = violations.len(),
list = violations.join("\n"),
inst = serde_json::to_string_pretty(instance).unwrap_or_default()
);
}