summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-02 21:44:57 +0000
committerjcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-02 21:44:57 +0000
commit98db79501ca09608742194a66d54e55f036450a8 (patch)
tree80ccb9c3cc29e313d7cef06d074013422aa12f7f
parent5f9c249d80cd424784f5c34542c82e5ef4188b1e (diff)
downloadchromium_src-98db79501ca09608742194a66d54e55f036450a8.zip
chromium_src-98db79501ca09608742194a66d54e55f036450a8.tar.gz
chromium_src-98db79501ca09608742194a66d54e55f036450a8.tar.bz2
Unit-tests that test the current WebEventListener WebKit API.
BUG=None TEST=Run the tests. Review URL: http://codereview.chromium.org/543182 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@37885 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--webkit/data/listener/mutation_event_listener.html37
-rw-r--r--webkit/tools/test_shell/event_listener_unittest.cc209
-rw-r--r--webkit/tools/test_shell/test_shell.gyp1
3 files changed, 247 insertions, 0 deletions
diff --git a/webkit/data/listener/mutation_event_listener.html b/webkit/data/listener/mutation_event_listener.html
new file mode 100644
index 0000000..56efe59
--- /dev/null
+++ b/webkit/data/listener/mutation_event_listener.html
@@ -0,0 +1,37 @@
+<html>
+<head>
+<script>
+function removeNode(id) {
+ var node = document.getElementById(id);
+ node.parentNode.removeChild(node);
+ }
+
+function addElement(id) {
+ var elem = document.createElement("div");
+ elem.setAttribute("id", id);
+ var text = document.createTextNode("Added node id=" + id);
+ elem.appendChild(text);
+ document.getElementById("topDiv").appendChild(elem);
+ }
+
+function changeText(id, newText) {
+ var node = document.getElementById(id);
+ node.childNodes[0].nodeValue = newText;
+}
+</script>
+</head>
+
+<body>
+
+<div id="topDiv">
+ <div id="div1">Div #1</div>
+ <div id="div2">Div #2</div>
+ <div id="div3">Div #3</div>
+</div>
+
+<button onclick="removeNode('div1')">Remove node</button><br>
+<button onclick="addElement('bidule')">Add node</button><br>
+<button onclick="changeText('div2', 'Bijour')">Change text</button><br>
+
+</body>
+</html>
diff --git a/webkit/tools/test_shell/event_listener_unittest.cc b/webkit/tools/test_shell/event_listener_unittest.cc
new file mode 100644
index 0000000..aacd1a1
--- /dev/null
+++ b/webkit/tools/test_shell/event_listener_unittest.cc
@@ -0,0 +1,209 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <vector>
+
+#include "base/file_path.h"
+#include "base/message_loop.h"
+#include "base/path_service.h"
+#include "base/string_util.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebDocument.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebElement.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebEvent.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebEventListener.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebFrame.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebMutationEvent.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebScriptSource.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebView.h"
+#include "webkit/tools/test_shell/test_shell.h"
+#include "webkit/tools/test_shell/test_shell_request_context.h"
+#include "webkit/tools/test_shell/test_shell_test.h"
+
+namespace {
+
+using namespace WebKit;
+
+// This test exercices the event listener API from the WebKit API.
+class WebEventListenerTest : public TestShellTest {
+ public:
+ virtual void SetUp() {
+ TestShellTest::SetUp();
+ FilePath event_test_file;
+ ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &event_test_file));
+ event_test_file = event_test_file.Append(FILE_PATH_LITERAL("webkit"))
+ .Append(FILE_PATH_LITERAL("data"))
+ .Append(FILE_PATH_LITERAL("listener"))
+ .Append(FILE_PATH_LITERAL("mutation_event_listener.html"));
+ test_shell_->LoadFile(event_test_file);
+ test_shell_->WaitTestFinished();
+ }
+
+ virtual void TearDown() {
+ TestShellTest::TearDown();
+ }
+
+ WebFrame* main_frame() const {
+ return test_shell_->webView()->mainFrame();
+ }
+
+ WebDocument document() const {
+ return main_frame()->document();
+ }
+
+ void ExecuteScript(const char* code) {
+ main_frame()->executeScript(WebScriptSource(WebString::fromUTF8(code)));
+ }
+
+ static WebString GetNodeID(const WebNode& node) {
+ if (node.nodeType() != WebNode::ElementNode)
+ return WebString();
+ WebElement element = node.toConstElement<WebElement>();
+ return element.getAttribute("id");
+ }
+};
+
+class TestWebEventListener : public WebEventListener {
+ public:
+ TestWebEventListener() {}
+ virtual ~TestWebEventListener() {}
+
+ virtual void handleEvent(const WebEvent& event) {
+ events_.push_back(event);
+ }
+
+ size_t event_count() const { return events_.size(); }
+
+ WebEvent GetEventAt(int index) const { return events_.at(index); }
+
+ void ClearEvents() { events_.clear(); }
+
+ private:
+ std::vector<WebEvent> events_;
+};
+
+// Tests that the right mutation events are fired when a node is added/removed.
+// Note that the DOMSubtreeModified event is fairly vage, it only tells you
+// something changed for the target node.
+TEST_F(WebEventListenerTest, NodeAddedRemovedMutationEvent) {
+ TestWebEventListener event_listener;
+ document().addEventListener("DOMSubtreeModified", &event_listener, false);
+
+ // Test adding a node.
+ ExecuteScript("addElement('newNode')");
+ ASSERT_EQ(1U, event_listener.event_count());
+ WebEvent event = event_listener.GetEventAt(0);
+ ASSERT_TRUE(event.isMutationEvent());
+ // No need to check any of the MutationEvent, WebKit does not set any.
+ EXPECT_EQ("DIV", event.target().nodeName());
+ EXPECT_EQ("topDiv", GetNodeID(event.target()));
+ event_listener.ClearEvents();
+
+ // Test removing a node.
+ ExecuteScript("removeNode('div1')");
+ ASSERT_EQ(1U, event_listener.event_count());
+ event = event_listener.GetEventAt(0);
+ ASSERT_TRUE(event.isMutationEvent());
+ EXPECT_EQ("DIV", event.target().nodeName());
+ EXPECT_EQ("topDiv", GetNodeID(event.target()));
+}
+
+// Tests the right mutation event is fired when a text node is modified.
+TEST_F(WebEventListenerTest, TextNodeModifiedMutationEvent) {
+ TestWebEventListener event_listener;
+ document().addEventListener("DOMSubtreeModified", &event_listener, false);
+ ExecuteScript("changeText('div2', 'Hello')");
+ ASSERT_EQ(1U, event_listener.event_count());
+ WebEvent event = event_listener.GetEventAt(0);
+ ASSERT_TRUE(event.isMutationEvent());
+ ASSERT_EQ(WebNode::TextNode, event.target().nodeType());
+}
+
+// Tests the right mutation events are fired when an attribute is added/removed.
+TEST_F(WebEventListenerTest, AttributeMutationEvent) {
+ TestWebEventListener event_listener;
+ document().addEventListener("DOMSubtreeModified", &event_listener, false);
+ ExecuteScript("document.getElementById('div2').setAttribute('myAttr',"
+ "'some value')");
+ ASSERT_EQ(1U, event_listener.event_count());
+ WebEvent event = event_listener.GetEventAt(0);
+ ASSERT_TRUE(event.isMutationEvent());
+ EXPECT_EQ("DIV", event.target().nodeName());
+ EXPECT_EQ("div2", GetNodeID(event.target()));
+ event_listener.ClearEvents();
+
+ ExecuteScript("document.getElementById('div2').removeAttribute('myAttr')");
+ ASSERT_EQ(1U, event_listener.event_count());
+ event = event_listener.GetEventAt(0);
+ ASSERT_TRUE(event.isMutationEvent());
+ EXPECT_EQ("DIV", event.target().nodeName());
+ EXPECT_EQ("div2", GetNodeID(event.target()));
+}
+
+// Tests destroying WebEventListener and triggering events, we shouldn't crash.
+TEST_F(WebEventListenerTest, FireEventDeletedListener) {
+ TestWebEventListener* event_listener = new TestWebEventListener();
+ document().addEventListener("DOMSubtreeModified", event_listener, false);
+ delete event_listener;
+ ExecuteScript("addElement('newNode')"); // That should fire an event.
+}
+
+// Tests registering several events on the same WebEventListener and triggering
+// events.
+TEST_F(WebEventListenerTest, SameListenerMultipleEvents) {
+ TestWebEventListener event_listener;
+ const WebString kDOMSubtreeModifiedType("DOMSubtreeModified");
+ const WebString kDOMNodeRemovedType("DOMNodeRemoved");
+ document().addEventListener(kDOMSubtreeModifiedType, &event_listener, false);
+ WebElement div1_elem = document().getElementById("div1");
+ div1_elem.addEventListener(kDOMNodeRemovedType, &event_listener, false);
+
+ // Trigger a DOMSubtreeModified event by adding a node.
+ ExecuteScript("addElement('newNode')");
+ ASSERT_EQ(1U, event_listener.event_count());
+ WebEvent event = event_listener.GetEventAt(0);
+ ASSERT_TRUE(event.isMutationEvent());
+ EXPECT_EQ("DIV", event.target().nodeName());
+ EXPECT_EQ("topDiv", GetNodeID(event.target()));
+ event_listener.ClearEvents();
+
+ // Trigger for both event listener by removing the div1 node.
+ ExecuteScript("removeNode('div1')");
+ ASSERT_EQ(2U, event_listener.event_count());
+ // Not sure if the order of the events is important. Assuming no specific
+ // order.
+ WebString type1 = event_listener.GetEventAt(0).type();
+ WebString type2 = event_listener.GetEventAt(1).type();
+ EXPECT_TRUE(type1 == kDOMSubtreeModifiedType || type1 == kDOMNodeRemovedType);
+ EXPECT_TRUE(type2 == kDOMSubtreeModifiedType || type2 == kDOMNodeRemovedType);
+ EXPECT_TRUE(type1 != type2);
+}
+
+// Tests removing event listeners.
+TEST_F(WebEventListenerTest, RemoveEventListener) {
+ TestWebEventListener event_listener;
+ const WebString kDOMSubtreeModifiedType("DOMSubtreeModified");
+ // Adding twice the same listener for the same event, should be supported.
+ document().addEventListener(kDOMSubtreeModifiedType, &event_listener, false);
+ document().addEventListener(kDOMSubtreeModifiedType, &event_listener, false);
+
+ // Add a node, that should trigger 2 events.
+ ExecuteScript("addElement('newNode')");
+ EXPECT_EQ(2U, event_listener.event_count());
+ event_listener.ClearEvents();
+
+ // Remove one listener and trigger an event again.
+ document().removeEventListener(kDOMSubtreeModifiedType,
+ &event_listener, false);
+ ExecuteScript("addElement('newerNode')");
+ EXPECT_EQ(1U, event_listener.event_count());
+ event_listener.ClearEvents();
+
+ // Remove the last listener and trigger yet another event.
+ document().removeEventListener(kDOMSubtreeModifiedType,
+ &event_listener, false);
+ ExecuteScript("addElement('newererNode')");
+ EXPECT_EQ(0U, event_listener.event_count());
+}
+
+} // namespace
diff --git a/webkit/tools/test_shell/test_shell.gyp b/webkit/tools/test_shell/test_shell.gyp
index d837d1f..e8f0c45 100644
--- a/webkit/tools/test_shell/test_shell.gyp
+++ b/webkit/tools/test_shell/test_shell.gyp
@@ -427,6 +427,7 @@
'../webcore_unit_tests/ICOImageDecoder_unittest.cpp',
'../webcore_unit_tests/UniscribeHelper_unittest.cpp',
'../webcore_unit_tests/TransparencyWin_unittest.cpp',
+ 'event_listener_unittest.cc',
'image_decoder_unittest.cc',
'image_decoder_unittest.h',
'keyboard_unittest.cc',