Integrate XCUI shell state and runtime frame seams

This commit is contained in:
2026-04-05 12:50:55 +08:00
parent ec97445071
commit e5e9f348a3
29 changed files with 3183 additions and 102 deletions

View File

@@ -56,6 +56,17 @@ UIInputEvent MakeKeyDownEvent(
return event;
}
UIInputEvent MakePointerButtonEvent(
UIInputEventType type,
const XCEngine::UI::UIPoint& position,
XCEngine::UI::UIPointerButton button = XCEngine::UI::UIPointerButton::Left) {
UIInputEvent event = {};
event.type = type;
event.pointerButton = button;
event.position = position;
return event;
}
fs::path FindDemoResourcePath() {
fs::path probe = fs::current_path();
for (int i = 0; i < 8; ++i) {
@@ -263,6 +274,25 @@ TEST(NewEditorXCUIDemoRuntimeTest, DrainPendingCommandIdsCapturesPointerActivati
EXPECT_TRUE(runtime.DrainPendingCommandIds().empty());
}
TEST(NewEditorXCUIDemoRuntimeTest, DrainPendingCommandIdsCapturesShortcutCommands) {
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::Editor::XCUIBackend::XCUIDemoInputState shortcutInput = BuildInputState();
shortcutInput.events.push_back(MakeKeyDownEvent(XCEngine::Input::KeyCode::P, false, false, true));
const auto& shortcutFrame = runtime.Update(shortcutInput);
ASSERT_TRUE(shortcutFrame.stats.documentsReady);
EXPECT_TRUE(shortcutFrame.stats.accentEnabled);
EXPECT_EQ(shortcutFrame.stats.lastCommandId, "demo.toggleAccent");
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());
@@ -313,6 +343,43 @@ TEST(NewEditorXCUIDemoRuntimeTest, DrainPendingCommandIdsPreservesMultipleTextEd
EXPECT_TRUE(runtime.DrainPendingCommandIds().empty());
}
TEST(NewEditorXCUIDemoRuntimeTest, DrainPendingCommandIdsPreserveMixedPointerTextAndShortcutOrder) {
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 mixedInput = BuildInputState();
mixedInput.pointerPosition = promptCenter;
mixedInput.events.push_back(MakePointerButtonEvent(UIInputEventType::PointerButtonDown, promptCenter));
mixedInput.events.push_back(MakePointerButtonEvent(UIInputEventType::PointerButtonUp, promptCenter));
mixedInput.events.push_back(MakeCharacterEvent('A'));
mixedInput.events.push_back(MakeKeyDownEvent(XCEngine::Input::KeyCode::P, false, false, true));
const auto& mixedFrame = runtime.Update(mixedInput);
ASSERT_TRUE(mixedFrame.stats.documentsReady);
EXPECT_EQ(mixedFrame.stats.focusedElementId, "agentPrompt");
EXPECT_TRUE(mixedFrame.stats.accentEnabled);
EXPECT_EQ(mixedFrame.stats.lastCommandId, "demo.toggleAccent");
EXPECT_NE(FindTextCommand(mixedFrame.drawData, "A"), nullptr);
EXPECT_EQ(
runtime.DrainPendingCommandIds(),
std::vector<std::string>({
"demo.activate.agentPrompt",
"demo.text.edit.agentPrompt",
"demo.toggleAccent" }));
EXPECT_TRUE(runtime.DrainPendingCommandIds().empty());
}
TEST(NewEditorXCUIDemoRuntimeTest, PointerToggleUpdatesFocusStatusTextAndAccentState) {
XCEngine::Editor::XCUIBackend::XCUIDemoRuntime runtime;
ASSERT_TRUE(runtime.ReloadDocuments());