From 3fd8136423d1b2af22b1bd99e0ddc30e0efb9f14 Mon Sep 17 00:00:00 2001 From: palaviv Date: Tue, 14 Jun 2016 22:21:30 +0300 Subject: [PATCH] sort: Support check --- src/sort/sort.rs | 34 ++++++++++++++++++++++-------- tests/fixtures/sort/check_fail.txt | 8 +++++++ tests/test_sort.rs | 28 ++++++++++++++++++++---- 3 files changed, 57 insertions(+), 13 deletions(-) create mode 100644 tests/fixtures/sort/check_fail.txt diff --git a/src/sort/sort.rs b/src/sort/sort.rs index ac0a17401..28e2251cf 100644 --- a/src/sort/sort.rs +++ b/src/sort/sort.rs @@ -44,6 +44,7 @@ struct Settings { reverse: bool, outfile: Option, unique: bool, + check: bool, } impl Default for Settings { @@ -53,6 +54,7 @@ impl Default for Settings { reverse: false, outfile: None, unique: false, + check: false, } } } @@ -70,6 +72,7 @@ pub fn uumain(args: Vec) -> i32 { opts.optopt("o", "output", "write output to FILENAME instead of stdout", "FILENAME"); opts.optflag("u", "unique", "output only the first of an equal run"); opts.optflag("V", "version-sort", "Sort by SemVer version number, eg 1.12.2 > 1.1.2"); + opts.optflag("c", "check", "check for sorted input; do not sort"); let matches = match opts.parse(&args[1..]) { Ok(m) => m, @@ -110,6 +113,7 @@ With no FILE, or when FILE is -, read standard input.", NAME, VERSION); settings.reverse = matches.opt_present("reverse"); settings.outfile = matches.opt_str("output"); settings.unique = matches.opt_present("unique"); + settings.check = matches.opt_present("check"); let mut files = matches.free; if files.is_empty() { @@ -117,12 +121,10 @@ With no FILE, or when FILE is -, read standard input.", NAME, VERSION); files.push("-".to_owned()); } - exec(files, &settings); - - 0 + exec(files, &settings) } -fn exec(files: Vec, settings: &Settings) { +fn exec(files: Vec, settings: &Settings) -> i32 { let mut lines = Vec::new(); for path in &files { let (reader, _) = match open(path) { @@ -142,6 +144,8 @@ fn exec(files: Vec, settings: &Settings) { } } + let original_lines = lines.to_vec(); + match settings.mode { SortMode::Numeric => lines.sort_by(numeric_compare), SortMode::HumanNumeric => lines.sort_by(human_numeric_size_compare), @@ -154,12 +158,24 @@ fn exec(files: Vec, settings: &Settings) { lines.dedup() } - let iter = lines.iter(); if settings.reverse { - print_sorted(iter.rev(), &settings.outfile); - } else { - print_sorted(iter, &settings.outfile) - }; + lines.reverse() + } + + if settings.check { + for (i, line) in lines.iter().enumerate() { + if line != &original_lines[i] { + println!("sort: disorder in line {}", i); + return 1; + } + } + } + else { + print_sorted(lines.iter(), &settings.outfile) + } + + 0 + } /// Parse the beginning string into an f64, returning -inf instead of NaN on errors. diff --git a/tests/fixtures/sort/check_fail.txt b/tests/fixtures/sort/check_fail.txt new file mode 100644 index 000000000..e15a1168c --- /dev/null +++ b/tests/fixtures/sort/check_fail.txt @@ -0,0 +1,8 @@ +1 +2 +3 +4 +6 +5 +9 +8 diff --git a/tests/test_sort.rs b/tests/test_sort.rs index cd2035710..321af096b 100644 --- a/tests/test_sort.rs +++ b/tests/test_sort.rs @@ -58,15 +58,35 @@ fn test_multiple_files() { ucmd.arg("-n"); ucmd.arg("multiple_files1.txt"); ucmd.arg("multiple_files2.txt"); - let out = ucmd.run().stdout; - assert_eq!(out, at.read("multiple_files.expected")); + let res = ucmd.run(); + assert_eq!(res.success, true); + assert_eq!(res.stdout, at.read("multiple_files.expected")); +} + +#[test] +fn test_check() { + let (_, mut ucmd) = testing(UTIL_NAME); + ucmd.arg("-c"); + let res = ucmd.arg("check_fail.txt").run(); + + assert_eq!(res.success, false); + assert_eq!(res.stdout, "sort: disorder in line 4\n"); + + let (_, mut ucmd) = testing(UTIL_NAME); + ucmd.arg("-c"); + let res = ucmd.arg("multiple_files.expected").run(); + + assert_eq!(res.success, true); + assert_eq!(res.stdout, ""); } fn test_helper(file_name: &str, args: &str) { let (at, mut ucmd) = testing(UTIL_NAME); ucmd.arg(args); - let out = ucmd.arg(format!("{}{}", file_name, ".txt")).run().stdout; + let res = ucmd.arg(format!("{}{}", file_name, ".txt")).run(); + + assert_eq!(res.success, true); let filename = format!("{}{}", file_name, ".expected"); - assert_eq!(out, at.read(&filename)); + assert_eq!(res.stdout, at.read(&filename)); }