mod common;
use common::sqry_bin;
use assert_cmd::Command;
use serde_json::Value;
use std::fs;
use std::io::Write;
use std::path::Path;
use tempfile::TempDir;
fn sqry_cmd() -> Command {
let path = sqry_bin();
Command::new(path)
}
fn write_file<P: AsRef<Path>>(root: &Path, rel: P, contents: &str) {
let path = root.join(rel);
if let Some(parent) = path.parent() {
fs::create_dir_all(parent).expect("create parent dirs");
}
let mut f = fs::File::create(&path).expect("create file");
f.write_all(contents.as_bytes()).expect("write file");
}
fn assert_nodes_and_edges_for_language(stats: &Value, lang: &str) {
let nodes_by_language = stats
.get("nodes_by_language")
.and_then(|v| v.as_object())
.expect("nodes_by_language map present");
assert!(
nodes_by_language.contains_key(lang),
"expected language '{}' in nodes_by_language, got {:?}",
lang,
nodes_by_language.keys().collect::<Vec<_>>()
);
let edge_count = stats
.get("edge_count")
.and_then(serde_json::Value::as_u64)
.unwrap_or(0);
assert!(
edge_count >= 1,
"expected at least 1 edge, found {edge_count}"
);
}
#[test]
fn phase5a_lua_cli_e2e() {
let project = TempDir::new().expect("create temp project");
write_file(
project.path(),
"main.lua",
r"
local M = {}
function M.add(a, b)
return a + b
end
local json = require('dkjson')
loadfile('scripts/init.lua')()
return M
",
);
write_file(project.path(), "scripts/init.lua", "return true\n");
sqry_cmd()
.arg("index")
.arg(project.path())
.assert()
.success();
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 failed");
let stats: Value = serde_json::from_slice(&output.stdout).expect("valid JSON");
assert_nodes_and_edges_for_language(&stats, "Lua");
}
#[test]
fn phase5a_shell_cli_e2e() {
let project = TempDir::new().expect("create temp project");
write_file(
project.path(),
"lib/common.sh",
r"#!/usr/bin/env bash
helper() { echo helper; }
",
);
write_file(
project.path(),
"run.sh",
r"#!/usr/bin/env bash
source ./lib/common.sh
main() { helper; }
main
",
);
sqry_cmd()
.arg("index")
.arg(project.path())
.assert()
.success();
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 failed");
let stats: Value = serde_json::from_slice(&output.stdout).expect("valid JSON");
assert_nodes_and_edges_for_language(&stats, "Shell");
}
#[test]
fn phase5a_perl_cli_e2e() {
let project = TempDir::new().expect("create temp project");
write_file(project.path(), "lib/common.pm", "package common; 1;\n");
write_file(
project.path(),
"main.pl",
r"use strict; use warnings;
use lib './lib';
use JSON qw(encode_json);
require 'common.pm';
sub main { my $x = 1; return $x; }
main();
",
);
sqry_cmd()
.arg("index")
.arg(project.path())
.assert()
.success();
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 failed");
let stats: Value = serde_json::from_slice(&output.stdout).expect("valid JSON");
assert_nodes_and_edges_for_language(&stats, "Perl");
}
#[test]
fn phase5a_groovy_cli_e2e() {
let project = TempDir::new().expect("create temp project");
write_file(
project.path(),
"App.groovy",
r"class App {
static void helper() { }
static void main(String[] args) {
helper()
}
}
",
);
sqry_cmd()
.arg("index")
.arg(project.path())
.assert()
.success();
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 failed");
let stats: Value = serde_json::from_slice(&output.stdout).expect("valid JSON");
assert_nodes_and_edges_for_language(&stats, "Groovy");
}