1use clap::{Parser, Subcommand};
4
5#[derive(Debug, Parser)]
6#[command(name = "node-headless")]
7#[command(author = "wowlab")]
8#[command(version)]
9#[command(about = "Headless WoW Lab simulation node for servers", long_about = None)]
10pub(crate) struct Cli {
11 #[command(subcommand)]
12 pub(crate) command: Option<Command>,
13
14 #[arg(long, global = true)]
16 pub(crate) no_update: bool,
17}
18
19#[derive(Debug, Eq, PartialEq, Subcommand)]
20pub(crate) enum Command {
21 Update {
23 #[arg(long)]
25 check: bool,
26 },
27 Run,
29}
30
31#[cfg(test)]
32mod tests {
33 use clap::{CommandFactory, error::ErrorKind};
34 use googletest::prelude::*;
35
36 use super::*;
37
38 #[gtest]
39 fn no_subcommand_selects_implicit_run_with_updates_enabled() -> Result<()> {
40 let cli = Cli::try_parse_from(["node-headless"]).or_fail()?;
41
42 verify_that!(cli.command, none())?;
43
44 verify_false!(cli.no_update)
45 }
46
47 #[gtest]
48 fn update_check_is_distinct_from_update_install() -> Result<()> {
49 let check = Cli::try_parse_from(["node-headless", "update", "--check"]).or_fail()?;
50 let install = Cli::try_parse_from(["node-headless", "update"]).or_fail()?;
51
52 verify_that!(check.command, eq(&Some(Command::Update { check: true })))?;
53
54 verify_that!(install.command, eq(&Some(Command::Update { check: false })))
55 }
56
57 #[gtest]
58 fn no_update_is_global_before_or_after_run_subcommand() -> Result<()> {
59 let before = Cli::try_parse_from(["node-headless", "--no-update", "run"]).or_fail()?;
60 let after = Cli::try_parse_from(["node-headless", "run", "--no-update"]).or_fail()?;
61
62 verify_that!(before.command, eq(&Some(Command::Run)))?;
63 verify_true!(before.no_update)?;
64 verify_that!(after.command, eq(&Some(Command::Run)))?;
65
66 verify_true!(after.no_update)
67 }
68
69 #[gtest]
70 fn invalid_subcommand_remains_a_command_line_error() -> Result<()> {
71 let error = Cli::try_parse_from(["node-headless", "unknown"])
72 .err()
73 .or_fail()?;
74
75 verify_that!(error.kind(), eq(ErrorKind::InvalidSubcommand))
76 }
77
78 #[gtest]
79 fn top_level_help_lists_both_commands_and_global_flag() -> Result<()> {
80 let help = Cli::command().render_long_help().to_string();
81
82 verify_that!(
83 help,
84 all!(
85 contains_substring("update Update to the latest version"),
86 contains_substring("run Start the node (default behavior)"),
87 contains_substring("--no-update"),
88 contains_substring("Skip automatic update check on startup")
89 )
90 )
91 }
92}