Skip to content

Commit a9db3d5

Browse files
bors[bot]matklad
andauthored
Merge #5159
5159: Don't fail expect tests in rewrite mode r=matklad a=matklad bors r+ Co-authored-by: Aleksey Kladov <[email protected]>
2 parents 99d6ef2 + 05d67a9 commit a9db3d5

File tree

9 files changed

+87
-34
lines changed

9 files changed

+87
-34
lines changed

crates/expect/src/lib.rs

Lines changed: 76 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//! https://github.com/rust-analyzer/rust-analyzer/pull/5101
33
use std::{
44
collections::HashMap,
5-
env, fmt, fs,
5+
env, fmt, fs, mem,
66
ops::Range,
77
panic,
88
path::{Path, PathBuf},
@@ -14,7 +14,7 @@ use once_cell::sync::Lazy;
1414
use stdx::{lines_with_ends, trim_indent};
1515

1616
const HELP: &str = "
17-
You can update all `expect![[]]` tests by:
17+
You can update all `expect![[]]` tests by running:
1818
1919
env UPDATE_EXPECT=1 cargo test
2020
@@ -25,24 +25,48 @@ fn update_expect() -> bool {
2525
env::var("UPDATE_EXPECT").is_ok()
2626
}
2727

28-
/// expect![[""]]
28+
/// expect![[r#"inline snapshot"#]]
2929
#[macro_export]
3030
macro_rules! expect {
31-
[[$lit:literal]] => {$crate::Expect {
32-
file: file!(),
33-
line: line!(),
34-
column: column!(),
35-
data: $lit,
31+
[[$data:literal]] => {$crate::Expect {
32+
position: $crate::Position {
33+
file: file!(),
34+
line: line!(),
35+
column: column!(),
36+
},
37+
data: $data,
3638
}};
3739
[[]] => { $crate::expect![[""]] };
3840
}
3941

42+
/// expect_file!["/crates/foo/test_data/bar.html"]
43+
#[macro_export]
44+
macro_rules! expect_file {
45+
[$path:literal] => {$crate::ExpectFile { path: $path }};
46+
}
47+
4048
#[derive(Debug)]
4149
pub struct Expect {
50+
pub position: Position,
51+
pub data: &'static str,
52+
}
53+
54+
#[derive(Debug)]
55+
pub struct ExpectFile {
56+
pub path: &'static str,
57+
}
58+
59+
#[derive(Debug)]
60+
pub struct Position {
4261
pub file: &'static str,
4362
pub line: u32,
4463
pub column: u32,
45-
pub data: &'static str,
64+
}
65+
66+
impl fmt::Display for Position {
67+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
68+
write!(f, "{}:{}:{}", self.file, self.line, self.column)
69+
}
4670
}
4771

4872
impl Expect {
@@ -51,7 +75,7 @@ impl Expect {
5175
if &trimmed == actual {
5276
return;
5377
}
54-
Runtime::fail(self, &trimmed, actual);
78+
Runtime::fail_expect(self, &trimmed, actual);
5579
}
5680
pub fn assert_debug_eq(&self, actual: &impl fmt::Debug) {
5781
let actual = format!("{:#?}\n", actual);
@@ -69,7 +93,7 @@ impl Expect {
6993
let mut target_line = None;
7094
let mut line_start = 0;
7195
for (i, line) in lines_with_ends(file).enumerate() {
72-
if i == self.line as usize - 1 {
96+
if i == self.position.line as usize - 1 {
7397
let pat = "expect![[";
7498
let offset = line.find(pat).unwrap();
7599
let literal_start = line_start + offset + pat.len();
@@ -87,6 +111,25 @@ impl Expect {
87111
}
88112
}
89113

114+
impl ExpectFile {
115+
pub fn assert_eq(&self, actual: &str) {
116+
let expected = self.read();
117+
if actual == expected {
118+
return;
119+
}
120+
Runtime::fail_file(self, &expected, actual);
121+
}
122+
fn read(&self) -> String {
123+
fs::read_to_string(self.abs_path()).unwrap_or_default().replace("\r\n", "\n")
124+
}
125+
fn write(&self, contents: &str) {
126+
fs::write(self.abs_path(), contents).unwrap()
127+
}
128+
fn abs_path(&self) -> PathBuf {
129+
workspace_root().join(self.path)
130+
}
131+
}
132+
90133
#[derive(Default)]
91134
struct Runtime {
92135
help_printed: bool,
@@ -95,27 +138,39 @@ struct Runtime {
95138
static RT: Lazy<Mutex<Runtime>> = Lazy::new(Default::default);
96139

97140
impl Runtime {
98-
fn fail(expect: &Expect, expected: &str, actual: &str) {
141+
fn fail_expect(expect: &Expect, expected: &str, actual: &str) {
99142
let mut rt = RT.lock().unwrap_or_else(|poisoned| poisoned.into_inner());
100-
let mut updated = "";
101143
if update_expect() {
102-
updated = " (updated)";
144+
println!("\x1b[1m\x1b[92mupdating\x1b[0m: {}", expect.position);
103145
rt.per_file
104-
.entry(expect.file)
146+
.entry(expect.position.file)
105147
.or_insert_with(|| FileRuntime::new(expect))
106148
.update(expect, actual);
149+
return;
107150
}
108-
let print_help = !rt.help_printed && !update_expect();
109-
rt.help_printed = true;
151+
rt.panic(expect.position.to_string(), expected, actual);
152+
}
153+
154+
fn fail_file(expect: &ExpectFile, expected: &str, actual: &str) {
155+
let mut rt = RT.lock().unwrap_or_else(|poisoned| poisoned.into_inner());
156+
if update_expect() {
157+
println!("\x1b[1m\x1b[92mupdating\x1b[0m: {}", expect.path);
158+
expect.write(actual);
159+
return;
160+
}
161+
rt.panic(expect.path.to_string(), expected, actual);
162+
}
110163

164+
fn panic(&mut self, position: String, expected: &str, actual: &str) {
165+
let print_help = !mem::replace(&mut self.help_printed, true);
111166
let help = if print_help { HELP } else { "" };
112167

113168
let diff = Changeset::new(actual, expected, "\n");
114169

115170
println!(
116171
"\n
117-
\x1b[1m\x1b[91merror\x1b[97m: expect test failed\x1b[0m{}
118-
\x1b[1m\x1b[34m-->\x1b[0m {}:{}:{}
172+
\x1b[1m\x1b[91merror\x1b[97m: expect test failed\x1b[0m
173+
\x1b[1m\x1b[34m-->\x1b[0m {}
119174
{}
120175
\x1b[1mExpect\x1b[0m:
121176
----
@@ -132,7 +187,7 @@ impl Runtime {
132187
{}
133188
----
134189
",
135-
updated, expect.file, expect.line, expect.column, help, expected, actual, diff
190+
position, help, expected, actual, diff
136191
);
137192
// Use resume_unwind instead of panic!() to prevent a backtrace, which is unnecessary noise.
138193
panic::resume_unwind(Box::new(()));
@@ -147,7 +202,7 @@ struct FileRuntime {
147202

148203
impl FileRuntime {
149204
fn new(expect: &Expect) -> FileRuntime {
150-
let path = workspace_root().join(expect.file);
205+
let path = workspace_root().join(expect.position.file);
151206
let original_text = fs::read_to_string(&path).unwrap();
152207
let patchwork = Patchwork::new(original_text.clone());
153208
FileRuntime { path, original_text, patchwork }

crates/ra_ide/src/syntax_highlighting/tests.rs

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::fs;
22

3-
use test_utils::{assert_eq_text, project_dir, read_text};
3+
use expect::{expect_file, ExpectFile};
4+
use test_utils::project_dir;
45

56
use crate::{mock_analysis::single_file, FileRange, TextRange};
67

@@ -91,7 +92,7 @@ impl<T> Option<T> {
9192
}
9293
"#
9394
.trim(),
94-
"crates/ra_ide/src/snapshots/highlighting.html",
95+
expect_file!["crates/ra_ide/test_data/highlighting.html"],
9596
false,
9697
);
9798
}
@@ -114,7 +115,7 @@ fn bar() {
114115
}
115116
"#
116117
.trim(),
117-
"crates/ra_ide/src/snapshots/rainbow_highlighting.html",
118+
expect_file!["crates/ra_ide/test_data/rainbow_highlighting.html"],
118119
true,
119120
);
120121
}
@@ -167,7 +168,7 @@ fn main() {
167168
);
168169
}"##
169170
.trim(),
170-
"crates/ra_ide/src/snapshots/highlight_injection.html",
171+
expect_file!["crates/ra_ide/test_data/highlight_injection.html"],
171172
false,
172173
);
173174
}
@@ -250,7 +251,7 @@ fn main() {
250251
println!("{ничоси}", ничоси = 92);
251252
}"#
252253
.trim(),
253-
"crates/ra_ide/src/snapshots/highlight_strings.html",
254+
expect_file!["crates/ra_ide/test_data/highlight_strings.html"],
254255
false,
255256
);
256257
}
@@ -278,7 +279,7 @@ fn main() {
278279
}
279280
"#
280281
.trim(),
281-
"crates/ra_ide/src/snapshots/highlight_unsafe.html",
282+
expect_file!["crates/ra_ide/test_data/highlight_unsafe.html"],
282283
false,
283284
);
284285
}
@@ -354,19 +355,16 @@ macro_rules! noop {
354355
}
355356
"#
356357
.trim(),
357-
"crates/ra_ide/src/snapshots/highlight_doctest.html",
358+
expect_file!["crates/ra_ide/test_data/highlight_doctest.html"],
358359
false,
359360
);
360361
}
361362

362363
/// Highlights the code given by the `ra_fixture` argument, renders the
363364
/// result as HTML, and compares it with the HTML file given as `snapshot`.
364365
/// Note that the `snapshot` file is overwritten by the rendered HTML.
365-
fn check_highlighting(ra_fixture: &str, snapshot: &str, rainbow: bool) {
366+
fn check_highlighting(ra_fixture: &str, expect: ExpectFile, rainbow: bool) {
366367
let (analysis, file_id) = single_file(ra_fixture);
367-
let dst_file = project_dir().join(snapshot);
368368
let actual_html = &analysis.highlight_as_html(file_id, rainbow).unwrap();
369-
let expected_html = &read_text(&dst_file);
370-
fs::write(dst_file, &actual_html).unwrap();
371-
assert_eq_text!(expected_html, actual_html);
369+
expect.assert_eq(actual_html)
372370
}

crates/rust-analyzer/src/handlers.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,7 @@ pub(crate) fn handle_runnables(
415415
let source_file = snap.analysis.parse(file_id)?;
416416
algo::find_node_at_offset::<ast::MacroCall>(source_file.syntax(), offset)
417417
.and_then(|it| it.path()?.segment()?.name_ref())
418-
.map_or(false, |it| it.text() == "expect")
418+
.map_or(false, |it| it.text() == "expect" || it.text() == "expect_file")
419419
}
420420
None => false,
421421
};

0 commit comments

Comments
 (0)