pub fn normalize_output(input: &str) -> String {
let input_lf = input.replace("\r\n", "\n");
let lines: Vec<&str> = input_lf.lines().collect();
let mut result_lines: Vec<&str> = Vec::with_capacity(lines.len());
let mut i = 0;
while i < lines.len() {
let line = lines[i];
let trimmed = line.trim();
if trimmed.is_empty() {
let mut j = i + 1;
let mut found_end = false;
while j < lines.len() {
let next_trimmed = lines[j].trim();
if next_trimmed.is_empty() {
j += 1;
continue;
}
if next_trimmed == "end" {
found_end = true;
}
break;
}
if found_end {
i += 1;
continue;
}
}
result_lines.push(line);
i += 1;
}
let processed = result_lines.join("\n");
let trimmed = processed.trim_end_matches([' ', '\t', '\r', '\n']);
format!("{}\n", trimmed)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_normalize_empty_input() {
assert_eq!(normalize_output(""), "\n");
}
#[test]
fn test_normalize_existing_single_newline() {
assert_eq!(normalize_output("code\n"), "code\n");
}
#[test]
fn test_normalize_single_extra_blank_line() {
assert_eq!(normalize_output("code\n\n"), "code\n");
}
#[test]
fn test_normalize_multiple_extra_blank_lines() {
assert_eq!(normalize_output("code\n\n\n"), "code\n");
}
#[test]
fn test_normalize_preserves_intermediate_blank_lines() {
assert_eq!(normalize_output("a\n\nb\n\n"), "a\n\nb\n");
}
#[test]
fn test_normalize_crlf_input() {
assert_eq!(normalize_output("code\r\n\r\n"), "code\n");
}
#[test]
fn test_normalize_mixed_line_endings() {
assert_eq!(normalize_output("a\r\nb\n\r\n\n"), "a\nb\n");
}
#[test]
fn test_normalize_trailing_whitespace_only() {
assert_eq!(normalize_output("code\n \t\n"), "code\n");
}
#[test]
fn test_normalize_no_trailing_newline() {
assert_eq!(normalize_output("code"), "code\n");
}
#[test]
fn test_normalize_multi_line_content() {
let input = "line1\nline2\nline3\n\n\n";
assert_eq!(normalize_output(input), "line1\nline2\nline3\n");
}
#[test]
fn test_normalize_blank_line_before_end() {
let input = " end\n\nend\n";
assert_eq!(normalize_output(input), " end\nend\n");
}
#[test]
fn test_normalize_multiple_blank_lines_before_end() {
let input = " end\n\n\nend\n";
assert_eq!(normalize_output(input), " end\nend\n");
}
#[test]
fn test_normalize_blank_line_before_indented_end() {
let input = "code\n\n end\n";
assert_eq!(normalize_output(input), "code\n end\n");
}
#[test]
fn test_normalize_lua_do_block() {
let input = "do\n function f()\n return 1\n end\n\nend\n";
assert_eq!(
normalize_output(input),
"do\n function f()\n return 1\n end\nend\n"
);
}
#[test]
fn test_normalize_nested_end_blocks() {
let input = " end\n\n end\n\nend\n";
assert_eq!(normalize_output(input), " end\n end\nend\n");
}
}