use super::types::gen_options_py;
use crate::core::config::DtoConfig;
use crate::core::ir::{ApiSurface, FieldDef, TypeDef, TypeRef};
const WIDGET: &str = "Widget";
const MODULE_NAME: &str = "_rust";
fn widget_api(type_has_serde: bool) -> ApiSurface {
ApiSurface {
types: vec![TypeDef {
name: WIDGET.to_owned(),
rust_path: format!("sample_core::{WIDGET}"),
has_default: true,
has_serde: type_has_serde,
fields: vec![FieldDef {
name: "label".to_owned(),
ty: TypeRef::String,
..FieldDef::default()
}],
..TypeDef::default()
}],
..ApiSurface::default()
}
}
#[test]
fn gen_options_py_emits_from_json_delegating_to_native_class() {
let api = widget_api(true);
let options_py = gen_options_py(&api, MODULE_NAME, &DtoConfig::default(), &[], true);
assert!(
options_py.contains("def from_json(json_str: str) -> \"Widget\":"),
"options.py must declare a from_json staticmethod on the Widget dataclass:\n{options_py}"
);
assert!(
options_py.contains(&format!(
"_from_native_widget({MODULE_NAME}.Widget.from_json(json_str))"
)),
"from_json must call the native class's from_json and lift the result back through \
the existing _from_native_widget converter, not construct Widget directly:\n{options_py}"
);
assert!(
options_py.contains(&format!("from . import {MODULE_NAME}\n")),
"the native module must be imported by name so from_json can reach {MODULE_NAME}.Widget:\n{options_py}"
);
}
#[test]
fn gen_options_py_omits_from_json_when_type_has_no_serde() {
let api = widget_api(false);
let options_py = gen_options_py(&api, MODULE_NAME, &DtoConfig::default(), &[], true);
assert!(
!options_py.contains("def from_json("),
"a type without core Deserialize must not get a from_json delegate:\n{options_py}"
);
assert!(
!options_py.contains(&format!("from . import {MODULE_NAME}\n")),
"no from_json delegate anywhere in the file means the native-module-alias import must \
not be emitted either -- it would be dead code:\n{options_py}"
);
}
#[test]
fn gen_options_py_omits_from_json_when_crate_has_no_serde() {
let api = widget_api(true);
let options_py = gen_options_py(&api, MODULE_NAME, &DtoConfig::default(), &[], false);
assert!(
!options_py.contains("def from_json("),
"no from_json delegate anywhere when the crate has no serde support:\n{options_py}"
);
}