gitignore-template-generator 0.3.11

A binary crate to generate templates for .gitignore files
Documentation
use std::ffi::OsString;

pub use crate::parser::impls::DefaultArgsParser;
use crate::{ProgramError, config::Args};

pub trait ArgsParser {
    fn parse(args: impl IntoIterator<Item = OsString>) -> Args;
    fn try_parse(
        args: impl IntoIterator<Item = OsString>,
    ) -> Result<Args, ProgramError>;
}

#[cfg(test)]
mod tests {
    use rstest::*;

    use super::*;
    use crate::helper::*;

    mod default_args_parser {
        use super::*;

        mod try_parse {
            use super::*;

            mod success {
                use crate::{ErrorKind, constant};

                use super::*;

                #[rstest]
                #[case("-V")]
                #[case("--version")]
                #[case("-V rust")]
                #[case("rust -V")]
                #[case("rust -s foo -V")]
                #[case("-aV")]
                fn it_parses_version_cli_option(#[case] cli_args: &str) {
                    let cli_args = parse_cli_args(cli_args);
                    let parsed_args = DefaultArgsParser::try_parse(cli_args);

                    let actual_error = parsed_args.as_ref().err();
                    let expected_error = ProgramError {
                        message: format!(
                            "{} {}",
                            env!("CARGO_PKG_NAME"),
                            env!("CARGO_PKG_VERSION")
                        ),
                        exit_status: 0,
                        styled_message: None,
                        error_kind: ErrorKind::VersionInfos,
                    };
                    let expected_error = Some(&expected_error);

                    assert!(actual_error.is_some());
                    assert_eq!(actual_error, expected_error);
                }

                #[rstest]
                #[case("-h")]
                #[case("--help")]
                #[case("-h rust")]
                #[case("rust -h")]
                #[case("rust -s foo -h")]
                #[case("-aVh")]
                fn it_parses_help_cli_option(#[case] cli_args: &str) {
                    let cli_args = parse_cli_args(cli_args);
                    let parsed_args = DefaultArgsParser::try_parse(cli_args);

                    let actual_error = parsed_args.as_ref().err();
                    let expected_error = ProgramError {
                        message: get_help_message(),
                        exit_status: 0,
                        styled_message: Some(get_ansi_help_message()),
                        error_kind: ErrorKind::HelpInfos,
                    };
                    let expected_error = Some(&expected_error);

                    assert!(actual_error.is_some());
                    assert_eq!(actual_error, expected_error);
                }

                #[rstest]
                #[case("-a")]
                #[case("--author")]
                #[case("-a rust")]
                #[case("rust -a")]
                #[case("rust -s foo -a")]
                fn it_parses_author_cli_option_preemptively(
                    #[case] cli_args: &str,
                ) {
                    let cli_args = parse_cli_args(cli_args);
                    let parsed_args = DefaultArgsParser::try_parse(cli_args);

                    let actual_error = parsed_args.as_ref().err();
                    let expected_error = ProgramError {
                        message: env!("CARGO_PKG_AUTHORS").to_string(),
                        exit_status: 0,
                        styled_message: None,
                        error_kind: ErrorKind::AuthorInfos,
                    };
                    let expected_error = Some(&expected_error);

                    assert!(actual_error.is_some());
                    assert_eq!(actual_error, expected_error);
                }

                #[rstest]
                #[case("rust")]
                #[case("rust python node")]
                fn it_parses_pos_args_without_server_url_cli_option(
                    #[case] cli_options: &str,
                ) {
                    let cli_args = parse_cli_args(cli_options);
                    let parsed_args = DefaultArgsParser::try_parse(cli_args);

                    let actual_result = parsed_args.as_ref().ok();
                    let expected_result = Args::default()
                        .with_template_names(make_string_vec(cli_options))
                        .with_server_url(
                            constant::template_generator::BASE_URL,
                        );
                    let expected_result = Some(&expected_result);

                    assert!(actual_result.is_some());
                    assert_eq!(actual_result, expected_result);
                }

                #[rstest]
                #[case("rust -s https://test.com")]
                #[case("rust --server-url https://test.com")]
                fn it_parses_pos_args_with_server_url_cli_option(
                    #[case] cli_args: &str,
                ) {
                    let cli_args = parse_cli_args(cli_args);
                    let parsed_args = DefaultArgsParser::try_parse(cli_args);

                    let actual_result = parsed_args.as_ref().ok();
                    let expected_result = Args::default()
                        .with_template_names(make_string_vec("rust"))
                        .with_server_url("https://test.com");
                    let expected_result = Some(&expected_result);

                    assert!(actual_result.is_some());
                    assert_eq!(actual_result, expected_result);
                }
            }

            mod failure {
                use crate::{ErrorKind, constant};

                use super::*;

                #[test]
                fn it_fails_parsing_when_no_pos_args_given() {
                    let cli_args = parse_cli_args("");
                    let parsed_args = DefaultArgsParser::try_parse(cli_args);

                    let actual_error = parsed_args.as_ref().err();
                    let expected_error = ProgramError {
                        message: load_expectation_file_as_string(
                            "no_pos_args_error",
                        ),
                        exit_status: constant::exit_status::GENERIC,

                        styled_message: Some(load_expectation_file_as_string(
                            "ansi_no_pos_args_error",
                        )),
                        error_kind: ErrorKind::Other,
                    };
                    let expected_error = Some(&expected_error);

                    assert!(actual_error.is_some());
                    assert_eq!(actual_error, expected_error);
                }

                #[test]
                fn it_fails_parsing_when_commas_in_pos_args() {
                    let cli_args = parse_cli_args("python,java");
                    let parsed_args = DefaultArgsParser::try_parse(cli_args);

                    let actual_error = parsed_args.as_ref().err();
                    let expected_error = ProgramError {
                        message: load_expectation_file_as_string(
                            "comma_pos_args_error",
                        ),
                        exit_status: constant::exit_status::GENERIC,

                        styled_message: Some(load_expectation_file_as_string(
                            "ansi_comma_pos_args_error",
                        )),
                        error_kind: ErrorKind::Other,
                    };
                    let expected_error = Some(&expected_error);

                    assert!(actual_error.is_some());
                    assert_eq!(actual_error, expected_error);
                }

                #[test]
                fn it_fails_parsing_when_server_url_but_no_pos_args() {
                    let cli_args = parse_cli_args("-s https://test.com");
                    let parsed_args = DefaultArgsParser::try_parse(cli_args);

                    let actual_error = parsed_args.as_ref().err();
                    let expected_error = ProgramError {
                        message: load_expectation_file_as_string(
                            "server_url_no_pos_args_error",
                        ),
                        exit_status: constant::exit_status::GENERIC,

                        styled_message: Some(load_expectation_file_as_string(
                            "ansi_server_url_no_pos_args_error",
                        )),
                        error_kind: ErrorKind::Other,
                    };
                    let expected_error = Some(&expected_error);

                    assert!(actual_error.is_some());
                    assert_eq!(actual_error, expected_error);
                }

                #[test]
                fn it_fails_parsing_when_inexistent_cli_option() {
                    let cli_args = parse_cli_args("-x");
                    let parsed_args = DefaultArgsParser::try_parse(cli_args);

                    let actual_error = parsed_args.as_ref().err();
                    let expected_error = ProgramError {
                        message: load_expectation_file_as_string(
                            "unexpected_argument_error",
                        ),
                        exit_status: constant::exit_status::GENERIC,
                        styled_message: Some(load_expectation_file_as_string(
                            "ansi_unexpected_argument_error",
                        )),
                        error_kind: ErrorKind::Other,
                    };
                    let expected_error = Some(&expected_error);

                    assert!(actual_error.is_some());
                    assert_eq!(actual_error, expected_error);
                }
            }
        }
    }
}