test(integration): 跨端验收补两类契约边界(不可用模型 / 场景 config 缺字段)
正常路径之外的**字段边界**同样只在跨端跑起来才暴露。配合 Web v0.7.5 增加:
1. 不可用模型:用 Assimp 把真实 PMX 转成 GLB 后入库(等价"管线只产出 GLB"),
Web 侧断言 usable=false、原因准确(骨架达标时不得说"humanoid 不达标")、
不在 catalog/export、defaultModelId 不变;Windows 侧(包内探针)断言
bundle.models 里没有任何非 VRM 模型、按 id 找不到该模型、defaultModelId 仍指向可用 VRM。
2. 场景 config 只给 {physics:{gravity:{y:-9.8}}}:Web 侧断言服务端补齐默认
(碰撞体 auto、地面 0.6/45°、静风、相机 follow、环境光 1、出生点 1 条);
Windows 侧断言客户端解析出的**同一组默认值**逐项一致。
实测(Web v0.7.5 × Windows v0.2.5 包内 pck,真实 MySQL):
✓ usable=false 且原因为「未产出 VRM(格式为 GLB;humanoid 覆盖 19/22 已达标)…」
✓ 目录里的模型全是 VRM/不可用模型 #2 不在目录里/defaultModelId 仍为 1
✓ 最简配置:重力 -9.8 保留,碰撞体 auto、地面 0.6/45°、静风、相机 follow、
环境光 1.0、出生点 1 条,两端逐项一致
跨端集成验收全部通过。
顺带修掉播种脚本自身的顺序错误(把依赖 catalog 的断言插到了 catalog 取回之前),
以及把断言改成「先取目录再断言」。不影响发布产物(build/ 已排除出 pck)。
This commit is contained in:
@@ -245,6 +245,45 @@ func _run() -> void:
|
||||
else:
|
||||
_fail("动作缩略图下载失败:%s" % thumb["error"])
|
||||
|
||||
# ---------- 5b. ② 目录边界:不可用模型不得出现在客户端目录里(①)----------
|
||||
var nonVrm: Array = []
|
||||
for m in models:
|
||||
if str(m.format) != "vrm":
|
||||
nonVrm.append("%s(%s)" % [m.name, m.format])
|
||||
_check(nonVrm.is_empty(),
|
||||
"目录里的模型全是 VRM(不可用模型不进目录):%s" % ("OK" if nonVrm.is_empty() else str(nonVrm)))
|
||||
if _expect.has("unusableModelId") and _expect["unusableModelId"] != null:
|
||||
var unusable_id := int(_expect["unusableModelId"])
|
||||
_check(bundle.find_model(unusable_id) == null,
|
||||
"不可用模型 #%d 不在客户端目录里" % unusable_id)
|
||||
_check(bundle.default_model_id == _expect["modelId"],
|
||||
"defaultModelId 仍指向可用的 VRM 模型(实际 %d)" % bundle.default_model_id)
|
||||
|
||||
# ---------- 5c. ④ 场景 config 缺字段时的默认值(契约 0.5.0 边界)----------
|
||||
if _expect.has("minimalSceneId") and _expect.has("minimalSceneExpect"):
|
||||
var minimal: CatalogTypes.Scene = bundle.find_scene(int(_expect["minimalSceneId"]))
|
||||
if minimal == null:
|
||||
_fail("目录里找不到最简配置场景 #%d" % int(_expect["minimalSceneId"]))
|
||||
else:
|
||||
var want_min: Dictionary = _expect["minimalSceneExpect"]
|
||||
var cfg2: CatalogTypes.SceneConfig = minimal.config
|
||||
_check(_near(cfg2.physics.gravity.y, float(want_min["gravityY"])),
|
||||
"最简配置:重力保留 %.1f" % cfg2.physics.gravity.y)
|
||||
_check(cfg2.physics.colliders == str(want_min["colliders"]),
|
||||
"最简配置:碰撞体补默认 %s" % cfg2.physics.colliders)
|
||||
_check(_near(cfg2.physics.ground.friction, float(want_min["groundFriction"]))
|
||||
and _near(cfg2.physics.ground.slope_limit, float(want_min["groundSlopeLimit"])),
|
||||
"最简配置:地面默认 摩擦 %.2f / 坡度 %.0f°" % [
|
||||
cfg2.physics.ground.friction, cfg2.physics.ground.slope_limit])
|
||||
_check(cfg2.physics.wind.is_calm() == bool(want_min["windCalm"]),
|
||||
"最简配置:风默认静风(is_calm=%s)" % str(cfg2.physics.wind.is_calm()))
|
||||
_check(cfg2.camera.mode == str(want_min["cameraMode"]),
|
||||
"最简配置:相机默认 %s" % cfg2.camera.mode)
|
||||
_check(_near(cfg2.environment.ambient_intensity, float(want_min["ambientIntensity"])),
|
||||
"最简配置:环境光默认 %.1f" % cfg2.environment.ambient_intensity)
|
||||
_check(cfg2.spawn_points.size() <= 1,
|
||||
"最简配置:出生点默认最多一条(实际 %d)" % cfg2.spawn_points.size())
|
||||
|
||||
# ---------- 6. ① 模型资源可下载 ----------
|
||||
var model: CatalogTypes.Model = bundle.find_model(_expect["modelId"])
|
||||
if model == null:
|
||||
|
||||
Reference in New Issue
Block a user