| use std::process::ExitCode; |
| use std::time::Duration; |
| |
| use test_float_parse as tfp; |
| |
| static HELP: &str = r#"Usage: |
| |
| ./test-float-parse [--timeout x] [--exclude x] [--max-failures x] [INCLUDE ...] |
| ./test-float-parse [--fuzz-count x] [INCLUDE ...] |
| ./test-float-parse [--skip-huge] [INCLUDE ...] |
| ./test-float-parse --list |
| |
| Args: |
| |
| INCLUDE Include only tests with names containing these |
| strings. If this argument is not specified, all tests |
| are run. |
| --timeout N Exit after this amount of time (in seconds). |
| --exclude FILTER Skip tests containing this string. May be specified |
| more than once. |
| --list List available tests. |
| --max-failures N Limit to N failures per test. Defaults to 20. Pass |
| "--max-failures none" to remove this limit. |
| --fuzz-count N Run the fuzzer with N iterations. Only has an effect |
| if fuzz tests are enabled. Pass `--fuzz-count none` |
| to remove this limit. |
| --skip-huge Skip tests that run for a long time. |
| --all Reset previous `--exclude`, `--skip-huge`, and |
| `INCLUDE` arguments (useful for running all tests |
| via `./x`). |
| "#; |
| |
| enum ArgMode { |
| Any, |
| Timeout, |
| Exclude, |
| FuzzCount, |
| MaxFailures, |
| } |
| |
| fn main() -> ExitCode { |
| if cfg!(debug_assertions) { |
| println!( |
| "WARNING: running in debug mode. Release mode is recommended to reduce test duration." |
| ); |
| std::thread::sleep(Duration::from_secs(2)); |
| } |
| |
| let args: Vec<_> = std::env::args().skip(1).collect(); |
| if args.iter().any(|arg| arg == "--help" || arg == "-h") { |
| println!("{HELP}"); |
| return ExitCode::SUCCESS; |
| } |
| |
| if args.iter().any(|arg| arg == "--list") { |
| let tests = tfp::register_tests(&tfp::Config::default()); |
| println!("Available tests:"); |
| for t in tests { |
| println!("{}", t.name); |
| } |
| |
| return ExitCode::SUCCESS; |
| } |
| |
| let (cfg, include, exclude) = parse_args(args); |
| |
| tfp::run(cfg, &include, &exclude) |
| } |
| |
| /// Simple command argument parser |
| fn parse_args(args: Vec<String>) -> (tfp::Config, Vec<String>, Vec<String>) { |
| let mut cfg = tfp::Config::default(); |
| |
| let mut mode = ArgMode::Any; |
| let mut include = Vec::new(); |
| let mut exclude = Vec::new(); |
| |
| for arg in args { |
| mode = match mode { |
| ArgMode::Any if arg == "--timeout" => ArgMode::Timeout, |
| ArgMode::Any if arg == "--exclude" => ArgMode::Exclude, |
| ArgMode::Any if arg == "--max-failures" => ArgMode::MaxFailures, |
| ArgMode::Any if arg == "--fuzz-count" => ArgMode::FuzzCount, |
| ArgMode::Any if arg == "--skip-huge" => { |
| cfg.skip_huge = true; |
| ArgMode::Any |
| } |
| ArgMode::Any if arg == "--all" => { |
| cfg.skip_huge = false; |
| include.clear(); |
| exclude.clear(); |
| ArgMode::Any |
| } |
| ArgMode::Any if arg.starts_with('-') => { |
| panic!("Unknown argument {arg}. Usage:\n{HELP}") |
| } |
| ArgMode::Any => { |
| include.push(arg); |
| ArgMode::Any |
| } |
| ArgMode::Timeout => { |
| cfg.timeout = Duration::from_secs(arg.parse().unwrap()); |
| ArgMode::Any |
| } |
| ArgMode::MaxFailures => { |
| if arg == "none" { |
| cfg.disable_max_failures = true; |
| } else { |
| cfg.max_failures = arg.parse().unwrap(); |
| } |
| ArgMode::Any |
| } |
| ArgMode::FuzzCount => { |
| if arg == "none" { |
| cfg.fuzz_count = Some(u64::MAX); |
| } else { |
| cfg.fuzz_count = Some(arg.parse().unwrap()); |
| } |
| ArgMode::Any |
| } |
| ArgMode::Exclude => { |
| exclude.push(arg); |
| ArgMode::Any |
| } |
| } |
| } |
| |
| (cfg, include, exclude) |
| } |