aboutsummaryrefslogtreecommitdiff
path: root/crates/libsyntax2/tests/testutils
diff options
context:
space:
mode:
Diffstat (limited to 'crates/libsyntax2/tests/testutils')
-rw-r--r--crates/libsyntax2/tests/testutils/Cargo.toml7
-rw-r--r--crates/libsyntax2/tests/testutils/src/lib.rs111
2 files changed, 118 insertions, 0 deletions
diff --git a/crates/libsyntax2/tests/testutils/Cargo.toml b/crates/libsyntax2/tests/testutils/Cargo.toml
new file mode 100644
index 000000000..53b20f17b
--- /dev/null
+++ b/crates/libsyntax2/tests/testutils/Cargo.toml
@@ -0,0 +1,7 @@
1[package]
2name = "testutils"
3version = "0.1.0"
4authors = ["Aleksey Kladov <[email protected]>"]
5
6[dependencies]
7difference = "2.0.0"
diff --git a/crates/libsyntax2/tests/testutils/src/lib.rs b/crates/libsyntax2/tests/testutils/src/lib.rs
new file mode 100644
index 000000000..39c821661
--- /dev/null
+++ b/crates/libsyntax2/tests/testutils/src/lib.rs
@@ -0,0 +1,111 @@
1extern crate difference;
2
3use std::{
4 fs,
5 path::{Path, PathBuf},
6};
7
8use difference::Changeset;
9
10/// Read file and normalize newlines.
11///
12/// `rustc` seems to always normalize `\r\n` newlines to `\n`:
13///
14/// ```
15/// let s = "
16/// ";
17/// assert_eq!(s.as_bytes(), &[10]);
18/// ```
19///
20/// so this should always be correct.
21fn read_text(path: &Path) -> String {
22 fs::read_to_string(path).unwrap().replace("\r\n", "\n")
23}
24
25pub fn dir_tests<F>(paths: &[&str], f: F)
26where
27 F: Fn(&str) -> String,
28{
29 for path in collect_tests(paths) {
30 let input_code = read_text(&path);
31 let parse_tree = f(&input_code);
32 let path = path.with_extension("txt");
33 if !path.exists() {
34 println!("\nfile: {}", path.display());
35 println!("No .txt file with expected result, creating...\n");
36 println!("{}\n{}", input_code, parse_tree);
37 fs::write(&path, parse_tree).unwrap();
38 panic!("No expected result")
39 }
40 let expected = read_text(&path);
41 let expected = expected.as_str();
42 let parse_tree = parse_tree.as_str();
43 assert_equal_text(expected, parse_tree, &path);
44 }
45}
46
47fn assert_equal_text(expected: &str, actual: &str, path: &Path) {
48 if expected != actual {
49 print_difference(expected, actual, path)
50 }
51}
52
53fn collect_tests(paths: &[&str]) -> Vec<PathBuf> {
54 paths
55 .iter()
56 .flat_map(|path| {
57 let path = test_data_dir().join(path);
58 test_from_dir(&path).into_iter()
59 })
60 .collect()
61}
62
63fn test_from_dir(dir: &Path) -> Vec<PathBuf> {
64 let mut acc = Vec::new();
65 for file in fs::read_dir(&dir).unwrap() {
66 let file = file.unwrap();
67 let path = file.path();
68 if path.extension().unwrap_or_default() == "rs" {
69 acc.push(path);
70 }
71 }
72 acc.sort();
73 acc
74}
75
76const REWRITE: bool = false;
77
78fn print_difference(expected: &str, actual: &str, path: &Path) {
79 let dir = project_dir();
80 let path = path.strip_prefix(&dir).unwrap_or_else(|_| path);
81 if expected.trim() == actual.trim() {
82 println!("whitespace difference, rewriting");
83 println!("file: {}\n", path.display());
84 fs::write(path, actual).unwrap();
85 return;
86 }
87 if REWRITE {
88 println!("rewriting {}", path.display());
89 fs::write(path, actual).unwrap();
90 return;
91 }
92 let changeset = Changeset::new(actual, expected, "\n");
93 println!("Expected:\n{}\n\nActual:\n{}\n", expected, actual);
94 print!("{}", changeset);
95 println!("file: {}\n", path.display());
96 panic!("Comparison failed")
97}
98
99fn project_dir() -> PathBuf {
100 let dir = env!("CARGO_MANIFEST_DIR");
101 PathBuf::from(dir)
102 .parent()
103 .unwrap()
104 .parent()
105 .unwrap()
106 .to_owned()
107}
108
109fn test_data_dir() -> PathBuf {
110 project_dir().join("tests/data")
111}