use heck::{ToLowerCamelCase, ToUpperCamelCase};
use std::fmt::Write as FmtWrite;
use crate::e2e::escape::escape_kotlin;
use crate::e2e::fixture::Assertion;
use super::values::json_to_kotlin;
pub(super) fn parse_discriminated_union_access(field: &str) -> Option<(String, String)> {
let parts: Vec<&str> = field.split('.').collect();
if !(parts.len() == 3 || parts.len() == 4) {
return None;
}
if parts[0] != "metadata" || parts[1] != "format" {
return None;
}
let variant_name = parts[2];
let known_variants = [
"pdf",
"docx",
"excel",
"email",
"pptx",
"archive",
"image",
"xml",
"text",
"html",
"ocr",
"csv",
"bibtex",
"citation",
"fiction_book",
"dbf",
"jats",
"epub",
"pst",
"code",
];
if !known_variants.contains(&variant_name) {
return None;
}
let variant_pascal = variant_name.to_upper_camel_case();
let inner_field = if parts.len() == 4 {
parts[3].to_string()
} else {
String::new()
};
Some((variant_pascal, inner_field))
}
pub(super) fn render_discriminated_union_assertion(
out: &mut String,
assertion: &Assertion,
variant_var: &str,
inner_field: &str,
) {
if inner_field.is_empty() {
return;
}
let field_camel = inner_field.to_lower_camel_case();
let field_expr = format!("{variant_var}.metadata.{field_camel}!!");
match assertion.assertion_type.as_str() {
"equals" => {
if let Some(expected) = &assertion.value {
let kt_val = json_to_kotlin(expected);
if expected.is_string() {
let _ = writeln!(
out,
" assertEquals({kt_val}, {field_expr}.trim(), \"expected: {}\")",
escape_kotlin(expected.as_str().unwrap_or(""))
);
} else if expected.as_bool() == Some(true) {
let _ = writeln!(out, " assertTrue({field_expr}, \"expected true\")");
} else if expected.as_bool() == Some(false) {
let _ = writeln!(out, " assertFalse({field_expr}, \"expected false\")");
} else {
let _ = writeln!(
out,
" assertEquals({kt_val}, {field_expr}, \"expected: {kt_val}\")"
);
}
}
}
"greater_than_or_equal" => {
if let Some(val) = &assertion.value {
let kt_val = json_to_kotlin(val);
let _ = writeln!(
out,
" assertTrue({field_expr} >= {kt_val}, \"expected >= {kt_val}\")"
);
}
}
"less_than_or_equal" => {
if let Some(val) = &assertion.value {
let kt_val = json_to_kotlin(val);
let _ = writeln!(
out,
" assertTrue({field_expr} <= {kt_val}, \"expected <= {kt_val}\")"
);
}
}
"greater_than" => {
if let Some(val) = &assertion.value {
let kt_val = json_to_kotlin(val);
let _ = writeln!(
out,
" assertTrue({field_expr} > {kt_val}, \"expected > {kt_val}\")"
);
}
}
"less_than" => {
if let Some(val) = &assertion.value {
let kt_val = json_to_kotlin(val);
let _ = writeln!(
out,
" assertTrue({field_expr} < {kt_val}, \"expected < {kt_val}\")"
);
}
}
"contains" => {
if let Some(expected) = &assertion.value {
if let Some(s) = expected.as_str() {
let lower = s.to_lowercase();
let _ = writeln!(
out,
" assertTrue({field_expr}.orEmpty().toString().lowercase().contains(\"{}\".lowercase()), \"expected to contain: {}\")",
escape_kotlin(&lower),
escape_kotlin(s)
);
}
}
}
"contains_all" => {
if let Some(values) = &assertion.values {
for val in values {
if let Some(s) = val.as_str() {
let lower = s.to_lowercase();
let _ = writeln!(
out,
" assertTrue({field_expr}.orEmpty().toString().lowercase().contains(\"{}\".lowercase()), \"expected to contain: {}\")",
escape_kotlin(&lower),
escape_kotlin(s)
);
}
}
}
}
"not_empty" => {
let _ = writeln!(
out,
" assertTrue({field_expr}.toString().isNotEmpty(), \"expected non-empty value\")"
);
}
"is_empty" => {
let _ = writeln!(
out,
" assertTrue({field_expr}.toString().isEmpty(), \"expected empty value\")"
);
}
_ => {
let _ = writeln!(
out,
" // skipped: assertion type '{}' not yet supported for discriminated union fields",
assertion.assertion_type
);
}
}
}