diff --git a/src/base/utils.rs b/src/base/utils.rs index 08a586c5..277497ca 100644 --- a/src/base/utils.rs +++ b/src/base/utils.rs @@ -31,3 +31,16 @@ pub fn check_path_type(path: &str) -> PathType { } PathType::new(ret.0, ret.1) } + +pub fn get_next_check_char(iter: &mut impl Iterator, mut check: impl FnMut(char) -> bool) -> Option { + loop { + let c = match iter.next() { + Some(c) => c, + None => return None, + }; + if check(c) { + continue; + } + return Some(c); + } +} diff --git a/src/compiler.rs b/src/compiler.rs index 7ded0bb6..919eca6d 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -427,24 +427,9 @@ impl Compiler { } mod tests { + use crate::base::utils::get_next_check_char; use super::*; - fn get_next_char( - iter: &mut impl Iterator, - mut is_ignore: impl FnMut(char) -> bool, - ) -> Option { - loop { - let c = match iter.next() { - None => return None, - Some(c) => c, - }; - if is_ignore(c) { - continue; - } - return Some(c); - } - } - fn check_read( reader: &mut impl TokenIo, s: &str, @@ -452,9 +437,9 @@ mod tests { ) { let mut iter = s.chars(); for i in reader { - assert_eq!(i, get_next_char(&mut iter, &mut is_ignore).unwrap()); + assert_eq!(i, get_next_check_char(&mut iter, &mut is_ignore).unwrap()); } - assert_eq!(get_next_char(&mut iter, &mut is_ignore), None); + assert_eq!(get_next_check_char(&mut iter, &mut is_ignore), None); } #[test] diff --git a/tests/test_all_examples.rs b/tests/test_all_examples.rs index 883f6b91..74c4c026 100644 --- a/tests/test_all_examples.rs +++ b/tests/test_all_examples.rs @@ -3,6 +3,45 @@ use std::fs::read_to_string; use assert_cmd::Command; +use trc::base::utils::get_next_check_char; + +/// 检查迭代器是否剩下的所有字符都满足某个条件 +fn check_whether_end(iter: &mut impl Iterator, condit: impl Fn(char) -> bool) -> bool { + loop { + match iter.next() { + Some(c) => { + if !condit(c) { + return false; + } + } + None => return true, + } + } +} + +/// 判断输出是否相同,忽略行末空格和最后的空行,自动处理\r\n等情况 +fn check_examples_eq(expected: &str, actual: &str) { + let mut iter1 = expected.chars(); + let mut iter2 = actual.chars(); + let checker = |c| c == '\r'; + let checker_end = |c| c == ' ' || c == '\n'; + loop { + let a = get_next_check_char(&mut iter1, checker); + let b = get_next_check_char(&mut iter2, checker); + if a != b { + panic!("expected: {}, actual: {}", expected, actual); + } + if a.is_none() && b.is_none() { + break; + } + if a.is_none() && !check_whether_end(&mut iter2, checker_end) { + panic!("expected: {}, actual: {}", expected, actual); + } + if b.is_none() && !check_whether_end(&mut iter1, checker_end) { + panic!("expected: {}, actual: {}", expected, actual); + } + } +} #[test] pub fn test_run_examples() { @@ -20,7 +59,11 @@ pub fn test_run_examples() { println!("checking {}", ans_path.display()); let expected_res = read_to_string(ans_path).unwrap(); let assert = cmd.arg("run").arg(path); - assert.assert().success().stdout(expected_res); + // assert.assert().success().stdout(expected_res); + let tmp = assert.assert(); + let output = tmp.get_output(); + let output = String::from_utf8_lossy(&output.stdout); + check_examples_eq(&expected_res, &output); } } }