| use proc_macro2::{Ident, Span}; |
| use quote::ToTokens; |
| |
| pub fn escape_test_name(input: impl AsRef<str>) -> Ident { |
| if input.as_ref().is_empty() { |
| return Ident::new("_empty", Span::call_site()); |
| } |
| |
| let mut last_under = false; |
| let mut ident: String = input |
| .as_ref() |
| .to_ascii_lowercase() |
| .chars() |
| .filter_map(|c| match c { |
| c if c.is_alphanumeric() => { |
| last_under = false; |
| Some(c.to_ascii_lowercase()) |
| } |
| _ if !last_under => { |
| last_under = true; |
| Some('_') |
| } |
| _ => None, |
| }) |
| .collect(); |
| |
| if !ident.starts_with(|c: char| c == '_' || c.is_ascii_alphabetic()) { |
| ident = format!("_{}", ident); |
| } |
| |
| Ident::new(&ident, Span::call_site()) |
| } |
| |
| pub fn fmt_syn(syn: &(impl ToTokens + Clone)) -> String { |
| syn.clone().into_token_stream().to_string() |
| } |
| |
| #[cfg(test)] |
| mod tests { |
| use super::*; |
| |
| mod escape_test_name { |
| use super::*; |
| |
| #[test] |
| fn converts_arbitrary_test_names() { |
| assert_eq!( |
| escape_test_name("word"), |
| Ident::new("word", Span::call_site()) |
| ); |
| assert_eq!( |
| escape_test_name("a simple sentence"), |
| Ident::new("a_simple_sentence", Span::call_site()) |
| ); |
| assert_eq!( |
| escape_test_name("extra spaces inbetween"), |
| Ident::new("extra_spaces_inbetween", Span::call_site()) |
| ); |
| assert_eq!( |
| escape_test_name(" extra end and start spaces "), |
| Ident::new("_extra_end_and_start_spaces_", Span::call_site()) |
| ); |
| assert_eq!( |
| escape_test_name("abcdefghijklmnoqprstuwvxyz1234567890"), |
| Ident::new("abcdefghijklmnoqprstuwvxyz1234567890", Span::call_site()) |
| ); |
| } |
| |
| #[test] |
| fn converts_to_lowercase() { |
| assert_eq!( |
| escape_test_name("ALL UPPER"), |
| Ident::new("all_upper", Span::call_site()) |
| ); |
| assert_eq!( |
| escape_test_name("MiXeD CaSe"), |
| Ident::new("mixed_case", Span::call_site()) |
| ); |
| } |
| |
| #[test] |
| fn handles_numeric_first_char() { |
| assert_eq!( |
| escape_test_name("1test"), |
| Ident::new("_1test", Span::call_site()) |
| ); |
| } |
| |
| #[test] |
| fn omits_unicode() { |
| assert_eq!( |
| escape_test_name("fromā¶to"), |
| Ident::new("from_to", Span::call_site()) |
| ); |
| } |
| |
| #[test] |
| fn handles_empty_input() { |
| assert_eq!( |
| escape_test_name(""), |
| Ident::new("_empty", Span::call_site()) |
| ); |
| } |
| } |
| } |