cairo_lang_test_utils/
lib.rs1#![cfg(feature = "testing")]
2
3pub mod parse_test_file;
4use std::fs;
5use std::path::Path;
6use std::str::FromStr;
7use std::sync::{Mutex, MutexGuard};
8
9use cairo_lang_utils::ordered_hash_map::OrderedHashMap;
10use cairo_lang_utils::require;
11pub use parse_test_file::parse_test_file;
12
13fn get_expected_contents(path: &Path) -> String {
15 fs::read_to_string(path).unwrap_or_else(|_| panic!("Could not read file: '{path:?}'"))
16}
17
18fn set_contents(path: &Path, content: String) {
20 fs::write(path, content).unwrap_or_else(|_| panic!("Could not write file: '{path:?}'"));
21}
22
23pub fn compare_contents_or_fix_with_path(path: &Path, content: String) {
26 let is_fix_mode = std::env::var("CAIRO_FIX_TESTS") == Ok("1".into());
27 if is_fix_mode {
28 set_contents(path, content);
29 } else {
30 pretty_assertions::assert_eq!(content, get_expected_contents(path));
31 }
32}
33
34pub fn test_lock<'a, T: ?Sized + 'a>(m: &'a Mutex<T>) -> MutexGuard<'a, T> {
36 match m.lock() {
37 Ok(guard) => guard,
38 Err(poisoned) => poisoned.into_inner(),
40 }
41}
42
43pub fn verify_diagnostics_expectation(
46 args: &OrderedHashMap<String, String>,
47 diagnostics: &str,
48) -> Option<String> {
49 let expect_diagnostics = args.get("expect_diagnostics")?;
50 require(expect_diagnostics != "*")?;
51
52 let expect_diagnostics = expect_diagnostics_input_input(expect_diagnostics);
53 let has_diagnostics = !diagnostics.trim().is_empty();
54 let has_errors = diagnostics.lines().any(|line| line.starts_with("error: "));
56 match expect_diagnostics {
57 ExpectDiagnostics::Any => {
58 if !has_diagnostics {
59 return Some(
60 "`expect_diagnostics` is true, but no diagnostics were generated.\n"
61 .to_string(),
62 );
63 }
64 }
65 ExpectDiagnostics::Warnings => {
66 if !has_diagnostics {
67 return Some(
68 "`expect_diagnostics` is 'warnings_only', but no diagnostics were generated.\n"
69 .to_string(),
70 );
71 } else if has_errors {
72 return Some(
73 "`expect_diagnostics` is 'warnings_only', but errors were generated.\n"
74 .to_string(),
75 );
76 }
77 }
78 ExpectDiagnostics::None => {
79 if has_diagnostics {
80 return Some(
81 "`expect_diagnostics` is false, but diagnostics were generated:\n".to_string(),
82 );
83 }
84 }
85 };
86 None
87}
88
89enum ExpectDiagnostics {
91 Any,
93 Warnings,
95 None,
97}
98
99fn expect_diagnostics_input_input(input: &str) -> ExpectDiagnostics {
102 let input = input.to_lowercase();
103 match input.as_str() {
104 "false" => ExpectDiagnostics::None,
105 "true" => ExpectDiagnostics::Any,
106 "warnings_only" => ExpectDiagnostics::Warnings,
107 _ => panic!("Expected 'true', 'false' or 'warnings', actual: {input}"),
108 }
109}
110
111pub fn bool_input(input: &str) -> bool {
114 let input = input.to_lowercase();
115 bool::from_str(&input).unwrap_or_else(|_| panic!("Expected 'true' or 'false', actual: {input}"))
116}
117
118pub fn get_direct_or_file_content(input: &str) -> (String, String) {
122 if let Some(path) = input.strip_prefix(">>> file: ") {
123 (
124 path.to_string(),
125 fs::read_to_string(path).unwrap_or_else(|_| panic!("Could not read file: '{path}'")),
126 )
127 } else {
128 ("dummy_file.cairo".to_string(), input.to_string())
129 }
130}