other: flatten process config struct and clean up help text (#1395)

* refactor: flatten process config field

* other: clean up some doc formatting using indoc and breaklines

* fix broken test

* remove default as that breaks things for now

* add test

* more tests
This commit is contained in:
Clement Tsang 2024-01-21 05:47:13 -05:00 committed by GitHub
parent 975e3d776b
commit 5cf17f6015
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 181 additions and 166 deletions

13
Cargo.lock generated
View File

@ -170,6 +170,7 @@ dependencies = [
"hashbrown", "hashbrown",
"humantime", "humantime",
"indexmap", "indexmap",
"indoc",
"itertools 0.12.0", "itertools 0.12.0",
"kstring", "kstring",
"libc", "libc",
@ -240,18 +241,18 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]] [[package]]
name = "clap" name = "clap"
version = "4.4.16" version = "4.4.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "58e54881c004cec7895b0068a0a954cd5d62da01aef83fa35b1e594497bf5445" checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c"
dependencies = [ dependencies = [
"clap_builder", "clap_builder",
] ]
[[package]] [[package]]
name = "clap_builder" name = "clap_builder"
version = "4.4.16" version = "4.4.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59cb82d7f531603d2fd1f507441cdd35184fa81beff7bd489570de7f773460bb" checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7"
dependencies = [ dependencies = [
"anstream", "anstream",
"anstyle", "anstyle",
@ -262,9 +263,9 @@ dependencies = [
[[package]] [[package]]
name = "clap_complete" name = "clap_complete"
version = "4.4.6" version = "4.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97aeaa95557bd02f23fbb662f981670c3d20c5a26e69f7354b28f57092437fcd" checksum = "eaf7dcb7c21d8ca1a2482ee0f1d341f437c9a7af6ca6da359dc5e1b164e98215"
dependencies = [ dependencies = [
"clap", "clap",
] ]

View File

@ -75,7 +75,7 @@ default = ["deploy"]
anyhow = "1.0.79" anyhow = "1.0.79"
backtrace = "0.3.69" backtrace = "0.3.69"
cfg-if = "1.0.0" cfg-if = "1.0.0"
clap = { version = "4.4.16", features = ["default", "cargo", "wrap_help"] } clap = { version = "4.4.18", features = ["default", "cargo", "wrap_help"] }
concat-string = "1.0.1" concat-string = "1.0.1"
crossterm = "0.27.0" crossterm = "0.27.0"
ctrlc = { version = "3.4.2", features = ["termination"] } ctrlc = { version = "3.4.2", features = ["termination"] }
@ -85,6 +85,7 @@ fern = { version = "0.6.2", optional = true }
hashbrown = "0.14.3" hashbrown = "0.14.3"
humantime = "2.1.0" humantime = "2.1.0"
indexmap = "2.1.0" indexmap = "2.1.0"
indoc = "2.0.4"
itertools = "0.12.0" itertools = "0.12.0"
kstring = { version = "2.0.0", features = ["arc"] } kstring = { version = "2.0.0", features = ["arc"] }
log = { version = "0.4.20", optional = true } log = { version = "0.4.20", optional = true }
@ -139,11 +140,12 @@ predicates = "3.0.4"
portable-pty = "0.8.1" portable-pty = "0.8.1"
[build-dependencies] [build-dependencies]
clap = { version = "4.4.16", features = ["default", "cargo", "wrap_help"] } clap = { version = "4.4.18", features = ["default", "cargo", "wrap_help"] }
clap_complete = "4.4.6" clap_complete = "4.4.8"
clap_complete_fig = "4.4.2" clap_complete_fig = "4.4.2"
clap_complete_nushell = "4.4.2" clap_complete_nushell = "4.4.2"
clap_mangen = "0.2.17" clap_mangen = "0.2.17"
indoc = "2.0.4"
[package.metadata.deb] [package.metadata.deb]
section = "utility" section = "utility"

View File

@ -147,6 +147,21 @@ The following are supported strings:
mod test { mod test {
use super::*; use super::*;
#[test]
fn general_str_to_colour() {
assert_eq!(str_to_colour("red").unwrap(), Color::Red);
assert!(str_to_colour("r ed").is_err());
assert_eq!(str_to_colour("#ffffff").unwrap(), Color::Rgb(255, 255, 255));
assert!(str_to_colour("#fff fff").is_err());
assert_eq!(
str_to_colour("255, 255, 255").unwrap(),
Color::Rgb(255, 255, 255)
);
assert!(str_to_colour("255, 256, 255").is_err());
}
#[test] #[test]
fn invalid_colour_names() { fn invalid_colour_names() {
// Test invalid spacing in single word. // Test invalid spacing in single word.
@ -265,4 +280,21 @@ mod test {
assert!(convert_hex_to_color("#हिन्दी").is_err()); assert!(convert_hex_to_color("#हिन्दी").is_err());
} }
#[test]
fn test_rgb_colours() {
assert_eq!(
convert_rgb_to_color("0, 0, 0").unwrap(),
Color::Rgb(0, 0, 0)
);
assert_eq!(
convert_rgb_to_color("255, 255, 255").unwrap(),
Color::Rgb(255, 255, 255)
);
assert!(convert_rgb_to_color("255, 256, 255").is_err());
assert!(convert_rgb_to_color("256, 0, 256").is_err());
assert!(convert_rgb_to_color("1, -1, 1").is_err());
assert!(convert_rgb_to_color("1, -100000, 1").is_err());
assert!(convert_rgb_to_color("1, -100000, 100000").is_err());
}
} }

View File

@ -112,10 +112,7 @@ pub fn init_app(
let network_use_binary_prefix = is_flag_enabled!(network_use_binary_prefix, matches, config); let network_use_binary_prefix = is_flag_enabled!(network_use_binary_prefix, matches, config);
let proc_columns: Option<IndexSet<ProcWidgetColumn>> = { let proc_columns: Option<IndexSet<ProcWidgetColumn>> = {
let columns = config let columns = config.processes.as_ref().map(|cfg| cfg.columns.clone());
.processes
.as_ref()
.and_then(|cfg| cfg.columns.clone());
match columns { match columns {
Some(columns) => { Some(columns) => {
@ -410,8 +407,6 @@ pub fn get_widget_layout(
// Confirm that we have at least ONE widget left - if not, error out! // Confirm that we have at least ONE widget left - if not, error out!
if iter_id > 0 { if iter_id > 0 {
ret_bottom_layout.get_movement_mappings(); ret_bottom_layout.get_movement_mappings();
// debug!("Bottom layout: {ret_bottom_layout:#?}");
ret_bottom_layout ret_bottom_layout
} else { } else {
return Err(BottomError::ConfigError( return Err(BottomError::ConfigError(

View File

@ -3,80 +3,12 @@
//! Note that you probably want to keep this as a single file so the build script doesn't //! Note that you probably want to keep this as a single file so the build script doesn't
//! trip all over itself. //! trip all over itself.
// TODO: New sections are misaligned! See if we can get that fixed.
use std::cmp::Ordering; use std::cmp::Ordering;
use clap::{builder::PossibleValuesParser, *}; use clap::*;
use indoc::indoc;
const DEFAULT_WIDGET_TYPE_STR: &str = {
#[cfg(feature = "battery")]
{
"\
Sets which widget type to use as the default widget.
For the default layout, this defaults to the 'process' widget.
For a custom layout, it defaults to the first widget it sees.
For example, suppose we have a layout that looks like:
+-------------------+-----------------------+
| CPU (1) | CPU (2) |
+---------+---------+-------------+---------+
| Process | CPU (3) | Temperature | CPU (4) |
+---------+---------+-------------+---------+
Setting '--default_widget_type Temp' will make the Temperature
widget selected by default.
Supported widget names:
+--------------------------+
| cpu |
+--------------------------+
| mem, memory |
+--------------------------+
| net, network |
+--------------------------+
| proc, process, processes |
+--------------------------+
| temp, temperature |
+--------------------------+
| disk |
+--------------------------+
| batt, battery |
+--------------------------+
"
}
#[cfg(not(feature = "battery"))]
{
"\
Sets which widget type to use as the default widget.
For the default layout, this defaults to the 'process' widget.
For a custom layout, it defaults to the first widget it sees.
For example, suppose we have a layout that looks like:
+-------------------+-----------------------+
| CPU (1) | CPU (2) |
+---------+---------+-------------+---------+
| Process | CPU (3) | Temperature | CPU (4) |
+---------+---------+-------------+---------+
Setting '--default_widget_type Temp' will make the Temperature
widget selected by default.
Supported widget names:
+--------------------------+
| cpu |
+--------------------------+
| mem, memory |
+--------------------------+
| net, network |
+--------------------------+
| proc, process, processes |
+--------------------------+
| temp, temperature |
+--------------------------+
| disk |
+--------------------------+
"
}
};
pub fn get_matches() -> ArgMatches { pub fn get_matches() -> ArgMatches {
build_app().get_matches() build_app().get_matches()
@ -175,16 +107,22 @@ fn general_args(cmd: Command) -> Command {
.action(ArgAction::Set) .action(ArgAction::Set)
.value_name("CONFIG PATH") .value_name("CONFIG PATH")
.help("Sets the location of the config file.") .help("Sets the location of the config file.")
.long_help("Sets the location of the config file. Expects a config file in the TOML format. If it doesn't exist, one is created.") .long_help(
"Sets the location of the config file. Expects a config file in the TOML format.\
If it doesn't exist, one is created.",
)
.value_hint(ValueHint::AnyPath); .value_hint(ValueHint::AnyPath);
let default_time_value = Arg::new("default_time_value") let default_time_value = Arg::new("default_time_value")
.short('t') .short('t')
.long("default_time_value") .long("default_time_value")
.action(ArgAction::Set) .action(ArgAction::Set)
.value_name("TIME") .value_name("TIME")
.help("Default time value for graphs.") .help("Default time value for graphs.")
.long_help("Default time value for graphs. Takes a number in milliseconds or a human duration (e.g. 60s). The minimum time is 30s, and the default is 60s."); .long_help(
"Default time value for graphs. Takes a number in milliseconds or a human \
duration (e.g. 60s). The minimum time is 30s, and the default is 60s.",
);
// TODO: Charts are broken in the manpage // TODO: Charts are broken in the manpage
let default_widget_count = Arg::new("default_widget_count") let default_widget_count = Arg::new("default_widget_count")
@ -193,39 +131,71 @@ fn general_args(cmd: Command) -> Command {
.requires_all(["default_widget_type"]) .requires_all(["default_widget_type"])
.value_name("INT") .value_name("INT")
.help("Sets the n'th selected widget type as the default.") .help("Sets the n'th selected widget type as the default.")
.long_help( .long_help(indoc! {
"\ "Sets the n'th selected widget type to use as the default widget.
Sets the n'th selected widget type to use as the default widget. Requires 'default_widget_type' to also be set, and defaults to 1.
Requires 'default_widget_type' to also be set, and defaults to 1.
This reads from left to right, top to bottom. For example, suppose This reads from left to right, top to bottom. For example, suppose
we have a layout that looks like: we have a layout that looks like:
+-------------------+-----------------------+ +-------------------+-----------------------+
| CPU (1) | CPU (2) | | CPU (1) | CPU (2) |
+---------+---------+-------------+---------+ +---------+---------+-------------+---------+
| Process | CPU (3) | Temperature | CPU (4) | | Process | CPU (3) | Temperature | CPU (4) |
+---------+---------+-------------+---------+ +---------+---------+-------------+---------+
And we set our default widget type to 'CPU'. If we set And we set our default widget type to 'CPU'. If we set
'--default_widget_count 1', then it would use the CPU (1) as '--default_widget_count 1', then it would use the CPU (1) as
the default widget. If we set '--default_widget_count 3', it would the default widget. If we set '--default_widget_count 3', it would
use CPU (3) as the default instead. use CPU (3) as the default instead."
", });
);
let default_widget_type = Arg::new("default_widget_type") let default_widget_type = Arg::new("default_widget_type")
.long("default_widget_type") .long("default_widget_type")
.action(ArgAction::Set) .action(ArgAction::Set)
.value_name("WIDGET TYPE") .value_name("WIDGET TYPE")
.help("Sets the default widget type, use --help for info.") .help("Sets the default widget type, use --help for info.")
.long_help(DEFAULT_WIDGET_TYPE_STR); .long_help(indoc!{
"Sets which widget type to use as the default widget. For the default \
layout, this defaults to the 'process' widget. For a custom layout, it defaults \
to the first widget it sees.
For example, suppose we have a layout that looks like:
+-------------------+-----------------------+
| CPU (1) | CPU (2) |
+---------+---------+-------------+---------+
| Process | CPU (3) | Temperature | CPU (4) |
+---------+---------+-------------+---------+
Setting '--default_widget_type Temp' will make the temperature widget selected by default."
})
.value_parser([
"cpu",
"mem",
"net",
"network",
"proc",
"process",
"processes",
"temp",
"temperature",
"disk",
#[cfg(not(feature = "battery"))]
"batt",
#[cfg(not(feature = "battery"))]
"battery",
]);
let expanded_on_startup = Arg::new("expanded_on_startup") let expanded_on_startup = Arg::new("expanded_on_startup")
.short('e') .short('e')
.long("expanded") .long("expanded")
.action(ArgAction::SetTrue) .action(ArgAction::SetTrue)
.help("Expand the default widget upon starting the app.") .help("Expand the default widget upon starting the app.")
.long_help("Expand the default widget upon starting the app. Same as pressing \"e\" inside the app. Use with \"default_widget_type\" and \"default_widget_count\" to select desired expanded widget. This flag has no effect in basic mode (--basic)."); .long_help(
"Expand the default widget upon starting the app. \
Same as pressing \"e\" inside the app. Use with \"default_widget_type\" \
and \"default_widget_count\" to select the desired expanded widget. This \
flag has no effect in basic mode (--basic).",
);
let rate = Arg::new("rate") let rate = Arg::new("rate")
.short('r') .short('r')
@ -233,7 +203,11 @@ use CPU (3) as the default instead.
.action(ArgAction::Set) .action(ArgAction::Set)
.value_name("TIME") .value_name("TIME")
.help("Sets the data refresh rate.") .help("Sets the data refresh rate.")
.long_help("Sets the data refresh rate. Takes a number in milliseconds or a human duration (e.g. 5s). The minimum is 250ms, and defaults to 1000ms. Smaller values may take more computer resources."); .long_help(
"Sets the data refresh rate. Takes a number in milliseconds or a human\
duration (e.g. 5s). The minimum is 250ms, and defaults to 1000ms. Smaller \
values may take more computer resources.",
);
let time_delta = Arg::new("time_delta") let time_delta = Arg::new("time_delta")
.short('d') .short('d')
@ -241,14 +215,23 @@ use CPU (3) as the default instead.
.action(ArgAction::Set) .action(ArgAction::Set)
.value_name("TIME") .value_name("TIME")
.help("The amount of time changed upon zooming.") .help("The amount of time changed upon zooming.")
.long_help("The amount of time changed when zooming in/out. Takes a number in milliseconds or a human duration (e.g. 30s). The minimum is 1s, and defaults to 15s."); .long_help(
"The amount of time changed when zooming in/out. Takes a number in \
milliseconds or a human duration (e.g. 30s). The minimum is 1s, and \
defaults to 15s.",
);
// TODO: Unify how we do defaults.
let retention = Arg::new("retention") let retention = Arg::new("retention")
.long("retention") .long("retention")
.action(ArgAction::Set) .action(ArgAction::Set)
.value_name("TIME") .value_name("TIME")
.help("The timespan of data stored.") .help("The timespan of data stored.")
.long_help("How much data is stored at once in terms of time. Takes a number in milliseconds or a human duration (e.g. 20m), with a minimum of 1 minute. Note higher values will take up more memory. Defaults to 10 minutes."); .long_help(
"How much data is stored at once in terms of time. Takes a number \
in milliseconds or a human duration (e.g. 20m), with a minimum of 1 minute. \
Note that higher values will take up more memory. Defaults to 10 minutes.",
);
cmd.args(args![ cmd.args(args![
autohide_time, autohide_time,
@ -278,35 +261,28 @@ fn style_args(cmd: Command) -> Command {
.long("color") .long("color")
.action(ArgAction::Set) .action(ArgAction::Set)
.value_name("COLOR SCHEME") .value_name("COLOR SCHEME")
.value_parser(PossibleValuesParser::new([ .value_parser([
"default", "default",
"default-light", "default-light",
"gruvbox", "gruvbox",
"gruvbox-light", "gruvbox-light",
"nord", "nord",
"nord-light", "nord-light",
])) ])
.hide_possible_values(true) .hide_possible_values(true)
.help("Use a color scheme, use --help for info.") .help(
.long_help( "Use a color scheme, use --help for info on the colors. \
"\ [possible values: default, default-light, gruvbox, gruvbox-light, nord, nord-light]",
Use a pre-defined color scheme. Currently supported values are: )
+------------------------------------------------------------+ .long_help(indoc! {
| default | "Use a pre-defined color scheme. Currently supported values are:
+------------------------------------------------------------+ - default
| default-light (default but for use with light backgrounds) | - default-light (default but adjusted for lighter backgrounds)
+------------------------------------------------------------+ - gruvbox (a bright theme with 'retro groove' colors)
| gruvbox (a bright theme with 'retro groove' colors) | - gruvbox-light (gruvbox but adjusted for lighter backgrounds)
+------------------------------------------------------------+ - nord (an arctic, north-bluish color palette)
| gruvbox-light (gruvbox but for use with light backgrounds) | - nord-light (nord but adjusted for lighter backgrounds)"
+------------------------------------------------------------+ });
| nord (an arctic, north-bluish color palette) |
+------------------------------------------------------------+
| nord-light (nord but for use with light backgrounds) |
+------------------------------------------------------------+
Defaults to \"default\".
",
);
cmd.arg(color) cmd.arg(color)
} }
@ -358,14 +334,20 @@ fn process_args(cmd: Command) -> Command {
.long("current_usage") .long("current_usage")
.action(ArgAction::SetTrue) .action(ArgAction::SetTrue)
.help("Sets process CPU% to be based on current CPU%.") .help("Sets process CPU% to be based on current CPU%.")
.long_help("Sets process CPU% usage to be based on the current system CPU% usage rather than total CPU usage."); .long_help(
"Sets process CPU% usage to be based on the current system CPU% usage rather \
than total CPU usage.",
);
let unnormalized_cpu = Arg::new("unnormalized_cpu") let unnormalized_cpu = Arg::new("unnormalized_cpu")
.short('n') .short('n')
.long("unnormalized_cpu") .long("unnormalized_cpu")
.action(ArgAction::SetTrue) .action(ArgAction::SetTrue)
.help("Show process CPU% usage without normalizing over the number of cores.") .help("Show process CPU% usage without normalizing over the number of cores.")
.long_help("Shows all process CPU% usage without averaging over the number of CPU cores in the system."); .long_help(
"Shows all process CPU% usage without averaging over the number of CPU cores \
in the system.",
);
let group_processes = Arg::new("group_processes") let group_processes = Arg::new("group_processes")
.short('g') .short('g')
@ -391,7 +373,10 @@ fn process_args(cmd: Command) -> Command {
.long("disable_advanced_kill") .long("disable_advanced_kill")
.action(ArgAction::SetTrue) .action(ArgAction::SetTrue)
.help("Hides advanced process killing.") .help("Hides advanced process killing.")
.long_help("Hides advanced options to stop a process on Unix-like systems. The only option shown is 15 (TERM)."); .long_help(
"Hides advanced options to stop a process on Unix-like systems. The only \
option shown is 15 (TERM).",
);
let whole_word = Arg::new("whole_word") let whole_word = Arg::new("whole_word")
.short('W') .short('W')
@ -446,7 +431,10 @@ fn mem_args(cmd: Command) -> Command {
.long("mem_as_value") .long("mem_as_value")
.action(ArgAction::SetTrue) .action(ArgAction::SetTrue)
.help("Defaults to showing process memory usage by value.") .help("Defaults to showing process memory usage by value.")
.long_help("Defaults to showing process memory usage by value. Otherwise, it defaults to showing it by percentage."); .long_help(
"Defaults to showing process memory usage by value. Otherwise, it defaults \
to showing it by percentage.",
);
#[cfg(not(target_os = "windows"))] #[cfg(not(target_os = "windows"))]
{ {
@ -466,11 +454,15 @@ fn mem_args(cmd: Command) -> Command {
fn network_args(cmd: Command) -> Command { fn network_args(cmd: Command) -> Command {
let cmd = cmd.next_help_heading("Network Options"); let cmd = cmd.next_help_heading("Network Options");
// TODO: Change this to be configured as network graph type?
let use_old_network_legend = Arg::new("use_old_network_legend") let use_old_network_legend = Arg::new("use_old_network_legend")
.long("use_old_network_legend") .long("use_old_network_legend")
.action(ArgAction::SetTrue) .action(ArgAction::SetTrue)
.help("DEPRECATED - uses a separate network legend.") .help("DEPRECATED - uses a separate network legend.")
.long_help("DEPRECATED - uses an older (pre-0.4), separate network widget legend. This display is not tested anymore and may be broken."); .long_help(
"DEPRECATED - uses an older (pre-0.4), separate network widget legend. This \
display is not tested anymore and may be broken.",
);
let network_use_bytes = Arg::new("network_use_bytes") let network_use_bytes = Arg::new("network_use_bytes")
.long("network_use_bytes") .long("network_use_bytes")
@ -488,7 +480,10 @@ fn network_args(cmd: Command) -> Command {
.long("network_use_binary_prefix") .long("network_use_binary_prefix")
.action(ArgAction::SetTrue) .action(ArgAction::SetTrue)
.help("Displays the network widget with binary prefixes.") .help("Displays the network widget with binary prefixes.")
.long_help("Displays the network widget with binary prefixes (i.e. kibibits, mebibits) rather than a decimal prefix (i.e. kilobits, megabits). Defaults to decimal prefixes."); .long_help(
"Displays the network widget with binary prefixes (i.e. kibibits, mebibits) \
rather than a decimal prefix (i.e. kilobits, megabits). Defaults to decimal prefixes.",
);
cmd.args(args![ cmd.args(args![
use_old_network_legend, use_old_network_legend,
@ -595,7 +590,8 @@ mod test {
assert!( assert!(
!help_str.to_string().contains("\nOptions:\n"), !help_str.to_string().contains("\nOptions:\n"),
"the default 'Options' heading should not exist; if it does then an argument is missing a help heading." "the default 'Options' heading should not exist; if it does then an argument is \
missing a help heading."
); );
} }
} }

View File

@ -5,7 +5,8 @@ use crate::widgets::ProcWidgetColumn;
/// Process column settings. /// Process column settings.
#[derive(Clone, Debug, Default, Deserialize)] #[derive(Clone, Debug, Default, Deserialize)]
pub struct ProcessConfig { pub struct ProcessConfig {
pub columns: Option<Vec<ProcWidgetColumn>>, #[serde(default)]
pub columns: Vec<ProcWidgetColumn>,
} }
#[cfg(test)] #[cfg(test)]
@ -17,7 +18,7 @@ mod test {
fn empty_column_setting() { fn empty_column_setting() {
let config = ""; let config = "";
let generated: ProcessConfig = toml_edit::de::from_str(config).unwrap(); let generated: ProcessConfig = toml_edit::de::from_str(config).unwrap();
assert!(generated.columns.is_none()); assert!(generated.columns.is_empty());
} }
#[test] #[test]
@ -29,7 +30,7 @@ mod test {
let generated: ProcessConfig = toml_edit::de::from_str(config).unwrap(); let generated: ProcessConfig = toml_edit::de::from_str(config).unwrap();
assert_eq!( assert_eq!(
generated.columns, generated.columns,
Some(vec![ vec![
ProcWidgetColumn::Cpu, ProcWidgetColumn::Cpu,
ProcWidgetColumn::PidOrCount, ProcWidgetColumn::PidOrCount,
ProcWidgetColumn::User, ProcWidgetColumn::User,
@ -41,7 +42,7 @@ mod test {
ProcWidgetColumn::Time, ProcWidgetColumn::Time,
ProcWidgetColumn::User, ProcWidgetColumn::User,
ProcWidgetColumn::State, ProcWidgetColumn::State,
]), ],
); );
} }
@ -55,30 +56,18 @@ mod test {
fn process_column_settings_3() { fn process_column_settings_3() {
let config = r#"columns = ["Twrite", "T.Write"]"#; let config = r#"columns = ["Twrite", "T.Write"]"#;
let generated: ProcessConfig = toml_edit::de::from_str(config).unwrap(); let generated: ProcessConfig = toml_edit::de::from_str(config).unwrap();
assert_eq!( assert_eq!(generated.columns, vec![ProcWidgetColumn::TotalWrite; 2]);
generated.columns,
Some(vec![ProcWidgetColumn::TotalWrite; 2])
);
let config = r#"columns = ["Tread", "T.read"]"#; let config = r#"columns = ["Tread", "T.read"]"#;
let generated: ProcessConfig = toml_edit::de::from_str(config).unwrap(); let generated: ProcessConfig = toml_edit::de::from_str(config).unwrap();
assert_eq!( assert_eq!(generated.columns, vec![ProcWidgetColumn::TotalRead; 2]);
generated.columns,
Some(vec![ProcWidgetColumn::TotalRead; 2])
);
let config = r#"columns = ["read", "rps", "r/s"]"#; let config = r#"columns = ["read", "rps", "r/s"]"#;
let generated: ProcessConfig = toml_edit::de::from_str(config).unwrap(); let generated: ProcessConfig = toml_edit::de::from_str(config).unwrap();
assert_eq!( assert_eq!(generated.columns, vec![ProcWidgetColumn::ReadPerSecond; 3]);
generated.columns,
Some(vec![ProcWidgetColumn::ReadPerSecond; 3])
);
let config = r#"columns = ["write", "wps", "w/s"]"#; let config = r#"columns = ["write", "wps", "w/s"]"#;
let generated: ProcessConfig = toml_edit::de::from_str(config).unwrap(); let generated: ProcessConfig = toml_edit::de::from_str(config).unwrap();
assert_eq!( assert_eq!(generated.columns, vec![ProcWidgetColumn::WritePerSecond; 3]);
generated.columns,
Some(vec![ProcWidgetColumn::WritePerSecond; 3])
);
} }
} }

View File

@ -109,7 +109,7 @@ fn test_invalid_default_widget_1() {
.arg("fake_widget") .arg("fake_widget")
.assert() .assert()
.failure() .failure()
.stderr(predicate::str::contains("invalid widget name")); .stderr(predicate::str::contains("invalid value"));
} }
#[test] #[test]