use std::path::Path;
use wavetools::{compare_signal_meta, open_wave_file, NameOptions};
fn get_signal_attrs(path: &str, signal_name: &str) -> Vec<String> {
let (_, hier) = open_wave_file(Path::new(path), &NameOptions::default()).unwrap();
for info in hier.signal_map.values() {
for var in &info.vars {
if hier.names.format_path(var.name) == signal_name {
return var.attrs.clone();
}
}
}
panic!("Signal '{}' not found in {}", signal_name, path);
}
#[test]
fn test_vcd_array_packed_attr() {
let attrs = get_signal_attrs("tests/data/struct_attrs.vcd", "top.arrp [2:1]");
assert_eq!(attrs.len(), 1);
assert_eq!(attrs[0], "array packed: bounds 17179869187");
}
#[test]
fn test_vcd_array_unpacked_attr() {
let attrs = get_signal_attrs("tests/data/struct_attrs.vcd", "top.v_real");
assert_eq!(attrs.len(), 1);
assert_eq!(attrs[0], "array unpacked: bounds 1");
}
#[test]
fn test_vcd_class_packed_attr() {
let attrs = get_signal_attrs("tests/data/struct_attrs.vcd", "top.cyc");
assert_eq!(attrs.len(), 1);
assert_eq!(attrs[0], "class packed: members 2");
}
#[test]
fn test_vcd_enum_attr_ordering() {
let attrs = get_signal_attrs("tests/data/struct_attrs.vcd", "top.state");
assert_eq!(attrs.len(), 1);
assert_eq!(attrs[0], "enum state_t: IDLE=00 ACTIVE=01 DONE=10");
}
#[test]
fn test_vcd_no_attr_signal() {
let attrs = get_signal_attrs("tests/data/struct_attrs.vcd", "top.clk");
assert!(attrs.is_empty(), "clk should have no attributes");
}
#[test]
fn test_enum_attr_format_vcd() {
let attrs = get_signal_attrs("tests/data/enum_attrs.a.vcd", "top.state");
assert_eq!(attrs.len(), 1);
assert!(
attrs[0].contains("IDLE=0"),
"Expected value_name=encoding format, got: {}",
attrs[0]
);
assert!(
!attrs[0].contains("0=IDLE"),
"Should not have encoding=value_name format, got: {}",
attrs[0]
);
}
#[test]
fn test_meta_self_comparison_vcd() {
let (_, hier) =
open_wave_file(Path::new("tests/data/struct_attrs.vcd"), &NameOptions::default()).unwrap();
let diffs = compare_signal_meta(&hier, &hier);
assert!(diffs.is_empty(), "Self-comparison should have no diffs: {:?}", diffs);
}
#[test]
fn test_meta_comparison_enum_files() {
let (_, hier_a) =
open_wave_file(Path::new("tests/data/enum_attrs.a.vcd"), &NameOptions::default()).unwrap();
let (_, hier_b) =
open_wave_file(Path::new("tests/data/enum_attrs.b.vcd"), &NameOptions::default()).unwrap();
let diffs = compare_signal_meta(&hier_a, &hier_b);
assert!(!diffs.is_empty(), "Expected meta diffs between a and b enum files");
}
fn run_wavecat_cli(args: &[&str]) -> std::process::Output {
let bin = env!("CARGO_BIN_EXE_wavecat");
std::process::Command::new(bin)
.args(args)
.output()
.expect("Failed to run wavecat")
}
fn run_wavediff_cli(args: &[&str]) -> std::process::Output {
let bin = env!("CARGO_BIN_EXE_wavediff");
std::process::Command::new(bin)
.args(args)
.output()
.expect("Failed to run wavediff")
}
#[test]
fn test_cli_struct_attrs_output() {
let output = run_wavecat_cli(&["--attrs", "--sort", "tests/data/struct_attrs.vcd"]);
assert!(output.status.success());
let stdout = String::from_utf8(output.stdout).unwrap();
assert!(stdout.contains("array packed: bounds 17179869187"));
assert!(stdout.contains("array unpacked: bounds 1"));
assert!(stdout.contains("class packed: members 2"));
assert!(stdout.contains("enum state_t: IDLE=00 ACTIVE=01 DONE=10"));
}
#[test]
fn test_cli_struct_attrs_self_diff() {
let output = run_wavediff_cli(&[
"tests/data/struct_attrs.vcd",
"tests/data/struct_attrs.vcd",
]);
assert!(
output.status.success(),
"Expected exit 0, stderr: {}",
String::from_utf8_lossy(&output.stderr)
);
}