Skip to content

Commit 09db62a

Browse files
authored
Test procmacros (#4372)
* Make the procmacros unit testable * Apply Clippy suggestion * unwrap less * Test (at least) the happy path for most procmacros * Increase coverage * More coverage * Address review comments
1 parent 370ad70 commit 09db62a

File tree

11 files changed

+1895
-128
lines changed

11 files changed

+1895
-128
lines changed

esp-hal-procmacros/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ documentation = "https://docs.espressif.com/projects/rust/esp-hal-procmacros/lat
88
repository = "https://github.com/esp-rs/esp-hal"
99
license = "MIT OR Apache-2.0"
1010

11+
exclude = ["testdata"]
12+
1113
[package.metadata.espressif]
1214
doc-config = { features = [] }
1315
check-configs = [

esp-hal-procmacros/src/blocking.rs

Lines changed: 68 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,24 @@
11
#![deny(warnings)]
22

3-
use proc_macro::TokenStream;
4-
use proc_macro2::Span;
3+
use proc_macro2::{Span, TokenStream};
54
use syn::{
65
ItemFn,
76
parse::{self},
8-
parse_macro_input,
97
};
108

119
/// Marks the firmware entry point.
12-
pub fn main(args: TokenStream, input: TokenStream) -> TokenStream {
13-
let f = parse_macro_input!(input as ItemFn);
14-
10+
pub fn main(args: TokenStream, f: ItemFn) -> TokenStream {
1511
if f.sig.asyncness.is_some() {
1612
return parse::Error::new(
1713
Span::call_site(),
1814
"If you want to use `async` please use `esp-rtos`'s `#[esp_rtos::main]` macro instead.",
1915
)
20-
.to_compile_error()
21-
.into();
16+
.to_compile_error();
2217
}
2318

2419
if !args.is_empty() {
2520
return parse::Error::new(Span::call_site(), "This attribute accepts no arguments")
26-
.to_compile_error()
27-
.into();
21+
.to_compile_error();
2822
}
2923

3024
let root = match proc_macro_crate::crate_name("esp-hal") {
@@ -37,5 +31,68 @@ pub fn main(args: TokenStream, input: TokenStream) -> TokenStream {
3731
#[#root::__macro_implementation::__entry]
3832
#f
3933
)
40-
.into()
34+
}
35+
36+
#[cfg(test)]
37+
mod tests {
38+
use super::*;
39+
40+
#[test]
41+
fn test_basic() {
42+
let result = main(
43+
quote::quote! {}.into(),
44+
syn::parse2(quote::quote! {
45+
fn main() {}
46+
})
47+
.unwrap(),
48+
);
49+
50+
assert_eq!(
51+
result.to_string(),
52+
quote::quote! {
53+
#[doc = "The main entry point of the firmware, generated by the `#[main]` macro."]
54+
#[esp_hal::__macro_implementation::__entry]
55+
fn main () { }
56+
}
57+
.to_string()
58+
);
59+
}
60+
61+
#[test]
62+
fn test_try_async() {
63+
let result = main(
64+
quote::quote! {}.into(),
65+
syn::parse2(quote::quote! {
66+
async fn main() {}
67+
})
68+
.unwrap(),
69+
);
70+
71+
assert_eq!(
72+
result.to_string(),
73+
quote::quote! {
74+
::core::compile_error!{ "If you want to use `async` please use `esp-rtos`'s `#[esp_rtos::main]` macro instead." }
75+
}
76+
.to_string()
77+
);
78+
}
79+
80+
#[test]
81+
fn test_try_non_emptyargs() {
82+
let result = main(
83+
quote::quote! {non_empty}.into(),
84+
syn::parse2(quote::quote! {
85+
fn main() {}
86+
})
87+
.unwrap(),
88+
);
89+
90+
assert_eq!(
91+
result.to_string(),
92+
quote::quote! {
93+
::core::compile_error!{ "This attribute accepts no arguments" }
94+
}
95+
.to_string()
96+
);
97+
}
4198
}

0 commit comments

Comments
 (0)