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 #include "chrome/test/base/module_system_test.h" 6 7 #include "grit/renderer_resources.h" 8 9 namespace extensions { 10 namespace { 11 12 class EventUnittest : public ModuleSystemTest { 13 virtual void SetUp() OVERRIDE { 14 ModuleSystemTest::SetUp(); 15 16 RegisterModule("event_bindings", IDR_EVENT_BINDINGS_JS); 17 RegisterModule("json_schema", IDR_JSON_SCHEMA_JS); 18 RegisterModule("schemaUtils", IDR_SCHEMA_UTILS_JS); 19 RegisterModule("unload_event", IDR_UNLOAD_EVENT_JS); 20 RegisterModule("utils", IDR_UTILS_JS); 21 22 // Mock out the native handler for event_bindings. These mocks will fail if 23 // any invariants maintained by the real event_bindings are broken. 24 OverrideNativeHandler("event_natives", 25 "var assert = requireNative('assert');" 26 "var attachedListeners = exports.attachedListeners = {};" 27 "var attachedFilteredListeners = " 28 " exports.attachedFilteredListeners = {};" 29 "var nextId = 0;" 30 "var idToName = {};" 31 32 "exports.AttachEvent = function(eventName) {" 33 " assert.AssertFalse(!!attachedListeners[eventName]);" 34 " attachedListeners[eventName] = 1;" 35 "};" 36 37 "exports.DetachEvent = function(eventName) {" 38 " assert.AssertTrue(!!attachedListeners[eventName]);" 39 " delete attachedListeners[eventName];" 40 "};" 41 42 "exports.IsEventAttached = function(eventName) {" 43 " return !!attachedListeners[eventName];" 44 "};" 45 46 "exports.AttachFilteredEvent = function(name, filters) {" 47 " var id = nextId++;" 48 " idToName[id] = name;" 49 " attachedFilteredListeners[name] =" 50 " attachedFilteredListeners[name] || [];" 51 " attachedFilteredListeners[name][id] = filters;" 52 " return id;" 53 "};" 54 55 "exports.DetachFilteredEvent = function(id, manual) {" 56 " var i = attachedFilteredListeners[idToName[id]].indexOf(id);" 57 " attachedFilteredListeners[idToName[id]].splice(i, 1);" 58 "};" 59 60 "exports.HasFilteredListener = function(name) {" 61 " return attachedFilteredListeners[name].length;" 62 "};"); 63 OverrideNativeHandler("sendRequest", 64 "exports.sendRequest = function() {};"); 65 OverrideNativeHandler("apiDefinitions", 66 "exports.GetExtensionAPIDefinitionsForTest = function() {};"); 67 OverrideNativeHandler("logging", 68 "exports.DCHECK = function() {};"); 69 OverrideNativeHandler("schema_registry", 70 "exports.GetSchema = function() {};"); 71 } 72 }; 73 74 TEST_F(EventUnittest, TestNothing) { 75 ExpectNoAssertionsMade(); 76 } 77 78 TEST_F(EventUnittest, AddRemoveTwoListeners) { 79 ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system_.get()); 80 RegisterModule("test", 81 "var assert = requireNative('assert');" 82 "var Event = require('event_bindings').Event;" 83 "var eventNatives = requireNative('event_natives');" 84 "var myEvent = new Event('named-event');" 85 "var cb1 = function() {};" 86 "var cb2 = function() {};" 87 "myEvent.addListener(cb1);" 88 "myEvent.addListener(cb2);" 89 "myEvent.removeListener(cb1);" 90 "assert.AssertTrue(!!eventNatives.attachedListeners['named-event']);" 91 "myEvent.removeListener(cb2);" 92 "assert.AssertFalse(!!eventNatives.attachedListeners['named-event']);"); 93 module_system_->Require("test"); 94 } 95 96 TEST_F(EventUnittest, OnUnloadDetachesAllListeners) { 97 ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system_.get()); 98 RegisterModule("test", 99 "var assert = requireNative('assert');" 100 "var Event = require('event_bindings').Event;" 101 "var eventNatives = requireNative('event_natives');" 102 "var myEvent = new Event('named-event');" 103 "var cb1 = function() {};" 104 "var cb2 = function() {};" 105 "myEvent.addListener(cb1);" 106 "myEvent.addListener(cb2);" 107 "require('unload_event').dispatch();" 108 "assert.AssertFalse(!!eventNatives.attachedListeners['named-event']);"); 109 module_system_->Require("test"); 110 } 111 112 TEST_F(EventUnittest, OnUnloadDetachesAllListenersEvenDupes) { 113 ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system_.get()); 114 RegisterModule("test", 115 "var assert = requireNative('assert');" 116 "var Event = require('event_bindings').Event;" 117 "var eventNatives = requireNative('event_natives');" 118 "var myEvent = new Event('named-event');" 119 "var cb1 = function() {};" 120 "myEvent.addListener(cb1);" 121 "myEvent.addListener(cb1);" 122 "require('unload_event').dispatch();" 123 "assert.AssertFalse(!!eventNatives.attachedListeners['named-event']);"); 124 module_system_->Require("test"); 125 } 126 127 TEST_F(EventUnittest, EventsThatSupportRulesMustHaveAName) { 128 ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system_.get()); 129 RegisterModule("test", 130 "var Event = require('event_bindings').Event;" 131 "var eventOpts = {supportsRules: true};" 132 "var assert = requireNative('assert');" 133 "var caught = false;" 134 "try {" 135 " var myEvent = new Event(undefined, undefined, eventOpts);" 136 "} catch (e) {" 137 " caught = true;" 138 "}" 139 "assert.AssertTrue(caught);"); 140 module_system_->Require("test"); 141 } 142 143 TEST_F(EventUnittest, NamedEventDispatch) { 144 ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system_.get()); 145 RegisterModule("test", 146 "var Event = require('event_bindings').Event;" 147 "var dispatchEvent = require('event_bindings').dispatchEvent;" 148 "var assert = requireNative('assert');" 149 "var e = new Event('myevent');" 150 "var called = false;" 151 "e.addListener(function() { called = true; });" 152 "dispatchEvent('myevent', []);" 153 "assert.AssertTrue(called);"); 154 module_system_->Require("test"); 155 } 156 157 TEST_F(EventUnittest, AddListenerWithFiltersThrowsErrorByDefault) { 158 ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system_.get()); 159 RegisterModule("test", 160 "var Event = require('event_bindings').Event;" 161 "var assert = requireNative('assert');" 162 "var e = new Event('myevent');" 163 "var filter = [{" 164 " url: {hostSuffix: 'google.com'}," 165 "}];" 166 "var caught = false;" 167 "try {" 168 " e.addListener(function() {}, filter);" 169 "} catch (e) {" 170 " caught = true;" 171 "}" 172 "assert.AssertTrue(caught);"); 173 module_system_->Require("test"); 174 } 175 176 TEST_F(EventUnittest, FilteredEventsAttachment) { 177 ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system_.get()); 178 RegisterModule("test", 179 "var Event = require('event_bindings').Event;" 180 "var assert = requireNative('assert');" 181 "var bindings = requireNative('event_natives');" 182 "var eventOpts = {supportsListeners: true, supportsFilters: true};" 183 "var e = new Event('myevent', undefined, eventOpts);" 184 "var cb = function() {};" 185 "var filters = {url: [{hostSuffix: 'google.com'}]};" 186 "e.addListener(cb, filters);" 187 "assert.AssertTrue(bindings.HasFilteredListener('myevent'));" 188 "e.removeListener(cb);" 189 "assert.AssertFalse(bindings.HasFilteredListener('myevent'));"); 190 module_system_->Require("test"); 191 } 192 193 TEST_F(EventUnittest, DetachFilteredEvent) { 194 ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system_.get()); 195 RegisterModule("test", 196 "var Event = require('event_bindings').Event;" 197 "var assert = requireNative('assert');" 198 "var bindings = requireNative('event_natives');" 199 "var eventOpts = {supportsListeners: true, supportsFilters: true};" 200 "var e = new Event('myevent', undefined, eventOpts);" 201 "var cb1 = function() {};" 202 "var cb2 = function() {};" 203 "var filters = {url: [{hostSuffix: 'google.com'}]};" 204 "e.addListener(cb1, filters);" 205 "e.addListener(cb2, filters);" 206 "e.detach_();" 207 "assert.AssertFalse(bindings.HasFilteredListener('myevent'));"); 208 module_system_->Require("test"); 209 } 210 211 TEST_F(EventUnittest, AttachAndRemoveSameFilteredEventListener) { 212 ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system_.get()); 213 RegisterModule("test", 214 "var Event = require('event_bindings').Event;" 215 "var assert = requireNative('assert');" 216 "var bindings = requireNative('event_natives');" 217 "var eventOpts = {supportsListeners: true, supportsFilters: true};" 218 "var e = new Event('myevent', undefined, eventOpts);" 219 "var cb = function() {};" 220 "var filters = {url: [{hostSuffix: 'google.com'}]};" 221 "e.addListener(cb, filters);" 222 "e.addListener(cb, filters);" 223 "assert.AssertTrue(bindings.HasFilteredListener('myevent'));" 224 "e.removeListener(cb);" 225 "assert.AssertTrue(bindings.HasFilteredListener('myevent'));" 226 "e.removeListener(cb);" 227 "assert.AssertFalse(bindings.HasFilteredListener('myevent'));"); 228 module_system_->Require("test"); 229 } 230 231 TEST_F(EventUnittest, AddingFilterWithUrlFieldNotAListThrowsException) { 232 ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system_.get()); 233 RegisterModule("test", 234 "var Event = require('event_bindings').Event;" 235 "var assert = requireNative('assert');" 236 "var eventOpts = {supportsListeners: true, supportsFilters: true};" 237 "var e = new Event('myevent', undefined, eventOpts);" 238 "var cb = function() {};" 239 "var filters = {url: {hostSuffix: 'google.com'}};" 240 "var caught = false;" 241 "try {" 242 " e.addListener(cb, filters);" 243 "} catch (e) {" 244 " caught = true;" 245 "}" 246 "assert.AssertTrue(caught);"); 247 module_system_->Require("test"); 248 } 249 250 TEST_F(EventUnittest, MaxListeners) { 251 ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system_.get()); 252 RegisterModule("test", 253 "var Event = require('event_bindings').Event;" 254 "var assert = requireNative('assert');" 255 "var eventOpts = {supportsListeners: true, maxListeners: 1};" 256 "var e = new Event('myevent', undefined, eventOpts);" 257 "var cb = function() {};" 258 "var caught = false;" 259 "try {" 260 " e.addListener(cb);" 261 "} catch (e) {" 262 " caught = true;" 263 "}" 264 "assert.AssertTrue(!caught);" 265 "try {" 266 " e.addListener(cb);" 267 "} catch (e) {" 268 " caught = true;" 269 "}" 270 "assert.AssertTrue(caught);"); 271 module_system_->Require("test"); 272 } 273 274 } // namespace 275 } // namespace extensions 276