From 28309e52e05c7de3209cbf564ce51c5a9d7d1948 Mon Sep 17 00:00:00 2001 From: Leynos Date: Thu, 17 Jul 2025 10:56:50 +0100 Subject: [PATCH 1/3] Replace vec patterns with lines_vec macro --- tests/integration.rs | 436 +++++++++++++++++-------------------------- 1 file changed, 169 insertions(+), 267 deletions(-) diff --git a/tests/integration.rs b/tests/integration.rs index 9bf50b22..e85e68ac 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -28,7 +28,7 @@ mod common; /// assert_eq!(table[0], "| A | B | |"); /// ``` fn broken_table() -> Vec { - let lines = lines_vec!("| A | B | |", "| 1 | 2 | | 3 | 4 |",); + let lines = lines_vec!["| A | B | |", "| 1 | 2 | | 3 | 4 |",]; lines } @@ -44,135 +44,135 @@ fn broken_table() -> Vec { /// let table = malformed_table(); /// assert_eq!( /// table, -/// vec![String::from("| A | |"), String::from("| 1 | 2 | 3 |")] +/// lines_vec![String::from("| A | |"), String::from("| 1 | 2 | 3 |")] /// ); /// ``` fn malformed_table() -> Vec { - let lines = lines_vec!("| A | |", "| 1 | 2 | 3 |"); + let lines = lines_vec!["| A | |", "| 1 | 2 | 3 |"]; lines } #[fixture] fn header_table() -> Vec { - lines_vec!("| A | B | |", "| --- | --- |", "| 1 | 2 | | 3 | 4 |",) + lines_vec!["| A | B | |", "| --- | --- |", "| 1 | 2 | | 3 | 4 |",] } #[fixture] fn escaped_pipe_table() -> Vec { - lines_vec!("| X | Y | |", "| a \\| b | 1 | | 2 | 3 |",) + lines_vec!["| X | Y | |", "| a \\| b | 1 | | 2 | 3 |",] } #[fixture] fn indented_table() -> Vec { - let lines = lines_vec!(" | I | J | |", " | 1 | 2 | | 3 | 4 |",); + let lines = lines_vec![" | I | J | |", " | 1 | 2 | | 3 | 4 |",]; lines } #[fixture] fn html_table() -> Vec { - lines_vec!( + lines_vec![ "", "", "", "
AB
12
", - ) + ] } #[fixture] fn html_table_with_attrs() -> Vec { - lines_vec!( + lines_vec![ "", "", "", "
AB
12
", - ) + ] } #[fixture] fn html_table_with_colspan() -> Vec { - lines_vec!( + lines_vec![ "", "", "", "
A
12
", - ) + ] } #[fixture] fn html_table_no_header() -> Vec { - lines_vec!( + lines_vec![ "", "", "", "
AB
12
", - ) + ] } #[fixture] fn html_table_empty_row() -> Vec { - lines_vec!( + lines_vec![ "", "", "", "
12
", - ) + ] } #[fixture] fn html_table_whitespace_header() -> Vec { - lines_vec!( + lines_vec![ "", "", "", "
12
", - ) + ] } #[fixture] fn html_table_inconsistent_first_row() -> Vec { - lines_vec!( + lines_vec![ "", "", "", "
A
12
", - ) + ] } #[fixture] fn html_table_empty() -> Vec { - let lines = lines_vec!("
"); + let lines = lines_vec!["
"]; lines } #[fixture] fn html_table_unclosed() -> Vec { - let lines = lines_vec!("", ""); + let lines = lines_vec!["
1
", ""]; lines } #[fixture] fn html_table_uppercase() -> Vec { - lines_vec!( + lines_vec![ "
1
", "", "", "
AB
12
", - ) + ] } #[fixture] fn html_table_mixed_case() -> Vec { - lines_vec!( + lines_vec![ "", "", "", "
AB
12
", - ) + ] } #[fixture] fn multiple_tables() -> Vec { - lines_vec!("| A | B |", "| 1 | 22 |", "", "| X | Y |", "| 3 | 4 |",) + lines_vec!["| A | B |", "| 1 | 22 |", "", "| X | Y |", "| 3 | 4 |",] } #[rstest] @@ -182,16 +182,16 @@ fn multiple_tables() -> Vec { /// # Examples /// /// ``` -/// let broken = vec![ +/// let broken = lines_vec![ /// String::from("| A | B |"), /// String::from("| 1 | 2 |"), /// String::from("| 3 | 4 |"), /// ]; -/// let expected = vec!["| A | B |", "| 1 | 2 |", "| 3 | 4 |"]; +/// let expected = lines_vec!["| A | B |", "| 1 | 2 |", "| 3 | 4 |"]; /// assert_eq!(reflow_table(&broken), expected); /// ``` fn test_reflow_basic(broken_table: Vec) { - let expected = vec!["| A | B |", "| 1 | 2 |", "| 3 | 4 |"]; + let expected = lines_vec!["| A | B |", "| 1 | 2 |", "| 3 | 4 |"]; assert_eq!(reflow_table(&broken_table), expected); } @@ -207,7 +207,7 @@ fn test_reflow_malformed_returns_original(malformed_table: Vec) { #[rstest] fn test_reflow_preserves_header(header_table: Vec) { - let expected = vec!["| A | B |", "| --- | --- |", "| 1 | 2 |", "| 3 | 4 |"]; + let expected = lines_vec!["| A | B |", "| --- | --- |", "| 1 | 2 |", "| 3 | 4 |"]; assert_eq!(reflow_table(&header_table), expected); } @@ -217,49 +217,49 @@ fn test_reflow_handles_escaped_pipes(escaped_pipe_table: Vec) { // pipe sequence (`a \| b`). After reflow the escaped pipe becomes a literal // `|` inside the first data cell, so the table has three columns and the // header row is padded to match. - let expected = vec!["| X | Y |", "| a | b | 1 |", "| 2 | 3 |"]; + let expected = lines_vec!["| X | Y |", "| a | b | 1 |", "| 2 | 3 |"]; assert_eq!(reflow_table(&escaped_pipe_table), expected); } #[rstest] fn test_reflow_preserves_indentation(indented_table: Vec) { - let expected = vec![" | I | J |", " | 1 | 2 |", " | 3 | 4 |"]; + let expected = lines_vec![" | I | J |", " | 1 | 2 |", " | 3 | 4 |"]; assert_eq!(reflow_table(&indented_table), expected); } #[rstest] fn test_process_stream_html_table(html_table: Vec) { - let expected = vec!["| A | B |", "| --- | --- |", "| 1 | 2 |"]; + let expected = lines_vec!["| A | B |", "| --- | --- |", "| 1 | 2 |"]; assert_eq!(process_stream(&html_table), expected); } #[rstest] fn test_process_stream_html_table_with_attrs(html_table_with_attrs: Vec) { - let expected = vec!["| A | B |", "| --- | --- |", "| 1 | 2 |"]; + let expected = lines_vec!["| A | B |", "| --- | --- |", "| 1 | 2 |"]; assert_eq!(process_stream(&html_table_with_attrs), expected); } #[rstest] fn test_process_stream_html_table_uppercase(html_table_uppercase: Vec) { - let expected = vec!["| A | B |", "| --- | --- |", "| 1 | 2 |"]; + let expected = lines_vec!["| A | B |", "| --- | --- |", "| 1 | 2 |"]; assert_eq!(process_stream(&html_table_uppercase), expected); } #[rstest] fn test_process_stream_html_table_mixed_case(html_table_mixed_case: Vec) { - let expected = vec!["| A | B |", "| --- | --- |", "| 1 | 2 |"]; + let expected = lines_vec!["| A | B |", "| --- | --- |", "| 1 | 2 |"]; assert_eq!(process_stream(&html_table_mixed_case), expected); } #[rstest] fn test_process_stream_multiple_tables(multiple_tables: Vec) { - let expected = lines_vec!( + let expected = lines_vec![ "| A | B |", "| 1 | 22 |", String::new(), "| X | Y |", "| 3 | 4 |", - ); + ]; assert_eq!(process_stream(&multiple_tables), expected); } @@ -269,11 +269,11 @@ fn test_process_stream_multiple_tables(multiple_tables: Vec) { /// processing logic, ensuring their contents are not altered. #[rstest] fn test_process_stream_ignores_code_fences() { - let lines = lines_vec!("```rust", "| not | a | table |", "```"); + let lines = lines_vec!["```rust", "| not | a | table |", "```"]; assert_eq!(process_stream(&lines), lines); // Test with tilde-based code fences - let tilde_lines = lines_vec!("~~~", "| not | a | table |", "~~~"); + let tilde_lines = lines_vec!["~~~", "| not | a | table |", "~~~"]; assert_eq!(process_stream(&tilde_lines), tilde_lines); } @@ -307,11 +307,7 @@ fn test_cli_in_place_requires_file() { /// # Examples /// /// ``` -/// let broken_table = vec![ -/// "| A | B |".to_string(), -/// "| 1 | 2 |".to_string(), -/// "| 3 | 4 |".to_string(), -/// ]; +/// let broken_table = lines_vec!["| A | B |", "| 1 | 2 |", "| 3 | 4 |",]; /// test_cli_process_file(broken_table); /// ``` fn test_cli_process_file(broken_table: Vec) { @@ -353,14 +349,14 @@ fn test_cli_wrap_option() { #[test] fn test_uniform_example_one() { - let input = vec![ - "| Logical type | PostgreSQL | SQLite notes |".to_string(), - "|--------------|-------------------------|---------------------------------------------------------------------------------|".to_string(), - "| strings | `TEXT` (or `VARCHAR`) | `TEXT` - SQLite ignores the length specifier anyway |".to_string(), - "| booleans | `BOOLEAN DEFAULT FALSE` | declare as `BOOLEAN`; Diesel serialises to 0 / 1 so this is fine |".to_string(), - "| integers | `INTEGER` / `BIGINT` | ditto |".to_string(), - "| decimals | `NUMERIC` | stored as FLOAT in SQLite; Diesel `Numeric` round-trips, but beware precision |".to_string(), - "| blobs / raw | `BYTEA` | `BLOB` |".to_string(), + let input = lines_vec![ + "| Logical type | PostgreSQL | SQLite notes |", + "|--------------|-------------------------|---------------------------------------------------------------------------------|", + "| strings | `TEXT` (or `VARCHAR`) | `TEXT` - SQLite ignores the length specifier anyway |", + "| booleans | `BOOLEAN DEFAULT FALSE` | declare as `BOOLEAN`; Diesel serialises to 0 / 1 so this is fine |", + "| integers | `INTEGER` / `BIGINT` | ditto |", + "| decimals | `NUMERIC` | stored as FLOAT in SQLite; Diesel `Numeric` round-trips, but beware precision |", + "| blobs / raw | `BYTEA` | `BLOB` |", ]; let output = reflow_table(&input); assert!(!output.is_empty()); @@ -379,12 +375,12 @@ fn test_uniform_example_one() { #[test] fn test_uniform_example_two() { - let input = vec![ - "| Option | How it works | When to choose it |".to_string(), - "|--------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------|".to_string(), - "| **B. Pure-Rust migrations** | Implement `diesel::migration::Migration` in a Rust file (`up.rs` / `down.rs`) and compile with both `features = [\"postgres\", \"sqlite\"]`. The query builder emits backend-specific SQL at runtime. | You prefer the type-checked DSL and can live with slightly slower compile times. |".to_string(), - "| **C. Lowest-common-denominator SQL** | Write one `up.sql`/`down.sql` that *already* works on both engines. This demands avoiding SERIAL/IDENTITY, JSONB, `TIMESTAMPTZ`, etc. | Simple schemas, embedded use-case only, you are happy to supply integer primary keys manually. |".to_string(), - "| **D. Two separate migration trees** | Maintain `migrations/sqlite` and `migrations/postgres` directories with identical version numbers. Use `embed_migrations!(\"migrations/\")` to compile the right set. | You ship a single binary with migrations baked in. |".to_string(), + let input = lines_vec![ + "| Option | How it works | When to choose it |", + "|--------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------|", + "| **B. Pure-Rust migrations** | Implement `diesel::migration::Migration` in a Rust file (`up.rs` / `down.rs`) and compile with both `features = [\"postgres\", \"sqlite\"]`. The query builder emits backend-specific SQL at runtime. | You prefer the type-checked DSL and can live with slightly slower compile times. |", + "| **C. Lowest-common-denominator SQL** | Write one `up.sql`/`down.sql` that *already* works on both engines. This demands avoiding SERIAL/IDENTITY, JSONB, `TIMESTAMPTZ`, etc. | Simple schemas, embedded use-case only, you are happy to supply integer primary keys manually. |", + "| **D. Two separate migration trees** | Maintain `migrations/sqlite` and `migrations/postgres` directories with identical version numbers. Use `embed_migrations!(\"migrations/\")` to compile the right set. | You ship a single binary with migrations baked in. |", ]; let output = reflow_table(&input); assert!(!output.is_empty()); @@ -403,27 +399,27 @@ fn test_uniform_example_two() { #[test] fn test_non_table_lines_unchanged() { - let input = vec![ - "# Title".to_string(), + let input = lines_vec![ + "# Title", String::new(), - "Para text.".to_string(), + "Para text.", String::new(), - "| a | b |".to_string(), - "| 1 | 22 |".to_string(), + "| a | b |", + "| 1 | 22 |", String::new(), - "* bullet".to_string(), + "* bullet", String::new(), ]; let output = process_stream(&input); - let expected = vec![ - "# Title".to_string(), + let expected = lines_vec![ + "# Title", String::new(), - "Para text.".to_string(), + "Para text.", String::new(), - "| a | b |".to_string(), - "| 1 | 22 |".to_string(), + "| a | b |", + "| 1 | 22 |", String::new(), - "* bullet".to_string(), + "* bullet", String::new(), ]; assert_eq!(output, expected); @@ -431,17 +427,13 @@ fn test_non_table_lines_unchanged() { #[test] fn test_convert_html_table_basic() { - let html_table = vec![ - "".to_string(), - "".to_string(), - "".to_string(), - "
AB
12
".to_string(), - ]; - let expected = vec![ - "| A | B |".to_string(), - "| --- | --- |".to_string(), - "| 1 | 2 |".to_string(), + let html_table = lines_vec![ + "", + "", + "", + "
AB
12
", ]; + let expected = lines_vec!["| A | B |", "| --- | --- |", "| 1 | 2 |",]; assert_eq!(convert_html_tables(&html_table), expected); } @@ -450,63 +442,63 @@ fn test_convert_html_table_basic() { #[case("~~~")] #[case("```rust")] fn test_convert_html_table_in_text_and_code(#[case] fence: &str) { - let lines = vec![ - "Intro".to_string(), - "".to_string(), - "".to_string(), - "".to_string(), - "
AB
12
".to_string(), - fence.to_string(), - "
x
".to_string(), - fence.to_string(), - "Outro".to_string(), + let lines = lines_vec![ + "Intro", + "", + "", + "", + "
AB
12
", + fence, + "
x
", + fence, + "Outro", ]; - let expected = vec![ - "Intro".to_string(), - "| A | B |".to_string(), - "| --- | --- |".to_string(), - "| 1 | 2 |".to_string(), - fence.to_string(), - "
x
".to_string(), - fence.to_string(), - "Outro".to_string(), + let expected = lines_vec![ + "Intro", + "| A | B |", + "| --- | --- |", + "| 1 | 2 |", + fence, + "
x
", + fence, + "Outro", ]; assert_eq!(convert_html_tables(&lines), expected); } #[test] fn test_convert_html_table_with_attrs_basic() { - let expected = vec!["| A | B |", "| --- | --- |", "| 1 | 2 |"]; + let expected = lines_vec!["| A | B |", "| --- | --- |", "| 1 | 2 |"]; assert_eq!(convert_html_tables(&html_table_with_attrs()), expected); } #[test] fn test_convert_html_table_uppercase() { - let expected = vec!["| A | B |", "| --- | --- |", "| 1 | 2 |"]; + let expected = lines_vec!["| A | B |", "| --- | --- |", "| 1 | 2 |"]; assert_eq!(convert_html_tables(&html_table_uppercase()), expected); } #[test] fn test_convert_html_table_with_colspan() { - let expected = vec!["| A |", "| --- |", "| 1 | 2 |"]; + let expected = lines_vec!["| A |", "| --- |", "| 1 | 2 |"]; assert_eq!(convert_html_tables(&html_table_with_colspan()), expected); } #[test] fn test_convert_html_table_no_header() { - let expected = vec!["| A | B |", "| --- | --- |", "| 1 | 2 |"]; + let expected = lines_vec!["| A | B |", "| --- | --- |", "| 1 | 2 |"]; assert_eq!(convert_html_tables(&html_table_no_header()), expected); } #[test] fn test_convert_html_table_empty_row() { - let expected = vec!["| 1 | 2 |", "| --- | --- |"]; + let expected = lines_vec!["| 1 | 2 |", "| --- | --- |"]; assert_eq!(convert_html_tables(&html_table_empty_row()), expected); } #[test] fn test_convert_html_table_whitespace_header() { - let expected = vec!["| --- | --- |", "| --- | --- |", "| 1 | 2 |"]; + let expected = lines_vec!["| --- | --- |", "| --- | --- |", "| 1 | 2 |"]; assert_eq!( convert_html_tables(&html_table_whitespace_header()), expected @@ -515,7 +507,7 @@ fn test_convert_html_table_whitespace_header() { #[test] fn test_convert_html_table_inconsistent_first_row() { - let expected = vec!["| A |", "| --- |", "| 1 | 2 |"]; + let expected = lines_vec!["| A |", "| --- |", "| 1 | 2 |"]; assert_eq!( convert_html_tables(&html_table_inconsistent_first_row()), expected @@ -647,10 +639,9 @@ fn test_process_stream_option_table() { /// Ensures that a single long paragraph is split into multiple lines, each not exceeding 80 /// characters. fn test_wrap_paragraph() { - let input = vec![ + let input = lines_vec![ "This is a very long paragraph that should be wrapped at eighty columns so it needs to \ - contain enough words to exceed that limit." - .to_string(), + contain enough words to exceed that limit.", ]; let output = process_stream(&input); assert!(output.len() > 1); @@ -659,9 +650,8 @@ fn test_wrap_paragraph() { #[test] fn test_wrap_list_item() { - let input = vec![ - r"- This bullet item is exceptionally long and must be wrapped to keep prefix formatting intact." - .to_string(), + let input = lines_vec![ + r"- This bullet item is exceptionally long and must be wrapped to keep prefix formatting intact.", ]; let output = process_stream(&input); common::assert_wrapped_list_item(&output, "- ", 2); @@ -673,7 +663,7 @@ fn test_wrap_list_item() { #[case("10. ", 3)] #[case("100. ", 3)] fn test_wrap_list_items_with_inline_code(#[case] prefix: &str, #[case] expected: usize) { - let input = vec![format!( + let input = lines_vec![format!( "{prefix}`script`: A multi-line script declared with the YAML `|` block style. The entire \ block is passed to an interpreter. If the first line begins with `#!`, Netsuke executes \ the script verbatim, respecting the shebang." @@ -684,11 +674,10 @@ fn test_wrap_list_items_with_inline_code(#[case] prefix: &str, #[case] expected: #[test] fn test_wrap_preserves_inline_code_spans() { - let input = vec![ + let input = lines_vec![ "- `script`: A multi-line script declared with the YAML `|` block style. The entire block \ is passed to an interpreter. If the first line begins with `#!`, Netsuke executes the \ - script verbatim, respecting the shebang." - .to_string(), + script verbatim, respecting the shebang.", ]; let output = process_stream(&input); common::assert_wrapped_list_item(&output, "- ", 3); @@ -696,10 +685,9 @@ fn test_wrap_preserves_inline_code_spans() { #[test] fn test_wrap_multi_backtick_code() { - let input = vec![ + let input = lines_vec![ "- ``cmd`` executes ```echo``` output with ``json`` format and prints results to the \ - console" - .to_string(), + console", ]; let output = process_stream(&input); common::assert_wrapped_list_item(&output, "- ", 2); @@ -707,25 +695,21 @@ fn test_wrap_multi_backtick_code() { #[test] fn test_wrap_multiple_inline_code_spans() { - let input = vec![ + let input = lines_vec![ "- Use `foo` and `bar` inside ``baz`` for testing with additional commentary to exceed \ - wrapping width" - .to_string(), + wrapping width", ]; let output = process_stream(&input); common::assert_wrapped_list_item(&output, "- ", 2); } #[test] fn test_wrap_long_inline_code_item() { - let input = vec![ - concat!( - "- `async def on_unhandled(self, ws: WebSocketLike, message: Union[str, bytes])`:", - " A fallback handler for messages that are not dispatched by the more specific", - " message handlers. This can be used for raw text/binary data or messages that", - " don't conform to the expected structured format." - ) - .to_string(), - ]; + let input = lines_vec![concat!( + "- `async def on_unhandled(self, ws: WebSocketLike, message: Union[str, bytes])`:", + " A fallback handler for messages that are not dispatched by the more specific", + " message handlers. This can be used for raw text/binary data or messages that", + " don't conform to the expected structured format." + ),]; let output = process_stream(&input); common::assert_wrapped_list_item(&output, "- ", 4); assert!( @@ -738,26 +722,20 @@ fn test_wrap_long_inline_code_item() { #[test] fn test_wrap_footnote_multiline() { - let input = vec![ - concat!( - "[^note]: This footnote is sufficiently long to require wrapping ", - "across multiple lines so we can verify indentation." - ) - .to_string(), - ]; + let input = lines_vec![concat!( + "[^note]: This footnote is sufficiently long to require wrapping ", + "across multiple lines so we can verify indentation." + ),]; let output = process_stream(&input); common::assert_wrapped_list_item(&output, "[^note]: ", 2); } #[test] fn test_wrap_footnote_with_inline_code() { - let input = vec![ - concat!( - " [^code_note]: A footnote containing inline `code` that should wrap ", - "across multiple lines without breaking the span." - ) - .to_string(), - ]; + let input = lines_vec![concat!( + " [^code_note]: A footnote containing inline `code` that should wrap ", + "across multiple lines without breaking the span." + ),]; let output = process_stream(&input); common::assert_wrapped_list_item(&output, " [^code_note]: ", 2); } @@ -768,7 +746,7 @@ fn test_wrap_footnote_with_inline_code() { /// unchanged when passed to `process_stream`. #[test] fn test_wrap_footnote_collection() { - let input = vec![ + let input = lines_vec![ "[^1]: ", "[^2]: ", "[^3]: ", @@ -777,10 +755,7 @@ fn test_wrap_footnote_collection() { "[^6]: ", "[^7]: ", "[^8]: ", - ] - .into_iter() - .map(str::to_string) - .collect::>(); + ]; let output = process_stream(&input); assert_eq!(output, input); @@ -791,38 +766,33 @@ fn test_wrap_footnote_collection() { /// /// Ensures that a single-line bullet list item remains unchanged after processing. fn test_wrap_short_list_item() { - let input = vec!["- short item".to_string()]; + let input = lines_vec!["- short item"]; let output = process_stream(&input); assert_eq!(output, input); } #[test] fn test_wrap_blockquote() { - let input = vec![ + let input = lines_vec![ "> **Deprecated**: A :class:`WebSocketRouter` and its `add_route` API should be used to \ - instantiate resources." - .to_string(), + instantiate resources.", ]; let output = process_stream(&input); assert_eq!( output, - vec![ - "> **Deprecated**: A :class:`WebSocketRouter` and its `add_route` API should be" - .to_string(), - "> used to instantiate resources.".to_string(), + lines_vec![ + "> **Deprecated**: A :class:`WebSocketRouter` and its `add_route` API should be", + "> used to instantiate resources.", ] ); } #[test] fn test_wrap_blockquote_nested() { - let input = vec![ - concat!( - "> > This nested quote contains enough text to require wrapping so that we ", - "can verify multi-level handling." - ) - .to_string(), - ]; + let input = lines_vec![concat!( + "> > This nested quote contains enough text to require wrapping so that we ", + "can verify multi-level handling." + ),]; let output = process_stream(&input); common::assert_wrapped_blockquote(&output, "> > ", 2); let joined = output @@ -835,20 +805,18 @@ fn test_wrap_blockquote_nested() { #[test] fn test_wrap_blockquote_with_blank_lines() { - let input = vec![ + let input = lines_vec![ concat!( "> The first paragraph in this quote is deliberately long enough to wrap ", "across multiple lines so" - ) - .to_string(), - "> demonstrate the behaviour.".to_string(), - ">".to_string(), + ), + "> demonstrate the behaviour.", + ">", concat!( "> The second paragraph is also extended to trigger wrapping in order to ", "ensure blank lines" - ) - .to_string(), - "> are preserved correctly.".to_string(), + ), + "> are preserved correctly.", ]; let output = process_stream(&input); assert_eq!(output[3], ">"); @@ -858,10 +826,9 @@ fn test_wrap_blockquote_with_blank_lines() { #[test] fn test_wrap_blockquote_extra_whitespace() { - let input = vec![ + let input = lines_vec![ "> Extra spacing should not prevent correct wrapping of this quoted text that exceeds \ - the line width." - .to_string(), + the line width.", ]; let output = process_stream(&input); common::assert_wrapped_blockquote(&output, "> ", 2); @@ -875,7 +842,7 @@ fn test_wrap_blockquote_extra_whitespace() { #[test] fn test_wrap_blockquote_short() { - let input = vec!["> short".to_string()]; + let input = lines_vec!["> short"]; let output = process_stream(&input); assert_eq!(output, input); } @@ -886,10 +853,7 @@ fn test_wrap_blockquote_short() { /// Ensures that the `process_stream` function does not remove or alter lines ending with Markdown /// hard line breaks. fn test_preserve_hard_line_breaks() { - let input = vec![ - "Line one with break. ".to_string(), - "Line two follows.".to_string(), - ]; + let input = lines_vec!["Line one with break. ", "Line two follows.",]; let output = process_stream(&input); assert_eq!(output.len(), 2); assert_eq!(output[0], "Line one with break."); @@ -916,34 +880,15 @@ fn test_regression_complex_table() { #[test] fn test_renumber_basic() { - let input = vec![ - "1. first".to_string(), - "2. second".to_string(), - "7. third".to_string(), - ]; - let expected = vec!["1. first", "2. second", "3. third"] - .into_iter() - .map(str::to_string) - .collect::>(); + let input = lines_vec!["1. first", "2. second", "7. third",]; + let expected = lines_vec!["1. first", "2. second", "3. third"]; assert_eq!(renumber_lists(&input), expected); } #[test] fn test_renumber_with_fence() { - let input = vec![ - "1. item".to_string(), - "```".to_string(), - "code".to_string(), - "```".to_string(), - "9. next".to_string(), - ]; - let expected = vec![ - "1. item".to_string(), - "```".to_string(), - "code".to_string(), - "```".to_string(), - "2. next".to_string(), - ]; + let input = lines_vec!["1. item", "```", "code", "```", "9. next",]; + let expected = lines_vec!["1. item", "```", "code", "```", "2. next",]; assert_eq!(renumber_lists(&input), expected); } @@ -962,70 +907,46 @@ fn test_cli_renumber_option() { #[test] fn test_renumber_nested_lists() { - let input = vec![ + let input = lines_vec![ "1. first", " 1. sub first", " 3. sub second", "2. second", - ] - .into_iter() - .map(str::to_string) - .collect::>(); + ]; - let expected = vec![ + let expected = lines_vec![ "1. first", " 1. sub first", " 2. sub second", "2. second", - ] - .into_iter() - .map(str::to_string) - .collect::>(); + ]; assert_eq!(renumber_lists(&input), expected); } #[test] fn test_renumber_tabs_in_indent() { - let input = vec!["1. first", "\t1. sub first", "\t5. sub second", "2. second"] - .into_iter() - .map(str::to_string) - .collect::>(); + let input = lines_vec!["1. first", "\t1. sub first", "\t5. sub second", "2. second"]; - let expected = vec!["1. first", "\t1. sub first", "\t2. sub second", "2. second"] - .into_iter() - .map(str::to_string) - .collect::>(); + let expected = lines_vec!["1. first", "\t1. sub first", "\t2. sub second", "2. second"]; assert_eq!(renumber_lists(&input), expected); } #[test] fn test_renumber_mult_paragraph_items() { - let input = vec!["1. first", "", " still first paragraph", "", "2. second"] - .into_iter() - .map(str::to_string) - .collect::>(); + let input = lines_vec!["1. first", "", " still first paragraph", "", "2. second"]; - let expected = vec!["1. first", "", " still first paragraph", "", "2. second"] - .into_iter() - .map(str::to_string) - .collect::>(); + let expected = lines_vec!["1. first", "", " still first paragraph", "", "2. second"]; assert_eq!(renumber_lists(&input), expected); } #[test] fn test_renumber_table_in_list() { - let input = vec!["1. first", " | A | B |", " | 1 | 2 |", "5. second"] - .into_iter() - .map(str::to_string) - .collect::>(); + let input = lines_vec!["1. first", " | A | B |", " | 1 | 2 |", "5. second"]; - let expected = vec!["1. first", " | A | B |", " | 1 | 2 |", "2. second"] - .into_iter() - .map(str::to_string) - .collect::>(); + let expected = lines_vec!["1. first", " | A | B |", " | 1 | 2 |", "2. second"]; assert_eq!(renumber_lists(&input), expected); } @@ -1045,53 +966,34 @@ fn test_renumber_restart_after_paragraph() { #[test] fn test_format_breaks_basic() { - let input = vec!["foo", "***", "bar"] - .into_iter() - .map(str::to_string) - .collect::>(); - let expected = vec![ - "foo".to_string(), - "_".repeat(THEMATIC_BREAK_LEN), - "bar".to_string(), - ]; + let input = lines_vec!["foo", "***", "bar"]; + let expected = lines_vec!["foo", "_".repeat(THEMATIC_BREAK_LEN), "bar",]; assert_eq!(format_breaks(&input), expected); } #[test] fn test_format_breaks_ignores_code() { - let input = vec!["```", "---", "```"] - .into_iter() - .map(str::to_string) - .collect::>(); + let input = lines_vec!["```", "---", "```"]; assert_eq!(format_breaks(&input), input); } #[test] fn test_format_breaks_mixed_chars() { - let input = vec!["-*-*-"] - .into_iter() - .map(str::to_string) - .collect::>(); + let input = lines_vec!["-*-*-"]; assert_eq!(format_breaks(&input), input); } #[test] fn test_format_breaks_with_spaces_and_indent() { - let input = vec![" - - - "] - .into_iter() - .map(str::to_string) - .collect::>(); - let expected = vec!["_".repeat(THEMATIC_BREAK_LEN)]; + let input = lines_vec![" - - - "]; + let expected = lines_vec!["_".repeat(THEMATIC_BREAK_LEN)]; assert_eq!(format_breaks(&input), expected); } #[test] fn test_format_breaks_with_tabs_and_underscores() { - let input = vec!["\t_\t_\t_\t"] - .into_iter() - .map(str::to_string) - .collect::>(); - let expected = vec!["_".repeat(THEMATIC_BREAK_LEN)]; + let input = lines_vec!["\t_\t_\t_\t"]; + let expected = lines_vec!["_".repeat(THEMATIC_BREAK_LEN)]; assert_eq!(format_breaks(&input), expected); } From 2987d62331df0f15c826ca1ae6e108cfb20863bf Mon Sep 17 00:00:00 2001 From: Leynos Date: Thu, 17 Jul 2025 11:27:00 +0100 Subject: [PATCH 2/3] Clean test docs and normalise lines_vec --- tests/integration.rs | 79 +++++++++----------------------------------- 1 file changed, 15 insertions(+), 64 deletions(-) diff --git a/tests/integration.rs b/tests/integration.rs index e85e68ac..503686b3 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -20,15 +20,8 @@ mod common; /// /// The returned vector contains lines representing a table with inconsistent columns, useful for /// validating table reflow logic. -/// -/// # Examples -/// -/// ``` -/// let table = broken_table(); -/// assert_eq!(table[0], "| A | B | |"); -/// ``` fn broken_table() -> Vec { - let lines = lines_vec!["| A | B | |", "| 1 | 2 | | 3 | 4 |",]; + let lines = lines_vec!["| A | B | |", "| 1 | 2 | | 3 | 4 |"]; lines } @@ -37,16 +30,6 @@ fn broken_table() -> Vec { /// /// The returned table has rows with differing numbers of columns, making it invalid for standard /// Markdown table parsing. -/// -/// # Examples -/// -/// ``` -/// let table = malformed_table(); -/// assert_eq!( -/// table, -/// lines_vec![String::from("| A | |"), String::from("| 1 | 2 | 3 |")] -/// ); -/// ``` fn malformed_table() -> Vec { let lines = lines_vec!["| A | |", "| 1 | 2 | 3 |"]; lines @@ -54,17 +37,17 @@ fn malformed_table() -> Vec { #[fixture] fn header_table() -> Vec { - lines_vec!["| A | B | |", "| --- | --- |", "| 1 | 2 | | 3 | 4 |",] + lines_vec!["| A | B | |", "| --- | --- |", "| 1 | 2 | | 3 | 4 |"] } #[fixture] fn escaped_pipe_table() -> Vec { - lines_vec!["| X | Y | |", "| a \\| b | 1 | | 2 | 3 |",] + lines_vec!["| X | Y | |", "| a \\| b | 1 | | 2 | 3 |"] } #[fixture] fn indented_table() -> Vec { - let lines = lines_vec![" | I | J | |", " | 1 | 2 | | 3 | 4 |",]; + let lines = lines_vec![" | I | J | |", " | 1 | 2 | | 3 | 4 |"]; lines } @@ -172,24 +155,12 @@ fn html_table_mixed_case() -> Vec { #[fixture] fn multiple_tables() -> Vec { - lines_vec!["| A | B |", "| 1 | 22 |", "", "| X | Y |", "| 3 | 4 |",] + lines_vec!["| A | B |", "| 1 | 22 |", "", "| X | Y |", "| 3 | 4 |"] } #[rstest] /// Tests that `reflow_table` correctly restructures a broken Markdown table into a well-formed /// table. -/// -/// # Examples -/// -/// ``` -/// let broken = lines_vec![ -/// String::from("| A | B |"), -/// String::from("| 1 | 2 |"), -/// String::from("| 3 | 4 |"), -/// ]; -/// let expected = lines_vec!["| A | B |", "| 1 | 2 |", "| 3 | 4 |"]; -/// assert_eq!(reflow_table(&broken), expected); -/// ``` fn test_reflow_basic(broken_table: Vec) { let expected = lines_vec!["| A | B |", "| 1 | 2 |", "| 3 | 4 |"]; assert_eq!(reflow_table(&broken_table), expected); @@ -282,13 +253,6 @@ fn test_process_stream_ignores_code_fences() { /// /// This test ensures that running `mdtablefix --in-place` without a file argument results in a /// command failure. -/// -/// # Examples -/// -/// ``` -/// test_cli_in_place_requires_file(); -/// // The command should fail as no file is provided. -/// ``` fn test_cli_in_place_requires_file() { Command::cargo_bin("mdtablefix") .unwrap() @@ -303,13 +267,6 @@ fn test_cli_in_place_requires_file() { /// /// This test creates a temporary file with a malformed table, runs the `mdtablefix` binary on it, /// and asserts that the output is the expected fixed table. -/// -/// # Examples -/// -/// ``` -/// let broken_table = lines_vec!["| A | B |", "| 1 | 2 |", "| 3 | 4 |",]; -/// test_cli_process_file(broken_table); -/// ``` fn test_cli_process_file(broken_table: Vec) { let dir = tempdir().unwrap(); let file_path = dir.path().join("sample.md"); @@ -433,7 +390,7 @@ fn test_convert_html_table_basic() { "12", "", ]; - let expected = lines_vec!["| A | B |", "| --- | --- |", "| 1 | 2 |",]; + let expected = lines_vec!["| A | B |", "| --- | --- |", "| 1 | 2 |"]; assert_eq!(convert_html_tables(&html_table), expected); } @@ -615,12 +572,6 @@ fn test_process_stream_logical_type_table() { /// /// Loads input and expected output from test data files, runs `process_stream` on the input, and /// asserts equality. -/// -/// # Examples -/// -/// ``` -/// test_process_stream_option_table(); -/// ``` fn test_process_stream_option_table() { let input: Vec = include_str!("data/option_table_input.txt") .lines() @@ -709,7 +660,7 @@ fn test_wrap_long_inline_code_item() { " A fallback handler for messages that are not dispatched by the more specific", " message handlers. This can be used for raw text/binary data or messages that", " don't conform to the expected structured format." - ),]; + )]; let output = process_stream(&input); common::assert_wrapped_list_item(&output, "- ", 4); assert!( @@ -725,7 +676,7 @@ fn test_wrap_footnote_multiline() { let input = lines_vec![concat!( "[^note]: This footnote is sufficiently long to require wrapping ", "across multiple lines so we can verify indentation." - ),]; + )]; let output = process_stream(&input); common::assert_wrapped_list_item(&output, "[^note]: ", 2); } @@ -735,7 +686,7 @@ fn test_wrap_footnote_with_inline_code() { let input = lines_vec![concat!( " [^code_note]: A footnote containing inline `code` that should wrap ", "across multiple lines without breaking the span." - ),]; + )]; let output = process_stream(&input); common::assert_wrapped_list_item(&output, " [^code_note]: ", 2); } @@ -792,7 +743,7 @@ fn test_wrap_blockquote_nested() { let input = lines_vec![concat!( "> > This nested quote contains enough text to require wrapping so that we ", "can verify multi-level handling." - ),]; + )]; let output = process_stream(&input); common::assert_wrapped_blockquote(&output, "> > ", 2); let joined = output @@ -853,7 +804,7 @@ fn test_wrap_blockquote_short() { /// Ensures that the `process_stream` function does not remove or alter lines ending with Markdown /// hard line breaks. fn test_preserve_hard_line_breaks() { - let input = lines_vec!["Line one with break. ", "Line two follows.",]; + let input = lines_vec!["Line one with break. ", "Line two follows."]; let output = process_stream(&input); assert_eq!(output.len(), 2); assert_eq!(output[0], "Line one with break."); @@ -880,15 +831,15 @@ fn test_regression_complex_table() { #[test] fn test_renumber_basic() { - let input = lines_vec!["1. first", "2. second", "7. third",]; + let input = lines_vec!["1. first", "2. second", "7. third"]; let expected = lines_vec!["1. first", "2. second", "3. third"]; assert_eq!(renumber_lists(&input), expected); } #[test] fn test_renumber_with_fence() { - let input = lines_vec!["1. item", "```", "code", "```", "9. next",]; - let expected = lines_vec!["1. item", "```", "code", "```", "2. next",]; + let input = lines_vec!["1. item", "```", "code", "```", "9. next"]; + let expected = lines_vec!["1. item", "```", "code", "```", "2. next"]; assert_eq!(renumber_lists(&input), expected); } @@ -967,7 +918,7 @@ fn test_renumber_restart_after_paragraph() { #[test] fn test_format_breaks_basic() { let input = lines_vec!["foo", "***", "bar"]; - let expected = lines_vec!["foo", "_".repeat(THEMATIC_BREAK_LEN), "bar",]; + let expected = lines_vec!["foo", "_".repeat(THEMATIC_BREAK_LEN), "bar"]; assert_eq!(format_breaks(&input), expected); } From 70b2f31537bf0c26ac2f727ef03d8c2fb354a25a Mon Sep 17 00:00:00 2001 From: Leynos Date: Thu, 17 Jul 2025 11:45:53 +0100 Subject: [PATCH 3/3] Simplify fixtures and adjust tests --- tests/integration.rs | 31 ++++++------------------------- 1 file changed, 6 insertions(+), 25 deletions(-) diff --git a/tests/integration.rs b/tests/integration.rs index 503686b3..8eccb8ca 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -20,20 +20,14 @@ mod common; /// /// The returned vector contains lines representing a table with inconsistent columns, useful for /// validating table reflow logic. -fn broken_table() -> Vec { - let lines = lines_vec!["| A | B | |", "| 1 | 2 | | 3 | 4 |"]; - lines -} +fn broken_table() -> Vec { return lines_vec!["| A | B | |", "| 1 | 2 | | 3 | 4 |"]; } #[fixture] /// Returns a vector of strings representing a malformed Markdown table with inconsistent columns. /// /// The returned table has rows with differing numbers of columns, making it invalid for standard /// Markdown table parsing. -fn malformed_table() -> Vec { - let lines = lines_vec!["| A | |", "| 1 | 2 | 3 |"]; - lines -} +fn malformed_table() -> Vec { return lines_vec!["| A | |", "| 1 | 2 | 3 |"]; } #[fixture] fn header_table() -> Vec { @@ -47,8 +41,7 @@ fn escaped_pipe_table() -> Vec { #[fixture] fn indented_table() -> Vec { - let lines = lines_vec![" | I | J | |", " | 1 | 2 | | 3 | 4 |"]; - lines + return lines_vec![" | I | J | |", " | 1 | 2 | | 3 | 4 |"]; } #[fixture] @@ -122,16 +115,10 @@ fn html_table_inconsistent_first_row() -> Vec { } #[fixture] -fn html_table_empty() -> Vec { - let lines = lines_vec!["
"]; - lines -} +fn html_table_empty() -> Vec { return lines_vec!["
"]; } #[fixture] -fn html_table_unclosed() -> Vec { - let lines = lines_vec!["", ""]; - lines -} +fn html_table_unclosed() -> Vec { return lines_vec!["
1
", ""]; } #[fixture] fn html_table_uppercase() -> Vec { @@ -224,13 +211,7 @@ fn test_process_stream_html_table_mixed_case(html_table_mixed_case: Vec) #[rstest] fn test_process_stream_multiple_tables(multiple_tables: Vec) { - let expected = lines_vec![ - "| A | B |", - "| 1 | 22 |", - String::new(), - "| X | Y |", - "| 3 | 4 |", - ]; + let expected = lines_vec!["| A | B |", "| 1 | 22 |", "", "| X | Y |", "| 3 | 4 |",]; assert_eq!(process_stream(&multiple_tables), expected); }
1