From 4a7d313712912c91997cb7a83067d97552513a51 Mon Sep 17 00:00:00 2001 From: sbentmar Date: Sat, 15 Jan 2022 13:30:17 +0100 Subject: [PATCH] numfmt: add unit test for io error --- src/uu/numfmt/src/numfmt.rs | 54 ++++++++++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 6 deletions(-) diff --git a/src/uu/numfmt/src/numfmt.rs b/src/uu/numfmt/src/numfmt.rs index 22e7210f1..0b0108453 100644 --- a/src/uu/numfmt/src/numfmt.rs +++ b/src/uu/numfmt/src/numfmt.rs @@ -66,11 +66,11 @@ fn handle_args<'a>(args: impl Iterator, options: NumfmtOptions) Ok(()) } -fn handle_stdin(options: NumfmtOptions) -> UResult<()> { - let stdin = std::io::stdin(); - let locked_stdin = stdin.lock(); - - let mut lines = locked_stdin.lines(); +fn handle_buffer(input: R, options: NumfmtOptions) -> UResult<()> +where + R: BufRead, +{ + let mut lines = input.lines(); for (idx, line) in lines.by_ref().enumerate() { match line { Ok(l) if idx < options.header => { @@ -174,7 +174,11 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let result = match matches.values_of(options::NUMBER) { Some(values) => handle_args(values, options), - None => handle_stdin(options), + None => { + let stdin = std::io::stdin(); + let mut locked_stdin = stdin.lock(); + handle_buffer(&mut locked_stdin, options) + } }; match result { @@ -264,3 +268,41 @@ pub fn uu_app() -> App<'static, 'static> { ) .arg(Arg::with_name(options::NUMBER).hidden(true).multiple(true)) } + +#[cfg(test)] +mod tests { + use super::{handle_buffer, NumfmtOptions, Range, RoundMethod, TransformOptions, Unit}; + use std::io::{BufReader, Error, ErrorKind, Read}; + struct MockBuffer {} + + impl Read for MockBuffer { + fn read(&mut self, _: &mut [u8]) -> Result { + Err(Error::new(ErrorKind::BrokenPipe, "broken pipe")) + } + } + + fn get_options() -> NumfmtOptions { + NumfmtOptions { + transform: TransformOptions { + from: Unit::Auto, + to: Unit::Auto, + }, + padding: 10, + header: 0, + fields: vec![Range { low: 0, high: 1 }], + delimiter: None, + round: RoundMethod::Nearest, + suffix: None, + } + } + + #[test] + fn broken_buffer_returns_io_error() { + let mock_buffer = MockBuffer {}; + let result = handle_buffer(BufReader::new(mock_buffer), get_options()) + .expect_err("returned Ok after receiving IO error"); + let result_debug = format!("{:?}", result); + assert_eq!(result_debug, "IoError(\"broken pipe\")"); + assert_eq!(result.code(), 1); + } +}