use super::*;
fn download_manager_new_method() -> crate::core::ir::MethodDef {
make_method(
"new",
vec![make_param("version", TypeRef::String, false)],
TypeRef::Named("DownloadManager".to_string()),
false,
true,
None,
)
}
#[test]
fn test_java_constructor_named_new_is_renamed_to_create_by_the_identifier_gate() {
let sig = render_method_signature(
&download_manager_new_method(),
"DownloadManager",
Language::Java,
TEST_PREFIX,
);
assert!(sig.contains("create"), "{sig}");
assert!(!sig.contains("new"), "{sig}");
}
#[test]
fn test_identifier_gate_still_rejects_a_raw_java_keyword() {
let violation = crate::docs::formatting::check_identifier(
"new",
Language::Java,
crate::docs::formatting::IdentifierPosition::Member,
"a test context",
)
.expect_err("`new` is a Java reserved word in every position");
assert_eq!(violation.reason, "reserved word");
assert!(violation.to_string().contains("member position"), "{violation}");
}
#[test]
fn test_dart_constructor_named_new_is_renamed_to_create_by_the_identifier_gate() {
let name = crate::docs::naming::method_name("DownloadManager", "new", Language::Dart, TEST_PREFIX);
assert_eq!(name, "create");
let sig = render_method_signature(
&download_manager_new_method(),
"DownloadManager",
Language::Dart,
TEST_PREFIX,
);
assert_eq!(sig, "static Future<DownloadManager> create(String version)");
}
#[test]
fn test_identifier_gate_still_rejects_raw_new_in_dart_member_position() {
let violation = crate::docs::formatting::check_identifier(
"new",
Language::Dart,
crate::docs::formatting::IdentifierPosition::Member,
"a test context",
)
.expect_err("`new` is a Dart reserved word in member position");
assert_eq!(violation.reason, "reserved word");
}
#[test]
fn test_swift_constructor_named_new_is_promoted_to_a_real_initializer() {
let sig = render_method_signature(
&download_manager_new_method(),
"DownloadManager",
Language::Swift,
TEST_PREFIX,
);
assert_eq!(sig, "public init(version: String)");
}
#[test]
fn test_identifier_gate_still_rejects_raw_init_in_swift_member_position() {
let violation = crate::docs::formatting::check_identifier(
"init",
Language::Swift,
crate::docs::formatting::IdentifierPosition::Member,
"a test context",
)
.expect_err("`init` is a Swift declaration keyword, not a legal member identifier");
assert_eq!(violation.reason, "reserved word");
}
#[test]
fn test_swift_instance_method_named_new_is_not_promoted_to_an_initializer() {
let method = make_method(
"new",
vec![make_param("version", TypeRef::String, false)],
TypeRef::Named("DownloadManager".to_string()),
false,
false,
None,
);
let sig = render_method_signature(&method, "DownloadManager", Language::Swift, TEST_PREFIX);
assert_eq!(sig, "public func new(version: String) -> DownloadManager");
}
#[test]
fn test_typescript_constructor_named_new_renders_instead_of_aborting_the_docs_run() {
let name = crate::docs::naming::method_name("DownloadManager", "new", Language::Node, TEST_PREFIX);
assert_eq!(name, "new");
assert_eq!(
crate::docs::formatting::check_identifier(
&name,
Language::Node,
crate::docs::formatting::IdentifierPosition::Member,
"a method signature",
),
Ok(())
);
let sig = render_method_signature(
&download_manager_new_method(),
"DownloadManager",
Language::Node,
TEST_PREFIX,
);
assert!(sig.contains("new("), "{sig}");
}
#[test]
fn test_php_constructor_named_new_renders_instead_of_aborting_the_docs_run() {
assert_eq!(
crate::docs::formatting::check_identifier(
"new",
Language::Php,
crate::docs::formatting::IdentifierPosition::Member,
"a method signature",
),
Ok(())
);
let sig = render_method_signature(
&download_manager_new_method(),
"DownloadManager",
Language::Php,
TEST_PREFIX,
);
assert!(sig.contains("new("), "{sig}");
}
#[test]
fn test_go_constructor_named_new_is_not_caught_by_the_identifier_gate() {
let sig = render_method_signature(
&download_manager_new_method(),
"DownloadManager",
Language::Go,
TEST_PREFIX,
);
assert_eq!(sig, "func DownloadManagerNew(version string) *DownloadManager");
}
#[test]
fn test_csharp_constructor_named_new_is_promoted_to_a_real_constructor() {
let sig = render_method_signature(
&download_manager_new_method(),
"DownloadManager",
Language::Csharp,
TEST_PREFIX,
);
assert_eq!(sig, "public DownloadManager(string version)");
}
#[test]
fn test_zig_constructor_named_new_renders_as_a_type_suffixed_free_function() {
let sig = render_method_signature(
&download_manager_new_method(),
"DownloadManager",
Language::Zig,
TEST_PREFIX,
);
assert_eq!(sig, "pub fn new_download_manager(version: []const u8) DownloadManager");
}
#[test]
fn test_elixir_constructor_named_new_is_the_positive_control() {
let sig = render_method_signature(
&download_manager_new_method(),
"DownloadManager",
Language::Elixir,
TEST_PREFIX,
);
assert!(sig.contains("new"), "{sig}");
}
#[test]
fn test_csharp_docs_constructor_predicate_matches_the_backend_predicate() {
use crate::backends::csharp::gen_bindings::types::constructors::is_static_constructor;
let string_param = || vec![make_param("version", TypeRef::String, false)];
let owner = TypeRef::Named("DownloadManager".to_string());
let cases = vec![
("new", string_param(), owner.clone(), true),
("new", vec![], owner.clone(), true),
("new", string_param(), owner.clone(), false),
("new", string_param(), TypeRef::String, true),
("new", string_param(), TypeRef::Named("Other".to_string()), true),
(
"new",
string_param(),
TypeRef::Named("crate::DownloadManager".to_string()),
true,
),
("create", string_param(), owner.clone(), true),
("with_cache_dir", string_param(), owner, true),
];
for (name, params, return_type, is_static) in cases {
let method = make_method(name, params, return_type, false, is_static, None);
assert_eq!(
is_csharp_static_constructor(&method, "DownloadManager"),
is_static_constructor(&method, "DownloadManager"),
"docs and the C# backend disagree about `{name}` (is_static={is_static})"
);
}
}
#[test]
fn test_zig_docs_static_name_matches_the_backend_template() {
let backend = crate::backends::zig::template_env::render(
"opaque_static_signature.jinja",
minijinja::context! {
method_snake => "new",
type_snake => "download_manager",
params => "",
return_ty => "DownloadManager",
},
);
let backend_head = backend
.split('(')
.next()
.expect("template always emits an opening paren");
let sig = render_method_signature(
&download_manager_new_method(),
"DownloadManager",
Language::Zig,
TEST_PREFIX,
);
assert!(
sig.starts_with(&format!("{backend_head}(")),
"docs `{sig}` does not open with the backend's `{backend_head}(`"
);
}
#[test]
fn test_go_docs_signature_and_example_both_match_the_backend_template() {
let backend = crate::backends::go::template_env::render(
"method_signature_static.jinja",
minijinja::context! {
receiver_type => "DownloadManager",
method_name => "New",
params => "",
return_type => "",
},
);
let backend_head = backend
.split('(')
.next()
.expect("template always emits an opening paren")
.trim_start_matches("func ")
.to_string();
let method = download_manager_new_method();
let sig = render_method_signature(&method, "DownloadManager", Language::Go, TEST_PREFIX);
assert!(
sig.starts_with(&format!("func {backend_head}(")),
"docs signature `{sig}` does not name the backend's `{backend_head}`"
);
let example = crate::docs::examples::render_method_example(&method, "DownloadManager", Language::Go, TEST_PREFIX);
assert!(
example.contains(&format!("{backend_head}(\"value\")")),
"docs example must call the package-level `{backend_head}`: {example}"
);
assert!(
!example.contains("DownloadManager.New("),
"docs example still uses member syntax Go has no equivalent for: {example}"
);
}
#[test]
fn test_csharp_docs_example_constructs_with_new() {
let example = crate::docs::examples::render_method_example(
&download_manager_new_method(),
"DownloadManager",
Language::Csharp,
TEST_PREFIX,
);
assert!(example.contains("new DownloadManager(\"value\")"), "{example}");
assert!(!example.contains("DownloadManager.New("), "{example}");
}
#[test]
fn test_zig_docs_example_calls_the_top_level_function() {
let example = crate::docs::examples::render_method_example(
&download_manager_new_method(),
"DownloadManager",
Language::Zig,
TEST_PREFIX,
);
assert!(example.contains("new_download_manager("), "{example}");
assert!(!example.contains("DownloadManager.new("), "{example}");
}
#[test]
fn test_python_free_function_named_global_is_escaped_by_func_name() {
assert_eq!(
crate::docs::naming::func_name("global", Language::Python, TEST_PREFIX),
"global_"
);
let func = crate::docs::test_helpers::make_function("global", vec![], TypeRef::Unit, false, None);
let sig = crate::docs::signatures::render_function_signature(
&func,
Language::Python,
TEST_PREFIX,
TEST_CRATE_NAME,
&crate::core::ir::ApiSurface::default(),
);
assert!(sig.contains("global_"), "{sig}");
assert!(!sig.contains("def global("), "{sig}");
}
#[test]
fn test_dart_instance_method_named_get_is_escaped_by_func_name() {
let name = crate::docs::naming::method_name("Registry", "get", Language::Dart, TEST_PREFIX);
assert_eq!(name, "get_");
let method = make_method(
"get",
vec![make_param("id", TypeRef::String, false)],
TypeRef::Optional(Box::new(TypeRef::Named("Preset".to_string()))),
false,
false,
None,
);
let sig = render_method_signature(&method, "Registry", Language::Dart, TEST_PREFIX);
assert!(sig.contains("get_("), "{sig}");
assert!(!sig.contains(" get("), "{sig}");
}
#[test]
fn test_kotlin_instance_method_named_get_is_escaped_by_func_name() {
assert_eq!(
crate::docs::naming::func_name("get", Language::Kotlin, TEST_PREFIX),
"get_"
);
assert_eq!(
crate::docs::formatting::check_identifier(
"get_",
Language::Kotlin,
crate::docs::formatting::IdentifierPosition::Member,
"a method signature",
),
Ok(())
);
}
#[test]
fn test_generic_reserved_word_sweep_does_not_touch_node_or_php() {
for lang in [Language::Node, Language::Wasm, Language::Php] {
assert_eq!(
crate::docs::naming::func_name("new", lang, TEST_PREFIX),
"new",
"{lang:?} must keep emitting the raw word -- its member-position relaxation depends on it"
);
}
}
#[test]
fn test_generic_reserved_word_sweep_leaves_ordinary_names_untouched() {
for lang in [
Language::Python,
Language::Ruby,
Language::Elixir,
Language::R,
Language::Go,
Language::Csharp,
Language::Kotlin,
Language::KotlinAndroid,
Language::Swift,
Language::Dart,
Language::Gleam,
Language::Zig,
] {
let name = crate::docs::naming::func_name("classify_link", lang, TEST_PREFIX);
assert!(!name.ends_with('_'), "{lang:?}: {name}");
}
}