补多视图请求契约的全字段往返用例
- 新增全字段往返:钉住 camelCase 字段名、各枚举线上取值与 Option 的可省略写法 - 新增显式 null 往返:确认可选字段回写时仍是 null 而不是整字段消失 - 补用例后字段改名或可空性漂移会被测试拦住,不再是只在 TS 绑定里可见
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
use serde_json::json;
|
||||
use shared_contracts::model3d::common::Model3dModelVersion;
|
||||
use shared_contracts::model3d::common::{
|
||||
Model3dCompression, Model3dExportOrientation, Model3dGeometryQuality, Model3dInputOrientation,
|
||||
Model3dModelVersion, Model3dTextureAlignment, Model3dTextureQuality, Model3dTextureVersion,
|
||||
};
|
||||
use shared_contracts::model3d::multiview_to_model::{
|
||||
Model3dMultiviewInputs, Model3dMultiviewToModelRequest,
|
||||
};
|
||||
@@ -76,3 +79,137 @@ fn multiview_request_rejects_unknown_top_level_fields() {
|
||||
"未知字段错误应指出 unknown field,实际为:{error}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiview_request_round_trips_every_optional_field() {
|
||||
// 全字段往返:钉住 camelCase 字段名、枚举线上取值与 Option 的可省略写法,
|
||||
// 与生成的 TypeScript 绑定保持一致。
|
||||
let payload = json!({
|
||||
"inputs": {
|
||||
"kind": "views",
|
||||
"front": "front.png",
|
||||
"left": "left.png",
|
||||
"back": "back.png",
|
||||
"right": "right.png"
|
||||
},
|
||||
"model": "v3.1-20260211",
|
||||
"modelSeed": 7,
|
||||
"textureSeed": 8,
|
||||
"texture": true,
|
||||
"pbr": true,
|
||||
"textureQuality": "standard",
|
||||
"textureVersion": "v3.0-20250812",
|
||||
"delight": false,
|
||||
"geometryQuality": "detailed",
|
||||
"textureAlignment": "original_image",
|
||||
"faceLimit": 20_000,
|
||||
"autoSize": false,
|
||||
"orientation": "align_image",
|
||||
"quad": false,
|
||||
"smartLowPoly": true,
|
||||
"generateParts": false,
|
||||
"compress": "geometry",
|
||||
"exportUv": true,
|
||||
"exportOrientation": "-y"
|
||||
});
|
||||
|
||||
let request: Model3dMultiviewToModelRequest =
|
||||
serde_json::from_value(payload.clone()).expect("全字段请求应可反序列化");
|
||||
|
||||
match &request.inputs {
|
||||
Model3dMultiviewInputs::Views {
|
||||
front,
|
||||
left,
|
||||
back,
|
||||
right,
|
||||
} => {
|
||||
assert_eq!(front, "front.png");
|
||||
assert_eq!(left.as_deref(), Some("left.png"));
|
||||
assert_eq!(back.as_deref(), Some("back.png"));
|
||||
assert_eq!(right.as_deref(), Some("right.png"));
|
||||
}
|
||||
Model3dMultiviewInputs::TaskId { .. } => panic!("kind=views 不应解成 taskId 变体"),
|
||||
}
|
||||
assert_eq!(request.model, Model3dModelVersion::H31);
|
||||
assert_eq!(request.model_seed, Some(7));
|
||||
assert_eq!(request.texture_seed, Some(8));
|
||||
assert_eq!(request.texture, Some(true));
|
||||
assert_eq!(request.pbr, Some(true));
|
||||
assert_eq!(
|
||||
request.texture_quality,
|
||||
Some(Model3dTextureQuality::Standard)
|
||||
);
|
||||
assert_eq!(request.texture_version, Some(Model3dTextureVersion::V30));
|
||||
assert_eq!(request.delight, Some(false));
|
||||
assert_eq!(
|
||||
request.geometry_quality,
|
||||
Some(Model3dGeometryQuality::Detailed)
|
||||
);
|
||||
assert_eq!(
|
||||
request.texture_alignment,
|
||||
Some(Model3dTextureAlignment::OriginalImage)
|
||||
);
|
||||
assert_eq!(request.face_limit, Some(20_000));
|
||||
assert_eq!(request.auto_size, Some(false));
|
||||
assert_eq!(
|
||||
request.orientation,
|
||||
Some(Model3dInputOrientation::AlignImage)
|
||||
);
|
||||
assert_eq!(request.quad, Some(false));
|
||||
assert_eq!(request.smart_low_poly, Some(true));
|
||||
assert_eq!(request.generate_parts, Some(false));
|
||||
assert_eq!(request.compress, Some(Model3dCompression::Geometry));
|
||||
assert_eq!(request.export_uv, Some(true));
|
||||
assert_eq!(
|
||||
request.export_orientation,
|
||||
Some(Model3dExportOrientation::MinusY)
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
serde_json::to_value(&request).expect("请求应可回写为 JSON"),
|
||||
payload
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiview_request_round_trips_explicit_nulls() {
|
||||
// 显式 null 是可省略写法之外的另一种合法形态,回写时必须仍是 null 而不是缺字段。
|
||||
let payload = json!({
|
||||
"inputs": { "kind": "taskId", "taskId": "tripo-task-1" },
|
||||
"model": "P2-20260801",
|
||||
"modelSeed": null,
|
||||
"textureSeed": null,
|
||||
"texture": null,
|
||||
"pbr": null,
|
||||
"textureQuality": null,
|
||||
"textureVersion": null,
|
||||
"delight": null,
|
||||
"geometryQuality": null,
|
||||
"textureAlignment": null,
|
||||
"faceLimit": null,
|
||||
"autoSize": null,
|
||||
"orientation": null,
|
||||
"quad": null,
|
||||
"smartLowPoly": null,
|
||||
"generateParts": null,
|
||||
"compress": null,
|
||||
"exportUv": null,
|
||||
"exportOrientation": null
|
||||
});
|
||||
|
||||
let request: Model3dMultiviewToModelRequest =
|
||||
serde_json::from_value(payload.clone()).expect("显式 null 的请求应可反序列化");
|
||||
|
||||
assert!(matches!(
|
||||
request.inputs,
|
||||
Model3dMultiviewInputs::TaskId { .. }
|
||||
));
|
||||
assert_eq!(request.model, Model3dModelVersion::P2);
|
||||
assert_eq!(request.model_seed, None);
|
||||
assert_eq!(request.export_orientation, None);
|
||||
|
||||
assert_eq!(
|
||||
serde_json::to_value(&request).expect("请求应可回写为 JSON"),
|
||||
payload
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user