Add XCUI command routing and widget state models

This commit is contained in:
2026-04-05 12:10:55 +08:00
parent 511e94fd30
commit 68c4c80b06
18 changed files with 1329 additions and 9 deletions

View File

@@ -219,6 +219,100 @@ TEST(NewEditorXCUIDemoRuntimeTest, InputStateTransitionsAreAcceptedAndFrameStill
}
}
TEST(NewEditorXCUIDemoRuntimeTest, DrainPendingCommandIdsReturnsEmptyForFramesWithoutCommands) {
XCEngine::Editor::XCUIBackend::XCUIDemoRuntime runtime;
ASSERT_TRUE(runtime.ReloadDocuments());
const auto& frame = runtime.Update(BuildInputState());
ASSERT_TRUE(frame.stats.documentsReady);
const std::vector<std::string> drainedCommandIds = runtime.DrainPendingCommandIds();
EXPECT_TRUE(drainedCommandIds.empty());
EXPECT_TRUE(runtime.DrainPendingCommandIds().empty());
}
TEST(NewEditorXCUIDemoRuntimeTest, DrainPendingCommandIdsCapturesPointerActivationCommands) {
XCEngine::Editor::XCUIBackend::XCUIDemoRuntime runtime;
ASSERT_TRUE(runtime.ReloadDocuments());
const auto& baselineFrame = runtime.Update(BuildInputState());
ASSERT_TRUE(baselineFrame.stats.documentsReady);
EXPECT_TRUE(runtime.DrainPendingCommandIds().empty());
XCEngine::UI::UIRect buttonRect = {};
ASSERT_TRUE(runtime.TryGetElementRect("toggleAccent", buttonRect));
const XCEngine::UI::UIPoint buttonCenter(
buttonRect.x + buttonRect.width * 0.5f,
buttonRect.y + buttonRect.height * 0.5f);
XCEngine::Editor::XCUIBackend::XCUIDemoInputState pressedInput = BuildInputState();
pressedInput.pointerPosition = buttonCenter;
pressedInput.pointerPressed = true;
pressedInput.pointerDown = true;
runtime.Update(pressedInput);
EXPECT_TRUE(runtime.DrainPendingCommandIds().empty());
XCEngine::Editor::XCUIBackend::XCUIDemoInputState releasedInput = BuildInputState();
releasedInput.pointerPosition = buttonCenter;
releasedInput.pointerReleased = true;
const auto& toggledFrame = runtime.Update(releasedInput);
ASSERT_TRUE(toggledFrame.stats.documentsReady);
EXPECT_EQ(runtime.DrainPendingCommandIds(), std::vector<std::string>({ "demo.toggleAccent" }));
EXPECT_TRUE(runtime.DrainPendingCommandIds().empty());
}
TEST(NewEditorXCUIDemoRuntimeTest, DrainPendingCommandIdsPreservesMultipleTextEditCommandsPerFrame) {
XCEngine::Editor::XCUIBackend::XCUIDemoRuntime runtime;
ASSERT_TRUE(runtime.ReloadDocuments());
const auto& baselineFrame = runtime.Update(BuildInputState());
ASSERT_TRUE(baselineFrame.stats.documentsReady);
EXPECT_TRUE(runtime.DrainPendingCommandIds().empty());
XCEngine::UI::UIRect promptRect = {};
ASSERT_TRUE(runtime.TryGetElementRect("agentPrompt", promptRect));
const XCEngine::UI::UIPoint promptCenter(
promptRect.x + promptRect.width * 0.5f,
promptRect.y + promptRect.height * 0.5f);
XCEngine::Editor::XCUIBackend::XCUIDemoInputState pressedInput = BuildInputState();
pressedInput.pointerPosition = promptCenter;
pressedInput.pointerPressed = true;
pressedInput.pointerDown = true;
runtime.Update(pressedInput);
EXPECT_TRUE(runtime.DrainPendingCommandIds().empty());
XCEngine::Editor::XCUIBackend::XCUIDemoInputState releasedInput = BuildInputState();
releasedInput.pointerPosition = promptCenter;
releasedInput.pointerReleased = true;
const auto& focusedFrame = runtime.Update(releasedInput);
ASSERT_TRUE(focusedFrame.stats.documentsReady);
EXPECT_EQ(focusedFrame.stats.focusedElementId, "agentPrompt");
EXPECT_EQ(
runtime.DrainPendingCommandIds(),
std::vector<std::string>({ "demo.activate.agentPrompt" }));
XCEngine::Editor::XCUIBackend::XCUIDemoInputState textInput = BuildInputState();
textInput.events.push_back(MakeCharacterEvent('A'));
textInput.events.push_back(MakeCharacterEvent('I'));
textInput.events.push_back(MakeKeyDownEvent(XCEngine::Input::KeyCode::Backspace));
const auto& typedFrame = runtime.Update(textInput);
ASSERT_TRUE(typedFrame.stats.documentsReady);
EXPECT_EQ(typedFrame.stats.focusedElementId, "agentPrompt");
EXPECT_EQ(
runtime.DrainPendingCommandIds(),
std::vector<std::string>({
"demo.text.edit.agentPrompt",
"demo.text.edit.agentPrompt",
"demo.text.edit.agentPrompt" }));
EXPECT_TRUE(runtime.DrainPendingCommandIds().empty());
}
TEST(NewEditorXCUIDemoRuntimeTest, PointerToggleUpdatesFocusStatusTextAndAccentState) {
XCEngine::Editor::XCUIBackend::XCUIDemoRuntime runtime;
ASSERT_TRUE(runtime.ReloadDocuments());