Files
modbison/scripts/smoke_test_creator_studio_inspector.gd
daddy 7ecf0d53bd
checkpoint / checkpoint (push) Failing after 3h14m9s
Complete M11 Creator Studio and M12 Trust & Safety for PC5
- Creator Studio: Visual behavior & property inspector, GLB model importer, binary persistence
- Trust & Safety: 18+ TOS confirmation (DOB removed), creator guidelines & briefing card on join, in-game reporting HUD
- Test Harness: Add --filter, --skip-backend, --skip-godot to run_checkpoint_tests.py
2026-09-17 23:13:57 +00:00

153 lines
5.2 KiB
GDScript

extends SceneTree
## Headless smoke test for Creator Studio Visual Property & Behavior Inspector
const FIXTURE_PATH := "res://backend/tests/fixtures/chunks/simple_tile_chunk.bin"
const ChunkEditorModelClass := preload("res://scripts/editor/chunk_editor_model.gd")
const EditorObjectCatalogClass := preload("res://scripts/editor/object_catalog.gd")
const EditorCoreClass := preload("res://scripts/editor/editor_core.gd")
const InspectorPanelClass := preload("res://scripts/editor/ui/inspector_panel.gd")
const StaticObjectNodeClass := preload("res://scripts/static_object_node.gd")
const WorldObjectClass := preload("res://scripts/world_object.gd")
const ChunkDataDecoderClass := preload("res://scripts/chunk_data_decoder.gd")
var passed := 0
var failed := 0
func _check(label: String, cond: bool) -> void:
if cond:
passed += 1
print(" PASS: ", label)
else:
failed += 1
printerr(" FAIL: ", label)
func _initialize() -> void:
await _run()
func _read_fixture() -> PackedByteArray:
var f := FileAccess.open(FIXTURE_PATH, FileAccess.READ)
if f == null:
push_error("Could not open fixture: " + FIXTURE_PATH)
return PackedByteArray()
return f.get_buffer(f.get_length())
func _run() -> void:
print("=== Running Creator Studio Inspector & Behavior Smoke Tests ===")
var root := Node.new()
root.name = "TestRoot"
get_root().add_child(root)
var fixture_bytes := _read_fixture()
_check("Loaded fixture binary bytes", fixture_bytes.size() > 0)
if fixture_bytes.is_empty():
quit(1)
return
var model := ChunkEditorModelClass.from_binary(fixture_bytes)
_check("Decoded ChunkEditorModel from binary", model != null)
var catalog := EditorObjectCatalogClass.new()
var cat_err := catalog.load_catalog()
_check("Loaded EditorObjectCatalog", cat_err == OK)
var core := EditorCoreClass.new(model, catalog)
_check("Initialized EditorCore", core != null)
# 1. Place an object
var obj_id := core.place_object("crate_small", Vector3(1.0, 1.0, 0.0))
_check("Placed object via EditorCore", obj_id != "")
var obj := model.find_object(obj_id)
_check("Object found in model", obj != null)
# 2. Attach and verify InspectorPanel
var inspector := InspectorPanelClass.new()
root.add_child(inspector)
await process_frame
inspector.setup(core)
inspector.show_object(obj_id)
_check("InspectorPanel loaded object view", true)
# 3. Add behavior rules to object
var test_behavior: Dictionary = {
"rules": [
{
"trigger": {"type": "on_interact"},
"conditions": [],
"actions": [
{"verb": "give_item", "item_id": "buffalo_chips", "count": 10}
]
},
{
"trigger": {"type": "on_timer", "interval": 1.5},
"conditions": [],
"actions": [
{"verb": "rotate", "degrees": 90.0, "axis": "y", "duration": 0.4}
]
}
]
}
var set_ok := core.set_object_behavior(obj_id, test_behavior)
_check("set_object_behavior executed via ToolRegistry", set_ok)
_check("Object properties has script_behavior", obj.properties.has("script_behavior"))
var attached = obj.properties.get("script_behavior", {})
_check("Attached behavior contains 2 rules", attached.get("rules", []).size() == 2)
# 4. Undo and Redo verification
var undo_ok := core.undo_redo.undo()
_check("Undo executed successfully", undo_ok)
_check("Undo cleared script_behavior property", not obj.properties.has("script_behavior"))
var redo_ok := core.undo_redo.redo()
_check("Redo executed successfully", redo_ok)
_check("Redo restored script_behavior property", obj.properties.has("script_behavior"))
_check("Redo preserved both rules", obj.properties.get("script_behavior", {}).get("rules", []).size() == 2)
# 5. Roundtrip through Chunk binary encode/decode
var re_encoded := model.encode_binary()
_check("Model encoded to binary bytes with behavior", re_encoded.size() > 0)
var re_decoded := ChunkDataDecoderClass.decode_binary(re_encoded)
_check("Decoded re-encoded binary chunk", re_decoded != null)
var persisted_obj: ChunkDataDecoderClass.WorldObjectData = null
for o in re_decoded.objects:
if o.id == obj_id:
persisted_obj = o
break
_check("Persisted object found in binary decoded chunk", persisted_obj != null)
_check("Persisted object retained script_behavior rules", persisted_obj.properties.has("script_behavior"))
# 6. StaticObjectNode & ScriptInterpreterNode verification
var wo := WorldObjectClass.new()
wo.id = obj.id
wo.type = obj.type
wo.asset_id = obj.asset_id
wo.position = obj.position
wo.rotation = obj.rotation
wo.scale = obj.scale
wo.properties = obj.properties.duplicate(true)
var static_node := StaticObjectNodeClass.new()
static_node.world_object = wo
root.add_child(static_node)
await process_frame
var interpreter := static_node.get_node_or_null("ScriptInterpreter")
_check("StaticObjectNode created ScriptInterpreter child", interpreter != null)
if interpreter != null:
_check("ScriptInterpreter parsed valid behavior", interpreter.behavior != null)
if interpreter.behavior != null:
_check("ScriptInterpreter rules count is 2", interpreter.behavior.rules.size() == 2)
# Refresh inspector display with rules
inspector.show_object(obj_id)
_check("Inspector refreshed object display", true)
print("Smoke test complete. Passed: %d, Failed: %d" % [passed, failed])
if failed > 0:
quit(1)
else:
quit(0)