diff options
Diffstat (limited to 'crates/test_utils/src')
-rw-r--r-- | crates/test_utils/src/fixture.rs | 114 | ||||
-rw-r--r-- | crates/test_utils/src/lib.rs | 2 |
2 files changed, 20 insertions, 96 deletions
diff --git a/crates/test_utils/src/fixture.rs b/crates/test_utils/src/fixture.rs index 0cd51ab3e..8747fa4a5 100644 --- a/crates/test_utils/src/fixture.rs +++ b/crates/test_utils/src/fixture.rs | |||
@@ -2,7 +2,7 @@ | |||
2 | //! rust-analyzer database from a single string. | 2 | //! rust-analyzer database from a single string. |
3 | 3 | ||
4 | use rustc_hash::FxHashMap; | 4 | use rustc_hash::FxHashMap; |
5 | use stdx::split_delim; | 5 | use stdx::{lines_with_ends, split_delim, trim_indent}; |
6 | 6 | ||
7 | #[derive(Debug, Eq, PartialEq)] | 7 | #[derive(Debug, Eq, PartialEq)] |
8 | pub struct Fixture { | 8 | pub struct Fixture { |
@@ -26,47 +26,35 @@ impl Fixture { | |||
26 | /// // - other meta | 26 | /// // - other meta |
27 | /// ``` | 27 | /// ``` |
28 | pub fn parse(ra_fixture: &str) -> Vec<Fixture> { | 28 | pub fn parse(ra_fixture: &str) -> Vec<Fixture> { |
29 | let fixture = indent_first_line(ra_fixture); | 29 | let fixture = trim_indent(ra_fixture); |
30 | let margin = fixture_margin(&fixture); | ||
31 | |||
32 | let mut lines = fixture | ||
33 | .split('\n') // don't use `.lines` to not drop `\r\n` | ||
34 | .enumerate() | ||
35 | .filter_map(|(ix, line)| { | ||
36 | if line.len() >= margin { | ||
37 | assert!(line[..margin].trim().is_empty()); | ||
38 | let line_content = &line[margin..]; | ||
39 | if !line_content.starts_with("//-") { | ||
40 | assert!( | ||
41 | !line_content.contains("//-"), | ||
42 | r#"Metadata line {} has invalid indentation. All metadata lines need to have the same indentation. | ||
43 | The offending line: {:?}"#, | ||
44 | ix, | ||
45 | line | ||
46 | ); | ||
47 | } | ||
48 | Some(line_content) | ||
49 | } else { | ||
50 | assert!(line.trim().is_empty()); | ||
51 | None | ||
52 | } | ||
53 | }); | ||
54 | 30 | ||
55 | let mut res: Vec<Fixture> = Vec::new(); | 31 | let mut res: Vec<Fixture> = Vec::new(); |
56 | for line in lines.by_ref() { | 32 | |
33 | for (ix, line) in lines_with_ends(&fixture).enumerate() { | ||
34 | if line.contains("//-") { | ||
35 | assert!( | ||
36 | line.starts_with("//-"), | ||
37 | "Metadata line {} has invalid indentation. \ | ||
38 | All metadata lines need to have the same indentation.\n\ | ||
39 | The offending line: {:?}", | ||
40 | ix, | ||
41 | line | ||
42 | ); | ||
43 | } | ||
44 | |||
57 | if line.starts_with("//-") { | 45 | if line.starts_with("//-") { |
58 | let meta = Fixture::parse_single(line); | 46 | let meta = Fixture::parse_meta_line(line); |
59 | res.push(meta) | 47 | res.push(meta) |
60 | } else if let Some(entry) = res.last_mut() { | 48 | } else if let Some(entry) = res.last_mut() { |
61 | entry.text.push_str(line); | 49 | entry.text.push_str(line); |
62 | entry.text.push('\n'); | ||
63 | } | 50 | } |
64 | } | 51 | } |
52 | |||
65 | res | 53 | res |
66 | } | 54 | } |
67 | 55 | ||
68 | //- /lib.rs crate:foo deps:bar,baz cfg:foo=a,bar=b env:OUTDIR=path/to,OTHER=foo | 56 | //- /lib.rs crate:foo deps:bar,baz cfg:foo=a,bar=b env:OUTDIR=path/to,OTHER=foo |
69 | pub fn parse_single(meta: &str) -> Fixture { | 57 | pub fn parse_meta_line(meta: &str) -> Fixture { |
70 | assert!(meta.starts_with("//-")); | 58 | assert!(meta.starts_with("//-")); |
71 | let meta = meta["//-".len()..].trim(); | 59 | let meta = meta["//-".len()..].trim(); |
72 | let components = meta.split_ascii_whitespace().collect::<Vec<_>>(); | 60 | let components = meta.split_ascii_whitespace().collect::<Vec<_>>(); |
@@ -118,51 +106,6 @@ The offending line: {:?}"#, | |||
118 | } | 106 | } |
119 | } | 107 | } |
120 | 108 | ||
121 | /// Adjusts the indentation of the first line to the minimum indentation of the rest of the lines. | ||
122 | /// This allows fixtures to start off in a different indentation, e.g. to align the first line with | ||
123 | /// the other lines visually: | ||
124 | /// ``` | ||
125 | /// let fixture = "//- /lib.rs | ||
126 | /// mod foo; | ||
127 | /// //- /foo.rs | ||
128 | /// fn bar() {} | ||
129 | /// "; | ||
130 | /// assert_eq!(fixture_margin(fixture), | ||
131 | /// " //- /lib.rs | ||
132 | /// mod foo; | ||
133 | /// //- /foo.rs | ||
134 | /// fn bar() {} | ||
135 | /// ") | ||
136 | /// ``` | ||
137 | fn indent_first_line(fixture: &str) -> String { | ||
138 | if fixture.is_empty() { | ||
139 | return String::new(); | ||
140 | } | ||
141 | let mut lines = fixture.lines(); | ||
142 | let first_line = lines.next().unwrap(); | ||
143 | if first_line.contains("//-") { | ||
144 | let rest = lines.collect::<Vec<_>>().join("\n"); | ||
145 | let fixed_margin = fixture_margin(&rest); | ||
146 | let fixed_indent = fixed_margin - indent_len(first_line); | ||
147 | format!("\n{}{}\n{}", " ".repeat(fixed_indent), first_line, rest) | ||
148 | } else { | ||
149 | fixture.to_owned() | ||
150 | } | ||
151 | } | ||
152 | |||
153 | fn fixture_margin(fixture: &str) -> usize { | ||
154 | fixture | ||
155 | .lines() | ||
156 | .filter(|it| it.trim_start().starts_with("//-")) | ||
157 | .map(indent_len) | ||
158 | .next() | ||
159 | .expect("empty fixture") | ||
160 | } | ||
161 | |||
162 | fn indent_len(s: &str) -> usize { | ||
163 | s.len() - s.trim_start().len() | ||
164 | } | ||
165 | |||
166 | #[test] | 109 | #[test] |
167 | #[should_panic] | 110 | #[should_panic] |
168 | fn parse_fixture_checks_further_indented_metadata() { | 111 | fn parse_fixture_checks_further_indented_metadata() { |
@@ -179,25 +122,6 @@ fn parse_fixture_checks_further_indented_metadata() { | |||
179 | } | 122 | } |
180 | 123 | ||
181 | #[test] | 124 | #[test] |
182 | fn parse_fixture_can_handle_dedented_first_line() { | ||
183 | let fixture = "//- /lib.rs | ||
184 | mod foo; | ||
185 | //- /foo.rs | ||
186 | struct Bar; | ||
187 | "; | ||
188 | assert_eq!( | ||
189 | Fixture::parse(fixture), | ||
190 | Fixture::parse( | ||
191 | "//- /lib.rs | ||
192 | mod foo; | ||
193 | //- /foo.rs | ||
194 | struct Bar; | ||
195 | " | ||
196 | ) | ||
197 | ) | ||
198 | } | ||
199 | |||
200 | #[test] | ||
201 | fn parse_fixture_gets_full_meta() { | 125 | fn parse_fixture_gets_full_meta() { |
202 | let parsed = Fixture::parse( | 126 | let parsed = Fixture::parse( |
203 | r" | 127 | r" |
@@ -208,7 +132,7 @@ fn parse_fixture_gets_full_meta() { | |||
208 | assert_eq!(1, parsed.len()); | 132 | assert_eq!(1, parsed.len()); |
209 | 133 | ||
210 | let meta = &parsed[0]; | 134 | let meta = &parsed[0]; |
211 | assert_eq!("mod m;\n\n", meta.text); | 135 | assert_eq!("mod m;\n", meta.text); |
212 | 136 | ||
213 | assert_eq!("foo", meta.crate_name.as_ref().unwrap()); | 137 | assert_eq!("foo", meta.crate_name.as_ref().unwrap()); |
214 | assert_eq!("/lib.rs", meta.path); | 138 | assert_eq!("/lib.rs", meta.path); |
diff --git a/crates/test_utils/src/lib.rs b/crates/test_utils/src/lib.rs index 3fd8505ed..eaeeeb97b 100644 --- a/crates/test_utils/src/lib.rs +++ b/crates/test_utils/src/lib.rs | |||
@@ -43,7 +43,7 @@ macro_rules! assert_eq_text { | |||
43 | if left.trim() == right.trim() { | 43 | if left.trim() == right.trim() { |
44 | eprintln!("Left:\n{:?}\n\nRight:\n{:?}\n\nWhitespace difference\n", left, right); | 44 | eprintln!("Left:\n{:?}\n\nRight:\n{:?}\n\nWhitespace difference\n", left, right); |
45 | } else { | 45 | } else { |
46 | let changeset = $crate::__Changeset::new(right, left, "\n"); | 46 | let changeset = $crate::__Changeset::new(left, right, "\n"); |
47 | eprintln!("Left:\n{}\n\nRight:\n{}\n\nDiff:\n{}\n", left, right, changeset); | 47 | eprintln!("Left:\n{}\n\nRight:\n{}\n\nDiff:\n{}\n", left, right, changeset); |
48 | } | 48 | } |
49 | eprintln!($($tt)*); | 49 | eprintln!($($tt)*); |