1use clap::{Parser, ValueEnum};
2
3#[derive(Parser, Debug, Clone, Default)]
13#[command(
14 help_template = "USAGE: [OPTIONS] [FILTER]\n\n{all-args}\n\n\n{after-help}",
15 disable_version_flag = true,
16 after_help = "By default, all tests are run in parallel. This can be altered with the \n\
17 --test-threads flag when running tests (set it to 1).",
18)]
19pub struct Arguments {
20 #[arg(long = "include-ignored", help = "Run ignored tests")]
23 pub include_ignored: bool,
24
25 #[arg(long = "ignored", help = "Run ignored tests")]
27 pub ignored: bool,
28
29 #[arg(
31 long = "test",
32 conflicts_with = "bench",
33 help = "Run tests and not benchmarks",
34 )]
35 pub test: bool,
36
37 #[arg(long = "bench", help = "Run benchmarks instead of tests")]
39 pub bench: bool,
40
41 #[arg(long = "list", help = "List all tests and benchmarks")]
43 pub list: bool,
44
45 #[arg(long = "nocapture", help = "No-op (libtest-mimic always runs in no-capture mode)")]
47 pub nocapture: bool,
48
49 #[arg(long = "show-output")]
51 pub show_output: bool,
52
53 #[arg(short = 'Z')]
55 pub unstable_flags: Option<UnstableFlags>,
56
57 #[arg(
59 long = "exact",
60 help = "Exactly match filters rather than by substring",
61 )]
62 pub exact: bool,
63
64 #[arg(
70 short = 'q',
71 long = "quiet",
72 conflicts_with = "format",
73 help = "Display one character per test instead of one line. Alias to --format=terse",
74 )]
75 pub quiet: bool,
76
77 #[arg(
80 long = "test-threads",
81 help = "Number of threads used for running tests in parallel. If set to 1, \n\
82 all tests are run in the main thread.",
83 )]
84 pub test_threads: Option<usize>,
85
86 #[arg(
89 long = "logfile",
90 value_name = "PATH",
91 help = "Write logs to the specified file instead of stdout",
92 )]
93 pub logfile: Option<String>,
94
95 #[arg(
98 long = "skip",
99 value_name = "FILTER",
100 help = "Skip tests whose names contain FILTER (this flag can be used multiple times)",
101 )]
102 pub skip: Vec<String>,
103
104 #[arg(
106 long = "color",
107 value_enum,
108 value_name = "auto|always|never",
109 help = "Configure coloring of output: \n\
110 - auto = colorize if stdout is a tty and tests are run on serially (default)\n\
111 - always = always colorize output\n\
112 - never = never colorize output\n",
113 )]
114 pub color: Option<ColorSetting>,
115
116 #[arg(
118 long = "format",
119 value_enum,
120 value_name = "pretty|terse|json",
121 help = "Configure formatting of output: \n\
122 - pretty = Print verbose output\n\
123 - terse = Display one character per test\n\
124 - json = Print json events\n",
125 )]
126 pub format: Option<FormatSetting>,
127
128 #[arg(
131 value_name = "FILTER",
132 help = "The FILTER string is tested against the name of all tests, and only those tests \
133 whose names contain the filter are run.",
134 )]
135 pub filter: Option<String>,
136}
137
138impl Arguments {
139 pub fn from_args() -> Self {
145 Parser::parse()
146 }
147
148 pub fn from_iter<I>(iter: I) -> Self
151 where
152 Self: Sized,
153 I: IntoIterator,
154 I::Item: Into<std::ffi::OsString> + Clone,
155 {
156 Parser::parse_from(iter)
157 }
158}
159
160#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
162pub enum ColorSetting {
163 Auto,
166
167 Always,
169
170 Never,
172}
173
174impl Default for ColorSetting {
175 fn default() -> Self {
176 ColorSetting::Auto
177 }
178}
179
180#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
182pub enum UnstableFlags {
183 UnstableOptions,
184}
185
186#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
188pub enum FormatSetting {
189 Pretty,
191
192 Terse,
194
195 Json,
197}
198
199impl Default for FormatSetting {
200 fn default() -> Self {
201 FormatSetting::Pretty
202 }
203}
204
205#[cfg(test)]
206mod tests {
207 use super::*;
208
209 #[test]
210 fn verify_cli() {
211 use clap::CommandFactory;
212 Arguments::command().debug_assert();
213 }
214}