[PATCH 7/7] oleacc: Add tests for default edit accessible object.

Connor McAdams cmcadams at codeweavers.com
Wed Sep 22 11:20:56 CDT 2021


Signed-off-by: Connor McAdams <cmcadams at codeweavers.com>
---
 dlls/oleacc/tests/main.c | 436 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 436 insertions(+)

diff --git a/dlls/oleacc/tests/main.c b/dlls/oleacc/tests/main.c
index 98da7eb3ddc..629813587b5 100644
--- a/dlls/oleacc/tests/main.c
+++ b/dlls/oleacc/tests/main.c
@@ -1313,6 +1313,441 @@ static void test_CAccPropServices(void)
     IAccPropServices_Release(acc_prop_services);
 }
 
+typedef struct
+{
+    INT child_id;
+
+    const WCHAR *expected_name;
+    HRESULT expected_name_hr;
+
+    const WCHAR *expected_value;
+    HRESULT expected_value_hr;
+
+    const WCHAR *expected_description;
+    HRESULT expected_description_hr;
+
+    const WCHAR *expected_help;
+    HRESULT expected_help_hr;
+
+    const WCHAR *expected_kbd_shortcut;
+    HRESULT expected_kbd_shortcut_hr;
+
+    const WCHAR *expected_default_action;
+    HRESULT expected_default_action_hr;
+
+    INT expected_role;
+    HRESULT expected_role_hr;
+
+    INT expected_state;
+    HRESULT expected_state_hr;
+
+    LONG left_offset, top_offset, width_offset, height_offset;
+    HRESULT expected_location_hr;
+
+    LONG    expected_child_count;
+    HRESULT expected_child_count_hr;
+
+    BOOL    expected_valid_child;
+    HRESULT expected_child_hr;
+
+    BOOL    expected_valid_parent;
+    HRESULT expected_parent_hr;
+
+    INT expected_focus_vt;
+    INT expected_focus_cid;
+    HRESULT expected_focus_hr;
+} acc_expected_vals;
+
+#define check_acc_vals( acc, vals) \
+        check_acc_vals_( (acc), (vals), __LINE__)
+static void check_acc_vals_(IAccessible *acc, const acc_expected_vals *vals,
+        int line)
+{
+    LONG left, top, width, height;
+    LONG child_count;
+    VARIANT vid, var;
+    IDispatch *disp;
+    HRESULT hr;
+    RECT rect;
+    HWND hwnd;
+    POINT pt;
+    BSTR str;
+
+    V_VT(&vid) = VT_I4;
+    V_I4(&vid) = vals->child_id;
+    hr = IAccessible_get_accName(acc, vid, &str);
+    ok_(__FILE__, line) (hr == vals->expected_name_hr, "get_accName returned %#x, expected %#x\n",
+            hr, vals->expected_name_hr);
+    ok_(__FILE__, line) (!lstrcmpW(str, vals->expected_name), "get_accName returned %s, expected %s\n",
+            wine_dbgstr_w(str), wine_dbgstr_w(vals->expected_name));
+    SysFreeString(str);
+
+    hr = IAccessible_get_accValue(acc, vid, &str);
+    ok_(__FILE__, line) (hr == vals->expected_value_hr, "get_accValue returned %#x, expected %#x\n",
+            hr, vals->expected_value_hr);
+    ok_(__FILE__, line) (!lstrcmpW(str, vals->expected_value), "get_accValue returned %s, expected %s\n",
+            wine_dbgstr_w(str), wine_dbgstr_w(vals->expected_value));
+    SysFreeString(str);
+
+    hr = IAccessible_get_accDescription(acc, vid, &str);
+    ok_(__FILE__, line) (hr == vals->expected_description_hr, "get_accDescription returned %#x, expected %#x\n",
+            hr, vals->expected_description_hr);
+    ok_(__FILE__, line) (!lstrcmpW(str, vals->expected_description), "get_accDescription returned %s, expected %s\n",
+            wine_dbgstr_w(str), wine_dbgstr_w(vals->expected_description));
+    SysFreeString(str);
+
+    hr = IAccessible_get_accHelp(acc, vid, &str);
+    ok_(__FILE__, line) (hr == vals->expected_help_hr, "get_accHelp returned %#x, expected %#x\n",
+            hr, vals->expected_help_hr);
+    ok_(__FILE__, line) (!lstrcmpW(str, vals->expected_help), "get_accHelp returned %s, expected %s\n",
+            wine_dbgstr_w(str), wine_dbgstr_w(vals->expected_help));
+    SysFreeString(str);
+
+    hr = IAccessible_get_accKeyboardShortcut(acc, vid, &str);
+    ok_(__FILE__, line) (hr == vals->expected_kbd_shortcut_hr, "get_accKeyboardShortcut returned %#x, expected %#x\n",
+            hr, vals->expected_kbd_shortcut_hr);
+    ok_(__FILE__, line) (!lstrcmpW(str, vals->expected_kbd_shortcut), "get_accKeyboardShortcut returned %s, expected %s\n",
+            wine_dbgstr_w(str), wine_dbgstr_w(vals->expected_kbd_shortcut));
+    SysFreeString(str);
+
+    hr = IAccessible_get_accDefaultAction(acc, vid, &str);
+    ok_(__FILE__, line) (hr == vals->expected_default_action_hr, "get_accDefaultAction returned %#x, expected %#x\n",
+            hr, vals->expected_default_action_hr);
+    ok_(__FILE__, line) (!lstrcmpW(str, vals->expected_default_action), "get_accDefaultAction returned %s, expected %s\n",
+            wine_dbgstr_w(str), wine_dbgstr_w(vals->expected_default_action));
+    SysFreeString(str);
+
+    V_VT(&var) = VT_DISPATCH;
+    V_DISPATCH(&var) = (void*)0xdeadbeef;
+    hr = IAccessible_get_accRole(acc, vid, &var);
+    ok_(__FILE__, line) (hr == vals->expected_role_hr, "get_accRole returned %#x, expected %#x\n",
+            hr, vals->expected_role_hr);
+    ok_(__FILE__, line) (V_VT(&var) == VT_I4, "V_VT(&var) returned %d, expected %d\n", V_VT(&var), VT_I4);
+    ok_(__FILE__, line) (V_I4(&var) == vals->expected_role, "get_accRole returned %d, expected %d\n",
+            V_I4(&var), vals->expected_role);
+
+    V_VT(&var) = VT_DISPATCH;
+    V_DISPATCH(&var) = (void*)0xdeadbeef;
+    hr = IAccessible_get_accState(acc, vid, &var);
+    ok_(__FILE__, line) (hr == vals->expected_state_hr, "get_accState returned %#x, expected %#x\n",
+            hr, vals->expected_state_hr);
+    ok_(__FILE__, line) (V_VT(&var) == VT_I4, "V_VT(&var) returned %d, expected %d\n", V_VT(&var), VT_I4);
+    ok_(__FILE__, line) (V_I4(&var) == vals->expected_state, "get_accState returned %#x, expected %#x\n",
+            V_I4(&var), vals->expected_state);
+
+    hr = WindowFromAccessibleObject(acc, &hwnd);
+    ok_(__FILE__, line) (hr == S_OK, "got %x\n", hr);
+    ok_(__FILE__, line) (GetClientRect(hwnd, &rect), "GetClientRect failed\n");
+    pt.x = rect.left + vals->left_offset;
+    pt.y = rect.top + vals->top_offset;
+    MapWindowPoints(hwnd, NULL, &pt, 1);
+    rect.left = pt.x;
+    rect.top = pt.y;
+    pt.x = rect.right + vals->width_offset;
+    pt.y = rect.bottom + vals->height_offset;
+    MapWindowPoints(hwnd, NULL, &pt, 1);
+    hr = IAccessible_accLocation(acc, &left, &top, &width, &height, vid);
+    ok_(__FILE__, line) (hr == vals->expected_location_hr, "got %x\n", hr);
+    ok_(__FILE__, line) (left == rect.left, "left = %d, expected %d\n", left, rect.left);
+    ok_(__FILE__, line) (top == rect.top, "top = %d, expected %d\n", top, rect.top);
+    ok_(__FILE__, line) (width == pt.x-rect.left, "width = %d, expected %d\n", width, pt.x-rect.left);
+    ok_(__FILE__, line) (height == pt.y-rect.top, "height = %d, expected %d\n", height, pt.y-rect.top);
+
+    /*
+     * Tests beyond this point are only applicable to full accessible objects
+     * and not simple elements.
+     */
+    if (vals->child_id != CHILDID_SELF)
+        return;
+
+    child_count = -1;
+    hr = IAccessible_get_accChildCount(acc, &child_count);
+    ok_(__FILE__, line) (hr == vals->expected_child_count_hr, "get_accChildCount returned %#x, expected %#x\n",
+            hr, vals->expected_child_count_hr);
+    ok_(__FILE__, line) (child_count == vals->expected_child_count, "get_accChildCount returned %d, expected %#x\n",
+            child_count, vals->expected_child_count);
+
+    disp = NULL;
+    V_VT(&var) = VT_I4;
+    V_I4(&var) = 1;
+    hr = IAccessible_get_accChild(acc, var, &disp);
+    ok_(__FILE__, line) (hr == vals->expected_child_hr, "get_accChild returned %#x, expected %#x\n",
+            hr, vals->expected_child_hr);
+    if (disp)
+    {
+        ok_(__FILE__, line) (vals->expected_valid_child, "get_accChild unexpectedly returned a child\n");
+        IDispatch_Release(disp);
+    }
+    else
+        ok_(__FILE__, line) (!vals->expected_valid_child, "get_accChild expected a valid child, none was returned\n");
+
+    disp = NULL;
+    hr = IAccessible_get_accParent(acc, &disp);
+    ok_(__FILE__, line) (hr == vals->expected_parent_hr, "get_accParent returned %#x, expected %#x\n",
+            hr, vals->expected_parent_hr);
+    if (disp)
+    {
+        ok_(__FILE__, line) (vals->expected_valid_parent, "get_accParent unexpectedly returned a parent\n");
+        IDispatch_Release(disp);
+    }
+    else
+        ok_(__FILE__, line) (!vals->expected_valid_parent, "get_accParent expected a valid parent, none was returned\n");
+
+    V_VT(&var) = VT_EMPTY;
+    hr = IAccessible_get_accFocus(acc, &var);
+    ok_(__FILE__, line) (hr == vals->expected_focus_hr, "get_accFocus returned %#x, expected %#x\n",
+            hr, vals->expected_focus_hr);
+    ok_(__FILE__, line) (V_VT(&var) == vals->expected_focus_vt, "get_accFocus returned V_VT(&var) %d, expected %d\n",
+            V_VT(&var), vals->expected_focus_vt);
+    if (V_VT(&var) == VT_I4)
+    {
+        ok_(__FILE__, line) (V_I4(&var) == vals->expected_focus_cid, "get_accFocus returned childID %d, expected %d\n",
+                V_I4(&var), vals->expected_focus_cid);
+    }
+}
+
+static const acc_expected_vals edit_acc_vals[] = {
+    /* edit0, regular edit, no label. */
+    { .child_id = CHILDID_SELF,
+      .expected_name              = NULL,
+      .expected_name_hr           = S_FALSE,
+      .expected_value             = L"edit0-test",
+      .expected_value_hr          = S_OK,
+      .expected_description       = NULL,
+      .expected_description_hr    = S_FALSE,
+      .expected_help              = NULL,
+      .expected_help_hr           = S_FALSE,
+      .expected_kbd_shortcut      = NULL,
+      .expected_kbd_shortcut_hr   = S_FALSE,
+      .expected_default_action    = NULL,
+      .expected_default_action_hr = S_FALSE,
+      .expected_role           = ROLE_SYSTEM_TEXT,
+      .expected_role_hr        = S_OK,
+      .expected_state          = STATE_SYSTEM_FOCUSABLE | STATE_SYSTEM_READONLY,
+      .expected_state_hr       = S_OK,
+      .left_offset             = 0,
+      .top_offset              = 0,
+      .width_offset            = 0,
+      .height_offset           = 0,
+      .expected_location_hr    = S_OK,
+      .expected_child_count    = 0,
+      .expected_child_count_hr = S_OK,
+      .expected_valid_child    = FALSE,
+      .expected_child_hr       = E_INVALIDARG,
+      .expected_valid_parent   = TRUE,
+      .expected_parent_hr      = S_OK,
+      .expected_focus_vt       = VT_EMPTY,
+      .expected_focus_cid      = 0,
+      .expected_focus_hr       = S_OK },
+    /* edit1, ES_PASSWORD edit style. */
+    { .child_id = CHILDID_SELF,
+      .expected_name              = L"label0:",
+      .expected_name_hr           = S_OK,
+      .expected_value             = NULL,
+      .expected_value_hr          = E_ACCESSDENIED,
+      .expected_description       = NULL,
+      .expected_description_hr    = S_FALSE,
+      .expected_help              = NULL,
+      .expected_help_hr           = S_FALSE,
+      .expected_kbd_shortcut      = L"Alt+l",
+      .expected_kbd_shortcut_hr   = S_OK,
+      .expected_default_action    = NULL,
+      .expected_default_action_hr = S_FALSE,
+      .expected_role           = ROLE_SYSTEM_TEXT,
+      .expected_role_hr        = S_OK,
+      .expected_state          = STATE_SYSTEM_PROTECTED | STATE_SYSTEM_FOCUSABLE,
+      .expected_state_hr       = S_OK,
+      .left_offset             = 0,
+      .top_offset              = 0,
+      .width_offset            = 0,
+      .height_offset           = 0,
+      .expected_location_hr    = S_OK,
+      .expected_child_count    = 0,
+      .expected_child_count_hr = S_OK,
+      .expected_valid_child    = FALSE,
+      .expected_child_hr       = E_INVALIDARG,
+      .expected_valid_parent   = TRUE,
+      .expected_parent_hr      = S_OK,
+      .expected_focus_vt       = VT_EMPTY,
+      .expected_focus_cid      = 0,
+      .expected_focus_hr       = S_OK },
+    /* edit2 */
+    { .child_id = CHILDID_SELF,
+      .expected_name              = L"label1:",
+      .expected_name_hr           = S_OK,
+      .expected_value             = L"edit2-test\r\ntest-edit2\n",
+      .expected_value_hr          = S_OK,
+      .expected_description       = NULL,
+      .expected_description_hr    = S_FALSE,
+      .expected_help              = NULL,
+      .expected_help_hr           = S_FALSE,
+      .expected_kbd_shortcut      = L"Alt+e",
+      .expected_kbd_shortcut_hr   = S_OK,
+      .expected_default_action    = NULL,
+      .expected_default_action_hr = S_FALSE,
+      .expected_role           = ROLE_SYSTEM_TEXT,
+      .expected_role_hr        = S_OK,
+      .expected_state          = STATE_SYSTEM_FOCUSABLE | STATE_SYSTEM_FOCUSED,
+      .expected_state_hr       = S_OK,
+      .left_offset             = 0,
+      .top_offset              = 0,
+      .width_offset            = 0,
+      .height_offset           = 0,
+      .expected_location_hr    = S_OK,
+      .expected_child_count    = 0,
+      .expected_child_count_hr = S_OK,
+      .expected_valid_child    = FALSE,
+      .expected_child_hr       = E_INVALIDARG,
+      .expected_valid_parent   = TRUE,
+      .expected_parent_hr      = S_OK,
+      .expected_focus_vt       = VT_I4,
+      .expected_focus_cid      = CHILDID_SELF,
+      .expected_focus_hr       = S_OK },
+    /* edit3 */
+    { .child_id = CHILDID_SELF,
+      .expected_name              = L"label1:",
+      .expected_name_hr           = S_OK,
+      .expected_value             = L"",
+      .expected_value_hr          = S_OK,
+      .expected_description       = NULL,
+      .expected_description_hr    = S_FALSE,
+      .expected_help              = NULL,
+      .expected_help_hr           = S_FALSE,
+      .expected_kbd_shortcut      = L"Alt+l",
+      .expected_kbd_shortcut_hr   = S_OK,
+      .expected_default_action    = NULL,
+      .expected_default_action_hr = S_FALSE,
+      .expected_role           = ROLE_SYSTEM_TEXT,
+      .expected_role_hr        = S_OK,
+      .expected_state          = STATE_SYSTEM_FOCUSABLE,
+      .expected_state_hr       = S_OK,
+      .left_offset             = 0,
+      .top_offset              = 0,
+      .width_offset            = 0,
+      .height_offset           = 0,
+      .expected_location_hr    = S_OK,
+      /* Embedded button control HWND. */
+      .expected_child_count    = 1,
+      .expected_child_count_hr = S_OK,
+      .expected_valid_child    = FALSE,
+      .expected_child_hr       = E_INVALIDARG,
+      .expected_valid_parent   = TRUE,
+      .expected_parent_hr      = S_OK,
+      .expected_focus_vt       = VT_DISPATCH,
+      .expected_focus_cid      = 0,
+      .expected_focus_hr       = S_OK },
+};
+
+static void test_default_edit_accessible_object(void)
+{
+    HWND hwnd, label0, label1, btn0, btn1;
+    IAccessible *acc;
+    HWND edit[4];
+    HRESULT hr;
+    VARIANT v;
+    BSTR str;
+
+    /* Create a window that looks like this:
+     * +----------------------------------------+
+     * |   ___________________________________  |
+     * |  |___________________________________| |
+     * |                (edit[0])               |
+     * |          ____________________________  |
+     * | Label0: |____________________________| |
+     * |(label0)       (edit[1])  (password)    |
+     * |          ______   _________________    |
+     * | Label1: |button| |multi-line edit  |   |
+     * |(label1)  (btn0)  |_________________|   |
+     * |                     (edit[2])          |
+     * |   __________________________________   |
+     * |  |                                  |  |
+     * |  |    edit with embedded button     |  |
+     * |  |__________________________________|  |
+     * |    (edit[3])             (btn1)        |
+     * +----------------------------------------+
+     */
+
+    hwnd = CreateWindowW(L"oleacc_test", L"edit_acc_test_win", WS_OVERLAPPEDWINDOW,
+            0, 0, 220, 160, NULL, NULL, NULL, NULL);
+    ok(!!hwnd, "CreateWindow failed\n");
+
+    edit[0] = CreateWindowW(L"EDIT", L"", WS_VISIBLE | WS_CHILD | ES_READONLY, 5, 5, 190, 20,
+            hwnd, NULL, NULL, NULL);
+    ok(!!edit[0], "Failed to create edit[0] hwnd\n");
+
+    label0 = CreateWindowW(L"STATIC", L"&label0:", WS_VISIBLE | WS_CHILD, 5, 30, 55, 20,
+            hwnd, NULL, NULL, NULL);
+    ok(!!label0, "Failed to create label0 hwnd\n");
+
+    edit[1] = CreateWindowW(L"EDIT", L"", WS_VISIBLE | WS_CHILD | ES_PASSWORD,
+            65, 30, 130, 20, hwnd, NULL, NULL, NULL);
+    ok(!!edit[1], "Failed to create edit[1] hwnd\n");
+
+    label1 = CreateWindowW(L"STATIC", L"lab&el1:", WS_VISIBLE | WS_CHILD, 5, 55, 45, 20,
+            hwnd, NULL, NULL, NULL);
+    ok(!!label1, "Failed to create label1 hwnd\n");
+
+    btn0 = CreateWindowW(L"BUTTON", L"but&ton0", WS_VISIBLE | WS_CHILD, 55, 55, 45, 20,
+            hwnd, NULL, NULL, NULL);
+    ok(!!btn0, "Failed to create btn0 hwnd\n");
+
+    edit[2] = CreateWindowW(L"EDIT", L"", WS_VISIBLE | WS_CHILD | ES_MULTILINE,
+            105, 55, 90, 40, hwnd, NULL, NULL, NULL);
+    ok(!!edit[2], "Failed to create edit[2] hwnd\n");
+
+    edit[3] = CreateWindowW(L"EDIT", L"", WS_VISIBLE | WS_CHILD, 5, 100, 190, 20,
+            hwnd, NULL, NULL, NULL);
+    ok(!!edit[3], "Failed to create edit[3] hwnd\n");
+
+    /* Button embedded within an edit control window. */
+    btn1 = CreateWindowW(L"BUTTON", L"button1", WS_VISIBLE | WS_CHILD, 100, 5, 85, 10,
+            edit[3], NULL, NULL, NULL);
+    ok(!!btn1, "Failed to create btn1 hwnd\n");
+
+    hr = CreateStdAccessibleObject(edit[0], OBJID_CLIENT, &IID_IAccessible, (void**)&acc);
+    ok(hr == S_OK, "got %x\n", hr);
+    V_VT(&v) = VT_I4;
+    V_I4(&v) = CHILDID_SELF;
+    str = SysAllocString(L"edit0-test");
+    hr = IAccessible_put_accValue(acc, v, str);
+    ok(hr == S_OK, "got %x\n", hr);
+    SysFreeString(str);
+    check_acc_vals(acc, &edit_acc_vals[0]);
+    IAccessible_Release(acc);
+
+    hr = CreateStdAccessibleObject(edit[1], OBJID_CLIENT, &IID_IAccessible, (void**)&acc);
+    ok(hr == S_OK, "got %x\n", hr);
+    str = SysAllocString(L"password");
+    hr = IAccessible_put_accValue(acc, v, str);
+    ok(hr == S_OK, "got %x\n", hr);
+    SysFreeString(str);
+    check_acc_vals(acc, &edit_acc_vals[1]);
+    IAccessible_Release(acc);
+
+    SetFocus(edit[2]);
+    hr = CreateStdAccessibleObject(edit[2], OBJID_CLIENT, &IID_IAccessible, (void**)&acc);
+    str = SysAllocString(L"edit2-test\r\ntest-edit2\n");
+    hr = IAccessible_put_accValue(acc, v, str);
+    ok(hr == S_OK, "got %x\n", hr);
+    SysFreeString(str);
+    check_acc_vals(acc, &edit_acc_vals[2]);
+    IAccessible_Release(acc);
+
+    /*
+     * Hiding a label with a keyboard shortcut makes get_accKeyboardShortcut
+     * on the edit no longer return the labels shortcut, however get_accName
+     * still returns the labels string.
+     */
+    ShowWindow(label1, SW_HIDE);
+    SetFocus(btn1);
+    hr = CreateStdAccessibleObject(edit[3], OBJID_CLIENT, &IID_IAccessible, (void**)&acc);
+    ok(hr == S_OK, "got %x\n", hr);
+    check_acc_vals(acc, &edit_acc_vals[3]);
+    IAccessible_Release(acc);
+
+    DestroyWindow(hwnd);
+}
+
 START_TEST(main)
 {
     int argc;
@@ -1351,6 +1786,7 @@ START_TEST(main)
     test_default_client_accessible_object();
     test_AccessibleChildren(&Accessible);
     test_AccessibleObjectFromEvent();
+    test_default_edit_accessible_object();
 
     unregister_window_class();
     CoUninitialize();
-- 
2.25.1




More information about the wine-devel mailing list