diff options
author | jcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-02 21:44:57 +0000 |
---|---|---|
committer | jcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-02 21:44:57 +0000 |
commit | 98db79501ca09608742194a66d54e55f036450a8 (patch) | |
tree | 80ccb9c3cc29e313d7cef06d074013422aa12f7f | |
parent | 5f9c249d80cd424784f5c34542c82e5ef4188b1e (diff) | |
download | chromium_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.html | 37 | ||||
-rw-r--r-- | webkit/tools/test_shell/event_listener_unittest.cc | 209 | ||||
-rw-r--r-- | webkit/tools/test_shell/test_shell.gyp | 1 |
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', |