browser_accessibility_mac_unittest.mm revision 8bcbed890bc3ce4d7a057a8f32cab53fa534672e
1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#import <Cocoa/Cocoa.h>
6
7#include "base/memory/scoped_ptr.h"
8#include "base/strings/string_util.h"
9#include "base/strings/utf_string_conversions.h"
10#include "content/browser/accessibility/browser_accessibility_cocoa.h"
11#include "content/browser/accessibility/browser_accessibility_manager.h"
12#include "content/browser/accessibility/browser_accessibility_manager_mac.h"
13#include "testing/gtest/include/gtest/gtest.h"
14#import "testing/gtest_mac.h"
15#import "ui/base/test/ui_cocoa_test_helper.h"
16
17@interface MockAccessibilityDelegate :
18    NSView<BrowserAccessibilityDelegateCocoa>
19
20- (NSPoint)accessibilityPointInScreen:(BrowserAccessibilityCocoa*)accessibility;
21- (void)doDefaultAction:(int32)accessibilityObjectId;
22- (void)accessibilitySetTextSelection:(int32)accId
23                          startOffset:(int32)startOffset
24                            endOffset:(int32)endOffset;
25- (void)performShowMenuAction:(BrowserAccessibilityCocoa*)accessibility;
26- (void)setAccessibilityFocus:(BOOL)focus
27              accessibilityId:(int32)accessibilityObjectId;
28- (NSWindow*)window;
29
30@end
31
32@implementation MockAccessibilityDelegate
33
34- (NSPoint)accessibilityPointInScreen:
35    (BrowserAccessibilityCocoa*)accessibility {
36  return NSZeroPoint;
37}
38- (void)doDefaultAction:(int32)accessibilityObjectId {
39}
40- (void)accessibilitySetTextSelection:(int32)accId
41                          startOffset:(int32)startOffset
42                            endOffset:(int32)endOffset {
43}
44- (void)performShowMenuAction:(BrowserAccessibilityCocoa*)accessibility {
45}
46- (void)setAccessibilityFocus:(BOOL)focus
47              accessibilityId:(int32)accessibilityObjectId {
48}
49- (NSWindow*)window {
50  return nil;
51}
52
53@end
54
55namespace content {
56
57class BrowserAccessibilityTest : public ui::CocoaTest {
58 public:
59  virtual void SetUp() {
60    CocoaTest::SetUp();
61    RebuildAccessibilityTree();
62  }
63
64 protected:
65  void RebuildAccessibilityTree() {
66    AccessibilityNodeData root;
67    root.id = 1000;
68    root.location.set_width(500);
69    root.location.set_height(100);
70    root.role = WebKit::WebAXRoleRootWebArea;
71    root.AddStringAttribute(AccessibilityNodeData::ATTR_HELP, "HelpText");
72    root.child_ids.push_back(1001);
73    root.child_ids.push_back(1002);
74
75    AccessibilityNodeData child1;
76    child1.id = 1001;
77    child1.SetName("Child1");
78    child1.location.set_width(250);
79    child1.location.set_height(100);
80    child1.role = WebKit::WebAXRoleButton;
81
82    AccessibilityNodeData child2;
83    child2.id = 1002;
84    child2.location.set_x(250);
85    child2.location.set_width(250);
86    child2.location.set_height(100);
87    child2.role = WebKit::WebAXRoleHeading;
88
89    delegate_.reset([[MockAccessibilityDelegate alloc] init]);
90    manager_.reset(
91        new BrowserAccessibilityManagerMac(delegate_, root, NULL));
92    manager_->UpdateNodesForTesting(child1, child2);
93    accessibility_.reset([manager_->GetRoot()->ToBrowserAccessibilityCocoa()
94        retain]);
95  }
96
97  base::scoped_nsobject<MockAccessibilityDelegate> delegate_;
98  base::scoped_nsobject<BrowserAccessibilityCocoa> accessibility_;
99  scoped_ptr<BrowserAccessibilityManager> manager_;
100};
101
102// Standard hit test.
103TEST_F(BrowserAccessibilityTest, HitTestTest) {
104  BrowserAccessibilityCocoa* firstChild =
105      [accessibility_ accessibilityHitTest:NSMakePoint(50, 50)];
106  EXPECT_NSEQ(@"Child1",
107      [firstChild accessibilityAttributeValue:NSAccessibilityTitleAttribute]);
108}
109
110// Test doing a hit test on the edge of a child.
111TEST_F(BrowserAccessibilityTest, EdgeHitTest) {
112  BrowserAccessibilityCocoa* firstChild =
113      [accessibility_ accessibilityHitTest:NSZeroPoint];
114  EXPECT_NSEQ(@"Child1",
115      [firstChild accessibilityAttributeValue:NSAccessibilityTitleAttribute]);
116}
117
118// This will test a hit test with invalid coordinates.  It is assumed that
119// the hit test has been narrowed down to this object or one of its children
120// so it should return itself since it has no better hit result.
121TEST_F(BrowserAccessibilityTest, InvalidHitTestCoordsTest) {
122  BrowserAccessibilityCocoa* hitTestResult =
123      [accessibility_ accessibilityHitTest:NSMakePoint(-50, 50)];
124  EXPECT_NSEQ(accessibility_, hitTestResult);
125}
126
127// Test to ensure querying standard attributes works.
128TEST_F(BrowserAccessibilityTest, BasicAttributeTest) {
129  NSString* helpText = [accessibility_
130      accessibilityAttributeValue:NSAccessibilityHelpAttribute];
131  EXPECT_NSEQ(@"HelpText", helpText);
132}
133
134// Test querying for an invalid attribute to ensure it doesn't crash.
135TEST_F(BrowserAccessibilityTest, InvalidAttributeTest) {
136  NSString* shouldBeNil = [accessibility_
137      accessibilityAttributeValue:@"NSAnInvalidAttribute"];
138  EXPECT_TRUE(shouldBeNil == nil);
139}
140
141TEST_F(BrowserAccessibilityTest, RetainedDetachedObjectsReturnNil) {
142  // Get the first child.
143  BrowserAccessibilityCocoa* retainedFirstChild =
144      [accessibility_ accessibilityHitTest:NSMakePoint(50, 50)];
145  EXPECT_NSEQ(@"Child1", [retainedFirstChild
146      accessibilityAttributeValue:NSAccessibilityTitleAttribute]);
147
148  // Retain it. This simulates what the system might do with an
149  // accessibility object.
150  [retainedFirstChild retain];
151
152  // Rebuild the accessibility tree, which should detach |retainedFirstChild|.
153  RebuildAccessibilityTree();
154
155  // Now any attributes we query should return nil.
156  EXPECT_EQ(nil, [retainedFirstChild
157      accessibilityAttributeValue:NSAccessibilityTitleAttribute]);
158
159  // Don't leak memory in the test.
160  [retainedFirstChild release];
161}
162
163}  // namespace content
164