From 86fa80e5b3860ee2446dcf29355c314d6dc4365a Mon Sep 17 00:00:00 2001 From: Timo Freiberg Date: Tue, 5 May 2020 23:36:51 +0200 Subject: Allow fixture strings with unindented first line This allows fixtures like "//- /lib.rs ... //- /foo.rs ... " --- crates/test_utils/src/lib.rs | 104 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 95 insertions(+), 9 deletions(-) (limited to 'crates/test_utils/src/lib.rs') diff --git a/crates/test_utils/src/lib.rs b/crates/test_utils/src/lib.rs index b1365444a..b13e13af2 100644 --- a/crates/test_utils/src/lib.rs +++ b/crates/test_utils/src/lib.rs @@ -155,7 +155,7 @@ pub fn add_cursor(text: &str, offset: TextSize) -> String { res } -#[derive(Debug)] +#[derive(Debug, Eq, PartialEq)] pub struct FixtureEntry { pub meta: String, pub text: String, @@ -170,19 +170,26 @@ pub struct FixtureEntry { /// // - other meta /// ``` pub fn parse_fixture(fixture: &str) -> Vec { - let margin = fixture - .lines() - .filter(|it| it.trim_start().starts_with("//-")) - .map(|it| it.len() - it.trim_start().len()) - .next() - .expect("empty fixture"); + let fixture = indent_first_line(fixture); + let margin = fixture_margin(&fixture); let mut lines = fixture .split('\n') // don't use `.lines` to not drop `\r\n` - .filter_map(|line| { + .enumerate() + .filter_map(|(ix, line)| { if line.len() >= margin { assert!(line[..margin].trim().is_empty()); - Some(&line[margin..]) + 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 @@ -202,6 +209,85 @@ pub fn parse_fixture(fixture: &str) -> Vec { res } +/// 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::>().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() { + parse_fixture( + r" + //- /lib.rs + mod bar; + + fn foo() {} + //- /bar.rs + pub fn baz() {} + ", + ); +} + +#[test] +fn parse_fixture_can_handle_unindented_first_line() { + let fixture = "//- /lib.rs + mod foo; + //- /foo.rs + struct Bar; +"; + assert_eq!( + parse_fixture(fixture), + parse_fixture( + "//- /lib.rs +mod foo; +//- /foo.rs +struct Bar; +" + ) + ) +} + /// Same as `parse_fixture`, except it allow empty fixture pub fn parse_single_fixture(fixture: &str) -> Option { if !fixture.lines().any(|it| it.trim_start().starts_with("//-")) { -- cgit v1.2.3 From 5c04d8544c647e1f9bbf3c5a2f1e86409d4080f5 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 9 May 2020 14:48:43 +0200 Subject: unindent -> dedent --- crates/test_utils/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'crates/test_utils/src/lib.rs') diff --git a/crates/test_utils/src/lib.rs b/crates/test_utils/src/lib.rs index b13e13af2..b1e3c328f 100644 --- a/crates/test_utils/src/lib.rs +++ b/crates/test_utils/src/lib.rs @@ -270,7 +270,7 @@ fn parse_fixture_checks_further_indented_metadata() { } #[test] -fn parse_fixture_can_handle_unindented_first_line() { +fn parse_fixture_can_handle_dedented_first_line() { let fixture = "//- /lib.rs mod foo; //- /foo.rs -- cgit v1.2.3 From d18d1c05949eaa890e7bb75710816a61b09a93dd Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 20 May 2020 00:19:59 +0200 Subject: Significantly more glorious marks --- crates/test_utils/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'crates/test_utils/src/lib.rs') diff --git a/crates/test_utils/src/lib.rs b/crates/test_utils/src/lib.rs index b1e3c328f..4e05d464f 100644 --- a/crates/test_utils/src/lib.rs +++ b/crates/test_utils/src/lib.rs @@ -8,6 +8,8 @@ #[macro_use] pub mod marks; +#[macro_use] +pub mod mark; use std::{ fs, -- cgit v1.2.3 From ecac5d7de2192873c24b7b06d4964d188d8abe6a Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 20 May 2020 12:59:20 +0200 Subject: Switch to new magic marks --- crates/test_utils/src/lib.rs | 2 -- 1 file changed, 2 deletions(-) (limited to 'crates/test_utils/src/lib.rs') diff --git a/crates/test_utils/src/lib.rs b/crates/test_utils/src/lib.rs index 4e05d464f..be2cfbaa2 100644 --- a/crates/test_utils/src/lib.rs +++ b/crates/test_utils/src/lib.rs @@ -6,8 +6,6 @@ //! * Extracting markup (mainly, `<|>` markers) out of fixture strings. //! * marks (see the eponymous module). -#[macro_use] -pub mod marks; #[macro_use] pub mod mark; -- cgit v1.2.3