From 7f03ecf74b7010cc54a308a5989ab5f248a7e0ab Mon Sep 17 00:00:00 2001 From: Tyler Date: Fri, 2 Jul 2021 13:17:34 -0700 Subject: [PATCH] Adds failures & tests for unimplmented flags. --- src/uu/dd/src/parseargs.rs | 102 ++++++++++++++++++++++---- src/uu/dd/src/parseargs/unit_tests.rs | 75 +++++++++++++++++++ 2 files changed, 163 insertions(+), 14 deletions(-) diff --git a/src/uu/dd/src/parseargs.rs b/src/uu/dd/src/parseargs.rs index 699334416..f134886b2 100644 --- a/src/uu/dd/src/parseargs.rs +++ b/src/uu/dd/src/parseargs.rs @@ -7,7 +7,7 @@ use std::error::Error; pub type Matches = clap::ArgMatches<'static>; /// Parser Errors describe errors with parser input -#[derive(Debug)] +#[derive(Debug, PartialEq)] pub enum ParseError { MultipleFmtTable, @@ -21,6 +21,7 @@ pub enum ParseError MultiplierStringWouldOverflow(String), BlockUnblockWithoutCBS, StatusLevelNotRecognized(String), + Unimplemented(String), } impl std::fmt::Display for ParseError @@ -72,6 +73,10 @@ impl std::fmt::Display for ParseError { write!(f, "status=LEVEL not recognized -> {}", arg) }, + Self::Unimplemented(arg) => + { + write!(f, "feature not implemented on this system -> {}", arg) + }, } } } @@ -193,31 +198,100 @@ impl std::str::FromStr for Flag Ok(Self::SkipBytes), // Either "cio" => - Ok(Self::Cio), + // Ok(Self::Cio), + Err(ParseError::Unimplemented(s.to_string())), "direct" => - Ok(Self::Direct), + // Ok(Self::Direct), + if cfg!(unix) + { + Ok(Self::Direct) + } + else + { + Err(ParseError::Unimplemented(s.to_string())) + }, "directory" => - Ok(Self::Directory), + // Ok(Self::Directory), + if cfg!(unix) + { + Ok(Self::Directory) + } + else + { + Err(ParseError::Unimplemented(s.to_string())) + }, "dsync" => - Ok(Self::Dsync), + // Ok(Self::Dsync), + if cfg!(unix) + { + Ok(Self::Dsync) + } + else + { + Err(ParseError::Unimplemented(s.to_string())) + }, "sync" => - Ok(Self::Sync), + // Ok(Self::Sync), + if cfg!(unix) + { + Ok(Self::Sync) + } + else + { + Err(ParseError::Unimplemented(s.to_string())) + }, "nocache" => - Ok(Self::NoCache), + // Ok(Self::NoCache), + Err(ParseError::Unimplemented(s.to_string())), "nonblock" => - Ok(Self::NonBlock), + // Ok(Self::NonBlock), + if cfg!(unix) + { + Ok(Self::NonBlock) + } + else + { + Err(ParseError::Unimplemented(s.to_string())) + }, "noatime" => - Ok(Self::NoATime), + // Ok(Self::NoATime), + if cfg!(unix) + { + Ok(Self::NoATime) + } + else + { + Err(ParseError::Unimplemented(s.to_string())) + }, "noctty" => - Ok(Self::NoCtty), + // Ok(Self::NoCtty), + if cfg!(unix) + { + Ok(Self::NoCtty) + } + else + { + Err(ParseError::Unimplemented(s.to_string())) + }, "nofollow" => - Ok(Self::NoFollow), + // Ok(Self::NoFollow), + if cfg!(unix) + { + Ok(Self::NoFollow) + } + else + { + Err(ParseError::Unimplemented(s.to_string())) + }, "nolinks" => - Ok(Self::NoLinks), + // Ok(Self::NoLinks), + Err(ParseError::Unimplemented(s.to_string())), "binary" => - Ok(Self::Binary), + // Ok(Self::Binary), + Err(ParseError::Unimplemented(s.to_string())), "text" => - Ok(Self::Text), + // Ok(Self::Text), + Err(ParseError::Unimplemented(s.to_string())), // Output only "append" => Ok(Self::Append), diff --git a/src/uu/dd/src/parseargs/unit_tests.rs b/src/uu/dd/src/parseargs/unit_tests.rs index 9742bcdcb..05d9176d0 100644 --- a/src/uu/dd/src/parseargs/unit_tests.rs +++ b/src/uu/dd/src/parseargs/unit_tests.rs @@ -5,6 +5,81 @@ use crate::{ StatusLevel, }; +#[cfg(not(unix))] +#[test] +fn unimplemented_flags_should_error_non_unix() +{ + let mut unfailed = Vec::new(); + + // The following flags are only implemented in unix + for flag in vec!["direct", "directory", "dsync", "sync", "nonblock", "noatime", "noctty", "nofollow"] + { + let args = vec![ + String::from("dd"), + format!("--iflag={}", flag), + format!("--oflag={}", flag), + ]; + let matches = build_dd_app!().get_matches_from_safe(args).unwrap(); + + match parse_iflags(&matches) + { + Ok(_) => + unfailed.push(format!("iflag={}", flag)), + Err(_) => + {/* expected behaviour :-) */}, + } + match parse_oflags(&matches) + { + Ok(_) => + unfailed.push(format!("oflag={}", flag)), + Err(_) => + {/* expected behaviour :-) */}, + } + } + + if !unfailed.is_empty() + { + panic!("The following flags did not panic as expected: {:?}", unfailed); + } +} + +#[test] +fn unimplemented_flags_should_error() +{ + let mut unfailed = Vec::new(); + + // The following flags are not implemented + for flag in vec!["cio", "nocache", "nolinks", "text", "binary"] + { + let args = vec![ + String::from("dd"), + format!("--iflag={}", flag), + format!("--oflag={}", flag), + ]; + let matches = build_dd_app!().get_matches_from_safe(args).unwrap(); + + match parse_iflags(&matches) + { + Ok(_) => + unfailed.push(format!("iflag={}", flag)), + Err(_) => + {/* expected behaviour :-) */}, + } + match parse_oflags(&matches) + { + Ok(_) => + unfailed.push(format!("oflag={}", flag)), + Err(_) => + {/* expected behaviour :-) */}, + } + } + + if !unfailed.is_empty() + { + panic!("The following flags did not panic as expected: {:?}", unfailed); + } +} + #[test] fn test_status_level_absent() {