test: Added integration tests for the ValidateTheme macro
This commit is contained in:
Generated
+1
@@ -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"
|
||||||
|
|||||||
@@ -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,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>,
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user