use super::*;
#[cfg(test)]
#[allow(clippy::too_many_arguments)]
pub(in crate::e2e::codegen::zig) fn render_snippet_body(
fixture: &Fixture,
e2e_config: &E2eConfig,
module_name: &str,
ffi_prefix: &str,
config: &ResolvedCrateConfig,
type_defs: &[crate::core::ir::TypeDef],
enums: &[crate::core::ir::EnumDef],
functions: &[crate::core::ir::FunctionDef],
) -> anyhow::Result<String> {
let session = crate::e2e::codegen::SnippetRenderSession::new(type_defs, enums, functions, &[]);
render_in_session(fixture, e2e_config, module_name, ffi_prefix, config, &session)
}
pub(in crate::e2e::codegen::zig) fn render_in_session(
fixture: &Fixture,
e2e_config: &E2eConfig,
module_name: &str,
ffi_prefix: &str,
config: &ResolvedCrateConfig,
session: &crate::e2e::codegen::SnippetRenderSession<'_>,
) -> anyhow::Result<String> {
let type_defs = session.type_defs();
let call = e2e_config.resolve_call_for_fixture(
fixture.call.as_deref(),
&fixture.id,
&fixture.resolved_category(),
&fixture.tags,
&fixture.input,
);
let result_var = call.effective_result_var();
let expects_error = fixture
.assertions
.iter()
.any(|assertion| assertion.assertion_type == "error");
if call.args.iter().any(|argument| argument.arg_type == "test_backend") {
anyhow::bail!("zig snippet `{}` requires test-backend lifecycle teardown", fixture.id);
}
let mut call_fixture = fixture.clone();
if !expects_error {
call_fixture.assertions.clear();
}
let mut test = String::new();
{
let _span = tracing::trace_span!("snippet_call_body").entered();
render_test_fn(
&mut test,
&call_fixture,
e2e_config,
"",
"",
&[],
module_name,
ffi_prefix,
config,
type_defs,
&[],
false,
true,
crate::e2e::codegen::call_ir::CallIr {
functions: &[],
type_defs,
},
&[],
);
}
let mut bound = false;
let mut body = test
.lines()
.map(|line| {
let line = line.replace(
"else |_| {}",
"else |err| { std.debug.print(\"call failed as expected: {s}\\n\", .{@errorName(err)}); }",
);
if expects_error || call.returns_void || bound {
return line;
}
let Some(discarded) = discarded_call_statement(&line) else {
return line;
};
bound = true;
let indent = &line[..line.len() - line.trim_start().len()];
format!("{indent}const {result_var} = {discarded}")
})
.collect::<Vec<_>>()
.join("\n");
let displays_stream = body.contains("const _stream_handle =");
let binds_typed_result =
!expects_error && !call.returns_void && !displays_stream && !body.contains("const _result_json =");
let presentation = if binds_typed_result {
session.resolve(fixture, e2e_config, "zig")
} else {
Vec::new()
};
if !expects_error && !call.returns_void && !displays_stream && presentation.is_empty() {
let displayed_result = if body.contains("const _result_json =") {
"_result_json"
} else {
result_var
};
let format = if displayed_result == "_result_json" {
"{s}"
} else {
"{any}"
};
if !body.is_empty() && !body.ends_with('\n') {
body.push('\n');
}
body.push_str(&format!(
" std.debug.print(\"{format}\\n\", .{{{displayed_result}}});\n"
));
}
Ok(crate::e2e::template_env::render(
"zig/snippet_body.jinja",
crate::alef_context! { module => module_name, body => body, body_is_indented => true,
presentation => presentation },
))
}