Files
EVEngine/test/editor_audio_editor.cpp
西风逍遥游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

92 lines
4.4 KiB
C++

#include "zeroerr/assert.h"
#include "zeroerr/unittest.h"
#include "audio/editor/AudioEditorModule.h"
#include "audio/editor/EditorAudioTarget.h"
#include "common/Capability.h"
#include "common/EditorAutomation.h"
#include "editor/Editor.h"
using namespace eve::editor;
TEST_CASE("editor.audio.adapter_registers_commands_and_owns_headless_targets") {
Editor editor;
eve::audio_editor::AudioEditorModule audioAdapter;
auto* automation = eve::cap::query<eve::IEditorAutomation>();
REQUIRE(automation != nullptr);
const std::string commands = automation->invoke("commands", "{}");
CHECK(commands.find("audio.source.property.set.v1") != std::string::npos);
const std::string created =
automation->invoke("target-create", R"({"target":"agent.audio","type":"audio-source"})");
REQUIRE(created.find("\"status\":\"applied\"") != std::string::npos);
const std::string changed = automation->invoke(
"execute",
R"({"target":"agent.audio","command":"audio.source.property.set.v1","payload":{"path":"play.volume","value":0.25}})");
REQUIRE(changed.find("\"status\":\"applied\"") != std::string::npos);
const std::string inspected = automation->invoke("inspect", R"({"target":"agent.audio"})");
CHECK(inspected.find("\"play.volume\"") != std::string::npos);
CHECK(inspected.find("0.25") != std::string::npos);
const std::string undone = automation->invoke("undo", R"({"target":"agent.audio"})");
REQUIRE(undone.find("\"status\":\"applied\"") != std::string::npos);
const std::string restored = automation->invoke("inspect", R"({"target":"agent.audio"})");
CHECK(restored.find("0.25") == std::string::npos);
const std::string mixer =
automation->invoke("target-create", R"({"target":"agent.mixer","type":"audio-mixer"})");
REQUIRE(mixer.find("\"status\":\"applied\"") != std::string::npos);
REQUIRE(automation->invoke("target-close", R"({"target":"agent.mixer"})")
.find("\"status\":\"applied\"") != std::string::npos);
REQUIRE(automation->invoke("target-close", R"({"target":"agent.audio"})")
.find("\"status\":\"applied\"") != std::string::npos);
}
TEST_CASE("editor.audio.property_command_keeps_bound_document_histories_independent") {
AudioSourceTarget river("level.river");
AudioSourceTarget wind("level.wind");
Editor editor;
eve::audio_editor::AudioEditorModule audioAdapter;
REQUIRE(editor.registerEditingTarget(river).ok());
REQUIRE(editor.registerEditingTarget(wind).ok());
auto* automation = eve::cap::query<eve::IEditorAutomation>();
REQUIRE(automation != nullptr);
REQUIRE(automation
->invoke("execute",
R"({"target":"level.river","command":"audio.source.property.set.v1","payload":{"path":"play.volume","value":0.4}})")
.find("\"status\":\"applied\"") != std::string::npos);
REQUIRE(automation
->invoke("execute",
R"({"target":"level.wind","command":"audio.source.property.set.v1","payload":{"path":"play.volume","value":0.8}})")
.find("\"status\":\"applied\"") != std::string::npos);
SelectionSnapshot riverSelection;
riverSelection.channel = "audio";
SelectionItem item;
item.domain = SelectionDomain::Asset;
item.target = TargetId(river.targetId());
item.item = StableId(river.targetId().value());
item.type = "audio.source";
riverSelection.items.push_back(item);
riverSelection.primary = item;
SelectionSnapshot windSelection = riverSelection;
windSelection.items.front().target = TargetId(wind.targetId());
windSelection.items.front().item = StableId(wind.targetId().value());
windSelection.primary = windSelection.items.front();
CHECK_EQ(river.read(riverSelection, PropertyPath("play.volume")).value, EditorValue(0.4));
CHECK_EQ(wind.read(windSelection, PropertyPath("play.volume")).value, EditorValue(0.8));
REQUIRE(automation->invoke("undo", R"({"target":"level.river"})")
.find("\"status\":\"applied\"") != std::string::npos);
CHECK_EQ(river.read(riverSelection, PropertyPath("play.volume")).value, EditorValue(1.0));
CHECK_EQ(wind.read(windSelection, PropertyPath("play.volume")).value, EditorValue(0.8));
CHECK(editor.unregisterEditingTarget(TargetId("level.river")).ok());
CHECK(editor.unregisterEditingTarget(TargetId("level.wind")).ok());
}