aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Lattimore <[email protected]>2020-07-03 04:15:00 +0100
committerDavid Lattimore <[email protected]>2020-07-03 23:56:58 +0100
commit4a8679824b9ddf950e6754231755d5d065692c47 (patch)
tree3b18c785b92b4c4619a877aaa26ec12a7302bba6
parenta5ef644a16f6d187fb6b612d30f19bf4f20fc6c4 (diff)
SSR: Improve error reporting when a test fails
-rw-r--r--crates/ra_ssr/src/lib.rs30
-rw-r--r--crates/ra_ssr/src/tests.rs27
2 files changed, 36 insertions, 21 deletions
diff --git a/crates/ra_ssr/src/lib.rs b/crates/ra_ssr/src/lib.rs
index d6862356d..cca4576ce 100644
--- a/crates/ra_ssr/src/lib.rs
+++ b/crates/ra_ssr/src/lib.rs
@@ -201,9 +201,8 @@ impl<'db> MatchFinder<'db> {
201 ); 201 );
202 } 202 }
203 } 203 }
204 } else {
205 self.output_debug_for_nodes_at_range(&node, range, restrict_range, out);
206 } 204 }
205 self.output_debug_for_nodes_at_range(&node, range, restrict_range, out);
207 } 206 }
208 } 207 }
209} 208}
@@ -218,25 +217,26 @@ pub struct MatchDebugInfo {
218 217
219impl std::fmt::Debug for MatchDebugInfo { 218impl std::fmt::Debug for MatchDebugInfo {
220 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 219 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
221 write!(f, "========= PATTERN ==========\n")?; 220 match &self.matched {
221 Ok(_) => writeln!(f, "Node matched")?,
222 Err(reason) => writeln!(f, "Node failed to match because: {}", reason.reason)?,
223 }
224 writeln!(
225 f,
226 "============ AST ===========\n\
227 {:#?}",
228 self.node
229 )?;
230 writeln!(f, "========= PATTERN ==========")?;
222 match &self.pattern { 231 match &self.pattern {
223 Ok(pattern) => { 232 Ok(pattern) => {
224 write!(f, "{:#?}", pattern)?; 233 writeln!(f, "{:#?}", pattern)?;
225 } 234 }
226 Err(err) => { 235 Err(err) => {
227 write!(f, "{}", err.reason)?; 236 writeln!(f, "{}", err.reason)?;
228 } 237 }
229 } 238 }
230 write!( 239 writeln!(f, "============================")?;
231 f,
232 "\n============ AST ===========\n\
233 {:#?}\n============================\n",
234 self.node
235 )?;
236 match &self.matched {
237 Ok(_) => write!(f, "Node matched")?,
238 Err(reason) => write!(f, "Node failed to match because: {}", reason.reason)?,
239 }
240 Ok(()) 240 Ok(())
241 } 241 }
242} 242}
diff --git a/crates/ra_ssr/src/tests.rs b/crates/ra_ssr/src/tests.rs
index 9568d4432..9628dcbac 100644
--- a/crates/ra_ssr/src/tests.rs
+++ b/crates/ra_ssr/src/tests.rs
@@ -91,6 +91,18 @@ fn assert_ssr_transforms(rules: &[&str], input: &str, result: &str) {
91 } 91 }
92} 92}
93 93
94fn print_match_debug_info(match_finder: &MatchFinder, file_id: FileId, snippet: &str) {
95 let debug_info = match_finder.debug_where_text_equal(file_id, snippet);
96 println!(
97 "Match debug info: {} nodes had text exactly equal to '{}'",
98 debug_info.len(),
99 snippet
100 );
101 for (index, d) in debug_info.iter().enumerate() {
102 println!("Node #{}\n{:#?}\n", index, d);
103 }
104}
105
94fn assert_matches(pattern: &str, code: &str, expected: &[&str]) { 106fn assert_matches(pattern: &str, code: &str, expected: &[&str]) {
95 let (db, file_id) = single_file(code); 107 let (db, file_id) = single_file(code);
96 let mut match_finder = MatchFinder::new(&db); 108 let mut match_finder = MatchFinder::new(&db);
@@ -103,17 +115,20 @@ fn assert_matches(pattern: &str, code: &str, expected: &[&str]) {
103 .map(|m| m.matched_text()) 115 .map(|m| m.matched_text())
104 .collect(); 116 .collect();
105 if matched_strings != expected && !expected.is_empty() { 117 if matched_strings != expected && !expected.is_empty() {
106 let debug_info = match_finder.debug_where_text_equal(file_id, &expected[0]); 118 print_match_debug_info(&match_finder, file_id, &expected[0]);
107 eprintln!("Test is about to fail. Some possibly useful info: {} nodes had text exactly equal to '{}'", debug_info.len(), &expected[0]);
108 for d in debug_info {
109 eprintln!("{:#?}", d);
110 }
111 } 119 }
112 assert_eq!(matched_strings, expected); 120 assert_eq!(matched_strings, expected);
113} 121}
114 122
115fn assert_no_match(pattern: &str, code: &str) { 123fn assert_no_match(pattern: &str, code: &str) {
116 assert_matches(pattern, code, &[]); 124 let (db, file_id) = single_file(code);
125 let mut match_finder = MatchFinder::new(&db);
126 match_finder.add_search_pattern(pattern.parse().unwrap());
127 let matches = match_finder.find_matches_in_file(file_id).flattened().matches;
128 if !matches.is_empty() {
129 print_match_debug_info(&match_finder, file_id, &matches[0].matched_text());
130 panic!("Got {} matches when we expected none: {:#?}", matches.len(), matches);
131 }
117} 132}
118 133
119fn assert_match_failure_reason(pattern: &str, code: &str, snippet: &str, expected_reason: &str) { 134fn assert_match_failure_reason(pattern: &str, code: &str, snippet: &str, expected_reason: &str) {