poolster-plugin-java 0.5.0-alpha.1

Native Java SDK generator for Poolster
Documentation
use super::*;

#[test]
fn uses_safe_output_paths_and_deterministic_defaults() {
    assert!(render_test_sdk(&contact_api(), "../escape", None).is_err());
    let tree = render_test_sdk(&contact_api(), "java", None).unwrap();
    assert!(
        tree.get("java/src/main/java/io/poolster/poolsteremailapi/Client.java")
            .is_some()
    );
    assert!(
        tree.get("java/pom.xml")
            .unwrap()
            .contains("<version>2026.09.19</version>")
    );
}

#[test]
fn generates_void_operations_without_decode() {
    let mut api = contact_api();
    api.operations[0].id = "deleteContact".into();
    api.operations[0].responses.clear();
    api.operations[0].request_body = None;
    let tree = render_test_sdk(&api, "java", None).unwrap();
    let client = rendered_java(&tree);
    assert!(client.contains("public void deleteContact(DeleteContactRequest input)"));
    assert!(!client.contains("return decode(response, Void.class)"));
}

#[test]
fn emits_binary_upload_download_and_sse_surfaces() {
    let mut source = contact_api();
    source.operations[0].id = "downloadContact".into();
    source.operations[0].request_body = Some(OperationRequestBody {
        required: true,
        description: None,
        media_types: vec![OperationMediaType {
            content_type: "application/octet-stream".into(),
            schema: Some(string()),
        }],
    });
    source.operations[0].responses = vec![OperationResponse {
        status: "200".into(),
        description: None,
        media_types: vec![OperationMediaType {
            content_type: "application/pdf".into(),
            schema: None,
        }],
    }];
    let mut stream = source.operations[0].clone();
    stream.id = "watchContacts".into();
    stream.request_body = None;
    stream.responses[0].media_types[0].content_type = "text/event-stream".into();
    source.operations.push(stream);
    let tree = render_test_sdk(&source, "java", None).unwrap();
    let client = rendered_java(&tree);
    assert!(client.contains("public byte[] downloadContact(DownloadContactRequest input)"));
    assert!(client.contains("byte[] body"));
    assert!(client.contains("requestBinary"));
    assert!(client.contains("public java.util.stream.Stream<String> watchContacts"));
    assert!(client.contains("requestEventStream"));
    source.operations[0]
        .request_body
        .as_mut()
        .unwrap()
        .media_types[0]
        .content_type = "multipart/form-data".into();
    let multipart = render_test_sdk(&source, "java", None).unwrap();
    assert!(
        multipart
            .iter()
            .any(|(_, source)| source.contains("java.util.List<OrderedMultipart.Part> parts"))
    );
}

#[test]
fn emits_operation_status_errors_with_declared_bodies() {
    let mut source = contact_api();
    source.operations[0].responses.push(OperationResponse {
        status: "404".into(),
        description: None,
        media_types: vec![OperationMediaType {
            content_type: "application/json".into(),
            schema: Some(SchemaValue::reference("#/components/schemas/Contact")),
        }],
    });
    let tree = render_test_sdk(&source, "java", None).unwrap();
    let client = rendered_java(&tree);
    assert!(client.contains("class GetContactStatus404Exception extends ApiException"));
    assert!(client.contains("mapGetContactError(error)"));
    assert!(client.contains("decodeDeclaredError(error.responseBody(), Contact.class)"));
}

#[test]
fn namespaced_style_exports_resource_facades_and_a_style_guide() {
    let tree = render_sdk(
        &contact_api(),
        "java",
        Some("com.poolster.email"),
        SdkClientStyle::Namespaced,
    )
    .unwrap();
    let client = rendered_java(&tree);
    let resource = tree
        .get("java/src/main/java/com/poolster/email/ContactsResource.java")
        .unwrap();
    assert!(client.contains("public ContactsResource contacts() { return contactsResource; }"));
    assert!(resource.contains("extends ContactsResourcePart000"));
    assert!(client.contains("public Contact get(Client.GetContactRequest input)"));
    assert!(client.contains("return client.getContact(input);"));
    assert!(
        tree.get("java/STYLE_GUIDE.md")
            .unwrap()
            .contains("client.contacts().get(input)")
    );
}

#[test]
fn partitions_large_resource_facades_without_changing_the_namespace() {
    let mut source = contact_api();
    let template = source.operations[0].clone();
    source.operations = (0..101)
        .map(|index| {
            let mut operation = template.clone();
            operation.id = format!("getContact{index}");
            operation
        })
        .collect();
    let tree = render_sdk(
        &source,
        "java",
        Some("com.poolster.email"),
        SdkClientStyle::Namespaced,
    )
    .unwrap();
    assert!(tree.iter().any(|(path, _)| {
        path.to_string_lossy()
            .ends_with("ContactsResourcePart001.java")
    }));
    assert!(
        tree.get("java/src/main/java/com/poolster/email/ContactsResource.java")
            .unwrap()
            .contains("extends ContactsResourcePart001")
    );
}

#[test]
fn partitions_verbose_operations_at_sixty_four_methods() {
    let mut source = contact_api();
    let template = source.operations[0].clone();
    source.operations = (0..65)
        .map(|index| {
            let mut operation = template.clone();
            operation.id = format!("getContact{index}");
            operation
        })
        .collect();
    let tree = render_test_sdk(&source, "java", Some("com.poolster.email")).unwrap();
    assert!(
        tree.get("java/src/main/java/com/poolster/email/internal/Operations001.java")
            .is_some()
    );
    assert!(
        tree.get("java/src/main/java/com/poolster/email/Client.java")
            .unwrap()
            .contains("extends com.poolster.email.internal.Operations001")
    );
}

#[test]
fn namespaced_accessor_avoids_a_direct_auth_check_operation_collision() {
    let mut source = contact_api();
    let mut auth_check = source.operations[0].clone();
    auth_check.id = "authCheck".into();
    auth_check.path = "/v1/auth-check".into();
    source.operations.push(auth_check);
    let tree = render_sdk(
        &source,
        "java",
        Some("com.poolster.email"),
        SdkClientStyle::Namespaced,
    )
    .unwrap();
    let client = rendered_java(&tree);
    assert!(client.contains("public ContactsResource contacts()"));
    assert!(client.contains("public AuthCheckResource authCheckResource()"));
    assert!(client.contains("public Contact authCheck(AuthCheckRequest input)"));
    assert!(!client.contains("public AuthCheckResource authCheck()"));
}