xlsynth_test_helpers/
assert_valid_sv.rs1use tempfile::NamedTempFile;
4
5fn can_use_slang() -> bool {
6 let maybe_slang_path = std::env::var("SLANG_PATH").unwrap_or_default();
7 !maybe_slang_path.is_empty()
8}
9
10pub fn assert_valid_sv(sv: &str) {
12 if !can_use_slang() {
13 log::warn!("Skipping SV validation because Slang is not available.");
14 return;
15 }
16
17 let temp_file = NamedTempFile::new().unwrap();
19 std::fs::write(temp_file.path(), sv).unwrap();
20
21 let cfg = slang_rs::SlangConfig {
23 sources: &[temp_file.path().to_str().unwrap()],
24 ..Default::default()
25 };
26 slang_rs::run_slang(&cfg).expect("expect single SystemVerilog file contents is valid");
27}
28
29pub struct FlistEntry {
30 pub filename: String,
31 pub contents: String,
32}
33
34pub fn assert_valid_sv_flist(files: &[FlistEntry]) {
35 if !can_use_slang() {
36 log::warn!("Skipping SV validation because Slang is not available.");
37 return;
38 }
39
40 let temp_dir = tempfile::tempdir().unwrap();
42
43 let mut sources = vec![];
45 for entry in files {
46 let path = temp_dir.path().join(&entry.filename);
47 sources.push(path.to_str().unwrap().to_string());
48 std::fs::write(path, &entry.contents).unwrap();
49 }
50
51 let sources_strs = sources.iter().map(|s| s.as_str()).collect::<Vec<_>>();
53 let cfg = slang_rs::SlangConfig {
54 sources: &sources_strs,
55 ..Default::default()
56 };
57 let result = slang_rs::run_slang(&cfg);
58 if result.is_err() {
59 panic!(
60 "expect we can parse valid SystemVerilog via whole file list; error:\n{}",
61 result.err().unwrap().to_string().replace("\\n", "\n")
62 );
63 }
64}
65
66#[cfg(test)]
67mod tests {
68 use super::*;
69
70 #[test]
71 fn test_observe_error_if_can_use_slang() {
72 let _ = env_logger::builder().is_test(true).try_init();
73 if !can_use_slang() {
74 log::warn!("Skipping SV validation because Slang is not available.");
75 return;
76 }
77 let invalid_sv = "module foo; garbage; endmodule";
78 let result = std::panic::catch_unwind(|| assert_valid_sv(invalid_sv));
80 assert!(result.is_err());
81 let error = result.err().unwrap();
82 let error_message = error.downcast_ref::<String>().unwrap();
83 assert!(error_message.contains("expected a declaration name"));
84 }
85}