Files
EVEngine/test/action_editor_adapter.cpp
T
西风逍遥游andCursor 24502babef Nest satellite packages under their host modules.
Keep CMake module names and trim switches, but stop flattening editing/editor and runtime bridges as top-level src/modules directories. Parent scans skip nested facets so runtime-3d can drop authoring by directory leaf.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-06 17:56:12 +08:00

74 lines
3.0 KiB
C++

#include "action/editor/ActionEditorModule.h"
#include "action/editor/ActionTimelineEditor.h"
#include "common/Capability.h"
#include "common/EditorAutomation.h"
#include "editor/Editor.h"
#include "zeroerr/assert.h"
#include "zeroerr/unittest.h"
using namespace eve::editor;
namespace {
SelectionSnapshot documentSelection(const ActionTimelineTarget& target) {
SelectionItem item;
item.domain = SelectionDomain::Asset;
item.target = TargetId(target.targetId());
item.item = StableId(target.targetId().value());
item.type = "action.timeline";
SelectionSnapshot selection;
selection.channel = "asset";
selection.items = {item};
selection.primary = item;
return selection;
}
} // namespace
TEST_CASE("actionEditor.seedTargetExposesCanonicalProperties") {
ActionTimelineTarget target("combat.light-attack");
CHECK_EQ(target.describe().type, std::string("action-timeline"));
CHECK_EQ(target.timeline().actionId.format(), std::string("action:combat.light-attack"));
CHECK_EQ(target.timeline().duration.nanoseconds(), 1'000'000'000);
const auto selection = documentSelection(target);
auto operation = target.makeSet(selection, PropertyPath("timeline.animationUri"),
EditorValue("asset://animations/light-attack.eva"), PropertySetMode::Absolute);
REQUIRE(operation.ok());
REQUIRE(target.applyDomainOperation(operation.value()).ok());
CHECK_EQ(target.timeline().animationUri, std::string("asset://animations/light-attack.eva"));
CHECK_EQ(target.revision(), 1u);
auto snapshot = target.snapshotValue();
const auto* root = snapshot.getIf<EditorValue::Object>();
REQUIRE(root != nullptr);
CHECK_EQ(root->at("schema").getIf<std::string>() ?
*root->at("schema").getIf<std::string>() :
std::string{},
std::string("eve.action.timeline"));
}
TEST_CASE("actionEditor.module_registers_automation_target_and_property_command") {
Editor editor;
eve::action_editor::ActionEditorModule adapter;
auto* automation = eve::cap::query<eve::IEditorAutomation>();
REQUIRE(automation != nullptr);
const std::string commands = automation->invoke("commands", "{}");
CHECK(commands.find("action.property.set.v1") != std::string::npos);
const std::string created = automation->invoke(
"target-create",
R"({"target":"agent.action","type":"action","animationUri":"asset://test/attack.glb#Attack"})");
REQUIRE(created.find("\"status\":\"applied\"") != std::string::npos);
const std::string changed = automation->invoke(
"execute",
R"({"target":"agent.action","command":"action.property.set.v1","payload":{"path":"timeline.animationUri","value":"asset://test/idle.glb#Idle"}})");
CHECK(changed.find("\"status\":\"applied\"") != std::string::npos);
const std::string closed = automation->invoke("target-close", R"({"target":"agent.action"})");
CHECK(closed.find("\"status\":\"applied\"") != std::string::npos);
}