aboutsummaryrefslogtreecommitdiff
path: root/crates/test_utils/src
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2021-03-08 17:27:08 +0000
committerAleksey Kladov <[email protected]>2021-03-08 17:37:20 +0000
commitda73c93c7f6d841496e75a16531d9be4aa23cada (patch)
tree360aae1dc872b22a71014f253e3a98f21a3502a6 /crates/test_utils/src
parentd57c9f79801762aa23adc21adbb638678268e96b (diff)
Don't punish every crate with serde-json
Diffstat (limited to 'crates/test_utils/src')
-rw-r--r--crates/test_utils/src/lib.rs96
1 files changed, 0 insertions, 96 deletions
diff --git a/crates/test_utils/src/lib.rs b/crates/test_utils/src/lib.rs
index 5be4a64fc..27b05e34b 100644
--- a/crates/test_utils/src/lib.rs
+++ b/crates/test_utils/src/lib.rs
@@ -18,7 +18,6 @@ use std::{
18}; 18};
19 19
20use profile::StopWatch; 20use profile::StopWatch;
21use serde_json::Value;
22use stdx::lines_with_ends; 21use stdx::lines_with_ends;
23use text_size::{TextRange, TextSize}; 22use text_size::{TextRange, TextSize};
24 23
@@ -281,101 +280,6 @@ fn main() {
281 ); 280 );
282} 281}
283 282
284// Comparison functionality borrowed from cargo:
285
286/// Compare a line with an expected pattern.
287/// - Use `[..]` as a wildcard to match 0 or more characters on the same line
288/// (similar to `.*` in a regex).
289pub fn lines_match(expected: &str, actual: &str) -> bool {
290 // Let's not deal with / vs \ (windows...)
291 // First replace backslash-escaped backslashes with forward slashes
292 // which can occur in, for example, JSON output
293 let expected = expected.replace(r"\\", "/").replace(r"\", "/");
294 let mut actual: &str = &actual.replace(r"\\", "/").replace(r"\", "/");
295 for (i, part) in expected.split("[..]").enumerate() {
296 match actual.find(part) {
297 Some(j) => {
298 if i == 0 && j != 0 {
299 return false;
300 }
301 actual = &actual[j + part.len()..];
302 }
303 None => return false,
304 }
305 }
306 actual.is_empty() || expected.ends_with("[..]")
307}
308
309#[test]
310fn lines_match_works() {
311 assert!(lines_match("a b", "a b"));
312 assert!(lines_match("a[..]b", "a b"));
313 assert!(lines_match("a[..]", "a b"));
314 assert!(lines_match("[..]", "a b"));
315 assert!(lines_match("[..]b", "a b"));
316
317 assert!(!lines_match("[..]b", "c"));
318 assert!(!lines_match("b", "c"));
319 assert!(!lines_match("b", "cb"));
320}
321
322/// Compares JSON object for approximate equality.
323/// You can use `[..]` wildcard in strings (useful for OS dependent things such
324/// as paths). You can use a `"{...}"` string literal as a wildcard for
325/// arbitrary nested JSON. Arrays are sorted before comparison.
326pub fn find_mismatch<'a>(expected: &'a Value, actual: &'a Value) -> Option<(&'a Value, &'a Value)> {
327 match (expected, actual) {
328 (Value::Number(l), Value::Number(r)) if l == r => None,
329 (Value::Bool(l), Value::Bool(r)) if l == r => None,
330 (Value::String(l), Value::String(r)) if lines_match(l, r) => None,
331 (Value::Array(l), Value::Array(r)) => {
332 if l.len() != r.len() {
333 return Some((expected, actual));
334 }
335
336 let mut l = l.iter().collect::<Vec<_>>();
337 let mut r = r.iter().collect::<Vec<_>>();
338
339 l.retain(|l| match r.iter().position(|r| find_mismatch(l, r).is_none()) {
340 Some(i) => {
341 r.remove(i);
342 false
343 }
344 None => true,
345 });
346
347 if !l.is_empty() {
348 assert!(!r.is_empty());
349 Some((&l[0], &r[0]))
350 } else {
351 assert_eq!(r.len(), 0);
352 None
353 }
354 }
355 (Value::Object(l), Value::Object(r)) => {
356 fn sorted_values(obj: &serde_json::Map<String, Value>) -> Vec<&Value> {
357 let mut entries = obj.iter().collect::<Vec<_>>();
358 entries.sort_by_key(|it| it.0);
359 entries.into_iter().map(|(_k, v)| v).collect::<Vec<_>>()
360 }
361
362 let same_keys = l.len() == r.len() && l.keys().all(|k| r.contains_key(k));
363 if !same_keys {
364 return Some((expected, actual));
365 }
366
367 let l = sorted_values(l);
368 let r = sorted_values(r);
369
370 l.into_iter().zip(r).filter_map(|(l, r)| find_mismatch(l, r)).next()
371 }
372 (Value::Null, Value::Null) => None,
373 // magic string literal "{...}" acts as wildcard for any sub-JSON
374 (Value::String(l), _) if l == "{...}" => None,
375 _ => Some((expected, actual)),
376 }
377}
378
379/// Returns `false` if slow tests should not run, otherwise returns `true` and 283/// Returns `false` if slow tests should not run, otherwise returns `true` and
380/// also creates a file at `./target/.slow_tests_cookie` which serves as a flag 284/// also creates a file at `./target/.slow_tests_cookie` which serves as a flag
381/// that slow tests did run. 285/// that slow tests did run.