other: add test to make sure default config is valid (#1552)

This commit is contained in:
Clement Tsang 2024-08-08 01:36:42 +00:00 committed by GitHub
parent 4c8367225a
commit cf47cb9fae
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 50 additions and 42 deletions

View file

@ -261,11 +261,11 @@ pub const DEFAULT_BATTERY_LAYOUT: &str = r#"
// Config and flags // Config and flags
// TODO: Eventually deprecate this, or grab from a file. // TODO: Eventually deprecate this, or grab from a file.
pub const CONFIG_TEXT: &str = r#"# This is a default config file for bottom. All of the settings are commented pub const CONFIG_TEXT: &str = r#"# This is a default config file for bottom. All of the settings are commented
# out by default; if you wish to change them uncomment and modify as you see # out by default; if you wish to change them uncomment and modify as you see
# fit. # fit.
# This group of options represents a command-line option. Flags explicitly # This group of options represents a command-line option. Flags explicitly
# added when running (ie: btm -a) will override this config file if an option # added when running (ie: btm -a) will override this config file if an option
# is also set here. # is also set here.
[flags] [flags]
@ -340,9 +340,9 @@ pub const CONFIG_TEXT: &str = r#"# This is a default config file for bottom. Al
# How much data is stored at once in terms of time. # How much data is stored at once in terms of time.
#retention = "10m" #retention = "10m"
# Where to place the legend for the memory widget. One of "none", "top-left", "top", "top-right", "left", "right", "bottom-left", "bottom", "bottom-right". # Where to place the legend for the memory widget. One of "none", "top-left", "top", "top-right", "left", "right", "bottom-left", "bottom", "bottom-right".
#memory_legend = "TopRight". #memory_legend = "TopRight"
# Where to place the legend for the network widget. One of "none", "top-left", "top", "top-right", "left", "right", "bottom-left", "bottom", "bottom-right". # Where to place the legend for the network widget. One of "none", "top-left", "top", "top-right", "left", "right", "bottom-left", "bottom", "bottom-right".
#network_legend = "TopRight". #network_legend = "TopRight"
# Processes widget configuration # Processes widget configuration
#[processes] #[processes]
@ -484,34 +484,12 @@ pub const CONFIG_TOP_HEAD: &str = r##"# This is bottom's config file.
"##; "##;
pub const CONFIG_DISPLAY_OPTIONS_HEAD: &str = r#"
# These options represent settings that affect how bottom functions.
# If a setting here corresponds to command-line option, then the flag will temporarily override
# the setting.
"#;
pub const CONFIG_COLOUR_HEAD: &str = r#"
# These options represent colour values for various parts of bottom. Note that colour support
# will ultimately depend on the terminal - for example, the Terminal for macOS does NOT like
# custom colours and it may glitch out.
"#;
pub const CONFIG_LAYOUT_HEAD: &str = r#"
# These options represent how bottom will lay out its widgets. Layouts follow a pattern like this:
# [[row]] represents a row in the application.
# [[row.child]] represents either a widget or a column.
# [[row.child.child]] represents a widget.
#
# All widgets must have the valid type value set to one of ["cpu", "mem", "proc", "net", "temp", "disk", "empty"].
# All layout components have a ratio value - if this is not set, then it defaults to 1.
"#;
pub const CONFIG_FILTER_HEAD: &str = r#"
# These options represent disabled entries for the temperature and disk widgets.
"#;
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use regex::Regex;
use crate::options::Config;
use super::*; use super::*;
#[test] #[test]
@ -543,4 +521,22 @@ mod test {
Borders::ALL.difference(Borders::TOP.union(Borders::BOTTOM)) Borders::ALL.difference(Borders::TOP.union(Borders::BOTTOM))
) )
} }
/// Checks that the default config is valid.
#[test]
fn check_default_config() {
let default_config = Regex::new(r"(?m)^#([a-zA-Z\[])")
.unwrap()
.replace_all(CONFIG_TEXT, "$1");
let default_config = Regex::new(r"(?m)^#(\s\s+)([a-zA-Z\[])")
.unwrap()
.replace_all(&default_config, "$2");
let _config: Config =
toml_edit::de::from_str(&default_config).expect("can parse default config");
// TODO: Check this.
// assert_eq!(config, Config::default());
}
} }

View file

@ -24,7 +24,7 @@ use self::{cpu::CpuConfig, layout::Row, process::ProcessesConfig};
derive(schemars::JsonSchema), derive(schemars::JsonSchema),
schemars(title = "Schema for bottom's configs (nightly)") schemars(title = "Schema for bottom's configs (nightly)")
)] )]
#[cfg_attr(test, serde(deny_unknown_fields))] #[cfg_attr(test, serde(deny_unknown_fields), derive(PartialEq, Eq))]
pub struct Config { pub struct Config {
pub(crate) flags: Option<FlagConfig>, pub(crate) flags: Option<FlagConfig>,
pub(crate) styles: Option<StyleConfig>, pub(crate) styles: Option<StyleConfig>,
@ -39,6 +39,7 @@ pub struct Config {
#[derive(Clone, Debug, Deserialize, Serialize)] #[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(untagged)] #[serde(untagged)]
#[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))] #[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))]
#[cfg_attr(test, derive(PartialEq, Eq))]
pub(crate) enum StringOrNum { pub(crate) enum StringOrNum {
String(String), String(String),
Num(u64), Num(u64),

View file

@ -5,6 +5,7 @@ use serde::Deserialize;
#[derive(Clone, Copy, Debug, Default, Deserialize)] #[derive(Clone, Copy, Debug, Default, Deserialize)]
#[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))] #[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))]
#[serde(rename_all = "lowercase")] #[serde(rename_all = "lowercase")]
#[cfg_attr(test, derive(PartialEq, Eq))]
pub enum CpuDefault { pub enum CpuDefault {
#[default] #[default]
All, All,
@ -15,7 +16,7 @@ pub enum CpuDefault {
/// CPU column settings. /// CPU column settings.
#[derive(Clone, Debug, Default, Deserialize)] #[derive(Clone, Debug, Default, Deserialize)]
#[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))] #[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))]
#[cfg_attr(test, serde(deny_unknown_fields))] #[cfg_attr(test, serde(deny_unknown_fields), derive(PartialEq, Eq))]
pub struct CpuConfig { pub struct CpuConfig {
#[serde(default)] #[serde(default)]
pub default: CpuDefault, pub default: CpuDefault,

View file

@ -5,7 +5,7 @@ use super::IgnoreList;
/// Disk configuration. /// Disk configuration.
#[derive(Clone, Debug, Default, Deserialize)] #[derive(Clone, Debug, Default, Deserialize)]
#[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))] #[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))]
#[cfg_attr(test, serde(deny_unknown_fields))] #[cfg_attr(test, serde(deny_unknown_fields), derive(PartialEq, Eq))]
pub struct DiskConfig { pub struct DiskConfig {
/// A filter over the disk names. /// A filter over the disk names.
pub name_filter: Option<IgnoreList>, pub name_filter: Option<IgnoreList>,

View file

@ -4,7 +4,7 @@ use super::StringOrNum;
#[derive(Clone, Debug, Default, Deserialize, Serialize)] #[derive(Clone, Debug, Default, Deserialize, Serialize)]
#[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))] #[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))]
#[cfg_attr(test, serde(deny_unknown_fields))] #[cfg_attr(test, serde(deny_unknown_fields), derive(PartialEq, Eq))]
pub(crate) struct FlagConfig { pub(crate) struct FlagConfig {
pub(crate) hide_avg_cpu: Option<bool>, pub(crate) hide_avg_cpu: Option<bool>,
pub(crate) dot_marker: Option<bool>, pub(crate) dot_marker: Option<bool>,

View file

@ -7,7 +7,7 @@ fn default_as_true() -> bool {
#[derive(Clone, Debug, Default, Deserialize, Serialize)] #[derive(Clone, Debug, Default, Deserialize, Serialize)]
#[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))] #[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))]
#[cfg_attr(test, serde(deny_unknown_fields))] #[cfg_attr(test, serde(deny_unknown_fields), derive(PartialEq, Eq))]
pub struct IgnoreList { pub struct IgnoreList {
#[serde(default = "default_as_true")] #[serde(default = "default_as_true")]
// TODO: Deprecate and/or rename, current name sounds awful. // TODO: Deprecate and/or rename, current name sounds awful.

View file

@ -6,7 +6,7 @@ use crate::{app::layout_manager::*, options::OptionResult};
/// of children. /// of children.
#[derive(Clone, Deserialize, Debug, Serialize)] #[derive(Clone, Deserialize, Debug, Serialize)]
#[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))] #[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))]
#[cfg_attr(test, serde(deny_unknown_fields))] #[cfg_attr(test, serde(deny_unknown_fields), derive(PartialEq, Eq))]
#[serde(rename = "row")] #[serde(rename = "row")]
pub struct Row { pub struct Row {
pub ratio: Option<u32>, pub ratio: Option<u32>,
@ -218,7 +218,7 @@ impl Row {
#[derive(Clone, Deserialize, Debug, Serialize)] #[derive(Clone, Deserialize, Debug, Serialize)]
#[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))] #[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))]
#[serde(untagged)] #[serde(untagged)]
#[cfg_attr(test, serde(deny_unknown_fields))] #[cfg_attr(test, serde(deny_unknown_fields), derive(PartialEq, Eq))]
pub enum RowChildren { pub enum RowChildren {
Widget(FinalWidget), Widget(FinalWidget),
Col { Col {
@ -230,7 +230,7 @@ pub enum RowChildren {
/// Represents a widget. /// Represents a widget.
#[derive(Clone, Deserialize, Debug, Serialize)] #[derive(Clone, Deserialize, Debug, Serialize)]
#[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))] #[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))]
#[cfg_attr(test, serde(deny_unknown_fields))] #[cfg_attr(test, serde(deny_unknown_fields), derive(PartialEq, Eq))]
pub struct FinalWidget { pub struct FinalWidget {
pub ratio: Option<u32>, pub ratio: Option<u32>,
#[serde(rename = "type")] #[serde(rename = "type")]

View file

@ -5,7 +5,7 @@ use super::IgnoreList;
/// Network configuration. /// Network configuration.
#[derive(Clone, Debug, Default, Deserialize)] #[derive(Clone, Debug, Default, Deserialize)]
#[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))] #[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))]
#[cfg_attr(test, serde(deny_unknown_fields))] #[cfg_attr(test, serde(deny_unknown_fields), derive(PartialEq, Eq))]
pub struct NetworkConfig { pub struct NetworkConfig {
/// A filter over the network interface names. /// A filter over the network interface names.
pub interface_filter: Option<IgnoreList>, pub interface_filter: Option<IgnoreList>,

View file

@ -5,7 +5,7 @@ use crate::widgets::ProcWidgetColumn;
/// Process configuration. /// Process configuration.
#[derive(Clone, Debug, Default, Deserialize)] #[derive(Clone, Debug, Default, Deserialize)]
#[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))] #[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))]
#[cfg_attr(test, serde(deny_unknown_fields))] #[cfg_attr(test, serde(deny_unknown_fields), derive(PartialEq, Eq))]
pub struct ProcessesConfig { pub struct ProcessesConfig {
/// A list of process widget columns. /// A list of process widget columns.
#[serde(default)] #[serde(default)]
@ -18,6 +18,7 @@ pub struct ProcessesConfig {
feature = "generate_schema", feature = "generate_schema",
derive(schemars::JsonSchema, strum::VariantArray) derive(schemars::JsonSchema, strum::VariantArray)
)] )]
#[cfg_attr(test, derive(PartialEq, Eq))]
pub enum ProcColumn { pub enum ProcColumn {
Pid, Pid,
Count, Count,

View file

@ -29,13 +29,14 @@ use super::Config;
#[derive(Clone, Debug, Deserialize, Serialize)] #[derive(Clone, Debug, Deserialize, Serialize)]
#[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))] #[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))]
#[cfg_attr(test, derive(PartialEq, Eq))]
pub(crate) struct ColorStr(Cow<'static, str>); pub(crate) struct ColorStr(Cow<'static, str>);
/// A style for text. /// A style for text.
#[derive(Clone, Debug, Deserialize, Serialize)] #[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(untagged)] #[serde(untagged)]
#[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))] #[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))]
#[cfg_attr(test, serde(deny_unknown_fields))] #[cfg_attr(test, serde(deny_unknown_fields), derive(PartialEq, Eq))]
pub(crate) enum TextStyleConfig { pub(crate) enum TextStyleConfig {
Colour(ColorStr), Colour(ColorStr),
TextStyle { TextStyle {
@ -60,6 +61,7 @@ pub(crate) enum TextStyleConfig {
/// Style-related configs. /// Style-related configs.
#[derive(Clone, Debug, Default, Deserialize, Serialize)] #[derive(Clone, Debug, Default, Deserialize, Serialize)]
#[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))] #[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))]
#[cfg_attr(test, serde(deny_unknown_fields), derive(PartialEq, Eq))]
pub(crate) struct StyleConfig { pub(crate) struct StyleConfig {
/// A built-in theme. /// A built-in theme.
/// ///

View file

@ -5,6 +5,7 @@ use super::ColorStr;
/// Styling specific to the battery widget. /// Styling specific to the battery widget.
#[derive(Clone, Debug, Default, Deserialize, Serialize)] #[derive(Clone, Debug, Default, Deserialize, Serialize)]
#[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))] #[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))]
#[cfg_attr(test, serde(deny_unknown_fields), derive(PartialEq, Eq))]
pub(crate) struct BatteryStyle { pub(crate) struct BatteryStyle {
/// The colour of the battery widget bar when the battery is over 50%. /// The colour of the battery widget bar when the battery is over 50%.
#[serde(alias = "high_battery_colour")] #[serde(alias = "high_battery_colour")]

View file

@ -5,6 +5,7 @@ use super::ColorStr;
/// Styling specific to the CPU widget. /// Styling specific to the CPU widget.
#[derive(Clone, Debug, Default, Deserialize, Serialize)] #[derive(Clone, Debug, Default, Deserialize, Serialize)]
#[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))] #[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))]
#[cfg_attr(test, serde(deny_unknown_fields), derive(PartialEq, Eq))]
pub(crate) struct CpuStyle { pub(crate) struct CpuStyle {
/// The colour of the "All" CPU label. /// The colour of the "All" CPU label.
#[serde(alias = "all_entry_colour")] #[serde(alias = "all_entry_colour")]

View file

@ -5,6 +5,7 @@ use super::{ColorStr, TextStyleConfig};
/// General styling for graph widgets. /// General styling for graph widgets.
#[derive(Clone, Debug, Default, Deserialize, Serialize)] #[derive(Clone, Debug, Default, Deserialize, Serialize)]
#[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))] #[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))]
#[cfg_attr(test, serde(deny_unknown_fields), derive(PartialEq, Eq))]
pub(crate) struct GraphStyle { pub(crate) struct GraphStyle {
/// The general colour of the parts of the graph. /// The general colour of the parts of the graph.
#[serde(alias = "graph_colour")] #[serde(alias = "graph_colour")]

View file

@ -6,6 +6,7 @@ use super::ColorStr;
/// Styling specific to the memory widget. /// Styling specific to the memory widget.
#[derive(Clone, Debug, Default, Deserialize, Serialize)] #[derive(Clone, Debug, Default, Deserialize, Serialize)]
#[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))] #[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))]
#[cfg_attr(test, serde(deny_unknown_fields), derive(PartialEq, Eq))]
pub(crate) struct MemoryStyle { pub(crate) struct MemoryStyle {
/// The colour of the RAM label and graph line. /// The colour of the RAM label and graph line.
#[serde(alias = "ram_colour")] #[serde(alias = "ram_colour")]

View file

@ -5,6 +5,7 @@ use super::ColorStr;
/// Styling specific to the network widget. /// Styling specific to the network widget.
#[derive(Clone, Debug, Default, Deserialize, Serialize)] #[derive(Clone, Debug, Default, Deserialize, Serialize)]
#[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))] #[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))]
#[cfg_attr(test, serde(deny_unknown_fields), derive(PartialEq, Eq))]
pub(crate) struct NetworkStyle { pub(crate) struct NetworkStyle {
/// The colour of the RX (download) label and graph line. /// The colour of the RX (download) label and graph line.
#[serde(alias = "rx_colour")] #[serde(alias = "rx_colour")]

View file

@ -5,6 +5,7 @@ use super::TextStyleConfig;
/// General styling for table widgets. /// General styling for table widgets.
#[derive(Clone, Debug, Default, Deserialize, Serialize)] #[derive(Clone, Debug, Default, Deserialize, Serialize)]
#[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))] #[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))]
#[cfg_attr(test, serde(deny_unknown_fields), derive(PartialEq, Eq))]
pub(crate) struct TableStyle { pub(crate) struct TableStyle {
/// Text styling for table headers. /// Text styling for table headers.
pub(crate) headers: Option<TextStyleConfig>, pub(crate) headers: Option<TextStyleConfig>,

View file

@ -5,6 +5,7 @@ use super::{ColorStr, TextStyleConfig};
/// General styling for generic widgets. /// General styling for generic widgets.
#[derive(Clone, Debug, Default, Deserialize, Serialize)] #[derive(Clone, Debug, Default, Deserialize, Serialize)]
#[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))] #[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))]
#[cfg_attr(test, serde(deny_unknown_fields), derive(PartialEq, Eq))]
pub(crate) struct WidgetStyle { pub(crate) struct WidgetStyle {
/// The colour of the widgets' borders. /// The colour of the widgets' borders.
#[serde(alias = "border_colour")] #[serde(alias = "border_colour")]

View file

@ -5,7 +5,7 @@ use super::IgnoreList;
/// Temperature configuration. /// Temperature configuration.
#[derive(Clone, Debug, Default, Deserialize)] #[derive(Clone, Debug, Default, Deserialize)]
#[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))] #[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))]
#[cfg_attr(test, serde(deny_unknown_fields))] #[cfg_attr(test, serde(deny_unknown_fields), derive(PartialEq, Eq))]
pub struct TempConfig { pub struct TempConfig {
/// A filter over the sensor names. /// A filter over the sensor names.
pub sensor_filter: Option<IgnoreList>, pub sensor_filter: Option<IgnoreList>,