nu-test-support 0.115.1

Support for writing Nushell tests
Documentation
use std::num::NonZeroUsize;

use kitest::formatter::common::color::ColorSetting;

#[derive(Debug)]
pub struct Args {
    pub color: ColorSetting,
    pub exact: bool,
    pub filter: Vec<String>,
    pub format: Format,
    pub help: bool,
    pub ignored: bool,
    pub include_ignored: bool,
    pub list: bool,
    pub no_capture: bool,
    pub skip: Vec<String>,
    pub test_threads: Option<NonZeroUsize>,
}

#[derive(Debug)]
pub enum Format {
    Pretty,
    Terse,
}

impl Default for Args {
    fn default() -> Self {
        Self {
            color: ColorSetting::Automatic,
            exact: false,
            filter: Vec::new(),
            format: Format::Pretty,
            help: false,
            ignored: false,
            include_ignored: false,
            list: false,
            no_capture: false,
            skip: Vec::new(),
            test_threads: None,
        }
    }
}

impl Args {
    pub fn parse() -> Result<Args, lexopt::Error> {
        use lexopt::prelude::*;

        let mut args = Args::default();
        let mut parser = lexopt::Parser::from_env();

        fn parse_flag(parser: &mut lexopt::Parser, flag: &mut bool) -> Result<(), lexopt::Error> {
            let _: () = match parser.optional_value() {
                None => *flag = true,
                Some(value) => *flag = value.parse()?,
            };
            Ok(())
        }

        while let Some(arg) = parser.next()? {
            match arg {
                Long("color") => {
                    let color = parser.value()?.string()?;
                    match color.as_str() {
                        "auto" | "automatic" => args.color = ColorSetting::Automatic,
                        "always" => args.color = ColorSetting::Always,
                        "never" => args.color = ColorSetting::Never,
                        _ => todo!(),
                    }
                }
                Long("exact") => parse_flag(&mut parser, &mut args.exact)?,
                Value(value) => args.filter.push(value.parse()?),
                Long("format") => {
                    let color: String = parser.value()?.parse()?;
                    match color.as_str() {
                        "pretty" => args.format = Format::Pretty,
                        "terse" => args.format = Format::Terse,
                        _ => todo!(),
                    }
                }
                Long("help") => parse_flag(&mut parser, &mut args.help)?,
                Long("ignored") => parse_flag(&mut parser, &mut args.ignored)?,
                Long("include-ignored") => parse_flag(&mut parser, &mut args.include_ignored)?,
                Long("list") => parse_flag(&mut parser, &mut args.list)?,
                Long("nocapture" | "no-capture") => parse_flag(&mut parser, &mut args.no_capture)?,
                Long("skip") => args.skip.push(parser.value()?.parse()?),
                Long("test-threads") => args.test_threads = Some(parser.value()?.parse()?),
                arg => return Err(arg.unexpected()),
            }
        }

        Ok(args)
    }

    #[rustfmt::skip]
    pub fn help() {
        indoc::printdoc! {r#"
            nu-test-support test harness (kitest based)

            Usage: [OPTIONS] [FILTERS...]

            Arguments:
              [OPTIONS]     Settings that adjust how the test binary runs
              [FILTERS...]  Names or patterns of tests to run

            Options:
              --color <auto|always|never>  Control colored output
              --exact                      Match filters exactly
              --format <pretty|terse>      Choose output style
              --help                       Show this help text
              --ignored                    Run only ignored tests
              --include-ignored            Include ignored tests
              --list                       List tests without running them
              --nocapture                  Print test output directly
              --skip <FILTER>              Skip matching tests, can be used multiple times
              --test-threads <N>           Number of test threads to use, default is {default_thread_count}

            Test Attributes
              #[test]                      Mark a function as a test. Must take no arguments.
              #[should_panic]              Test passes only if it panics.
                                           Can check the panic message with #[should_panic(expected = "foo")].
              #[ignore]                    Skip this test in normal runs. Use --ignored to run it.
              #[exp(option = true|false)]  Set an experimental option for this test.
                                           For the key import an `ExperimentalOption` and set it to
                                           true or false to enable or disable it.
              #[env(KEY = "value")]        Set environment variables for this test.
              #[deps(TESTBIN_MEOW)]        Set a required binary for a test.
                                           The required binary is automatically available to `test()`.
              #[serial]                    Run this test serially, with no other tests at the same time.
            "#, 
            default_thread_count = *super::DEFAULT_THREAD_COUNT
        };
    }
}