test: Added integration tests for the ValidateTheme macro

This commit is contained in:
2025-03-06 16:00:50 -07:00
parent b012fc29e4
commit 709f6ca6ca
7 changed files with 112 additions and 12 deletions
Generated
+1
View File
@@ -2752,6 +2752,7 @@ dependencies = [
name = "validate_theme_derive" name = "validate_theme_derive"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"log",
"quote", "quote",
"syn 2.0.99", "syn 2.0.99",
] ]
@@ -5,7 +5,7 @@ use darling::FromVariant;
use quote::quote; use quote::quote;
use syn::{Data, DeriveInput, parse_macro_input}; use syn::{Data, DeriveInput, parse_macro_input};
/// Derive macro for the EnumDisplayStyle trait. /// Derive macro for generating a `to_display_str` method for an enum.
/// ///
/// # Example /// # Example
/// ///
@@ -16,13 +16,12 @@ use syn::{Data, DeriveInput, parse_macro_input};
/// ///
/// #[derive(EnumDisplayStyle)] /// #[derive(EnumDisplayStyle)]
/// enum Weekend { /// enum Weekend {
/// Saturday, /// Saturday,
/// Sunday, /// Sunday,
/// } /// }
/// ///
/// assert_eq!(Weekend::Saturday.to_display_str(), "Saturday"); /// assert_eq!(Weekend::Saturday.to_display_str(), "Saturday");
/// assert_eq!(Weekend::Sunday.to_display_str(), "Sunday"); /// assert_eq!(Weekend::Sunday.to_display_str(), "Sunday");
///
/// ``` /// ```
/// ///
/// Using custom values for the display style: /// Using custom values for the display style:
@@ -32,10 +31,10 @@ use syn::{Data, DeriveInput, parse_macro_input};
/// ///
/// #[derive(EnumDisplayStyle)] /// #[derive(EnumDisplayStyle)]
/// enum MonitorStatus { /// enum MonitorStatus {
/// #[display_style(name = "Monitor Transactions")] /// #[display_style(name = "Monitor Transactions")]
/// Active, /// Active,
/// #[display_style(name = "Don't Monitor Transactions")] /// #[display_style(name = "Don't Monitor Transactions")]
/// None, /// None,
/// } /// }
/// ///
/// assert_eq!(MonitorStatus::Active.to_display_str(), "Monitor Transactions"); /// assert_eq!(MonitorStatus::Active.to_display_str(), "Monitor Transactions");
@@ -9,3 +9,6 @@ proc-macro = true
[dependencies] [dependencies]
quote = "1.0.39" quote = "1.0.39"
syn = "2.0.99" syn = "2.0.99"
[dev-dependencies]
log = "0.4.17"
+65 -2
View File
@@ -2,6 +2,69 @@ use proc_macro::TokenStream;
use quote::quote; use quote::quote;
use syn::{parse_macro_input, Data, DeriveInput, Fields}; use syn::{parse_macro_input, Data, DeriveInput, Fields};
/// Derive macro for generating a `validate` method for a Theme struct.
/// The `validate` method ensures that all values with the `validate` attribute are not `None`.
/// Otherwise, an error message it output to both the log file and stdout and the program exits.
///
/// # Example
///
/// Valid themes pass through the program transitively without any messages being output.
///
/// ```
/// use validate_theme_derive::ValidateTheme;
///
/// #[derive(ValidateTheme, Default)]
/// struct Theme {
/// pub name: String,
/// #[validate]
/// pub good: Option<Style>,
/// #[validate]
/// pub bad: Option<Style>,
/// pub ugly: Option<Style>,
/// }
///
/// struct Style {
/// color: String,
/// }
///
/// let theme = Theme {
/// good: Some(Style { color: "Green".to_owned() }),
/// bad: Some(Style { color: "Red".to_owned() }),
/// ..Theme::default()
/// };
///
/// // Since only `good` and `bad` have the `validate` attribute, the `validate` method will only check those fields.
/// theme.validate();
/// // Since both `good` and `bad` have values, the program will not exit and no message is output.
/// ```
///
/// Invalid themes will output an error message to both the log file and stdout and the program will exit.
///
/// ```should_panic
/// use validate_theme_derive::ValidateTheme;
///
/// #[derive(ValidateTheme, Default)]
/// struct Theme {
/// pub name: String,
/// #[validate]
/// pub good: Option<Style>,
/// #[validate]
/// pub bad: Option<Style>,
/// pub ugly: Option<Style>,
/// }
///
/// struct Style {
/// color: String,
/// }
///
/// let theme = Theme {
/// bad: Some(Style { color: "Red".to_owned() }),
/// ..Theme::default()
/// };
///
/// // Since `good` has the `validate` attribute and since `good` is `None`, the `validate` method will output an error message and exit the program.
/// theme.validate();
/// ```
#[proc_macro_derive(ValidateTheme, attributes(validate))] #[proc_macro_derive(ValidateTheme, attributes(validate))]
pub fn derive_validate_theme(input: TokenStream) -> TokenStream { pub fn derive_validate_theme(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput); let input = parse_macro_input!(input as DeriveInput);
@@ -22,8 +85,8 @@ pub fn derive_validate_theme(input: TokenStream) -> TokenStream {
validation_checks.push(quote! { validation_checks.push(quote! {
if self.#field_name.is_none() { if self.#field_name.is_none() {
log::error!("{} is missing a color value.", stringify!(#field_name)); log::error!("{} is missing a color value.", stringify!(#field_name));
eprintln!("{} is missing a color value.", stringify!(#field_name)); eprintln!("{} is missing a color value.", stringify!(#field_name));
process::exit(1); std::process::exit(1);
} }
}) })
} }
-1
View File
@@ -1,4 +1,3 @@
use crate::process;
use anyhow::Result; use anyhow::Result;
use derivative::Derivative; use derivative::Derivative;
use ratatui::style::Color; use ratatui::style::Color;
@@ -8,7 +8,7 @@ fn test_derive_enum_display_style() {
} }
#[derive(EnumDisplayStyle)] #[derive(EnumDisplayStyle)]
pub enum TestEnum { enum TestEnum {
#[display_style(name = "Testing 123")] #[display_style(name = "Testing 123")]
Test, Test,
Ignored, Ignored,
@@ -0,0 +1,35 @@
use validate_theme_derive::ValidateTheme;
#[test]
fn test_validate_theme_derive() {
let theme = Theme {
name: "test".to_string(),
good: Some(Style {
color: "Green".to_owned(),
}),
bad: Some(Style {
color: "Red".to_owned(),
}),
ugly: Some(Style {
color: "Magenta".to_owned(),
}),
};
theme.validate();
}
#[allow(dead_code)]
struct Style {
color: String,
}
#[allow(dead_code)]
#[derive(ValidateTheme)]
struct Theme {
pub name: String,
#[validate]
pub good: Option<Style>,
#[validate]
pub bad: Option<Style>,
pub ugly: Option<Style>,
}