mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-08-30 07:07:32 +00:00
More principled indentation trimming in fixtures
This commit is contained in:
parent
f2f69e75c8
commit
aa69757a01
16 changed files with 540 additions and 557 deletions
|
@ -2,7 +2,7 @@
|
|||
//! rust-analyzer database from a single string.
|
||||
|
||||
use rustc_hash::FxHashMap;
|
||||
use stdx::split_delim;
|
||||
use stdx::{lines_with_ends, split_delim, trim_indent};
|
||||
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
pub struct Fixture {
|
||||
|
@ -26,42 +26,30 @@ impl Fixture {
|
|||
/// // - other meta
|
||||
/// ```
|
||||
pub fn parse(ra_fixture: &str) -> Vec<Fixture> {
|
||||
let fixture = indent_first_line(ra_fixture);
|
||||
let margin = fixture_margin(&fixture);
|
||||
|
||||
let mut lines = fixture
|
||||
.split('\n') // don't use `.lines` to not drop `\r\n`
|
||||
.enumerate()
|
||||
.filter_map(|(ix, line)| {
|
||||
if line.len() >= margin {
|
||||
assert!(line[..margin].trim().is_empty());
|
||||
let line_content = &line[margin..];
|
||||
if !line_content.starts_with("//-") {
|
||||
assert!(
|
||||
!line_content.contains("//-"),
|
||||
r#"Metadata line {} has invalid indentation. All metadata lines need to have the same indentation.
|
||||
The offending line: {:?}"#,
|
||||
ix,
|
||||
line
|
||||
);
|
||||
}
|
||||
Some(line_content)
|
||||
} else {
|
||||
assert!(line.trim().is_empty());
|
||||
None
|
||||
}
|
||||
});
|
||||
let fixture = trim_indent(ra_fixture);
|
||||
|
||||
let mut res: Vec<Fixture> = Vec::new();
|
||||
for line in lines.by_ref() {
|
||||
|
||||
for (ix, line) in lines_with_ends(&fixture).enumerate() {
|
||||
if line.contains("//-") {
|
||||
assert!(
|
||||
line.starts_with("//-"),
|
||||
"Metadata line {} has invalid indentation. \
|
||||
All metadata lines need to have the same indentation.\n\
|
||||
The offending line: {:?}",
|
||||
ix,
|
||||
line
|
||||
);
|
||||
}
|
||||
|
||||
if line.starts_with("//-") {
|
||||
let meta = Fixture::parse_meta_line(line);
|
||||
res.push(meta)
|
||||
} else if let Some(entry) = res.last_mut() {
|
||||
entry.text.push_str(line);
|
||||
entry.text.push('\n');
|
||||
}
|
||||
}
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
|
@ -118,51 +106,6 @@ The offending line: {:?}"#,
|
|||
}
|
||||
}
|
||||
|
||||
/// Adjusts the indentation of the first line to the minimum indentation of the rest of the lines.
|
||||
/// This allows fixtures to start off in a different indentation, e.g. to align the first line with
|
||||
/// the other lines visually:
|
||||
/// ```
|
||||
/// let fixture = "//- /lib.rs
|
||||
/// mod foo;
|
||||
/// //- /foo.rs
|
||||
/// fn bar() {}
|
||||
/// ";
|
||||
/// assert_eq!(fixture_margin(fixture),
|
||||
/// " //- /lib.rs
|
||||
/// mod foo;
|
||||
/// //- /foo.rs
|
||||
/// fn bar() {}
|
||||
/// ")
|
||||
/// ```
|
||||
fn indent_first_line(fixture: &str) -> String {
|
||||
if fixture.is_empty() {
|
||||
return String::new();
|
||||
}
|
||||
let mut lines = fixture.lines();
|
||||
let first_line = lines.next().unwrap();
|
||||
if first_line.contains("//-") {
|
||||
let rest = lines.collect::<Vec<_>>().join("\n");
|
||||
let fixed_margin = fixture_margin(&rest);
|
||||
let fixed_indent = fixed_margin - indent_len(first_line);
|
||||
format!("\n{}{}\n{}", " ".repeat(fixed_indent), first_line, rest)
|
||||
} else {
|
||||
fixture.to_owned()
|
||||
}
|
||||
}
|
||||
|
||||
fn fixture_margin(fixture: &str) -> usize {
|
||||
fixture
|
||||
.lines()
|
||||
.filter(|it| it.trim_start().starts_with("//-"))
|
||||
.map(indent_len)
|
||||
.next()
|
||||
.expect("empty fixture")
|
||||
}
|
||||
|
||||
fn indent_len(s: &str) -> usize {
|
||||
s.len() - s.trim_start().len()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn parse_fixture_checks_further_indented_metadata() {
|
||||
|
@ -178,25 +121,6 @@ fn parse_fixture_checks_further_indented_metadata() {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_fixture_can_handle_dedented_first_line() {
|
||||
let fixture = "//- /lib.rs
|
||||
mod foo;
|
||||
//- /foo.rs
|
||||
struct Bar;
|
||||
";
|
||||
assert_eq!(
|
||||
Fixture::parse(fixture),
|
||||
Fixture::parse(
|
||||
"//- /lib.rs
|
||||
mod foo;
|
||||
//- /foo.rs
|
||||
struct Bar;
|
||||
"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_fixture_gets_full_meta() {
|
||||
let parsed = Fixture::parse(
|
||||
|
@ -208,7 +132,7 @@ fn parse_fixture_gets_full_meta() {
|
|||
assert_eq!(1, parsed.len());
|
||||
|
||||
let meta = &parsed[0];
|
||||
assert_eq!("mod m;\n\n", meta.text);
|
||||
assert_eq!("mod m;\n", meta.text);
|
||||
|
||||
assert_eq!("foo", meta.crate_name.as_ref().unwrap());
|
||||
assert_eq!("/lib.rs", meta.path);
|
||||
|
|
|
@ -43,7 +43,7 @@ macro_rules! assert_eq_text {
|
|||
if left.trim() == right.trim() {
|
||||
eprintln!("Left:\n{:?}\n\nRight:\n{:?}\n\nWhitespace difference\n", left, right);
|
||||
} else {
|
||||
let changeset = $crate::__Changeset::new(right, left, "\n");
|
||||
let changeset = $crate::__Changeset::new(left, right, "\n");
|
||||
eprintln!("Left:\n{}\n\nRight:\n{}\n\nDiff:\n{}\n", left, right, changeset);
|
||||
}
|
||||
eprintln!($($tt)*);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue