use super::*;
#[test]
fn test_render_c_fn_sig_fallible_void_return_is_int32_t_not_void() {
let func = make_function(
"init",
vec![make_param("config", TypeRef::Named("ClientConfig".to_string()), false)],
TypeRef::Unit,
false,
Some("InitError"),
);
let sig = render_c_fn_sig(&func, TEST_PREFIX);
assert_eq!(sig, "int32_t htm_init(HTMAlefHandle config);");
assert!(
!sig.starts_with("void"),
"fallible void-return functions must report a status code: {sig}"
);
}
#[test]
fn test_render_c_fn_sig_infallible_void_return_stays_void() {
let func = make_function("touch", vec![], TypeRef::Unit, false, None);
let sig = render_c_fn_sig(&func, TEST_PREFIX);
assert_eq!(sig, "void htm_touch();");
}
#[test]
fn test_render_c_fn_sig_fallible_non_void_return_is_unaffected() {
let func = make_function(
"parse_document",
vec![make_param("input", TypeRef::String, false)],
TypeRef::Named("ConversionResult".to_string()),
false,
Some("ParseError"),
);
let sig = render_c_fn_sig(&func, TEST_PREFIX);
assert_eq!(sig, "HTMAlefHandle htm_parse_document(const char* input);");
}
#[test]
fn test_render_method_signature_ffi_fallible_void_return_is_int32_t() {
let method = make_method(
"attach",
vec![make_param("config", TypeRef::Named("ClientConfig".to_string()), false)],
TypeRef::Unit,
false,
false,
Some("AttachError"),
);
let sig = render_method_signature(&method, "Client", Language::Ffi, TEST_PREFIX);
assert_eq!(
sig,
"int32_t htm_client_attach(HTMAlefHandle this, HTMAlefHandle config);"
);
}
#[test]
fn test_render_method_signature_ffi_infallible_void_return_stays_void() {
let method = make_method("reset", vec![], TypeRef::Unit, false, false, None);
let sig = render_method_signature(&method, "Client", Language::Ffi, TEST_PREFIX);
assert_eq!(sig, "void htm_client_reset(HTMAlefHandle this);");
}
#[test]
fn test_render_method_signature_ffi_status_code_fix_does_not_leak_to_other_languages() {
let method = make_method("attach", vec![], TypeRef::Unit, false, false, Some("AttachError"));
let python_sig = render_method_signature(&method, "Client", Language::Python, TEST_PREFIX);
assert!(!python_sig.contains("int32_t"), "{python_sig}");
}
#[test]
fn test_render_method_signature_ffi_respects_explicit_return_type_override() {
let method = make_method("attach", vec![], TypeRef::Unit, false, false, Some("AttachError"));
let override_ = MethodSignatureOverride {
return_type: Some("void".to_string()),
..Default::default()
};
let sig = render_method_signature_with_override(
&method,
"Client",
Language::Ffi,
TEST_PREFIX,
TEST_CRATE_NAME,
Some(&override_),
);
assert!(
sig.starts_with("void"),
"an explicit override must win over the status-code inference: {sig}"
);
}
#[test]
fn test_c_signature_and_error_phrase_agree_on_fallible_void_status_value() {
let func = make_function(
"init",
vec![make_param("config", TypeRef::Named("ClientConfig".to_string()), false)],
TypeRef::Unit,
false,
Some("InitError"),
);
let signature = render_function_signature(&func, Language::C, TEST_PREFIX, TEST_CRATE_NAME);
let error_phrase = crate::docs::formatting::format_error_phrase(
func.error_type.as_deref().expect("fallible"),
&func.return_type,
Language::C,
TEST_CRATE_NAME,
);
assert!(signature.starts_with("int32_t "), "signature: {signature}");
assert_eq!(error_phrase, "Returns `-1` on error.");
}
#[test]
fn test_c_signature_and_error_phrase_agree_named_return_uses_integer_not_null() {
let func = make_function(
"parse_document",
vec![make_param("input", TypeRef::String, false)],
TypeRef::Named("ConversionResult".to_string()),
false,
Some("ParseError"),
);
let signature = render_function_signature(&func, Language::C, TEST_PREFIX, TEST_CRATE_NAME);
let error_phrase = crate::docs::formatting::format_error_phrase(
func.error_type.as_deref().expect("fallible"),
&func.return_type,
Language::C,
TEST_CRATE_NAME,
);
assert!(signature.contains("HTMAlefHandle"), "signature: {signature}");
assert!(
!error_phrase.contains("NULL"),
"a scalar handle has no pointer to compare against NULL, so the error phrase must \
not claim one exists just because the signature declares a handle return: {error_phrase}"
);
assert_eq!(error_phrase, "Returns the sentinel handle `0` on error.");
}