OLD | NEW |
| (Empty) |
1 // Copyright (c) 2006-2008 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 // The DomAutocompleteTests in this file are responsible for ensuring the | |
6 // abstract dom autocomplete framework is correctly responding to events and | |
7 // delegating to appropriate places. This means concrete implementations should | |
8 // focus only on testing the code actually written for that implementation and | |
9 // those tests should be completely decoupled from WebCore::Event. | |
10 | |
11 #include <string> | |
12 | |
13 #include "config.h" | |
14 | |
15 #include "base/compiler_specific.h" | |
16 | |
17 MSVC_PUSH_WARNING_LEVEL(0); | |
18 #include "HTMLInputElement.h" | |
19 #include "HTMLFormElement.h" | |
20 #include "Document.h" | |
21 #include "Frame.h" | |
22 #include "Editor.h" | |
23 #include "EventNames.h" | |
24 #include "Event.h" | |
25 #include "EventListener.h" | |
26 #include <wtf/Threading.h> | |
27 MSVC_POP_WARNING(); | |
28 | |
29 #undef LOG | |
30 | |
31 #include "webkit/glue/autocomplete_input_listener.h" | |
32 #include "webkit/glue/webframe.h" | |
33 #include "webkit/glue/webframe_impl.h" | |
34 #include "webkit/glue/webview.h" | |
35 #include "webkit/tools/test_shell/test_shell_test.h" | |
36 #include "testing/gtest/include/gtest/gtest.h" | |
37 | |
38 using WebCore::Event; | |
39 | |
40 namespace webkit_glue { | |
41 | |
42 class TestAutocompleteBodyListener : public AutocompleteBodyListener { | |
43 public: | |
44 TestAutocompleteBodyListener() { | |
45 } | |
46 | |
47 void SetCaretAtEnd(WebCore::HTMLInputElement* element, bool value) { | |
48 std::vector<WebCore::HTMLInputElement*>::iterator iter = | |
49 std::find(caret_at_end_elements_.begin(), caret_at_end_elements_.end(), | |
50 element); | |
51 if (value) { | |
52 if (iter == caret_at_end_elements_.end()) | |
53 caret_at_end_elements_.push_back(element); | |
54 } else { | |
55 if (iter != caret_at_end_elements_.end()) | |
56 caret_at_end_elements_.erase(iter); | |
57 } | |
58 } | |
59 | |
60 void ResetTestState() { | |
61 caret_at_end_elements_.clear(); | |
62 } | |
63 | |
64 protected: | |
65 // AutocompleteBodyListener override. | |
66 virtual bool IsCaretAtEndOfText(WebCore::HTMLInputElement* element, | |
67 size_t input_length, | |
68 size_t previous_length) const { | |
69 return std::find(caret_at_end_elements_.begin(), | |
70 caret_at_end_elements_.end(), | |
71 element) != caret_at_end_elements_.end(); | |
72 } | |
73 | |
74 private: | |
75 // List of elements for which the caret is at the end of the text. | |
76 std::vector<WebCore::HTMLInputElement*> caret_at_end_elements_; | |
77 }; | |
78 | |
79 class TestAutocompleteInputListener : public AutocompleteInputListener { | |
80 public: | |
81 TestAutocompleteInputListener() | |
82 : blurred_(false), | |
83 did_request_inline_autocomplete_(false) { | |
84 } | |
85 | |
86 void ResetTestState() { | |
87 blurred_ = false; | |
88 did_request_inline_autocomplete_ = false; | |
89 } | |
90 | |
91 bool blurred() const { return blurred_; } | |
92 bool did_request_inline_autocomplete() const { | |
93 return did_request_inline_autocomplete_; | |
94 } | |
95 | |
96 virtual void OnBlur(WebCore::HTMLInputElement* element, | |
97 const std::wstring& user_input) { | |
98 blurred_ = true; | |
99 } | |
100 virtual void OnInlineAutocompleteNeeded(WebCore::HTMLInputElement* element, | |
101 const std::wstring& user_input) { | |
102 did_request_inline_autocomplete_ = true; | |
103 } | |
104 | |
105 private: | |
106 bool blurred_; | |
107 bool did_request_inline_autocomplete_; | |
108 }; | |
109 | |
110 namespace { | |
111 | |
112 class DomAutocompleteTests : public TestShellTest { | |
113 public: | |
114 virtual void SetUp() { | |
115 TestShellTest::SetUp(); | |
116 // We need a document in order to create HTMLInputElements. | |
117 WebView* view = test_shell_->webView(); | |
118 WebFrameImpl* frame = static_cast<WebFrameImpl*>(view->GetMainFrame()); | |
119 document_ = frame->frame()->document(); | |
120 } | |
121 | |
122 void FireAndHandleInputEvent(AutocompleteBodyListener* listener, | |
123 WebCore::HTMLInputElement* element) { | |
124 RefPtr<Event> event(Event::create(WebCore::eventNames().inputEvent, | |
125 false, false)); | |
126 event->setTarget(element); | |
127 listener->handleEvent(event.get(), false); | |
128 } | |
129 | |
130 void SimulateTypedInput(TestAutocompleteBodyListener* listener, | |
131 WebCore::HTMLInputElement* element, | |
132 const std::wstring& new_input, | |
133 bool caret_at_end) { | |
134 element->setValue(StdWStringToString(new_input)); | |
135 listener->SetCaretAtEnd(element, caret_at_end); | |
136 FireAndHandleInputEvent(listener, element); | |
137 } | |
138 | |
139 WebCore::Document* document_; | |
140 }; | |
141 } // namespace | |
142 | |
143 TEST_F(DomAutocompleteTests, OnBlur) { | |
144 RefPtr<WebCore::HTMLInputElement> ignored_element = | |
145 new WebCore::HTMLInputElement(document_); | |
146 RefPtr<WebCore::HTMLInputElement> listened_element = | |
147 new WebCore::HTMLInputElement(document_); | |
148 RefPtr<TestAutocompleteBodyListener> body_listener = | |
149 new TestAutocompleteBodyListener; | |
150 TestAutocompleteInputListener* listener = new TestAutocompleteInputListener(); | |
151 // body_listener takes ownership of the listener. | |
152 body_listener->AddInputListener(listened_element.get(), listener); | |
153 | |
154 // Simulate a blur event to the element we are not listening to. | |
155 // Our listener should not be notified. | |
156 RefPtr<Event> event(Event::create(WebCore::eventNames().DOMFocusOutEvent, | |
157 false, false)); | |
158 event->setTarget(ignored_element.get()); | |
159 body_listener->handleEvent(event.get(), false); | |
160 EXPECT_FALSE(listener->blurred()); | |
161 | |
162 // Now simulate the event on the input element we are listening to. | |
163 event->setTarget(listened_element.get()); | |
164 body_listener->handleEvent(event.get(), false); | |
165 EXPECT_TRUE(listener->blurred()); | |
166 } | |
167 | |
168 TEST_F(DomAutocompleteTests, InlineAutocompleteTriggeredByInputEvent) { | |
169 RefPtr<WebCore::HTMLInputElement> ignored_element = | |
170 new WebCore::HTMLInputElement(document_); | |
171 RefPtr<WebCore::HTMLInputElement> listened_element = | |
172 new WebCore::HTMLInputElement(document_); | |
173 RefPtr<TestAutocompleteBodyListener> body_listener = | |
174 new TestAutocompleteBodyListener; | |
175 | |
176 TestAutocompleteInputListener* listener = new TestAutocompleteInputListener(); | |
177 body_listener->AddInputListener(listened_element.get(), listener); | |
178 | |
179 // Simulate an inputEvent by setting the value and artificially firing evt. | |
180 // The user typed 'g'. | |
181 SimulateTypedInput(body_listener.get(), ignored_element.get(), L"g", true); | |
182 EXPECT_FALSE(listener->did_request_inline_autocomplete()); | |
183 SimulateTypedInput(body_listener.get(), listened_element.get(), L"g", true); | |
184 EXPECT_TRUE(listener->did_request_inline_autocomplete()); | |
185 } | |
186 | |
187 TEST_F(DomAutocompleteTests, InlineAutocompleteHeuristics) { | |
188 RefPtr<WebCore::HTMLInputElement> input_element = | |
189 new WebCore::HTMLInputElement(document_); | |
190 RefPtr<TestAutocompleteBodyListener> body_listener = | |
191 new TestAutocompleteBodyListener(); | |
192 | |
193 TestAutocompleteInputListener* listener = new TestAutocompleteInputListener(); | |
194 body_listener->AddInputListener(input_element.get(), listener); | |
195 | |
196 // Simulate a user entering some text, and then backspacing to remove | |
197 // a character. | |
198 SimulateTypedInput(body_listener.get(), input_element.get(), L"g", true); | |
199 EXPECT_TRUE(listener->did_request_inline_autocomplete()); | |
200 listener->ResetTestState(); | |
201 body_listener->ResetTestState(); | |
202 | |
203 SimulateTypedInput(body_listener.get(), input_element.get(), L"go", true); | |
204 EXPECT_TRUE(listener->did_request_inline_autocomplete()); | |
205 listener->ResetTestState(); | |
206 body_listener->ResetTestState(); | |
207 | |
208 SimulateTypedInput(body_listener.get(), input_element.get(), L"g", true); | |
209 EXPECT_FALSE(listener->did_request_inline_autocomplete()); | |
210 listener->ResetTestState(); | |
211 body_listener->ResetTestState(); | |
212 | |
213 // Now simulate the user moving the cursor to a position other than the end, | |
214 // and adding text. | |
215 SimulateTypedInput(body_listener.get(), input_element.get(), L"og", false); | |
216 EXPECT_FALSE(listener->did_request_inline_autocomplete()); | |
217 listener->ResetTestState(); | |
218 body_listener->ResetTestState(); | |
219 | |
220 // Test that same input doesn't trigger autocomplete. | |
221 SimulateTypedInput(body_listener.get(), input_element.get(), L"og", true); | |
222 EXPECT_FALSE(listener->did_request_inline_autocomplete()); | |
223 listener->ResetTestState(); | |
224 body_listener->ResetTestState(); | |
225 } | |
226 | |
227 } // webkit_glue | |
OLD | NEW |