From be0180747c094639679e4af96c99ebbc65f22b57 Mon Sep 17 00:00:00 2001 From: Jeffrey Finkelstein Date: Mon, 19 Jan 2026 21:19:16 -0500 Subject: [PATCH] pr: add passing tests for merging files Add a passing unit tests for `pr` for merging two files. --- tests/by-util/test_pr.rs | 69 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) diff --git a/tests/by-util/test_pr.rs b/tests/by-util/test_pr.rs index 1beed2305..c4fee97ae 100644 --- a/tests/by-util/test_pr.rs +++ b/tests/by-util/test_pr.rs @@ -7,8 +7,8 @@ use jiff::{Timestamp, ToSpan}; use regex::Regex; use std::fs::metadata; -use uutests::new_ucmd; use uutests::util::UCommand; +use uutests::{at_and_ucmd, new_ucmd}; const DATE_TIME_FORMAT_DEFAULT: &str = "%Y-%m-%d %H:%M"; @@ -666,3 +666,70 @@ fn test_form_feed_followed_by_new_line() { .succeeds() .stdout_matches(®ex); } + +#[test] +fn test_merge() { + // Create the two files to merge. + let (at, mut ucmd) = at_and_ucmd!(); + at.write("f", "a\n"); + at.write("g", "b\n"); + + let whitespace = " ".repeat(50); + let datetime_pattern = r"\d\d\d\d-\d\d-\d\d \d\d:\d\d"; + let header = format!("\n\n{datetime_pattern}{whitespace}Page 1\n\n\n"); + // TODO Our output still does not match the behavior of GNU + // pr. The correct output should be: + // + // "a\t\t\t\t b\n"; + // + // and the blank lines should actually be empty lines. + let data = "a \tb \n"; + let blank_lines_55 = + " \t \n".repeat(55); + let footer = "\n".repeat(5); + let pattern = format!("{header}{data}{blank_lines_55}{footer}"); + let regex = Regex::new(&pattern).unwrap(); + + // Command line: `(echo "a" > f; echo "b" > g; pr -m f g)`. + ucmd.args(&["-m", "f", "g"]) + .succeeds() + .stdout_matches(®ex); +} + +#[test] +fn test_merge_one_long_one_short() { + // Create the two files to merge. + let (at, mut ucmd) = at_and_ucmd!(); + at.write("f", "a\na\n"); + at.write("g", "b\n"); + + // Page 1 should have the first line of `f` and the first line of + // `b` side-by-side. + let whitespace = " ".repeat(50); + let datetime_pattern = r"\d\d\d\d-\d\d-\d\d \d\d:\d\d"; + let header = format!("\n\n{datetime_pattern}{whitespace}Page 1\n\n\n"); + let data = "a \tb \n"; + let footer = "\n".repeat(5); + let page1 = format!("{header}{data}{footer}"); + + // Page 2 should have just the second line of `f`. + let header = format!("\n\n{datetime_pattern}{whitespace}Page 2\n\n\n"); + let data = "a \t \n"; + let page2 = format!("{header}{data}{footer}"); + + let pattern = format!("{page1}{page2}"); + let regex = Regex::new(&pattern).unwrap(); + + // Command line: + // + // printf "a\na\n" > f + // printf "b\n" > g + // pr -l11 -m f g + // + // The line length of 11 leaves room for a 5-line header, a 5-line + // footer, and one line of data from the input files. The extra + // line from the file `f` will be on the second page. + ucmd.args(&["-l", "11", "-m", "f", "g"]) + .succeeds() + .stdout_matches(®ex); +}