1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2026-01-20 04:01:06 +00:00

Testt conv arg parsing.

This commit is contained in:
Tyler 2021-04-21 15:24:14 -07:00
parent 7f7dd2ad4e
commit b461f102cc
4 changed files with 358 additions and 269 deletions

View file

@ -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<ConversionTable>,
ctable: Option<&'static ConversionTable>,
block: bool,
unblock: bool,
swab: bool,

View file

@ -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 {

View file

@ -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<usize, ParseError>
}
}
fn parse_ctable(fmt: Option<ConvFlag>, case: Option<ConvFlag>) -> Option<ConversionTable>
fn parse_ctable(fmt: Option<ConvFlag>, case: Option<ConvFlag>) -> Option<&'static ConversionTable>
{
match (fmt, case)
{
@ -222,17 +231,17 @@ fn parse_ctable(fmt: Option<ConvFlag>, case: Option<ConvFlag>) -> Option<Convers
match (fmt, case)
{
(ConvFlag::FmtAtoE, ConvFlag::UCase) =>
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<ConvFlag>, case: Option<ConvFlag>) -> Option<Convers
match fmt
{
ConvFlag::FmtAtoE =>
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<Vec<ConvFlag>, 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<ConvFlagOutp
fsync,
})
}
#[cfg(test)]
mod test {
use super::*;
// ----- 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("ketchup"),
String::from("mustard"),
String::from("--conv=ibm"),
String::from("relish"),
];
let matches = build_app!().parse(args);
let cfi_parsed = parse_conv_flag_input(&matches).unwrap();
unimplemented!()
// assert_eq!(cfi_expd, cfi_parsed);
}
// ----- 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();
}
}

View file

@ -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();
}