Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions crates/impossible-ocr-domain/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,10 @@ pub enum OcrLanguage {
}

/// Caller-controlled OCR behavior within the v0.1 contract.
///
/// Every field is optional on the wire; omitted fields take their [`Default`] values.
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
#[serde(default)]
pub struct OcrOptions {
/// Requested language contract.
pub language: OcrLanguage,
Expand Down
30 changes: 30 additions & 0 deletions crates/impossible-ocr-server/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2214,6 +2214,36 @@ mod tests {
Ok(())
}

#[tokio::test]
async fn partial_json_options_use_defaults_for_omitted_fields()
-> Result<(), Box<dyn std::error::Error>> {
for (options, expected_words) in [
(json!({}), 1),
(json!({"include_words": false}), 0),
(json!({"minimum_confidence": 0.5}), 1),
(json!({"language": "english"}), 1),
] {
let mut request = request_json();
request["options"] = options;
let response = test_server()
.router()
.oneshot(
Request::post(http::OCR_ROUTE)
.header("content-type", "application/json")
.body(Body::from(serde_json::to_vec(&request)?))?,
)
.await?;
assert_eq!(response.status(), StatusCode::OK);
let body: Value =
serde_json::from_slice(&response.into_body().collect().await?.to_bytes())?;
let words = body["result"]["pages"][0]["blocks"][0]["lines"][0]["words"]
.as_array()
.map(Vec::len);
assert_eq!(words, Some(expected_words));
}
Ok(())
}

#[tokio::test]
async fn malformed_oversized_and_poisoned_batches_fail_before_backend()
-> Result<(), Box<dyn std::error::Error>> {
Expand Down
Loading