use crate::e2e::codegen::TestBackendEmission;
use crate::e2e::escape::sanitize_ident;
use heck::ToSnakeCase;
use std::fmt::Write as FmtWrite;
pub(super) fn extract_backend_name_from_input(input: &serde_json::Value, fallback: &str) -> String {
if let Some(obj) = input.as_object() {
if let Some(s) = obj.get("name").and_then(|v| v.as_str()) {
return s.to_string();
}
for v in obj.values() {
if let Some(inner) = v.as_object() {
if let Some(s) = inner.get("name").and_then(|v| v.as_str()) {
return s.to_string();
}
}
}
for v in obj.values() {
if let Some(s) = v.as_str() {
return s.to_string();
}
}
}
fallback.to_string()
}
pub fn emit_test_backend(
trait_bridge: &crate::core::config::TraitBridgeConfig,
methods: &[&crate::core::ir::MethodDef],
fixture: &crate::e2e::fixture::Fixture,
) -> TestBackendEmission {
use crate::codegen::defaults::language_defaults;
use crate::core::ir::{PrimitiveType, TypeRef};
let defaults = language_defaults("ruby");
let safe_id = sanitize_ident(&fixture.id);
let backend_name = extract_backend_name_from_input(&fixture.input, &fixture.id);
let var_name = format!("stub_{safe_id}");
let mut setup = String::new();
let _ = writeln!(setup, "{var_name} = Class.new do");
if trait_bridge.super_trait.is_some() {
let _ = writeln!(setup, " def name = '{backend_name}'");
let _ = writeln!(setup, " def initialize");
let _ = writeln!(setup, " nil");
let _ = writeln!(setup, " end");
let _ = writeln!(setup, " def shutdown");
let _ = writeln!(setup, " nil");
let _ = writeln!(setup, " end");
let _ = writeln!(setup, " def version = '1.0.0'");
}
for method in methods.iter().filter(|m| !m.has_default_impl) {
let ruby_name = method.name.to_snake_case();
let params: Vec<String> = method.params.iter().map(|p| sanitize_ident(&p.name)).collect();
let param_str = params.join(", ");
let default_val = match &method.return_type {
TypeRef::Named(_) => "'{}'".to_string(),
TypeRef::Primitive(PrimitiveType::Bool) => "false".to_string(),
TypeRef::Primitive(_) => "1".to_string(),
other => defaults.emit_default(other),
};
if param_str.is_empty() {
let _ = writeln!(setup, " def {ruby_name} = {default_val}");
} else {
let _ = writeln!(setup, " def {ruby_name}({param_str}) = {default_val}");
}
}
let _ = writeln!(setup, "end.new");
TestBackendEmission {
setup_block: setup,
arg_expr: var_name,
type_imports: Vec::new(),
teardown_block: String::new(),
}
}