From aa69757a01c26cfad12498053c55cbc3d66a4bdb Mon Sep 17 00:00:00 2001
From: Aleksey Kladov <aleksey.kladov@gmail.com>
Date: Tue, 23 Jun 2020 22:27:24 +0200
Subject: More principled indentation trimming in fixtures

---
 crates/test_utils/src/fixture.rs | 110 ++++++---------------------------------
 crates/test_utils/src/lib.rs     |   2 +-
 2 files changed, 18 insertions(+), 94 deletions(-)

(limited to 'crates/test_utils/src')

diff --git a/crates/test_utils/src/fixture.rs b/crates/test_utils/src/fixture.rs
index ba928bb9c..8747fa4a5 100644
--- a/crates/test_utils/src/fixture.rs
+++ b/crates/test_utils/src/fixture.rs
@@ -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);
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 {
             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)*);
-- 
cgit v1.2.3