aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/config.rs73
-rw-r--r--src/func.rs12
-rw-r--r--src/invoke.rs17
3 files changed, 96 insertions, 6 deletions
diff --git a/src/config.rs b/src/config.rs
index 06aa088..5962103 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -22,17 +22,78 @@ fn read_default_feature_name() -> String {
Err(_) => return "async".to_string(),
};
- let value: toml::Value = match content.parse() {
- Ok(v) => v,
- Err(_) => return "async".to_string(),
- };
+ parse_feature_name_from_toml(&content).unwrap_or_else(|| "async".to_string())
+}
+/// Pure function: parse `default_feature_name` from TOML content.
+/// Returns `None` if the key is missing, unreadable, or not a string.
+fn parse_feature_name_from_toml(content: &str) -> Option<String> {
+ let value: toml::Value = content.parse().ok()?;
value
.get("package")
.and_then(|p| p.get("metadata"))
.and_then(|m| m.get("might_be_async"))
.and_then(|a| a.get("default_feature_name"))
.and_then(|v| v.as_str())
- .unwrap_or("async")
- .to_string()
+ .map(|s| s.to_string())
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn parses_custom_feature_name() {
+ let toml = r#"
+ [package]
+ [package.metadata.might_be_async]
+ default_feature_name = "my_async"
+ "#;
+ assert_eq!(
+ parse_feature_name_from_toml(toml),
+ Some("my_async".to_string())
+ );
+ }
+
+ #[test]
+ fn missing_metadata_returns_none() {
+ let toml = "[package]\nname = \"foo\"\n";
+ assert_eq!(parse_feature_name_from_toml(toml), None);
+ }
+
+ #[test]
+ fn missing_might_be_async_section_returns_none() {
+ let toml = r#"
+ [package]
+ [package.metadata]
+ some_other_key = "value"
+ "#;
+ assert_eq!(parse_feature_name_from_toml(toml), None);
+ }
+
+ #[test]
+ fn empty_string_returns_none() {
+ assert_eq!(parse_feature_name_from_toml(""), None);
+ }
+
+ #[test]
+ fn invalid_toml_returns_none() {
+ assert_eq!(parse_feature_name_from_toml("not valid toml {{"), None);
+ }
+
+ #[test]
+ fn value_is_not_string_returns_none() {
+ let toml = r#"
+ [package.metadata.might_be_async]
+ default_feature_name = 42
+ "#;
+ assert_eq!(parse_feature_name_from_toml(toml), None);
+ }
+
+ #[test]
+ fn env_default_returns_foo_async() {
+ // In `cargo test`, CARGO_MANIFEST_DIR is set to this crate's directory,
+ // whose Cargo.toml has `default_feature_name = "foo_async"`.
+ assert_eq!(default_feature_name(), "foo_async");
+ }
}
diff --git a/src/func.rs b/src/func.rs
index 5557992..a502e36 100644
--- a/src/func.rs
+++ b/src/func.rs
@@ -78,4 +78,16 @@ mod tests {
let args: FuncArgs = syn::parse2(input).unwrap();
assert_eq!(args.feature_name, "custom_name");
}
+
+ #[test]
+ fn integer_literal_is_rejected() {
+ let input: proc_macro2::TokenStream = "42".parse().unwrap();
+ assert!(syn::parse2::<FuncArgs>(input).is_err());
+ }
+
+ #[test]
+ fn multiple_args_are_rejected() {
+ let input: proc_macro2::TokenStream = r#""a" "b""#.parse().unwrap();
+ assert!(syn::parse2::<FuncArgs>(input).is_err());
+ }
}
diff --git a/src/invoke.rs b/src/invoke.rs
index f7da20a..2ada0b4 100644
--- a/src/invoke.rs
+++ b/src/invoke.rs
@@ -86,4 +86,21 @@ mod tests {
_ => panic!("expected Explicit variant"),
}
}
+
+ #[test]
+ fn explicit_missing_arrow_is_rejected() {
+ let input: proc_macro2::TokenStream = r#""ft" expr()"#.parse().unwrap();
+ assert!(syn::parse2::<InvokeArgs>(input).is_err());
+ }
+
+ #[test]
+ fn integer_parses_as_default_variant() {
+ // integer literal is not a LitStr, so it falls through to Default variant
+ let input: proc_macro2::TokenStream = "42".parse().unwrap();
+ let args: InvokeArgs = syn::parse2(input).unwrap();
+ match args {
+ InvokeArgs::Default(_) => {} // expected
+ _ => panic!("expected Default variant"),
+ }
+ }
}