From b461f102cceb4683e1a291a5593367ed397eca24 Mon Sep 17 00:00:00 2001 From: Tyler Date: Wed, 21 Apr 2021 15:24:14 -0700 Subject: [PATCH] Testt conv arg parsing. --- src/uu/dd/src/dd.rs | 6 +- .../src/{test_dd_internal.rs => dd_test.rs} | 62 +--- src/uu/dd/src/parseargs.rs | 242 ++----------- src/uu/dd/src/parseargs/test.rs | 317 ++++++++++++++++++ 4 files changed, 358 insertions(+), 269 deletions(-) rename src/uu/dd/src/{test_dd_internal.rs => dd_test.rs} (81%) create mode 100644 src/uu/dd/src/parseargs/test.rs diff --git a/src/uu/dd/src/dd.rs b/src/uu/dd/src/dd.rs index aa5f9e4b4..87949a08e 100644 --- a/src/uu/dd/src/dd.rs +++ b/src/uu/dd/src/dd.rs @@ -11,11 +11,11 @@ extern crate uucore; #[cfg(test)] -mod test_dd_internal; +mod dd_test; mod parseargs; -mod conversion_tables; +mod conversion_tables; use conversion_tables::*; use std::error::Error; @@ -46,7 +46,7 @@ enum SrcStat /// Captures all Conv Flags that apply to the input pub struct ConvFlagInput { - ctable: Option, + ctable: Option<&'static ConversionTable>, block: bool, unblock: bool, swab: bool, diff --git a/src/uu/dd/src/test_dd_internal.rs b/src/uu/dd/src/dd_test.rs similarity index 81% rename from src/uu/dd/src/test_dd_internal.rs rename to src/uu/dd/src/dd_test.rs index 66edd1c88..c2167a5e6 100644 --- a/src/uu/dd/src/test_dd_internal.rs +++ b/src/uu/dd/src/dd_test.rs @@ -135,7 +135,7 @@ make_spec_test!( atoe_conv_spec_test, "atoe-conv-spec-test", File::open("./test-resources/seq-byte-values-b632a992d3aed5d8d1a59cc5a5a455ba.test").unwrap(), - Some(ASCII_TO_EBCDIC), + Some(&ASCII_TO_EBCDIC), File::open("./test-resources/gnudd-conv-atoe-seq-byte-values.spec").unwrap() ); @@ -143,7 +143,7 @@ make_spec_test!( etoa_conv_spec_test, "etoa-conv-spec-test", File::open("./test-resources/seq-byte-values-b632a992d3aed5d8d1a59cc5a5a455ba.test").unwrap(), - Some(EBCDIC_TO_ASCII), + Some(&EBCDIC_TO_ASCII), File::open("./test-resources/gnudd-conv-etoa-seq-byte-values.spec").unwrap() ); @@ -151,7 +151,7 @@ make_spec_test!( atoibm_conv_spec_test, "atoibm-conv-spec-test", File::open("./test-resources/seq-byte-values-b632a992d3aed5d8d1a59cc5a5a455ba.test").unwrap(), - Some(ASCII_TO_IBM), + Some(&ASCII_TO_IBM), File::open("./test-resources/gnudd-conv-atoibm-seq-byte-values.spec").unwrap() ); @@ -159,7 +159,7 @@ make_spec_test!( lcase_ascii_to_ucase_ascii, "lcase_ascii_to_ucase_ascii", File::open("./test-resources/lcase-ascii.test").unwrap(), - Some(ASCII_LCASE_TO_UCASE), + Some(&ASCII_LCASE_TO_UCASE), File::open("./test-resources/ucase-ascii.test").unwrap() ); @@ -167,56 +167,16 @@ make_spec_test!( ucase_ascii_to_lcase_ascii, "ucase_ascii_to_lcase_ascii", File::open("./test-resources/ucase-ascii.test").unwrap(), - Some(ASCII_UCASE_TO_LCASE), + Some(&ASCII_UCASE_TO_LCASE), File::open("./test-resources/lcase-ascii.test").unwrap() ); -// // *** -// make_spec_test!( -// lcase_ebcdic_to_ucase_ebcdic, -// "lcase_ebcdic_to_ucase_ebcdic", -// File::open("./test-resources/lcase-ebcdic.test").unwrap(), -// None, -// Some(EBCDIC_LCASE_TO_UCASE), -// File::open("./test-resources/ucase-ebcdic.test").unwrap() -// ); -// -// // *** -// make_spec_test!( -// ucase_ebcdic_to_lcase_ebcdic, -// "ucase_ebcdic_to_lcase_ebcdic", -// File::open("./test-resources/ucase-ebcdic.test").unwrap(), -// None, -// Some(EBCDIC_UCASE_TO_LCASE), -// File::open("./test-resources/lcase-ebcdic.test").unwrap() -// ); -// -// // *** -// make_spec_test!( -// lcase_ibm_to_ucase_ibm, -// "lcase_ibm_to_ucase_ibm", -// File::open("./test-resources/lcase-ibm.test").unwrap(), -// None, -// Some(IBM_LCASE_TO_UCASE), -// File::open("./test-resources/ucase-ibm.test").unwrap() -// ); -// -// // *** -// make_spec_test!( -// ucase_ibm_to_lcase_ibm, -// "ucase_ibm_to_lcase_ibm", -// File::open("./test-resources/ucase-ibm.test").unwrap(), -// None, -// Some(IBM_UCASE_TO_LCASE), -// File::open("./test-resources/lcase-ibm.test").unwrap() -// ); - make_spec_test!( // conv=ebcdic,ucase atoe_and_ucase_conv_spec_test, "atoe-and-ucase-conv-spec-test", File::open("./test-resources/seq-byte-values-b632a992d3aed5d8d1a59cc5a5a455ba.test").unwrap(), - Some(ASCII_TO_EBCDIC_LCASE_TO_UCASE), + Some(&ASCII_TO_EBCDIC_LCASE_TO_UCASE), File::open("./test-resources/ucase-ebcdic.test").unwrap() ); @@ -225,7 +185,7 @@ make_spec_test!( atoe_and_lcase_conv_spec_test, "atoe-and-lcase-conv-spec-test", File::open("./test-resources/seq-byte-values-b632a992d3aed5d8d1a59cc5a5a455ba.test").unwrap(), - Some(ASCII_TO_EBCDIC_UCASE_TO_LCASE), + Some(&ASCII_TO_EBCDIC_UCASE_TO_LCASE), File::open("./test-resources/lcase-ebcdic.test").unwrap() ); @@ -234,7 +194,7 @@ make_spec_test!( atoibm_and_ucase_conv_spec_test, "atoibm-and-ucase-conv-spec-test", File::open("./test-resources/seq-byte-values-b632a992d3aed5d8d1a59cc5a5a455ba.test").unwrap(), - Some(ASCII_TO_IBM_UCASE_TO_LCASE), + Some(&ASCII_TO_IBM_UCASE_TO_LCASE), File::open("./test-resources/lcase-ibm.test").unwrap() ); @@ -243,7 +203,7 @@ make_spec_test!( atoibm_and_lcase_conv_spec_test, "atoibm-and-lcase-conv-spec-test", File::open("./test-resources/seq-byte-values-b632a992d3aed5d8d1a59cc5a5a455ba.test").unwrap(), - Some(ASCII_TO_IBM_LCASE_TO_UCASE), + Some(&ASCII_TO_IBM_LCASE_TO_UCASE), File::open("./test-resources/ucase-ibm.test").unwrap() ); @@ -258,7 +218,7 @@ fn all_valid_ascii_ebcdic_ascii_roundtrip_conv_test() src: File::open("./test-resources/all-valid-ascii-chars-37eff01866ba3f538421b30b7cbefcac.test").unwrap(), ibs: 256, xfer_stats: StatusLevel::None, - cf: cfi!(Some(ASCII_TO_EBCDIC)), + cf: cfi!(Some(&ASCII_TO_EBCDIC)), }; let o = Output { @@ -277,7 +237,7 @@ fn all_valid_ascii_ebcdic_ascii_roundtrip_conv_test() src: File::open(&tmp_fname_ae).unwrap(), ibs: 256, xfer_stats: StatusLevel::None, - cf: cfi!(Some(EBCDIC_TO_ASCII)), + cf: cfi!(Some(&EBCDIC_TO_ASCII)), }; let o = Output { diff --git a/src/uu/dd/src/parseargs.rs b/src/uu/dd/src/parseargs.rs index 8105efc9a..b1f157da6 100644 --- a/src/uu/dd/src/parseargs.rs +++ b/src/uu/dd/src/parseargs.rs @@ -1,8 +1,16 @@ -use super::*; +#[cfg(test)] +mod test; use crate::conversion_tables::*; +use crate::{ + ConvFlagInput, ConvFlagOutput, + StatusLevel, +}; -/// Parser Errors indicate erroneous cl-args +use std::error::Error; + + +/// Parser Errors describe errors with input #[derive(Debug)] pub enum ParseError { @@ -26,6 +34,7 @@ impl Error for ParseError {} /// Some flags specified as part of a conv=CONV[,CONV]... block /// relate to the input file, others to the output file. +#[derive(Debug, PartialEq)] enum ConvFlag { // Input @@ -64,9 +73,9 @@ impl std::str::FromStr for ConvFlag "ibm" => Ok(Self::FmtAtoI), "lcase" => - Ok(Self::UCase), - "ucase" => Ok(Self::LCase), + "ucase" => + Ok(Self::UCase), "block" => Ok(Self::Block), "unblock" => @@ -213,7 +222,7 @@ pub fn parse_obs(matches: &getopts::Matches) -> Result } } -fn parse_ctable(fmt: Option, case: Option) -> Option +fn parse_ctable(fmt: Option, case: Option) -> Option<&'static ConversionTable> { match (fmt, case) { @@ -222,17 +231,17 @@ fn parse_ctable(fmt: Option, case: Option) -> Option - Some(ASCII_TO_EBCDIC_LCASE_TO_UCASE), + Some(&ASCII_TO_EBCDIC_LCASE_TO_UCASE), (ConvFlag::FmtAtoE, ConvFlag::LCase) => - Some(ASCII_TO_EBCDIC_UCASE_TO_LCASE), + Some(&ASCII_TO_EBCDIC_UCASE_TO_LCASE), (ConvFlag::FmtEtoA, ConvFlag::UCase) => - Some(EBCDIC_TO_ASCII_LCASE_TO_UCASE), + Some(&EBCDIC_TO_ASCII_LCASE_TO_UCASE), (ConvFlag::FmtEtoA, ConvFlag::LCase) => - Some(EBCDIC_TO_ASCII_UCASE_TO_LCASE), + Some(&EBCDIC_TO_ASCII_UCASE_TO_LCASE), (ConvFlag::FmtAtoI, ConvFlag::UCase) => - Some(ASCII_TO_IBM_UCASE_TO_LCASE), + Some(&ASCII_TO_IBM_UCASE_TO_LCASE), (ConvFlag::FmtAtoI, ConvFlag::LCase) => - Some(ASCII_TO_IBM_LCASE_TO_UCASE), + Some(&ASCII_TO_IBM_LCASE_TO_UCASE), (_, _) => None, }, @@ -241,19 +250,19 @@ fn parse_ctable(fmt: Option, case: Option) -> Option - Some(ASCII_TO_EBCDIC), + Some(&ASCII_TO_EBCDIC), ConvFlag::FmtEtoA => - Some(EBCDIC_TO_ASCII), + Some(&EBCDIC_TO_ASCII), ConvFlag::FmtAtoI => - Some(ASCII_TO_IBM), + Some(&ASCII_TO_IBM), _ => None, }, // Only one of {ucase, lcase} specified (None, Some(ConvFlag::UCase)) => - Some(ASCII_LCASE_TO_UCASE), + Some(&ASCII_LCASE_TO_UCASE), (None, Some(ConvFlag::LCase)) => - Some(ASCII_UCASE_TO_LCASE), + Some(&ASCII_UCASE_TO_LCASE), (_, _) => None, } @@ -265,12 +274,13 @@ fn parse_conv_opts(matches: &getopts::Matches) -> Result, ParseErr if let Some(comma_str) = matches.opt_str("conv") { + println!("Parsing conv: {}", comma_str); for s in comma_str.split(",") { let flag = s.parse()?; + println!("found flag: {:?}", &flag); flags.push(flag); } - } Ok(flags) @@ -421,201 +431,3 @@ pub fn parse_conv_flag_output(matches: &getopts::Matches) -> Result - { - #[allow(non_snake_case)] - #[test] - fn $test_name() - { - let bs_str = String::from($bs_str); - assert_eq!($bs, parse_bytes_with_opt_multiplier(bs_str).unwrap()) - } - } - ); - - test_byte_parser!( - test_bytes_n, - "765", - 765 - ); - test_byte_parser!( - test_bytes_c, - "13c", - 13 - ); - - test_byte_parser!( - test_bytes_w, - "1w", - 2 - ); - - test_byte_parser!( - test_bytes_b, - "1b", - 512 - ); - - test_byte_parser!( - test_bytes_k, - "1kB", - 1000 - ); - test_byte_parser!( - test_bytes_K, - "1K", - 1024 - ); - test_byte_parser!( - test_bytes_Ki, - "1KiB", - 1024 - ); - - test_byte_parser!( - test_bytes_MB, - "2MB", - 2*1000*1000 - ); - test_byte_parser!( - test_bytes_M, - "2M", - 2*1024*1024 - ); - test_byte_parser!( - test_bytes_Mi, - "2MiB", - 2*1024*1024 - ); - - test_byte_parser!( - test_bytes_GB, - "3GB", - 3*1000*1000*1000 - ); - test_byte_parser!( - test_bytes_G, - "3G", - 3*1024*1024*1024 - ); - test_byte_parser!( - test_bytes_Gi, - "3GiB", - 3*1024*1024*1024 - ); - - test_byte_parser!( - test_bytes_TB, - "4TB", - 4*1000*1000*1000*1000 - ); - test_byte_parser!( - test_bytes_T, - "4T", - 4*1024*1024*1024*1024 - ); - test_byte_parser!( - test_bytes_Ti, - "4TiB", - 4*1024*1024*1024*1024 - ); - - test_byte_parser!( - test_bytes_PB, - "5PB", - 5*1000*1000*1000*1000*1000 - ); - test_byte_parser!( - test_bytes_P, - "5P", - 5*1024*1024*1024*1024*1024 - ); - test_byte_parser!( - test_bytes_Pi, - "5PiB", - 5*1024*1024*1024*1024*1024 - ); - - test_byte_parser!( - test_bytes_EB, - "6EB", - 6*1000*1000*1000*1000*1000*1000 - ); - test_byte_parser!( - test_bytes_E, - "6E", - 6*1024*1024*1024*1024*1024*1024 - ); - test_byte_parser!( - test_bytes_Ei, - "6EiB", - 6*1024*1024*1024*1024*1024*1024 - ); - - #[test] - #[should_panic] - #[allow(non_snake_case)] - fn test_KB_multiplier_error() - { - // KB is not valid (kB, K, and KiB are) - let bs_str = String::from("2000KB"); - - parse_bytes_with_opt_multiplier(bs_str).unwrap(); - } - - #[test] - #[should_panic] - fn test_overflow_panic() - { - let bs_str = format!("{}KiB", usize::MAX); - - parse_bytes_with_opt_multiplier(bs_str).unwrap(); - } - - #[test] - #[should_panic] - fn test_neg_panic() - { - let bs_str = format!("{}KiB", -1); - - parse_bytes_with_opt_multiplier(bs_str).unwrap(); - } - -} diff --git a/src/uu/dd/src/parseargs/test.rs b/src/uu/dd/src/parseargs/test.rs new file mode 100644 index 000000000..0a1db2868 --- /dev/null +++ b/src/uu/dd/src/parseargs/test.rs @@ -0,0 +1,317 @@ +use super::*; + +use crate::{ + build_app, + SYNTAX, SUMMARY, LONG_HELP, + ConvFlagInput, ConvFlagOutput, + StatusLevel, +}; + +// ----- ConvFlagInput/Output ----- + +#[test] +fn build_cfi() +{ + let cfi_expd = ConvFlagInput { + ctable: Some(&ASCII_TO_IBM), + block: false, + unblock: false, + swab: false, + sync: false, + noerror: false, + }; + + let args = vec![ + String::from("dd"), + String::from("--conv=ibm"), + ]; + + let matches = build_app!().parse(args); + + let cfi_parsed = parse_conv_flag_input(&matches).unwrap(); + + unimplemented!() + // assert_eq!(cfi_expd, cfi_parsed); +} + +#[test] +#[should_panic] +fn cfi_ctable_error() +{ + let args = vec![ + String::from("dd"), + String::from("--conv=ascii,ebcdic,ibm"), + ]; + + let matches = build_app!().parse(args); + + let cfi_parsed = parse_conv_flag_input(&matches).unwrap(); +} + +#[test] +#[should_panic] +fn cfi_case_error() +{ + let args = vec![ + String::from("dd"), + String::from("--conv=ucase,lcase"), + ]; + + let matches = build_app!().parse(args); + + let cfi_parsed = parse_conv_flag_input(&matches).unwrap(); +} + +#[test] +#[should_panic] +fn cfi_block_error() +{ + let args = vec![ + String::from("dd"), + String::from("--conv=block,unblock"), + ]; + + let matches = build_app!().parse(args); + + let cfi_parsed = parse_conv_flag_input(&matches).unwrap(); +} + +#[test] +fn parse_cfi_token_ibm() +{ + let exp = vec![ + ConvFlag::FmtAtoI, + ]; + + let args = vec![ + String::from("dd"), + String::from("--conv=ibm"), + ]; + let matches = build_app!().parse(args); + + let act = parse_conv_opts(&matches).unwrap(); + + assert_eq!(exp.len(), act.len()); + for cf in &exp + { + assert!(exp.contains(&cf)); + } +} + +#[test] +fn parse_cfi_tokens_elu() +{ + let exp = vec![ + ConvFlag::FmtEtoA, + ConvFlag::LCase, + ConvFlag::Unblock, + ]; + + let args = vec![ + String::from("dd"), + String::from("--conv=ebcdic,lcase,unblock"), + ]; + let matches = build_app!().parse(args); + let act = parse_conv_opts(&matches).unwrap(); + + assert_eq!(exp.len(), act.len()); + for cf in &exp + { + assert!(exp.contains(&cf)); + } +} + +#[test] +fn parse_cfi_tokens_remaining() +{ + let exp = vec![ + ConvFlag::FmtAtoE, + ConvFlag::UCase, + ConvFlag::Block, + ConvFlag::Sparse, + ConvFlag::Swab, + ConvFlag::Sync, + ConvFlag::NoError, + ConvFlag::Excl, + ConvFlag::NoCreat, + ConvFlag::NoTrunc, + ConvFlag::NoError, + ConvFlag::FDataSync, + ConvFlag::FSync, + ]; + + let args = vec![ + String::from("dd"), + String::from("--conv=ascii,ucase,block,sparse,swab,sync,noerror,excl,nocreat,notrunc,noerror,fdatasync,fsync"), + ]; + let matches = build_app!().parse(args); + let act = parse_conv_opts(&matches).unwrap(); + + assert_eq!(exp.len(), act.len()); + for cf in &exp + { + assert!(exp.contains(&cf)); + } +} + +// ----- Multiplier Strings etc. ----- +macro_rules! test_byte_parser ( + ( $test_name:ident, $bs_str:expr, $bs:expr ) => + { + #[allow(non_snake_case)] + #[test] + fn $test_name() + { + let bs_str = String::from($bs_str); + assert_eq!($bs, parse_bytes_with_opt_multiplier(bs_str).unwrap()) + } + } +); + +test_byte_parser!( + test_bytes_n, + "765", + 765 +); +test_byte_parser!( + test_bytes_c, + "13c", + 13 +); + +test_byte_parser!( + test_bytes_w, + "1w", + 2 +); + +test_byte_parser!( + test_bytes_b, + "1b", + 512 +); + +test_byte_parser!( + test_bytes_k, + "1kB", + 1000 +); +test_byte_parser!( + test_bytes_K, + "1K", + 1024 +); +test_byte_parser!( + test_bytes_Ki, + "1KiB", + 1024 +); + +test_byte_parser!( + test_bytes_MB, + "2MB", + 2*1000*1000 +); +test_byte_parser!( + test_bytes_M, + "2M", + 2*1024*1024 +); +test_byte_parser!( + test_bytes_Mi, + "2MiB", + 2*1024*1024 +); + +test_byte_parser!( + test_bytes_GB, + "3GB", + 3*1000*1000*1000 +); +test_byte_parser!( + test_bytes_G, + "3G", + 3*1024*1024*1024 +); +test_byte_parser!( + test_bytes_Gi, + "3GiB", + 3*1024*1024*1024 +); + +test_byte_parser!( + test_bytes_TB, + "4TB", + 4*1000*1000*1000*1000 +); +test_byte_parser!( + test_bytes_T, + "4T", + 4*1024*1024*1024*1024 +); +test_byte_parser!( + test_bytes_Ti, + "4TiB", + 4*1024*1024*1024*1024 +); + +test_byte_parser!( + test_bytes_PB, + "5PB", + 5*1000*1000*1000*1000*1000 +); +test_byte_parser!( + test_bytes_P, + "5P", + 5*1024*1024*1024*1024*1024 +); +test_byte_parser!( + test_bytes_Pi, + "5PiB", + 5*1024*1024*1024*1024*1024 +); + +test_byte_parser!( + test_bytes_EB, + "6EB", + 6*1000*1000*1000*1000*1000*1000 +); +test_byte_parser!( + test_bytes_E, + "6E", + 6*1024*1024*1024*1024*1024*1024 +); +test_byte_parser!( + test_bytes_Ei, + "6EiB", + 6*1024*1024*1024*1024*1024*1024 +); + +#[test] +#[should_panic] +#[allow(non_snake_case)] +fn test_KB_multiplier_error() +{ + // KB is not valid (kB, K, and KiB are) + let bs_str = String::from("2000KB"); + + parse_bytes_with_opt_multiplier(bs_str).unwrap(); +} + +#[test] +#[should_panic] +fn test_overflow_panic() +{ + let bs_str = format!("{}KiB", usize::MAX); + + parse_bytes_with_opt_multiplier(bs_str).unwrap(); +} + +#[test] +#[should_panic] +fn test_neg_panic() +{ + let bs_str = format!("{}KiB", -1); + + parse_bytes_with_opt_multiplier(bs_str).unwrap(); +}