#![cfg(any())]
#![allow(
clippy::unwrap_used,
clippy::expect_used,
clippy::panic,
clippy::needless_raw_string_hashes,
clippy::duration_suboptimal_units,
clippy::branches_sharing_code,
clippy::used_underscore_binding,
clippy::single_char_pattern,
clippy::ignore_without_reason,
clippy::cloned_ref_to_slice_refs,
clippy::doc_overindented_list_items,
clippy::match_wildcard_for_single_variants,
clippy::ignored_unit_patterns,
clippy::needless_collect,
clippy::unnecessary_map_or,
clippy::manual_flatten,
clippy::manual_strip,
clippy::future_not_send,
clippy::unnested_or_patterns,
clippy::no_effect_underscore_binding,
clippy::literal_string_with_formatting_args
)]
use serde_json::Value;
use std::process::Command;
use std::time::Instant;
fn run_packs_command(args: &[&str]) -> Result<String, String> {
let output = Command::new("cargo")
.args(["run", "--bin", "ggen", "--"])
.args(["pack"])
.args(args)
.output()
.map_err(|e| format!("Failed to execute command: {}", e))?;
if output.status.success() {
Ok(String::from_utf8_lossy(&output.stdout).to_string())
} else {
Err(String::from_utf8_lossy(&output.stderr).to_string())
}
}
fn parse_json_output(output: &str) -> Result<Value, String> {
serde_json::from_str(output).map_err(|e| format!("Invalid JSON: {}", e))
}
#[test]
fn test_packs_list_returns_valid_json() {
let output = run_packs_command(&["list"]).expect("packs list should execute successfully");
let json = parse_json_output(&output).expect("Output should be valid JSON");
assert!(json.get("packs").is_some(), "Should have 'packs' field");
assert!(json.get("total").is_some(), "Should have 'total' field");
let packs = json["packs"].as_array().expect("packs should be an array");
assert_eq!(packs.len(), 5, "Should have exactly 5 packs");
for pack in packs {
assert!(pack.get("id").is_some(), "Pack should have 'id'");
assert!(pack.get("name").is_some(), "Pack should have 'name'");
assert!(
pack.get("description").is_some(),
"Pack should have 'description'"
);
assert!(
pack.get("package_count").is_some(),
"Pack should have 'package_count'"
);
assert!(
pack.get("category").is_some(),
"Pack should have 'category'"
);
}
}
#[test]
fn test_packs_show_returns_pack_details() {
let output = run_packs_command(&["show", "--pack_id", "startup-essentials"])
.expect("packs show should execute successfully");
let json = parse_json_output(&output).expect("Output should be valid JSON");
assert_eq!(
json["id"], "startup-essentials",
"Should have correct pack ID"
);
assert_eq!(
json["name"], "Startup Essentials",
"Should have correct pack name"
);
assert!(json.get("description").is_some(), "Should have description");
assert!(json.get("category").is_some(), "Should have category");
assert!(json.get("packages").is_some(), "Should have packages list");
let packages = json["packages"]
.as_array()
.expect("packages should be an array");
assert!(!packages.is_empty(), "Should have at least one package");
assert_eq!(
json["package_count"],
packages.len(),
"package_count should match packages length"
);
}
#[test]
#[ignore = "Live `pack add` (crates/ggen-cli/src/cmds/pack.rs::add) has no `--dry_run` \
and emits no 'DRY RUN'/'Would install' status — those assertions are fabricated. \
Invocation migrated to `pack add startup-essentials`. Real add-path coverage lives in \
proof_pack_test.rs::test_add_writes_lockfile_with_digest_and_emits_signed_receipt."]
fn test_packs_install_lists_packages() {
let result = run_packs_command(&["add", "startup-essentials"]);
match result {
Ok(output) => {
let json = parse_json_output(&output).expect("Output should be valid JSON");
assert_eq!(
json["pack_id"], "startup-essentials",
"Should have correct pack ID"
);
assert!(json.get("pack_name").is_some(), "Should have pack_name");
assert!(json.get("status").is_some(), "Should have status");
let status = json["status"].as_str().expect("status should be string");
assert!(
status.contains("DRY RUN") || status.contains("Would install"),
"Status should indicate dry run, got: {}",
status
);
}
Err(e) if e.contains("marketplace") => {
eprintln!("Note: Marketplace unavailable in test environment: {}", e);
}
Err(e) => panic!("Unexpected error: {}", e),
}
}
#[test]
#[ignore = "The live `pack` noun has NO `validate` verb (only `policy validate` exists, \
crates/ggen-cli/src/cmds/policy.rs). Intent (validate a pack by id) is impossible on the \
current CLI; no equivalent migration target. Invocation left referencing the removed \
verb intentionally — test stays ignored until/unless a `pack validate` verb is added."]
fn test_packs_validate_checks_pack() {
let output = run_packs_command(&["validate", "--pack_id", "startup-essentials"])
.expect("packs validate should execute successfully");
let json = parse_json_output(&output).expect("Output should be valid JSON");
assert_eq!(
json["pack_id"], "startup-essentials",
"Should have correct pack ID"
);
assert_eq!(json["valid"], true, "Pack should be valid");
assert!(json.get("message").is_some(), "Should have message");
assert!(
json.get("package_count").is_some(),
"Should have package_count"
);
let message = json["message"].as_str().expect("message should be string");
assert!(
message.contains("valid"),
"Message should indicate pack is valid"
);
}
#[test]
fn test_packs_invalid_id_returns_error() {
let result = run_packs_command(&["show", "--pack_id", "nonexistent-pack"]);
assert!(result.is_err(), "Invalid pack ID should return error");
let error = result.unwrap_err();
assert!(
error.contains("Pack not found") || error.contains("nonexistent-pack"),
"Error should mention pack not found or the invalid pack ID"
);
}
#[test]
#[ignore = "The live `pack` noun has NO `validate` verb (only `policy validate` exists, \
crates/ggen-cli/src/cmds/policy.rs). Intent (validate detects an invalid pack) is \
impossible on the current CLI; no equivalent migration target. Stays ignored until a \
`pack validate` verb is added."]
fn test_packs_validate_invalid_pack_returns_false() {
let output = run_packs_command(&["validate", "--pack_id", "invalid-pack-xyz"])
.expect("validate should handle invalid packs gracefully");
let json = parse_json_output(&output).expect("Output should be valid JSON");
assert_eq!(
json["pack_id"], "invalid-pack-xyz",
"Should have correct pack ID"
);
assert_eq!(json["valid"], false, "Pack should be marked as invalid");
assert!(
json["package_count"].is_null(),
"Invalid pack should have null package_count"
);
let message = json["message"].as_str().expect("message should be string");
assert!(
message.contains("not found"),
"Message should indicate pack not found"
);
}
#[test]
#[ignore = "Step 4 calls the removed `validate` verb (no live `pack validate`; only \
`policy validate`, crates/ggen-cli/src/cmds/policy.rs). list/show were migrated to the \
live `pack` noun and `install --dry_run` to `pack add`, but the validate assertion \
cannot pass on the current CLI. Live list/show/add coverage lives in proof_pack_test.rs."]
fn test_packs_all_commands_work_end_to_end() {
let list_output = run_packs_command(&["list"]).expect("list should work");
let list_json = parse_json_output(&list_output).expect("list should return JSON");
assert_eq!(list_json["total"], 5, "Should have 5 packs");
let pack_id = list_json["packs"][0]["id"]
.as_str()
.expect("First pack should have ID");
let show_output = run_packs_command(&["show", "--pack_id", pack_id]).expect("show should work");
let show_json = parse_json_output(&show_output).expect("show should return JSON");
assert_eq!(show_json["id"], pack_id, "Should return correct pack");
let _install_result = run_packs_command(&["add", pack_id]);
let validate_output =
run_packs_command(&["validate", "--pack_id", pack_id]).expect("validate should work");
let validate_json = parse_json_output(&validate_output).expect("validate should return JSON");
assert_eq!(validate_json["valid"], true, "Pack should be valid");
}
#[test]
fn test_packs_list_with_category_filter() {
let output = run_packs_command(&["list", "--category", "startup"])
.expect("list with category should work");
let json = parse_json_output(&output).expect("Should return JSON");
let packs = json["packs"].as_array().expect("Should have packs array");
for pack in packs {
let category = pack["category"]
.as_str()
.expect("Pack should have category");
assert_eq!(
category, "startup",
"All packs should have 'startup' category"
);
}
assert!(!packs.is_empty(), "Should have at least one startup pack");
}
#[test]
#[ignore = "Exercises the removed `validate` verb (no live `pack validate`; only \
`policy validate`, crates/ggen-cli/src/cmds/policy.rs) with `.expect(...)`. list/show \
migrated to the live `pack` noun and `install --dry_run` to `pack add`, but the validate \
step cannot run on the current CLI. Stays ignored until a `pack validate` verb exists."]
fn test_packs_commands_execute_quickly() {
let start = Instant::now();
run_packs_command(&["list"]).expect("list should work");
let list_duration = start.elapsed();
assert!(
list_duration.as_millis() < 60000,
"list should complete in < 60000ms (got {}ms)",
list_duration.as_millis()
);
let start = Instant::now();
run_packs_command(&["show", "--pack_id", "startup-essentials"]).expect("show should work");
let show_duration = start.elapsed();
assert!(
show_duration.as_millis() < 60000,
"show should complete in < 60000ms (got {}ms)",
show_duration.as_millis()
);
let start = Instant::now();
let _install_result = run_packs_command(&["add", "startup-essentials"]);
let install_duration = start.elapsed();
assert!(
install_duration.as_millis() < 60000,
"add should complete in < 60000ms (got {}ms), even if marketplace unavailable",
install_duration.as_millis()
);
let start = Instant::now();
run_packs_command(&["validate", "--pack_id", "startup-essentials"])
.expect("validate should work");
let validate_duration = start.elapsed();
assert!(
validate_duration.as_millis() < 60000,
"validate should complete in < 60000ms (got {}ms)",
validate_duration.as_millis()
);
}
#[test]
#[ignore = "Validates every listed pack via the removed `validate` verb (no live \
`pack validate`; only `policy validate`, crates/ggen-cli/src/cmds/policy.rs). The `list` \
call migrated to the live `pack` noun, but the per-pack validate loop cannot run on the \
current CLI. Stays ignored until a `pack validate` verb exists."]
fn test_packs_all_defined_packs_are_valid() {
let output = run_packs_command(&["list"]).expect("list should work");
let json = parse_json_output(&output).expect("Should return JSON");
let packs = json["packs"].as_array().expect("Should have packs array");
for pack in packs {
let pack_id = pack["id"].as_str().expect("Pack should have ID");
let validate_output = run_packs_command(&["validate", "--pack_id", pack_id])
.unwrap_or_else(|_| panic!("validate should work for pack {}", pack_id));
let validate_json = parse_json_output(&validate_output)
.unwrap_or_else(|_| panic!("validate should return JSON for pack {}", pack_id));
assert_eq!(
validate_json["valid"], true,
"Pack {} should be valid",
pack_id
);
assert!(
validate_json["package_count"].as_u64().unwrap() > 0,
"Pack {} should have at least one package",
pack_id
);
}
}