use alef_core::config::NewAlefConfig;
use alef_e2e::codegen::E2eCodegen;
use alef_e2e::codegen::java::JavaCodegen;
use alef_e2e::fixture::{Assertion, Fixture, FixtureGroup, MockResponse};
use std::collections::HashMap;
fn make_smoke_fixture(id: &str) -> Fixture {
Fixture {
id: id.to_string(),
category: Some("smoke".to_string()),
description: "basic chat smoke test".to_string(),
tags: Vec::new(),
skip: None,
env: None,
call: None,
input: serde_json::json!({
"request": {
"model": "gpt-4o",
"messages": [{"role": "user", "content": "hi"}]
}
}),
mock_response: Some(MockResponse {
status: 200,
body: Some(serde_json::json!({"id": "chatcmpl-1", "object": "chat.completion", "choices": []})),
stream_chunks: None,
headers: HashMap::new(),
}),
visitor: None,
assertions: vec![Assertion {
assertion_type: "not_error".to_string(),
field: None,
value: None,
values: None,
method: None,
check: None,
args: None,
return_type: None,
}],
source: "smoke.json".to_string(),
http: None,
}
}
const TOML: &str = r#"
[workspace]
languages = ["java"]
[[crates]]
name = "liter-llm"
sources = ["src/lib.rs"]
[crates.java]
package = "dev.kreuzberg.literllm"
[crates.e2e]
fixtures = "fixtures"
output = "e2e"
java_group_id = "dev.kreuzberg"
[crates.e2e.call]
function = "chat"
module = "LiterLlm"
result_var = "result"
returns_result = true
[crates.e2e.call.overrides.java]
class = "LiterLlm"
function = "chat"
options_type = "ChatCompletionRequest"
[[crates.e2e.call.args]]
name = "request"
field = "input.request"
type = "json_object"
"#;
fn render_java_smoke(fixture_id: &str) -> String {
let cfg: NewAlefConfig = toml::from_str(TOML).expect("config parses");
let resolved = cfg.clone().resolve().expect("config resolves").remove(0);
let e2e = cfg.crates[0].e2e.clone().expect("e2e config present");
let groups = vec![FixtureGroup {
category: "smoke".to_string(),
fixtures: vec![make_smoke_fixture(fixture_id)],
}];
let files = JavaCodegen
.generate(&groups, &e2e, &resolved, &[], &[])
.expect("generation succeeds");
files
.iter()
.find(|f| {
let p = f.path.to_string_lossy();
p.contains("SmokeTest.java")
})
.expect("SmokeTest.java is emitted")
.content
.clone()
}
#[test]
fn from_json_arg_emits_json_util_from_json() {
let rendered = render_java_smoke("smoke_basic");
assert!(
rendered.contains("JsonUtil.fromJson("),
"must use JsonUtil.fromJson(...) for deserialization. Rendered:\n{rendered}"
);
assert!(
!rendered.contains("ChatCompletionRequest.fromJson("),
"must NOT emit per-DTO ChatCompletionRequest.fromJson(...) calls. Rendered:\n{rendered}"
);
assert!(
rendered.contains("ChatCompletionRequest.class"),
"must pass the target class as the second argument. Rendered:\n{rendered}"
);
}
#[test]
fn from_json_arg_imports_json_util() {
let rendered = render_java_smoke("smoke_basic");
assert!(
rendered.contains("import dev.kreuzberg.literllm.JsonUtil;"),
"must import JsonUtil from the binding package. Rendered:\n{rendered}"
);
}