use super::*;
#[test]
fn some_int_literal_unwraps_to_inner_int() {
assert_eq!(
default_value_of("Some(50 * 1024 * 1024)"),
DefaultValue::IntLiteral(52_428_800)
);
}
#[test]
fn some_string_literal_unwraps_to_inner_string() {
assert_eq!(
default_value_of(r#"Some("hi".to_string())"#),
DefaultValue::StringLiteral("hi".to_string())
);
}
#[test]
fn qualified_option_some_unwraps() {
assert_eq!(default_value_of("Option::Some(5)"), DefaultValue::IntLiteral(5));
}
#[test]
fn bare_none_stays_none() {
assert_eq!(default_value_of("None"), DefaultValue::None);
}
#[test]
fn zero_argument_function_call_preserves_its_path() {
assert_eq!(
default_value_of("defaults::retry_limit()"),
DefaultValue::FunctionCall("defaults::retry_limit".to_string())
);
}
#[test]
fn const_to_string_resolves_to_the_consts_literal_value() {
assert_eq!(
default_value_of_with_consts(
"DEFAULT_CATALOG_URL.to_string()",
&[("DEFAULT_CATALOG_URL", "https://example.com/catalog.json")]
),
DefaultValue::StringLiteral("https://example.com/catalog.json".to_string())
);
}
#[test]
fn const_into_resolves_to_the_consts_literal_value() {
assert_eq!(
default_value_of_with_consts("HOST.into()", &[("HOST", "localhost")]),
DefaultValue::StringLiteral("localhost".to_string())
);
}
#[test]
fn bare_const_path_resolves_to_the_consts_literal_value() {
assert_eq!(
default_value_of_with_consts("HOST", &[("HOST", "localhost")]),
DefaultValue::StringLiteral("localhost".to_string())
);
}
#[test]
fn unresolvable_const_reference_is_unresolved_not_empty() {
assert!(
matches!(
default_value_of("UNKNOWN_CONST.to_string()"),
DefaultValue::Unresolved(_)
),
"an unresolvable const reference must be reported, not silently zeroed"
);
}
#[test]
fn collect_literal_consts_collects_every_literal_kind_and_nothing_computed() {
let file: syn::File = syn::parse_str(
r#"
pub const DEFAULT_CATALOG_URL: &str = "https://example.com/catalog.json";
const CACHE_DIR_NAME: &str = "sample-crate";
const RETRY_LIMIT: u32 = 3;
const DET_DB_THRESH: f32 = 0.3;
const VERBOSE: bool = false;
const MIN_OFFSET: i32 = -5;
const COMPUTED: &str = some_fn();
const WINDOW: Duration = Duration::from_secs(5);
"#,
)
.expect("valid file");
let consts = collect_literal_consts(&file.items);
assert_eq!(
consts.get("DEFAULT_CATALOG_URL"),
Some(&DefaultValue::StringLiteral(
"https://example.com/catalog.json".to_string()
))
);
assert_eq!(
consts.get("CACHE_DIR_NAME"),
Some(&DefaultValue::StringLiteral("sample-crate".to_string()))
);
assert_eq!(consts.get("RETRY_LIMIT"), Some(&DefaultValue::IntLiteral(3)));
assert_eq!(consts.get("DET_DB_THRESH"), Some(&DefaultValue::FloatLiteral(0.3)));
assert_eq!(consts.get("VERBOSE"), Some(&DefaultValue::BoolLiteral(false)));
assert_eq!(consts.get("MIN_OFFSET"), Some(&DefaultValue::IntLiteral(-5)));
assert_eq!(
consts.get("COMPUTED"),
None,
"non-literal initializers must not be collected"
);
assert_eq!(
consts.get("WINDOW"),
None,
"evaluating a const-fn initializer would be interpretation, not reading"
);
}
#[test]
fn collect_literal_consts_folds_a_tuple_struct_literal_to_its_inner_scalar() {
let file: syn::File = syn::parse_str(
r#"
impl Weight {
pub const ONE: Weight = Weight(1);
pub const MAX: Weight = Weight(u32::MAX);
}
"#,
)
.expect("valid file");
let consts = collect_literal_consts(&file.items);
assert_eq!(consts.get("Weight::ONE"), Some(&DefaultValue::IntLiteral(1)));
assert_eq!(
consts.get("Weight::MAX"),
None,
"the inner expression `u32::MAX` is not itself a literal; guessing its value is worse \
than leaving the const unindexed"
);
}
#[test]
fn collect_literal_consts_does_not_fold_a_lowercase_call_as_a_tuple_struct_literal() {
let file: syn::File = syn::parse_str(r#"const RETRY_LIMIT: u32 = compute(3);"#).expect("valid file");
let consts = collect_literal_consts(&file.items);
assert_eq!(
consts.get("RETRY_LIMIT"),
None,
"a snake_case call is a function invocation and must not be folded"
);
}