228 lines
6.5 KiB
C++
228 lines
6.5 KiB
C++
#include "ui_core/overlay_lifetime.h"
|
|
#include "test_harness.h"
|
|
|
|
using pp::foundation::StatusCode;
|
|
using pp::ui::NodeLifetimeTree;
|
|
using pp::ui::UiCaptureKind;
|
|
using pp::ui::UiOverlayLifetime;
|
|
|
|
namespace {
|
|
|
|
void opens_root_and_child_popups_with_capture_restore(pp::tests::Harness& h)
|
|
{
|
|
NodeLifetimeTree tree;
|
|
const auto root = tree.create_root();
|
|
PP_EXPECT(h, root);
|
|
if (!root) {
|
|
return;
|
|
}
|
|
|
|
UiOverlayLifetime overlays(tree, root.value());
|
|
const auto popup = overlays.open_popup();
|
|
PP_EXPECT(h, popup);
|
|
if (!popup) {
|
|
return;
|
|
}
|
|
|
|
const auto child = overlays.open_child_popup(popup.value());
|
|
PP_EXPECT(h, child);
|
|
if (!child) {
|
|
return;
|
|
}
|
|
|
|
PP_EXPECT(h, overlays.overlay_count() == 2U);
|
|
const auto captured_child = tree.captured_node(UiCaptureKind::pointer);
|
|
PP_EXPECT(h, captured_child);
|
|
if (captured_child) {
|
|
PP_EXPECT(h, captured_child.value() == child.value());
|
|
}
|
|
|
|
PP_EXPECT(h, overlays.close(child.value()).ok());
|
|
PP_EXPECT(h, overlays.overlay_count() == 1U);
|
|
PP_EXPECT(h, !tree.contains(child.value()));
|
|
PP_EXPECT(h, tree.contains(popup.value()));
|
|
|
|
const auto captured_parent = tree.captured_node(UiCaptureKind::pointer);
|
|
PP_EXPECT(h, captured_parent);
|
|
if (captured_parent) {
|
|
PP_EXPECT(h, captured_parent.value() == popup.value());
|
|
}
|
|
}
|
|
|
|
void closing_parent_popup_closes_child_branch(pp::tests::Harness& h)
|
|
{
|
|
NodeLifetimeTree tree;
|
|
const auto root = tree.create_root();
|
|
PP_EXPECT(h, root);
|
|
if (!root) {
|
|
return;
|
|
}
|
|
|
|
UiOverlayLifetime overlays(tree, root.value());
|
|
const auto popup = overlays.open_popup();
|
|
PP_EXPECT(h, popup);
|
|
if (!popup) {
|
|
return;
|
|
}
|
|
|
|
const auto child = overlays.open_child_popup(popup.value());
|
|
PP_EXPECT(h, child);
|
|
if (!child) {
|
|
return;
|
|
}
|
|
|
|
PP_EXPECT(h, overlays.close(popup.value()).ok());
|
|
PP_EXPECT(h, overlays.overlay_count() == 0U);
|
|
PP_EXPECT(h, !tree.contains(popup.value()));
|
|
PP_EXPECT(h, !tree.contains(child.value()));
|
|
PP_EXPECT(h, !tree.captured_node(UiCaptureKind::pointer).ok());
|
|
}
|
|
|
|
void modal_dialog_captures_pointer_and_keyboard(pp::tests::Harness& h)
|
|
{
|
|
NodeLifetimeTree tree;
|
|
const auto root = tree.create_root();
|
|
PP_EXPECT(h, root);
|
|
if (!root) {
|
|
return;
|
|
}
|
|
|
|
UiOverlayLifetime overlays(tree, root.value());
|
|
const auto popup = overlays.open_popup();
|
|
PP_EXPECT(h, popup);
|
|
if (!popup) {
|
|
return;
|
|
}
|
|
|
|
const auto dialog = overlays.open_dialog(true);
|
|
PP_EXPECT(h, dialog);
|
|
if (!dialog) {
|
|
return;
|
|
}
|
|
|
|
const auto pointer = tree.captured_node(UiCaptureKind::pointer);
|
|
const auto keyboard = tree.captured_node(UiCaptureKind::keyboard);
|
|
PP_EXPECT(h, pointer);
|
|
PP_EXPECT(h, keyboard);
|
|
if (pointer) {
|
|
PP_EXPECT(h, pointer.value() == dialog.value());
|
|
}
|
|
if (keyboard) {
|
|
PP_EXPECT(h, keyboard.value() == dialog.value());
|
|
}
|
|
|
|
PP_EXPECT(h, overlays.close(dialog.value()).ok());
|
|
const auto restored_pointer = tree.captured_node(UiCaptureKind::pointer);
|
|
PP_EXPECT(h, restored_pointer);
|
|
if (restored_pointer) {
|
|
PP_EXPECT(h, restored_pointer.value() == popup.value());
|
|
}
|
|
PP_EXPECT(h, !tree.captured_node(UiCaptureKind::keyboard).ok());
|
|
}
|
|
|
|
void modeless_dialog_does_not_steal_capture(pp::tests::Harness& h)
|
|
{
|
|
NodeLifetimeTree tree;
|
|
const auto root = tree.create_root();
|
|
PP_EXPECT(h, root);
|
|
if (!root) {
|
|
return;
|
|
}
|
|
|
|
UiOverlayLifetime overlays(tree, root.value());
|
|
const auto popup = overlays.open_popup();
|
|
PP_EXPECT(h, popup);
|
|
if (!popup) {
|
|
return;
|
|
}
|
|
|
|
const auto dialog = overlays.open_dialog(false);
|
|
PP_EXPECT(h, dialog);
|
|
if (!dialog) {
|
|
return;
|
|
}
|
|
|
|
const auto pointer = tree.captured_node(UiCaptureKind::pointer);
|
|
PP_EXPECT(h, pointer);
|
|
if (pointer) {
|
|
PP_EXPECT(h, pointer.value() == popup.value());
|
|
}
|
|
PP_EXPECT(h, !tree.captured_node(UiCaptureKind::keyboard).ok());
|
|
PP_EXPECT(h, overlays.top_overlay());
|
|
if (const auto top = overlays.top_overlay()) {
|
|
PP_EXPECT(h, top.value() == dialog.value());
|
|
}
|
|
}
|
|
|
|
void rejects_untracked_or_dead_overlay_closes(pp::tests::Harness& h)
|
|
{
|
|
NodeLifetimeTree tree;
|
|
const auto root = tree.create_root();
|
|
PP_EXPECT(h, root);
|
|
if (!root) {
|
|
return;
|
|
}
|
|
|
|
const auto raw_child = tree.create_child(root.value());
|
|
PP_EXPECT(h, raw_child);
|
|
if (!raw_child) {
|
|
return;
|
|
}
|
|
|
|
UiOverlayLifetime overlays(tree, root.value());
|
|
const auto close_raw = overlays.close(raw_child.value());
|
|
const auto child_popup = overlays.open_child_popup(raw_child.value());
|
|
PP_EXPECT(h, !close_raw.ok());
|
|
PP_EXPECT(h, close_raw.code == StatusCode::invalid_argument);
|
|
PP_EXPECT(h, !child_popup.ok());
|
|
PP_EXPECT(h, child_popup.status().code == StatusCode::invalid_argument);
|
|
}
|
|
|
|
void clear_for_layout_reload_invalidates_overlays(pp::tests::Harness& h)
|
|
{
|
|
NodeLifetimeTree tree;
|
|
const auto root = tree.create_root();
|
|
PP_EXPECT(h, root);
|
|
if (!root) {
|
|
return;
|
|
}
|
|
|
|
UiOverlayLifetime overlays(tree, root.value());
|
|
const auto popup = overlays.open_popup();
|
|
PP_EXPECT(h, popup);
|
|
if (!popup) {
|
|
return;
|
|
}
|
|
|
|
const auto dialog = overlays.open_dialog(true);
|
|
PP_EXPECT(h, dialog);
|
|
if (!dialog) {
|
|
return;
|
|
}
|
|
|
|
overlays.clear_for_layout_reload();
|
|
PP_EXPECT(h, overlays.overlay_count() == 0U);
|
|
PP_EXPECT(h, !overlays.top_overlay().ok());
|
|
PP_EXPECT(h, !tree.contains(root.value()));
|
|
PP_EXPECT(h, !tree.contains(popup.value()));
|
|
PP_EXPECT(h, !tree.contains(dialog.value()));
|
|
PP_EXPECT(h, !tree.captured_node(UiCaptureKind::pointer).ok());
|
|
PP_EXPECT(h, !tree.captured_node(UiCaptureKind::keyboard).ok());
|
|
}
|
|
|
|
}
|
|
|
|
int main()
|
|
{
|
|
pp::tests::Harness harness;
|
|
harness.run(
|
|
"opens_root_and_child_popups_with_capture_restore",
|
|
opens_root_and_child_popups_with_capture_restore);
|
|
harness.run("closing_parent_popup_closes_child_branch", closing_parent_popup_closes_child_branch);
|
|
harness.run("modal_dialog_captures_pointer_and_keyboard", modal_dialog_captures_pointer_and_keyboard);
|
|
harness.run("modeless_dialog_does_not_steal_capture", modeless_dialog_does_not_steal_capture);
|
|
harness.run("rejects_untracked_or_dead_overlay_closes", rejects_untracked_or_dead_overlay_closes);
|
|
harness.run("clear_for_layout_reload_invalidates_overlays", clear_for_layout_reload_invalidates_overlays);
|
|
return harness.finish();
|
|
}
|