#![allow(clippy::unwrap_used)]
use std::process::Command;
fn cli() -> Command {
Command::new(env!("CARGO_BIN_EXE_fraiseql-cli"))
}
#[test]
fn sbom_exits_zero() {
let out = cli().arg("sbom").output().unwrap();
assert!(out.status.success(), "sbom must exit 0; status: {:?}", out.status);
assert!(!out.stdout.is_empty(), "sbom output must not be empty");
}
#[test]
fn sbom_default_format_is_cyclonedx() {
let out = cli().arg("sbom").output().unwrap();
assert!(out.status.success());
let stdout = String::from_utf8_lossy(&out.stdout);
let parsed: serde_json::Value = serde_json::from_str(&stdout)
.unwrap_or_else(|e| panic!("sbom default output must be valid JSON: {e}\ngot: {stdout}"));
assert_eq!(
parsed["bomFormat"].as_str().unwrap_or(""),
"CycloneDX",
"default sbom format must be CycloneDX"
);
}
#[test]
fn sbom_cyclonedx_has_components() {
let out = cli().arg("sbom").output().unwrap();
assert!(out.status.success());
let stdout = String::from_utf8_lossy(&out.stdout);
let parsed: serde_json::Value = serde_json::from_str(&stdout).unwrap();
assert!(parsed["components"].is_array(), "sbom output must contain a `components` array");
assert!(
!parsed["components"].as_array().unwrap().is_empty(),
"components array must not be empty"
);
}
#[test]
fn sbom_includes_fraiseql_core() {
let out = cli().arg("sbom").output().unwrap();
assert!(out.status.success());
let stdout = String::from_utf8_lossy(&out.stdout);
assert!(stdout.contains("fraiseql-core"), "sbom output must mention fraiseql-core");
}
#[test]
fn sbom_explicit_cyclonedx_format_works() {
let out = cli().args(["sbom", "--format", "cyclonedx"]).output().unwrap();
assert!(out.status.success(), "sbom --format cyclonedx must exit 0");
}
#[test]
fn sbom_spdx_format_exits_zero() {
let out = cli().args(["sbom", "--format", "spdx"]).output().unwrap();
assert!(out.status.success(), "sbom --format spdx must exit 0");
let stdout = String::from_utf8_lossy(&out.stdout);
assert!(
stdout.contains("SPDX") || stdout.contains("spdx"),
"SPDX output must contain SPDX identifiers; got: {stdout}"
);
}
#[test]
fn sbom_output_to_file() {
let dir = tempfile::tempdir().unwrap();
let outfile = dir.path().join("sbom.json").to_string_lossy().to_string();
let out = cli().args(["sbom", "--output", &outfile]).output().unwrap();
assert!(out.status.success(), "sbom --output must exit 0");
let contents = std::fs::read_to_string(&outfile)
.unwrap_or_else(|e| panic!("sbom --output must write to file {outfile}: {e}"));
assert!(!contents.is_empty(), "sbom output file must not be empty");
}
#[test]
fn sbom_unknown_format_exits_nonzero() {
let out = cli().args(["sbom", "--format", "unknown_format"]).output().unwrap();
assert!(!out.status.success(), "sbom --format unknown_format must exit non-zero");
}