diff options
Diffstat (limited to 'contexts/data/lib/closure-library/closure/goog/testing/events')
20 files changed, 2751 insertions, 0 deletions
diff --git a/contexts/data/lib/closure-library/closure/goog/testing/events/.svn/all-wcprops b/contexts/data/lib/closure-library/closure/goog/testing/events/.svn/all-wcprops new file mode 100644 index 0000000..40217df --- /dev/null +++ b/contexts/data/lib/closure-library/closure/goog/testing/events/.svn/all-wcprops @@ -0,0 +1,41 @@ +K 25 +svn:wc:ra_dav:version-url +V 52 +/svn/!svn/ver/1121/trunk/closure/goog/testing/events +END +events.js +K 25 +svn:wc:ra_dav:version-url +V 62 +/svn/!svn/ver/1121/trunk/closure/goog/testing/events/events.js +END +matchers.js +K 25 +svn:wc:ra_dav:version-url +V 63 +/svn/!svn/ver/850/trunk/closure/goog/testing/events/matchers.js +END +eventobserver.js +K 25 +svn:wc:ra_dav:version-url +V 68 +/svn/!svn/ver/850/trunk/closure/goog/testing/events/eventobserver.js +END +events_test.html +K 25 +svn:wc:ra_dav:version-url +V 68 +/svn/!svn/ver/850/trunk/closure/goog/testing/events/events_test.html +END +matchers_test.html +K 25 +svn:wc:ra_dav:version-url +V 70 +/svn/!svn/ver/850/trunk/closure/goog/testing/events/matchers_test.html +END +eventobserver_test.html +K 25 +svn:wc:ra_dav:version-url +V 75 +/svn/!svn/ver/850/trunk/closure/goog/testing/events/eventobserver_test.html +END diff --git a/contexts/data/lib/closure-library/closure/goog/testing/events/.svn/entries b/contexts/data/lib/closure-library/closure/goog/testing/events/.svn/entries new file mode 100644 index 0000000..5f866d1 --- /dev/null +++ b/contexts/data/lib/closure-library/closure/goog/testing/events/.svn/entries @@ -0,0 +1,232 @@ +10 + +dir +1494 +http://closure-library.googlecode.com/svn/trunk/closure/goog/testing/events +http://closure-library.googlecode.com/svn + + + +2011-07-13T20:14:20.000000Z +1121 +mariakhomenko@google.com + + + + + + + + + + + + + + +0b95b8e8-c90f-11de-9d4f-f947ee5921c8 + +events.js +file + + + + +2011-12-23T22:42:26.643307Z +e80b3f1837081d109617ca4492cc79c5 +2011-07-13T20:14:20.000000Z +1121 +mariakhomenko@google.com +has-props + + + + + + + + + + + + + + + + + + + + +22268 + +matchers.js +file + + + + +2011-12-23T22:42:26.644307Z +0868ba07c360e7c0bbacc323ffe7dc48 +2011-04-12T20:35:47.000000Z +850 +diegosalas@google.com +has-props + + + + + + + + + + + + + + + + + + + + +1446 + +eventobserver.js +file + + + + +2011-12-23T22:42:26.645307Z +63e612ab2b563faea779310778325f0e +2011-04-12T20:35:47.000000Z +850 +diegosalas@google.com +has-props + + + + + + + + + + + + + + + + + + + + +2567 + +events_test.html +file + + + + +2011-12-23T22:42:26.646307Z +13aa8b71279f7a76677065217ff78310 +2011-04-12T20:35:47.000000Z +850 +diegosalas@google.com +has-props + + + + + + + + + + + + + + + + + + + + +15057 + +matchers_test.html +file + + + + +2011-12-23T22:42:26.646307Z +122f3cc4347b5bebf86da42e712bb0c1 +2011-04-12T20:35:47.000000Z +850 +diegosalas@google.com +has-props + + + + + + + + + + + + + + + + + + + + +1099 + +eventobserver_test.html +file + + + + +2011-12-23T22:42:26.646307Z +24ad4c01167ec29fda328f32f7cd4e3c +2011-04-12T20:35:47.000000Z +850 +diegosalas@google.com +has-props + + + + + + + + + + + + + + + + + + + + +2185 + diff --git a/contexts/data/lib/closure-library/closure/goog/testing/events/.svn/prop-base/eventobserver.js.svn-base b/contexts/data/lib/closure-library/closure/goog/testing/events/.svn/prop-base/eventobserver.js.svn-base new file mode 100644 index 0000000..530636b --- /dev/null +++ b/contexts/data/lib/closure-library/closure/goog/testing/events/.svn/prop-base/eventobserver.js.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 15 +text/javascript +END diff --git a/contexts/data/lib/closure-library/closure/goog/testing/events/.svn/prop-base/eventobserver_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/testing/events/.svn/prop-base/eventobserver_test.html.svn-base new file mode 100644 index 0000000..d356868 --- /dev/null +++ b/contexts/data/lib/closure-library/closure/goog/testing/events/.svn/prop-base/eventobserver_test.html.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 9 +text/html +END diff --git a/contexts/data/lib/closure-library/closure/goog/testing/events/.svn/prop-base/events.js.svn-base b/contexts/data/lib/closure-library/closure/goog/testing/events/.svn/prop-base/events.js.svn-base new file mode 100644 index 0000000..530636b --- /dev/null +++ b/contexts/data/lib/closure-library/closure/goog/testing/events/.svn/prop-base/events.js.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 15 +text/javascript +END diff --git a/contexts/data/lib/closure-library/closure/goog/testing/events/.svn/prop-base/events_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/testing/events/.svn/prop-base/events_test.html.svn-base new file mode 100644 index 0000000..d356868 --- /dev/null +++ b/contexts/data/lib/closure-library/closure/goog/testing/events/.svn/prop-base/events_test.html.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 9 +text/html +END diff --git a/contexts/data/lib/closure-library/closure/goog/testing/events/.svn/prop-base/matchers.js.svn-base b/contexts/data/lib/closure-library/closure/goog/testing/events/.svn/prop-base/matchers.js.svn-base new file mode 100644 index 0000000..530636b --- /dev/null +++ b/contexts/data/lib/closure-library/closure/goog/testing/events/.svn/prop-base/matchers.js.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 15 +text/javascript +END diff --git a/contexts/data/lib/closure-library/closure/goog/testing/events/.svn/prop-base/matchers_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/testing/events/.svn/prop-base/matchers_test.html.svn-base new file mode 100644 index 0000000..d356868 --- /dev/null +++ b/contexts/data/lib/closure-library/closure/goog/testing/events/.svn/prop-base/matchers_test.html.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 9 +text/html +END diff --git a/contexts/data/lib/closure-library/closure/goog/testing/events/.svn/text-base/eventobserver.js.svn-base b/contexts/data/lib/closure-library/closure/goog/testing/events/.svn/text-base/eventobserver.js.svn-base new file mode 100644 index 0000000..83d6888 --- /dev/null +++ b/contexts/data/lib/closure-library/closure/goog/testing/events/.svn/text-base/eventobserver.js.svn-base @@ -0,0 +1,85 @@ +// Copyright 2010 The Closure Library Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Event observer. + * + * Provides an event observer that holds onto events that it handles. This + * can be used in unit testing to verify an event target's events -- + * that the order count, types, etc. are correct. + * + * Example usage: + * <pre> + * var observer = new goog.testing.events.EventObserver(); + * var widget = new foo.Widget(); + * goog.events.listen(widget, ['select', 'submit'], observer); + * // Simulate user action of 3 select events and 2 submit events. + * assertEquals(3, observer.getEvents('select').length); + * assertEquals(2, observer.getEvents('submit').length); + * </pre> + * + */ + +goog.provide('goog.testing.events.EventObserver'); + +goog.require('goog.array'); + + + +/** + * Event observer. Implements a handleEvent interface so it may be used as + * a listener in listening functions and methods. + * @see goog.events.listen + * @see goog.events.EventHandler + * @constructor + */ +goog.testing.events.EventObserver = function() { + + /** + * A list of events handled by the observer in order of handling, oldest to + * newest. + * @type {!Array.<!goog.events.Event>} + * @private + */ + this.events_ = []; +}; + + +/** + * Handles an event and remembers it. Event listening functions and methods + * will call this method when this observer is used as a listener. + * @see goog.events.listen + * @see goog.events.EventHandler + * @param {!goog.events.Event} e Event to handle. + */ +goog.testing.events.EventObserver.prototype.handleEvent = function(e) { + this.events_.push(e); +}; + + +/** + * @param {string=} opt_type If given, only return events of this type. + * @return {!Array.<!goog.events.Event>} The events handled, oldest to newest. + */ +goog.testing.events.EventObserver.prototype.getEvents = function(opt_type) { + var events = goog.array.clone(this.events_); + + if (opt_type) { + events = goog.array.filter(events, function(event) { + return event.type == opt_type; + }); + } + + return events; +}; diff --git a/contexts/data/lib/closure-library/closure/goog/testing/events/.svn/text-base/eventobserver_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/testing/events/.svn/text-base/eventobserver_test.html.svn-base new file mode 100644 index 0000000..200eae6 --- /dev/null +++ b/contexts/data/lib/closure-library/closure/goog/testing/events/.svn/text-base/eventobserver_test.html.svn-base @@ -0,0 +1,70 @@ +<!DOCTYPE html> +<html> +<!-- +Copyright 2010 The Closure Library Authors. All Rights Reserved. + +Use of this source code is governed by the Apache License, Version 2.0. +See the COPYING file for details. +--> +<head> +<meta http-equiv="X-UA-Compatible" content="IE=edge"> +<title>Closure Unit Tests - goog.testing.events.EventObserver</title> + <script src="../../base.js"></script> +<script> + goog.require('goog.array'); + goog.require('goog.events'); + goog.require('goog.events.EventTarget'); + goog.require('goog.testing.events.EventObserver'); + goog.require('goog.testing.jsunit'); +</script> +</head> +<body> +<script> + + // Return an event's type + function getEventType(e) { + return e.type; + } + + function testGetEvents() { + var observer = new goog.testing.events.EventObserver(); + var target = new goog.events.EventTarget(); + goog.events.listen(target, ['foo', 'bar', 'baz'], observer); + + var eventTypes = [ + 'bar', 'baz', 'foo', 'qux', 'quux', 'corge', 'foo', 'baz']; + goog.array.forEach(eventTypes, goog.bind(target.dispatchEvent, target)); + + var replayEvents = observer.getEvents(); + + assertArrayEquals('Only the listened-for event types should be remembered', + ['bar', 'baz', 'foo', 'foo', 'baz'], + goog.array.map(observer.getEvents(), getEventType)); + + assertArrayEquals(['bar'], + goog.array.map(observer.getEvents('bar'), getEventType)); + assertArrayEquals(['baz', 'baz'], + goog.array.map(observer.getEvents('baz'), getEventType)); + assertArrayEquals(['foo', 'foo'], + goog.array.map(observer.getEvents('foo'), getEventType)); + } + + function testHandleEvent() { + var events = [ + new goog.events.Event('foo'), + new goog.events.Event('bar'), + new goog.events.Event('baz') + ]; + + var observer = new goog.testing.events.EventObserver(); + goog.array.forEach(events, goog.bind(observer.handleEvent, observer)); + + assertArrayEquals(events, observer.getEvents()); + assertArrayEquals([events[0]], observer.getEvents('foo')); + assertArrayEquals([events[1]], observer.getEvents('bar')); + assertArrayEquals([events[2]], observer.getEvents('baz')); + } + +</script> +</body> +</html> diff --git a/contexts/data/lib/closure-library/closure/goog/testing/events/.svn/text-base/events.js.svn-base b/contexts/data/lib/closure-library/closure/goog/testing/events/.svn/text-base/events.js.svn-base new file mode 100644 index 0000000..8928c0b --- /dev/null +++ b/contexts/data/lib/closure-library/closure/goog/testing/events/.svn/text-base/events.js.svn-base @@ -0,0 +1,554 @@ +// Copyright 2008 The Closure Library Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Event Simulation. + * + * Utility functions for simulating events at the Closure level. All functions + * in this package generate events by calling goog.events.fireListeners, + * rather than interfacing with the browser directly. This is intended for + * testing purposes, and should not be used in production code. + * + * The decision to use Closure events and dispatchers instead of the browser's + * native events and dispatchers was conscious and deliberate. Native event + * dispatchers have their own set of quirks and edge cases. Pure JS dispatchers + * are more robust and transparent. + * + * If you think you need a testing mechanism that uses native Event objects, + * please, please email closure-tech first to explain your use case before you + * sink time into this. + * + * @author nicksantos@google.com (Nick Santos) + */ + +goog.provide('goog.testing.events'); +goog.provide('goog.testing.events.Event'); + +goog.require('goog.events'); +goog.require('goog.events.BrowserEvent'); +goog.require('goog.events.BrowserEvent.MouseButton'); +goog.require('goog.events.BrowserFeature'); +goog.require('goog.events.Event'); +goog.require('goog.events.EventType'); +goog.require('goog.events.KeyCodes'); +goog.require('goog.object'); +goog.require('goog.style'); +goog.require('goog.userAgent'); + + + +/** + * goog.events.BrowserEvent expects an Event so we provide one for JSCompiler. + * + * @param {string} type Event Type. + * @param {Object=} opt_target Reference to the object that is the target of + * this event. + * @constructor + * @extends {Event} + */ +goog.testing.events.Event = function(type, opt_target) { + /** + * Event type. + * @type {string} + */ + this.type = type; + + /** + * Target of the event. + * @type {Object|undefined} + */ + this.target = opt_target; + + /** + * Object that had the listener attached. + * @type {Object|undefined} + */ + this.currentTarget = this.target; +}; +goog.object.extend( + goog.testing.events.Event.prototype, goog.events.Event.prototype); + + +/** + * A static helper function that sets the mouse position to the event. + * @param {Event} event A simulated native event. + * @param {goog.math.Coordinate=} opt_coords Mouse position. Defaults to event's + * target's position (if available), otherwise (0, 0). + * @private + */ +goog.testing.events.setEventClientXY_ = function(event, opt_coords) { + if (!opt_coords && event.target && + event.target.nodeType == goog.dom.NodeType.ELEMENT) { + try { + opt_coords = + goog.style.getClientPosition(/** @type {Element} **/ (event.target)); + } catch (ex) { + // IE sometimes throws if it can't get the position. + } + } + event.clientX = opt_coords ? opt_coords.x : 0; + event.clientY = opt_coords ? opt_coords.y : 0; + + // Pretend the browser window is at (0, 0). + event.screenX = event.clientX; + event.screenY = event.clientY; +}; + + +/** + * Simulates a mousedown, mouseup, and then click on the given event target, + * with the left mouse button. + * @param {EventTarget} target The target for the event. + * @param {goog.events.BrowserEvent.MouseButton=} opt_button Mouse button; + * defaults to {@code goog.events.BrowserEvent.MouseButton.LEFT}. + * @param {goog.math.Coordinate=} opt_coords Mouse position. Defaults to event's + * target's position (if available), otherwise (0, 0). + * @param {Object=} opt_eventProperties Event properties to be mixed into the + * BrowserEvent. + * @return {boolean} The returnValue of the sequence: false if preventDefault() + * was called on any of the events, true otherwise. + */ +goog.testing.events.fireClickSequence = + function(target, opt_button, opt_coords, opt_eventProperties) { + // Fire mousedown, mouseup, and click. Then return the bitwise AND of the 3. + return !!(goog.testing.events.fireMouseDownEvent( + target, opt_button, opt_coords, opt_eventProperties) & + goog.testing.events.fireMouseUpEvent( + target, opt_button, opt_coords, opt_eventProperties) & + goog.testing.events.fireClickEvent( + target, opt_button, opt_coords, opt_eventProperties)); +}; + + +/** + * Simulates the sequence of events fired by the browser when the user double- + * clicks the given target. + * @param {EventTarget} target The target for the event. + * @param {goog.math.Coordinate=} opt_coords Mouse position. Defaults to event's + * target's position (if available), otherwise (0, 0). + * @param {Object=} opt_eventProperties Event properties to be mixed into the + * BrowserEvent. + * @return {boolean} The returnValue of the sequence: false if preventDefault() + * was called on any of the events, true otherwise. + */ +goog.testing.events.fireDoubleClickSequence = function( + target, opt_coords, opt_eventProperties) { + // Fire mousedown, mouseup, click, mousedown, mouseup, click, dblclick. + // Then return the bitwise AND of the 7. + var btn = goog.events.BrowserEvent.MouseButton.LEFT; + return !!(goog.testing.events.fireMouseDownEvent( + target, btn, opt_coords, opt_eventProperties) & + goog.testing.events.fireMouseUpEvent( + target, btn, opt_coords, opt_eventProperties) & + goog.testing.events.fireClickEvent( + target, btn, opt_coords, opt_eventProperties) & + // IE fires a selectstart instead of the second mousedown in a + // dblclick, but we don't care about selectstart. + (goog.userAgent.IE || + goog.testing.events.fireMouseDownEvent( + target, btn, opt_coords, opt_eventProperties)) & + goog.testing.events.fireMouseUpEvent( + target, btn, opt_coords, opt_eventProperties) & + // IE doesn't fire the second click in a dblclick. + (goog.userAgent.IE || + goog.testing.events.fireClickEvent( + target, btn, opt_coords, opt_eventProperties)) & + goog.testing.events.fireDoubleClickEvent( + target, opt_coords, opt_eventProperties)); +}; + + +/** + * Simulates a complete keystroke (keydown, keypress, and keyup). Note that + * if preventDefault is called on the keydown, the keypress will not fire. + * + * @param {EventTarget} target The target for the event. + * @param {number} keyCode The keycode of the key pressed. + * @param {Object=} opt_eventProperties Event properties to be mixed into the + * BrowserEvent. + * @return {boolean} The returnValue of the sequence: false if preventDefault() + * was called on any of the events, true otherwise. + */ +goog.testing.events.fireKeySequence = function( + target, keyCode, opt_eventProperties) { + return goog.testing.events.fireNonAsciiKeySequence(target, keyCode, keyCode, + opt_eventProperties); +}; + + +/** + * Simulates a complete keystroke (keydown, keypress, and keyup) when typing + * a non-ASCII character. Same as fireKeySequence, the keypress will not fire + * if preventDefault is called on the keydown. + * + * @param {EventTarget} target The target for the event. + * @param {number} keyCode The keycode of the keydown and keyup events. + * @param {number} keyPressKeyCode The keycode of the keypress event. + * @param {Object=} opt_eventProperties Event properties to be mixed into the + * BrowserEvent. + * @return {boolean} The returnValue of the sequence: false if preventDefault() + * was called on any of the events, true otherwise. + */ +goog.testing.events.fireNonAsciiKeySequence = function( + target, keyCode, keyPressKeyCode, opt_eventProperties) { + var keydown = + new goog.testing.events.Event(goog.events.EventType.KEYDOWN, target); + var keyup = + new goog.testing.events.Event(goog.events.EventType.KEYUP, target); + var keypress = + new goog.testing.events.Event(goog.events.EventType.KEYPRESS, target); + keydown.keyCode = keyup.keyCode = keyCode; + keypress.keyCode = keyPressKeyCode; + + if (opt_eventProperties) { + goog.object.extend(keydown, opt_eventProperties); + goog.object.extend(keyup, opt_eventProperties); + goog.object.extend(keypress, opt_eventProperties); + } + + // Fire keydown, keypress, and keyup. Note that if the keydown is + // prevent-defaulted, then the keypress will not fire on IE. + var result = true; + if (!goog.testing.events.isBrokenGeckoMacActionKey_(keydown)) { + result = goog.testing.events.fireBrowserEvent(keydown); + } + if (goog.events.KeyCodes.firesKeyPressEvent( + keyCode, undefined, keydown.shiftKey, keydown.ctrlKey, + keydown.altKey) && + !(goog.userAgent.IE && !result)) { + result &= goog.testing.events.fireBrowserEvent(keypress); + } + return !!(result & goog.testing.events.fireBrowserEvent(keyup)); +}; + + +/** + * @param {goog.testing.events.Event} e The event. + * @return {boolean} Whether this is the Gecko/Mac's Meta-C/V/X, which + * is broken and requires special handling. + * @private + */ +goog.testing.events.isBrokenGeckoMacActionKey_ = function(e) { + return goog.userAgent.MAC && goog.userAgent.GECKO && + (e.keyCode == goog.events.KeyCodes.C || + e.keyCode == goog.events.KeyCodes.X || + e.keyCode == goog.events.KeyCodes.V) && e.metaKey; +}; + + +/** + * Simulates a mouseover event on the given target. + * @param {EventTarget} target The target for the event. + * @param {EventTarget} relatedTarget The related target for the event (e.g., + * the node that the mouse is being moved out of). + * @param {goog.math.Coordinate=} opt_coords Mouse position. Defaults to event's + * target's position (if available), otherwise (0, 0). + * @return {boolean} The returnValue of the event: false if preventDefault() was + * called on it, true otherwise. + */ +goog.testing.events.fireMouseOverEvent = function(target, relatedTarget, + opt_coords) { + var mouseover = + new goog.testing.events.Event(goog.events.EventType.MOUSEOVER, target); + mouseover.relatedTarget = relatedTarget; + goog.testing.events.setEventClientXY_(mouseover, opt_coords); + return goog.testing.events.fireBrowserEvent(mouseover); +}; + + +/** + * Simulates a mousemove event on the given target. + * @param {EventTarget} target The target for the event. + * @param {goog.math.Coordinate=} opt_coords Mouse position. Defaults to event's + * target's position (if available), otherwise (0, 0). + * @return {boolean} The returnValue of the event: false if preventDefault() was + * called on it, true otherwise. + */ +goog.testing.events.fireMouseMoveEvent = function(target, opt_coords) { + var mousemove = + new goog.testing.events.Event(goog.events.EventType.MOUSEMOVE, target); + + goog.testing.events.setEventClientXY_(mousemove, opt_coords); + return goog.testing.events.fireBrowserEvent(mousemove); +}; + + +/** + * Simulates a mouseout event on the given target. + * @param {EventTarget} target The target for the event. + * @param {EventTarget} relatedTarget The related target for the event (e.g., + * the node that the mouse is being moved into). + * @param {goog.math.Coordinate=} opt_coords Mouse position. Defaults to event's + * target's position (if available), otherwise (0, 0). + * @return {boolean} The returnValue of the event: false if preventDefault() was + * called on it, true otherwise. + */ +goog.testing.events.fireMouseOutEvent = function(target, relatedTarget, + opt_coords) { + var mouseout = + new goog.testing.events.Event(goog.events.EventType.MOUSEOUT, target); + mouseout.relatedTarget = relatedTarget; + goog.testing.events.setEventClientXY_(mouseout, opt_coords); + return goog.testing.events.fireBrowserEvent(mouseout); +}; + + +/** + * Simulates a mousedown event on the given target. + * @param {EventTarget} target The target for the event. + * @param {goog.events.BrowserEvent.MouseButton=} opt_button Mouse button; + * defaults to {@code goog.events.BrowserEvent.MouseButton.LEFT}. + * @param {goog.math.Coordinate=} opt_coords Mouse position. Defaults to event's + * target's position (if available), otherwise (0, 0). + * @param {Object=} opt_eventProperties Event properties to be mixed into the + * BrowserEvent. + * @return {boolean} The returnValue of the event: false if preventDefault() was + * called on it, true otherwise. + */ +goog.testing.events.fireMouseDownEvent = + function(target, opt_button, opt_coords, opt_eventProperties) { + + var button = opt_button || goog.events.BrowserEvent.MouseButton.LEFT; + button = !goog.events.BrowserFeature.HAS_W3C_BUTTON ? + goog.events.BrowserEvent.IEButtonMap[button] : button; + return goog.testing.events.fireMouseButtonEvent_( + goog.events.EventType.MOUSEDOWN, target, button, opt_coords, + opt_eventProperties); +}; + + +/** + * Simulates a mouseup event on the given target. + * @param {EventTarget} target The target for the event. + * @param {goog.events.BrowserEvent.MouseButton=} opt_button Mouse button; + * defaults to {@code goog.events.BrowserEvent.MouseButton.LEFT}. + * @param {goog.math.Coordinate=} opt_coords Mouse position. Defaults to event's + * target's position (if available), otherwise (0, 0). + * @param {Object=} opt_eventProperties Event properties to be mixed into the + * BrowserEvent. + * @return {boolean} The returnValue of the event: false if preventDefault() was + * called on it, true otherwise. + */ +goog.testing.events.fireMouseUpEvent = + function(target, opt_button, opt_coords, opt_eventProperties) { + var button = opt_button || goog.events.BrowserEvent.MouseButton.LEFT; + button = !goog.events.BrowserFeature.HAS_W3C_BUTTON ? + goog.events.BrowserEvent.IEButtonMap[button] : button; + return goog.testing.events.fireMouseButtonEvent_( + goog.events.EventType.MOUSEUP, target, button, opt_coords, + opt_eventProperties); +}; + + +/** + * Simulates a click event on the given target. IE only supports click with + * the left mouse button. + * @param {EventTarget} target The target for the event. + * @param {goog.events.BrowserEvent.MouseButton=} opt_button Mouse button; + * defaults to {@code goog.events.BrowserEvent.MouseButton.LEFT}. + * @param {goog.math.Coordinate=} opt_coords Mouse position. Defaults to event's + * target's position (if available), otherwise (0, 0). + * @param {Object=} opt_eventProperties Event properties to be mixed into the + * BrowserEvent. + * @return {boolean} The returnValue of the event: false if preventDefault() was + * called on it, true otherwise. + */ +goog.testing.events.fireClickEvent = + function(target, opt_button, opt_coords, opt_eventProperties) { + return goog.testing.events.fireMouseButtonEvent_(goog.events.EventType.CLICK, + target, opt_button, opt_coords, opt_eventProperties); +}; + + +/** + * Simulates a double-click event on the given target. Always double-clicks + * with the left mouse button since no browser supports double-clicking with + * any other buttons. + * @param {EventTarget} target The target for the event. + * @param {goog.math.Coordinate=} opt_coords Mouse position. Defaults to event's + * target's position (if available), otherwise (0, 0). + * @param {Object=} opt_eventProperties Event properties to be mixed into the + * BrowserEvent. + * @return {boolean} The returnValue of the event: false if preventDefault() was + * called on it, true otherwise. + */ +goog.testing.events.fireDoubleClickEvent = + function(target, opt_coords, opt_eventProperties) { + return goog.testing.events.fireMouseButtonEvent_( + goog.events.EventType.DBLCLICK, target, + goog.events.BrowserEvent.MouseButton.LEFT, opt_coords, + opt_eventProperties); +}; + + +/** + * Helper function to fire a mouse event. + * with the left mouse button since no browser supports double-clicking with + * any other buttons. + * @param {string} type The event type. + * @param {EventTarget} target The target for the event. + * @param {number=} opt_button Mouse button; defaults to + * {@code goog.events.BrowserEvent.MouseButton.LEFT}. + * @param {goog.math.Coordinate=} opt_coords Mouse position. Defaults to event's + * target's position (if available), otherwise (0, 0). + * @param {Object=} opt_eventProperties Event properties to be mixed into the + * BrowserEvent. + * @return {boolean} The returnValue of the event: false if preventDefault() was + * called on it, true otherwise. + * @private + */ +goog.testing.events.fireMouseButtonEvent_ = + function(type, target, opt_button, opt_coords, opt_eventProperties) { + var e = + new goog.testing.events.Event(type, target); + e.button = opt_button || goog.events.BrowserEvent.MouseButton.LEFT; + goog.testing.events.setEventClientXY_(e, opt_coords); + if (opt_eventProperties) { + goog.object.extend(e, opt_eventProperties); + } + return goog.testing.events.fireBrowserEvent(e); +}; + + +/** + * Simulates a contextmenu event on the given target. + * @param {EventTarget} target The target for the event. + * @param {goog.math.Coordinate=} opt_coords Mouse position. Defaults to event's + * target's position (if available), otherwise (0, 0). + * @return {boolean} The returnValue of the event: false if preventDefault() was + * called on it, true otherwise. + */ +goog.testing.events.fireContextMenuEvent = function(target, opt_coords) { + var button = (goog.userAgent.MAC && goog.userAgent.WEBKIT) ? + goog.events.BrowserEvent.MouseButton.LEFT : + goog.events.BrowserEvent.MouseButton.RIGHT; + var contextmenu = + new goog.testing.events.Event(goog.events.EventType.CONTEXTMENU, target); + contextmenu.button = !goog.events.BrowserFeature.HAS_W3C_BUTTON ? + goog.events.BrowserEvent.IEButtonMap[button] : button; + contextmenu.ctrlKey = goog.userAgent.MAC; + goog.testing.events.setEventClientXY_(contextmenu, opt_coords); + return goog.testing.events.fireBrowserEvent(contextmenu); +}; + + +/** + * Simulates a mousedown, contextmenu, and the mouseup on the given event + * target, with the right mouse button. + * @param {EventTarget} target The target for the event. + * @param {goog.math.Coordinate=} opt_coords Mouse position. Defaults to event's + * target's position (if available), otherwise (0, 0). + * @return {boolean} The returnValue of the sequence: false if preventDefault() + * was called on any of the events, true otherwise. + */ +goog.testing.events.fireContextMenuSequence = function(target, opt_coords) { + var props = goog.userAgent.MAC ? {ctrlKey: true} : {}; + var button = (goog.userAgent.MAC && goog.userAgent.WEBKIT) ? + goog.events.BrowserEvent.MouseButton.LEFT : + goog.events.BrowserEvent.MouseButton.RIGHT; + + var result = goog.testing.events.fireMouseDownEvent(target, + button, opt_coords, props); + if (goog.userAgent.WINDOWS) { + // All browsers are consistent on Windows. + result &= goog.testing.events.fireMouseUpEvent(target, + button, opt_coords) & + goog.testing.events.fireContextMenuEvent(target, opt_coords); + } else { + result &= goog.testing.events.fireContextMenuEvent(target, opt_coords); + + // GECKO on Mac and Linux always fires the mouseup after the contextmenu. + + // WEBKIT is really weird. + // + // On Linux, it sometimes fires mouseup, but most of the time doesn't. + // It's really hard to reproduce consistently. I think there's some + // internal race condition. If contextmenu is preventDefaulted, then + // mouseup always fires. + // + // On Mac, it always fires mouseup and then fires a click. + result &= goog.testing.events.fireMouseUpEvent(target, + button, opt_coords, props); + + if (goog.userAgent.WEBKIT && goog.userAgent.MAC) { + result &= goog.testing.events.fireClickEvent( + target, button, opt_coords, props); + } + } + return !!result; +}; + + +/** + * Simulates a popstate event on the given target. + * @param {EventTarget} target The target for the event. + * @param {Object} state History state object. + * @return {boolean} The returnValue of the event: false if preventDefault() was + * called on it, true otherwise. + */ +goog.testing.events.firePopStateEvent = function(target, state) { + var e = new goog.testing.events.Event(goog.events.EventType.POPSTATE, target); + e.state = state; + return goog.testing.events.fireBrowserEvent(e); +}; + + +/** + * Simulate a focus event on the given target. + * @param {EventTarget} target The target for the event. + * @return {boolean} The value returned by firing the focus browser event, + * which returns false iff 'preventDefault' was invoked. + */ +goog.testing.events.fireFocusEvent = function(target) { + var e = new goog.testing.events.Event( + goog.events.EventType.FOCUS, target); + return goog.testing.events.fireBrowserEvent(e); +}; + + +/** + * Simulates an event's capturing and bubbling phases. + * @param {Event} event A simulated native event. It will be wrapped in a + * normalized BrowserEvent and dispatched to Closure listeners on all + * ancestors of its target (inclusive). + * @return {boolean} The returnValue of the event: false if preventDefault() was + * called on it, true otherwise. + */ +goog.testing.events.fireBrowserEvent = function(event) { + event.returnValue_ = true; + + // generate a list of ancestors + var ancestors = []; + for (var current = event.target; current; current = current.parentNode) { + ancestors.push(current); + } + + // dispatch capturing listeners + for (var j = ancestors.length - 1; + j >= 0 && !event.propagationStopped_; + j--) { + goog.events.fireListeners(ancestors[j], event.type, true, + new goog.events.BrowserEvent(event, ancestors[j])); + } + + // dispatch bubbling listeners + for (var j = 0; + j < ancestors.length && !event.propagationStopped_; + j++) { + goog.events.fireListeners(ancestors[j], event.type, false, + new goog.events.BrowserEvent(event, ancestors[j])); + } + + return event.returnValue_; +}; diff --git a/contexts/data/lib/closure-library/closure/goog/testing/events/.svn/text-base/events_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/testing/events/.svn/text-base/events_test.html.svn-base new file mode 100644 index 0000000..fd28121 --- /dev/null +++ b/contexts/data/lib/closure-library/closure/goog/testing/events/.svn/text-base/events_test.html.svn-base @@ -0,0 +1,434 @@ +<!-- +Copyright 2008 The Closure Library Authors. All Rights Reserved. + +Use of this source code is governed by the Apache License, Version 2.0. +See the COPYING file for details. +--> +<!DOCTYPE html> +<html lang="en" dir="ltr"> +<head> +<meta http-equiv="X-UA-Compatible" content="IE=edge"> + <!-- + + Author: nicksantos@google.com (Nick Santos) + --> + <title>Closure Unit Tests - goog.testing.events</title> + <script src="../../base.js"></script> + <script> + goog.require('goog.array'); + goog.require('goog.dom'); + goog.require('goog.math.Coordinate'); + goog.require('goog.string'); + goog.require('goog.testing.PropertyReplacer'); + goog.require('goog.testing.events'); + goog.require('goog.testing.jsunit'); + goog.require('goog.userAgent'); + + + </script> +</head> +<body> +<div id="root"></div> +<input id='testButton' type='input' value='Click Me' /> +<div id='input'>Prevent Default these events:<br/></div> +<div id='log' style='position:absolute;right:0;top:0'>Logged events:</div> +<script type="text/javascript"> + var firedEventTypes; + var firedEventCoordinates; + var firedScreenCoordinates; + var firedShiftKeys; + var firedKeyCodes; + var root = goog.dom.getElement('root'); + var log = goog.dom.getElement('log'); + var input = goog.dom.getElement('input'); + var testButton = goog.dom.getElement('testButton'); + var coordinate = new goog.math.Coordinate(123, 456); + var stubs = new goog.testing.PropertyReplacer(); + + function setUp() { + stubs.reset(); + goog.events.removeAll(); + root.innerHTML = ''; + firedEventTypes = []; + firedEventCoordinates = []; + firedScreenCoordinates = []; + firedShiftKeys = []; + firedKeyCodes = []; + + for (var key in goog.events.EventType) { + goog.events.listen(root, goog.events.EventType[key], function(e) { + firedEventTypes.push(e.type); + var coord = new goog.math.Coordinate(e.clientX, e.clientY); + firedEventCoordinates.push(coord); + + firedScreenCoordinates.push( + new goog.math.Coordinate(e.screenX, e.screenY)); + + firedShiftKeys.push(!!e.shiftKey); + firedKeyCodes.push(e.keyCode); + }); + } + } + + function tearDownPage() { + for (var key in goog.events.EventType) { + var type = goog.events.EventType[key]; + if (type == 'mousemove' || type == 'mouseout' || type == 'mouseover') { + continue; + } + goog.dom.appendChild(input, + goog.dom.createDom('label', null, + goog.dom.createDom('input', + {'id': type, 'type': 'checkbox'}), + type, + goog.dom.createDom('br'))); + goog.events.listen(testButton, type, function(e) { + if (goog.dom.getElement(e.type).checked) { + e.preventDefault(); + } + + log.innerHTML += goog.string.subs('<br/>%s (%s, %s)', + e.type, e.clientX, e.clientY); + }); + } + } + + function testMouseOver() { + goog.testing.events.fireMouseOverEvent(root, null); + goog.testing.events.fireMouseOverEvent(root, null, coordinate); + assertEventTypes(['mouseover', 'mouseover']); + assertCoordinates([goog.style.getClientPosition(root), coordinate]); + } + + function testMouseOut() { + goog.testing.events.fireMouseOutEvent(root, null); + goog.testing.events.fireMouseOutEvent(root, null, coordinate); + assertEventTypes(['mouseout', 'mouseout']); + assertCoordinates([goog.style.getClientPosition(root), coordinate]); + } + + function testClickSequence() { + assertTrue(goog.testing.events.fireClickSequence(root)); + assertEventTypes(['mousedown', 'mouseup', 'click']); + var rootPosition = goog.style.getClientPosition(root); + assertCoordinates([rootPosition, rootPosition, rootPosition]); + } + + function testClickSequenceWithCoordinate() { + assertTrue(goog.testing.events.fireClickSequence(root, null, coordinate)); + assertCoordinates([coordinate, coordinate, coordinate]); + assertArrayEquals([false, false, false], firedShiftKeys); + } + + function testClickSequenceWithEventProperty() { + assertTrue(goog.testing.events.fireClickSequence( + root, null, undefined, { shiftKey: true })); + assertArrayEquals([true, true, true], firedShiftKeys); + } + + function testClickSequenceCancellingMousedown() { + preventDefaultEventType('mousedown'); + assertFalse(goog.testing.events.fireClickSequence(root)); + assertEventTypes(['mousedown', 'mouseup', 'click']); + } + + function testClickSequenceCancellingMousedownWithCoordinate() { + preventDefaultEventType('mousedown'); + assertFalse(goog.testing.events.fireClickSequence(root, null, coordinate)); + assertCoordinates([coordinate, coordinate, coordinate]); + } + + function testClickSequenceCancellingMouseup() { + preventDefaultEventType('mouseup'); + assertFalse(goog.testing.events.fireClickSequence(root)); + assertEventTypes(['mousedown', 'mouseup', 'click']); + } + + function testClickSequenceCancellingMouseupWithCoordinate() { + preventDefaultEventType('mouseup'); + assertFalse(goog.testing.events.fireClickSequence(root, null, coordinate)); + assertCoordinates([coordinate, coordinate, coordinate]); + } + + function testClickSequenceCancellingClick() { + preventDefaultEventType('click'); + assertFalse(goog.testing.events.fireClickSequence(root)); + assertEventTypes(['mousedown', 'mouseup', 'click']); + } + + function testClickSequenceCancellingClickWithCoordinate() { + preventDefaultEventType('click'); + assertFalse(goog.testing.events.fireClickSequence(root, null, coordinate)); + assertCoordinates([coordinate, coordinate, coordinate]); + } + + // For a double click, IE fires selectstart instead of the second mousedown, + // but we don't simulate selectstart. Also, IE doesn't fire the second click. + var DBLCLICK_SEQ = (goog.userAgent.IE ? + ['mousedown', + 'mouseup', + 'click', + 'mouseup', + 'dblclick'] : + ['mousedown', + 'mouseup', + 'click', + 'mousedown', + 'mouseup', + 'click', + 'dblclick']); + + + var DBLCLICK_SEQ_COORDS = goog.array.repeat(coordinate, DBLCLICK_SEQ.length); + + function testDoubleClickSequence() { + assertTrue(goog.testing.events.fireDoubleClickSequence(root)); + assertEventTypes(DBLCLICK_SEQ); + } + + function testDoubleClickSequenceWithCoordinate() { + assertTrue(goog.testing.events.fireDoubleClickSequence(root, coordinate)); + assertCoordinates(DBLCLICK_SEQ_COORDS); + } + + function testDoubleClickSequenceCancellingMousedown() { + preventDefaultEventType('mousedown'); + assertFalse(goog.testing.events.fireDoubleClickSequence(root)); + assertEventTypes(DBLCLICK_SEQ); + } + + function testDoubleClickSequenceCancellingMousedownWithCoordinate() { + preventDefaultEventType('mousedown'); + assertFalse(goog.testing.events.fireDoubleClickSequence(root, coordinate)); + assertCoordinates(DBLCLICK_SEQ_COORDS); + } + + function testDoubleClickSequenceCancellingMouseup() { + preventDefaultEventType('mouseup'); + assertFalse(goog.testing.events.fireDoubleClickSequence(root)); + assertEventTypes(DBLCLICK_SEQ); + } + + function testDoubleClickSequenceCancellingMouseupWithCoordinate() { + preventDefaultEventType('mouseup'); + assertFalse(goog.testing.events.fireDoubleClickSequence(root, coordinate)); + assertCoordinates(DBLCLICK_SEQ_COORDS); + } + + function testDoubleClickSequenceCancellingClick() { + preventDefaultEventType('click'); + assertFalse(goog.testing.events.fireDoubleClickSequence(root)); + assertEventTypes(DBLCLICK_SEQ); + } + + function testDoubleClickSequenceCancellingClickWithCoordinate() { + preventDefaultEventType('click'); + assertFalse(goog.testing.events.fireDoubleClickSequence(root, coordinate)); + assertCoordinates(DBLCLICK_SEQ_COORDS); + } + + function testDoubleClickSequenceCancellingDoubleClick() { + preventDefaultEventType('dblclick'); + assertFalse(goog.testing.events.fireDoubleClickSequence(root)); + assertEventTypes(DBLCLICK_SEQ); + } + + function testDoubleClickSequenceCancellingDoubleClickWithCoordinate() { + preventDefaultEventType('dblclick'); + assertFalse(goog.testing.events.fireDoubleClickSequence(root, coordinate)); + assertCoordinates(DBLCLICK_SEQ_COORDS); + } + + function testKeySequence() { + assertTrue(goog.testing.events.fireKeySequence( + root, goog.events.KeyCodes.ZERO)); + assertEventTypes(['keydown', 'keypress', 'keyup']); + } + + function testKeySequenceCancellingKeydown() { + preventDefaultEventType('keydown'); + assertFalse(goog.testing.events.fireKeySequence( + root, goog.events.KeyCodes.ZERO)); + if (goog.userAgent.IE) { + assertEventTypes(['keydown', 'keyup']); + } else { + assertEventTypes(['keydown', 'keypress', 'keyup']); + } + } + + function testKeySequenceCancellingKeypress() { + preventDefaultEventType('keypress'); + assertFalse(goog.testing.events.fireKeySequence( + root, goog.events.KeyCodes.ZERO)); + assertEventTypes(['keydown', 'keypress', 'keyup']); + } + + function testKeySequenceCancellingKeyup() { + preventDefaultEventType('keyup'); + assertFalse(goog.testing.events.fireKeySequence( + root, goog.events.KeyCodes.ZERO)); + assertEventTypes(['keydown', 'keypress', 'keyup']); + } + + function testKeySequenceWithEscapeKey() { + assertTrue(goog.testing.events.fireKeySequence( + root, goog.events.KeyCodes.ESC)); + if (goog.userAgent.WEBKIT && goog.userAgent.isVersion('525')) { + assertEventTypes(['keydown', 'keyup']); + } else { + assertEventTypes(['keydown', 'keypress', 'keyup']); + } + } + + function testKeySequenceForMacActionKeysNegative() { + stubs.set(goog.userAgent, 'GECKO', false); + goog.testing.events.fireKeySequence( + root, goog.events.KeyCodes.C, {'metaKey': true}); + assertEventTypes(['keydown', 'keypress', 'keyup']); + } + + function testKeySequenceForMacActionKeysPositive() { + stubs.set(goog.userAgent, 'GECKO', true); + stubs.set(goog.userAgent, 'MAC', true); + goog.testing.events.fireKeySequence( + root, goog.events.KeyCodes.C, {'metaKey': true}); + assertEventTypes(['keypress', 'keyup']); + } + + function testKeySequenceForOptionKeysOnMac() { + // Mac uses an option (or alt) key to type non-ASCII characters. This test + // verifies we can emulate key events sent when typing such non-ASCII + // characters. + stubs.set(goog.userAgent, 'WEBKIT', true); + stubs.set(goog.userAgent, 'MAC', true); + + var optionKeyCodes = [ + [0xc0, 0x00e6], // option+' + [0xbc, 0x2264], // option+, + [0xbd, 0x2013], // option+- + [0xbe, 0x2265], // option+. + [0xbf, 0x00f7], // option+/ + [0x30, 0x00ba], // option+0 + [0x31, 0x00a1], // option+1 + [0x32, 0x2122], // option+2 + [0x33, 0x00a3], // option+3 + [0x34, 0x00a2], // option+4 + [0x35, 0x221e], // option+5 + [0x36, 0x00a7], // option+6 + [0x37, 0x00b6], // option+7 + [0x38, 0x2022], // option+8 + [0x39, 0x00aa], // option+9 + [0xba, 0x2026], // option+; + [0xbb, 0x2260], // option+= + [0xdb, 0x201c], // option+[ + [0xdc, 0x00ab], // option+\ + [0xdd, 0x2018], // option+] + [0x41, 0x00e5], // option+a + [0x42, 0x222b], // option+b + [0x43, 0x00e7], // option+c + [0x44, 0x2202], // option+d + [0x45, 0x00b4], // option+e + [0x46, 0x0192], // option+f + [0x47, 0x00a9], // option+g + [0x48, 0x02d9], // option+h + [0x49, 0x02c6], // option+i + [0x4a, 0x2206], // option+j + [0x4b, 0x02da], // option+k + [0x4c, 0x00ac], // option+l + [0x4d, 0x00b5], // option+m + [0x4e, 0x02dc], // option+n + [0x4f, 0x00f8], // option+o + [0x50, 0x03c0], // option+p + [0x51, 0x0153], // option+q + [0x52, 0x00ae], // option+r + [0x53, 0x00df], // option+s + [0x54, 0x2020], // option+t + [0x56, 0x221a], // option+v + [0x57, 0x2211], // option+w + [0x58, 0x2248], // option+x + [0x59, 0x00a5], // option+y + [0x5a, 0x03a9] // option+z + ]; + + for (var i = 0; i < optionKeyCodes.length; ++i) { + firedEventTypes = []; + firedKeyCodes = []; + var keyCode = optionKeyCodes[i][0]; + var keyPressKeyCode = optionKeyCodes[i][1]; + goog.testing.events.fireNonAsciiKeySequence( + root, keyCode, keyPressKeyCode, {'altKey': true}); + assertEventTypes(['keydown', 'keypress', 'keyup']); + assertArrayEquals([keyCode, keyPressKeyCode, keyCode], firedKeyCodes); + } + } + + var CONTEXTMENU_SEQ = + goog.userAgent.WINDOWS ? ['mousedown', 'mouseup', 'contextmenu'] : + goog.userAgent.GECKO ? ['mousedown', 'contextmenu', 'mouseup'] : + goog.userAgent.WEBKIT && goog.userAgent.MAC ? + ['mousedown', 'contextmenu', 'mouseup', 'click'] : + ['mousedown', 'contextmenu', 'mouseup']; + + function testContextMenuSequence() { + assertTrue(goog.testing.events.fireContextMenuSequence(root)); + assertEventTypes(CONTEXTMENU_SEQ); + } + + function testContextMenuSequenceWithCoordinate() { + assertTrue(goog.testing.events.fireContextMenuSequence(root, coordinate)); + assertEventTypes(CONTEXTMENU_SEQ); + assertCoordinates(goog.array.repeat(coordinate, CONTEXTMENU_SEQ.length)); + } + + function testContextMenuSequenceCancellingMousedown() { + preventDefaultEventType('mousedown'); + assertFalse(goog.testing.events.fireContextMenuSequence(root)); + assertEventTypes(CONTEXTMENU_SEQ); + } + + function testContextMenuSequenceCancellingMouseup() { + preventDefaultEventType('mouseup'); + assertFalse(goog.testing.events.fireContextMenuSequence(root)); + assertEventTypes(CONTEXTMENU_SEQ); + } + + function testContextMenuSequenceCancellingContextMenu() { + preventDefaultEventType('contextmenu'); + assertFalse(goog.testing.events.fireContextMenuSequence(root)); + assertEventTypes(CONTEXTMENU_SEQ); + } + + function testContextMenuSequenceFakeMacWebkit() { + stubs.set(goog.userAgent, 'WINDOWS', false); + stubs.set(goog.userAgent, 'MAC', true); + stubs.set(goog.userAgent, 'WEBKIT', true); + assertTrue(goog.testing.events.fireContextMenuSequence(root)); + assertEventTypes(['mousedown', 'contextmenu', 'mouseup', 'click']); + } + + /** + * Assert that the list of events given was fired, in that order. + */ + function assertEventTypes(list) { + assertArrayEquals(list, firedEventTypes); + } + + /** + * Assert that the list of event coordinates given was caught, in that order. + */ + function assertCoordinates(list) { + assertArrayEquals(list, firedEventCoordinates); + assertArrayEquals(list, firedScreenCoordinates); + } + + /** Prevent default the event of the given type on the root element. */ + function preventDefaultEventType(type) { + goog.events.listen(root, type, preventDefault); + } + + function preventDefault(e) { + e.preventDefault(); + } +</script> +</body> +</html> diff --git a/contexts/data/lib/closure-library/closure/goog/testing/events/.svn/text-base/matchers.js.svn-base b/contexts/data/lib/closure-library/closure/goog/testing/events/.svn/text-base/matchers.js.svn-base new file mode 100644 index 0000000..2566cab --- /dev/null +++ b/contexts/data/lib/closure-library/closure/goog/testing/events/.svn/text-base/matchers.js.svn-base @@ -0,0 +1,41 @@ +// Copyright 2009 The Closure Library Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Mock matchers for event related arguments. + */ + +goog.provide('goog.testing.events.EventMatcher'); + +goog.require('goog.events.Event'); +goog.require('goog.testing.mockmatchers.ArgumentMatcher'); + + + +/** + * A matcher that verifies that an argument is a {@code goog.events.Event} of a + * particular type. + * @param {string} type The single type the event argument must be of. + * @constructor + * @extends {goog.testing.mockmatchers.ArgumentMatcher} + */ +goog.testing.events.EventMatcher = function(type) { + goog.testing.mockmatchers.ArgumentMatcher.call(this, + function(obj) { + return obj instanceof goog.events.Event && + obj.type == type; + }, 'isEventOfType(' + type + ')'); +}; +goog.inherits(goog.testing.events.EventMatcher, + goog.testing.mockmatchers.ArgumentMatcher); diff --git a/contexts/data/lib/closure-library/closure/goog/testing/events/.svn/text-base/matchers_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/testing/events/.svn/text-base/matchers_test.html.svn-base new file mode 100644 index 0000000..90c1819 --- /dev/null +++ b/contexts/data/lib/closure-library/closure/goog/testing/events/.svn/text-base/matchers_test.html.svn-base @@ -0,0 +1,40 @@ +<!DOCTYPE html> +<html> +<!-- +Copyright 2009 The Closure Library Authors. All Rights Reserved. + +Use of this source code is governed by the Apache License, Version 2.0. +See the COPYING file for details. +--> +<head> +<meta http-equiv="X-UA-Compatible" content="IE=edge"> + <!-- + + --> + <title>Closure Unit Tests - goog.testing.events.EventMatcher</title> + <script src="../../base.js"></script> + <script> + goog.require('goog.testing.events.EventMatcher'); + goog.require('goog.testing.jsunit'); + </script> +</head> +<body> +<script> + function testEventMatcher() { + var matcher = new goog.testing.events.EventMatcher('foo'); + assertFalse(matcher.matches(undefined)); + assertFalse(matcher.matches(null)); + assertFalse(matcher.matches({type: 'foo'})); + assertFalse(matcher.matches(new goog.events.Event('bar'))); + + assertTrue(matcher.matches(new goog.events.Event('foo'))); + var FooEvent = function() { + goog.events.Event.call(this, 'foo'); + }; + goog.inherits(FooEvent, goog.events.Event); + assertTrue(matcher.matches(new FooEvent())); + } +</script> +</body> +</html> + diff --git a/contexts/data/lib/closure-library/closure/goog/testing/events/eventobserver.js b/contexts/data/lib/closure-library/closure/goog/testing/events/eventobserver.js new file mode 100644 index 0000000..83d6888 --- /dev/null +++ b/contexts/data/lib/closure-library/closure/goog/testing/events/eventobserver.js @@ -0,0 +1,85 @@ +// Copyright 2010 The Closure Library Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Event observer. + * + * Provides an event observer that holds onto events that it handles. This + * can be used in unit testing to verify an event target's events -- + * that the order count, types, etc. are correct. + * + * Example usage: + * <pre> + * var observer = new goog.testing.events.EventObserver(); + * var widget = new foo.Widget(); + * goog.events.listen(widget, ['select', 'submit'], observer); + * // Simulate user action of 3 select events and 2 submit events. + * assertEquals(3, observer.getEvents('select').length); + * assertEquals(2, observer.getEvents('submit').length); + * </pre> + * + */ + +goog.provide('goog.testing.events.EventObserver'); + +goog.require('goog.array'); + + + +/** + * Event observer. Implements a handleEvent interface so it may be used as + * a listener in listening functions and methods. + * @see goog.events.listen + * @see goog.events.EventHandler + * @constructor + */ +goog.testing.events.EventObserver = function() { + + /** + * A list of events handled by the observer in order of handling, oldest to + * newest. + * @type {!Array.<!goog.events.Event>} + * @private + */ + this.events_ = []; +}; + + +/** + * Handles an event and remembers it. Event listening functions and methods + * will call this method when this observer is used as a listener. + * @see goog.events.listen + * @see goog.events.EventHandler + * @param {!goog.events.Event} e Event to handle. + */ +goog.testing.events.EventObserver.prototype.handleEvent = function(e) { + this.events_.push(e); +}; + + +/** + * @param {string=} opt_type If given, only return events of this type. + * @return {!Array.<!goog.events.Event>} The events handled, oldest to newest. + */ +goog.testing.events.EventObserver.prototype.getEvents = function(opt_type) { + var events = goog.array.clone(this.events_); + + if (opt_type) { + events = goog.array.filter(events, function(event) { + return event.type == opt_type; + }); + } + + return events; +}; diff --git a/contexts/data/lib/closure-library/closure/goog/testing/events/eventobserver_test.html b/contexts/data/lib/closure-library/closure/goog/testing/events/eventobserver_test.html new file mode 100644 index 0000000..200eae6 --- /dev/null +++ b/contexts/data/lib/closure-library/closure/goog/testing/events/eventobserver_test.html @@ -0,0 +1,70 @@ +<!DOCTYPE html> +<html> +<!-- +Copyright 2010 The Closure Library Authors. All Rights Reserved. + +Use of this source code is governed by the Apache License, Version 2.0. +See the COPYING file for details. +--> +<head> +<meta http-equiv="X-UA-Compatible" content="IE=edge"> +<title>Closure Unit Tests - goog.testing.events.EventObserver</title> + <script src="../../base.js"></script> +<script> + goog.require('goog.array'); + goog.require('goog.events'); + goog.require('goog.events.EventTarget'); + goog.require('goog.testing.events.EventObserver'); + goog.require('goog.testing.jsunit'); +</script> +</head> +<body> +<script> + + // Return an event's type + function getEventType(e) { + return e.type; + } + + function testGetEvents() { + var observer = new goog.testing.events.EventObserver(); + var target = new goog.events.EventTarget(); + goog.events.listen(target, ['foo', 'bar', 'baz'], observer); + + var eventTypes = [ + 'bar', 'baz', 'foo', 'qux', 'quux', 'corge', 'foo', 'baz']; + goog.array.forEach(eventTypes, goog.bind(target.dispatchEvent, target)); + + var replayEvents = observer.getEvents(); + + assertArrayEquals('Only the listened-for event types should be remembered', + ['bar', 'baz', 'foo', 'foo', 'baz'], + goog.array.map(observer.getEvents(), getEventType)); + + assertArrayEquals(['bar'], + goog.array.map(observer.getEvents('bar'), getEventType)); + assertArrayEquals(['baz', 'baz'], + goog.array.map(observer.getEvents('baz'), getEventType)); + assertArrayEquals(['foo', 'foo'], + goog.array.map(observer.getEvents('foo'), getEventType)); + } + + function testHandleEvent() { + var events = [ + new goog.events.Event('foo'), + new goog.events.Event('bar'), + new goog.events.Event('baz') + ]; + + var observer = new goog.testing.events.EventObserver(); + goog.array.forEach(events, goog.bind(observer.handleEvent, observer)); + + assertArrayEquals(events, observer.getEvents()); + assertArrayEquals([events[0]], observer.getEvents('foo')); + assertArrayEquals([events[1]], observer.getEvents('bar')); + assertArrayEquals([events[2]], observer.getEvents('baz')); + } + +</script> +</body> +</html> diff --git a/contexts/data/lib/closure-library/closure/goog/testing/events/events.js b/contexts/data/lib/closure-library/closure/goog/testing/events/events.js new file mode 100644 index 0000000..8928c0b --- /dev/null +++ b/contexts/data/lib/closure-library/closure/goog/testing/events/events.js @@ -0,0 +1,554 @@ +// Copyright 2008 The Closure Library Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Event Simulation. + * + * Utility functions for simulating events at the Closure level. All functions + * in this package generate events by calling goog.events.fireListeners, + * rather than interfacing with the browser directly. This is intended for + * testing purposes, and should not be used in production code. + * + * The decision to use Closure events and dispatchers instead of the browser's + * native events and dispatchers was conscious and deliberate. Native event + * dispatchers have their own set of quirks and edge cases. Pure JS dispatchers + * are more robust and transparent. + * + * If you think you need a testing mechanism that uses native Event objects, + * please, please email closure-tech first to explain your use case before you + * sink time into this. + * + * @author nicksantos@google.com (Nick Santos) + */ + +goog.provide('goog.testing.events'); +goog.provide('goog.testing.events.Event'); + +goog.require('goog.events'); +goog.require('goog.events.BrowserEvent'); +goog.require('goog.events.BrowserEvent.MouseButton'); +goog.require('goog.events.BrowserFeature'); +goog.require('goog.events.Event'); +goog.require('goog.events.EventType'); +goog.require('goog.events.KeyCodes'); +goog.require('goog.object'); +goog.require('goog.style'); +goog.require('goog.userAgent'); + + + +/** + * goog.events.BrowserEvent expects an Event so we provide one for JSCompiler. + * + * @param {string} type Event Type. + * @param {Object=} opt_target Reference to the object that is the target of + * this event. + * @constructor + * @extends {Event} + */ +goog.testing.events.Event = function(type, opt_target) { + /** + * Event type. + * @type {string} + */ + this.type = type; + + /** + * Target of the event. + * @type {Object|undefined} + */ + this.target = opt_target; + + /** + * Object that had the listener attached. + * @type {Object|undefined} + */ + this.currentTarget = this.target; +}; +goog.object.extend( + goog.testing.events.Event.prototype, goog.events.Event.prototype); + + +/** + * A static helper function that sets the mouse position to the event. + * @param {Event} event A simulated native event. + * @param {goog.math.Coordinate=} opt_coords Mouse position. Defaults to event's + * target's position (if available), otherwise (0, 0). + * @private + */ +goog.testing.events.setEventClientXY_ = function(event, opt_coords) { + if (!opt_coords && event.target && + event.target.nodeType == goog.dom.NodeType.ELEMENT) { + try { + opt_coords = + goog.style.getClientPosition(/** @type {Element} **/ (event.target)); + } catch (ex) { + // IE sometimes throws if it can't get the position. + } + } + event.clientX = opt_coords ? opt_coords.x : 0; + event.clientY = opt_coords ? opt_coords.y : 0; + + // Pretend the browser window is at (0, 0). + event.screenX = event.clientX; + event.screenY = event.clientY; +}; + + +/** + * Simulates a mousedown, mouseup, and then click on the given event target, + * with the left mouse button. + * @param {EventTarget} target The target for the event. + * @param {goog.events.BrowserEvent.MouseButton=} opt_button Mouse button; + * defaults to {@code goog.events.BrowserEvent.MouseButton.LEFT}. + * @param {goog.math.Coordinate=} opt_coords Mouse position. Defaults to event's + * target's position (if available), otherwise (0, 0). + * @param {Object=} opt_eventProperties Event properties to be mixed into the + * BrowserEvent. + * @return {boolean} The returnValue of the sequence: false if preventDefault() + * was called on any of the events, true otherwise. + */ +goog.testing.events.fireClickSequence = + function(target, opt_button, opt_coords, opt_eventProperties) { + // Fire mousedown, mouseup, and click. Then return the bitwise AND of the 3. + return !!(goog.testing.events.fireMouseDownEvent( + target, opt_button, opt_coords, opt_eventProperties) & + goog.testing.events.fireMouseUpEvent( + target, opt_button, opt_coords, opt_eventProperties) & + goog.testing.events.fireClickEvent( + target, opt_button, opt_coords, opt_eventProperties)); +}; + + +/** + * Simulates the sequence of events fired by the browser when the user double- + * clicks the given target. + * @param {EventTarget} target The target for the event. + * @param {goog.math.Coordinate=} opt_coords Mouse position. Defaults to event's + * target's position (if available), otherwise (0, 0). + * @param {Object=} opt_eventProperties Event properties to be mixed into the + * BrowserEvent. + * @return {boolean} The returnValue of the sequence: false if preventDefault() + * was called on any of the events, true otherwise. + */ +goog.testing.events.fireDoubleClickSequence = function( + target, opt_coords, opt_eventProperties) { + // Fire mousedown, mouseup, click, mousedown, mouseup, click, dblclick. + // Then return the bitwise AND of the 7. + var btn = goog.events.BrowserEvent.MouseButton.LEFT; + return !!(goog.testing.events.fireMouseDownEvent( + target, btn, opt_coords, opt_eventProperties) & + goog.testing.events.fireMouseUpEvent( + target, btn, opt_coords, opt_eventProperties) & + goog.testing.events.fireClickEvent( + target, btn, opt_coords, opt_eventProperties) & + // IE fires a selectstart instead of the second mousedown in a + // dblclick, but we don't care about selectstart. + (goog.userAgent.IE || + goog.testing.events.fireMouseDownEvent( + target, btn, opt_coords, opt_eventProperties)) & + goog.testing.events.fireMouseUpEvent( + target, btn, opt_coords, opt_eventProperties) & + // IE doesn't fire the second click in a dblclick. + (goog.userAgent.IE || + goog.testing.events.fireClickEvent( + target, btn, opt_coords, opt_eventProperties)) & + goog.testing.events.fireDoubleClickEvent( + target, opt_coords, opt_eventProperties)); +}; + + +/** + * Simulates a complete keystroke (keydown, keypress, and keyup). Note that + * if preventDefault is called on the keydown, the keypress will not fire. + * + * @param {EventTarget} target The target for the event. + * @param {number} keyCode The keycode of the key pressed. + * @param {Object=} opt_eventProperties Event properties to be mixed into the + * BrowserEvent. + * @return {boolean} The returnValue of the sequence: false if preventDefault() + * was called on any of the events, true otherwise. + */ +goog.testing.events.fireKeySequence = function( + target, keyCode, opt_eventProperties) { + return goog.testing.events.fireNonAsciiKeySequence(target, keyCode, keyCode, + opt_eventProperties); +}; + + +/** + * Simulates a complete keystroke (keydown, keypress, and keyup) when typing + * a non-ASCII character. Same as fireKeySequence, the keypress will not fire + * if preventDefault is called on the keydown. + * + * @param {EventTarget} target The target for the event. + * @param {number} keyCode The keycode of the keydown and keyup events. + * @param {number} keyPressKeyCode The keycode of the keypress event. + * @param {Object=} opt_eventProperties Event properties to be mixed into the + * BrowserEvent. + * @return {boolean} The returnValue of the sequence: false if preventDefault() + * was called on any of the events, true otherwise. + */ +goog.testing.events.fireNonAsciiKeySequence = function( + target, keyCode, keyPressKeyCode, opt_eventProperties) { + var keydown = + new goog.testing.events.Event(goog.events.EventType.KEYDOWN, target); + var keyup = + new goog.testing.events.Event(goog.events.EventType.KEYUP, target); + var keypress = + new goog.testing.events.Event(goog.events.EventType.KEYPRESS, target); + keydown.keyCode = keyup.keyCode = keyCode; + keypress.keyCode = keyPressKeyCode; + + if (opt_eventProperties) { + goog.object.extend(keydown, opt_eventProperties); + goog.object.extend(keyup, opt_eventProperties); + goog.object.extend(keypress, opt_eventProperties); + } + + // Fire keydown, keypress, and keyup. Note that if the keydown is + // prevent-defaulted, then the keypress will not fire on IE. + var result = true; + if (!goog.testing.events.isBrokenGeckoMacActionKey_(keydown)) { + result = goog.testing.events.fireBrowserEvent(keydown); + } + if (goog.events.KeyCodes.firesKeyPressEvent( + keyCode, undefined, keydown.shiftKey, keydown.ctrlKey, + keydown.altKey) && + !(goog.userAgent.IE && !result)) { + result &= goog.testing.events.fireBrowserEvent(keypress); + } + return !!(result & goog.testing.events.fireBrowserEvent(keyup)); +}; + + +/** + * @param {goog.testing.events.Event} e The event. + * @return {boolean} Whether this is the Gecko/Mac's Meta-C/V/X, which + * is broken and requires special handling. + * @private + */ +goog.testing.events.isBrokenGeckoMacActionKey_ = function(e) { + return goog.userAgent.MAC && goog.userAgent.GECKO && + (e.keyCode == goog.events.KeyCodes.C || + e.keyCode == goog.events.KeyCodes.X || + e.keyCode == goog.events.KeyCodes.V) && e.metaKey; +}; + + +/** + * Simulates a mouseover event on the given target. + * @param {EventTarget} target The target for the event. + * @param {EventTarget} relatedTarget The related target for the event (e.g., + * the node that the mouse is being moved out of). + * @param {goog.math.Coordinate=} opt_coords Mouse position. Defaults to event's + * target's position (if available), otherwise (0, 0). + * @return {boolean} The returnValue of the event: false if preventDefault() was + * called on it, true otherwise. + */ +goog.testing.events.fireMouseOverEvent = function(target, relatedTarget, + opt_coords) { + var mouseover = + new goog.testing.events.Event(goog.events.EventType.MOUSEOVER, target); + mouseover.relatedTarget = relatedTarget; + goog.testing.events.setEventClientXY_(mouseover, opt_coords); + return goog.testing.events.fireBrowserEvent(mouseover); +}; + + +/** + * Simulates a mousemove event on the given target. + * @param {EventTarget} target The target for the event. + * @param {goog.math.Coordinate=} opt_coords Mouse position. Defaults to event's + * target's position (if available), otherwise (0, 0). + * @return {boolean} The returnValue of the event: false if preventDefault() was + * called on it, true otherwise. + */ +goog.testing.events.fireMouseMoveEvent = function(target, opt_coords) { + var mousemove = + new goog.testing.events.Event(goog.events.EventType.MOUSEMOVE, target); + + goog.testing.events.setEventClientXY_(mousemove, opt_coords); + return goog.testing.events.fireBrowserEvent(mousemove); +}; + + +/** + * Simulates a mouseout event on the given target. + * @param {EventTarget} target The target for the event. + * @param {EventTarget} relatedTarget The related target for the event (e.g., + * the node that the mouse is being moved into). + * @param {goog.math.Coordinate=} opt_coords Mouse position. Defaults to event's + * target's position (if available), otherwise (0, 0). + * @return {boolean} The returnValue of the event: false if preventDefault() was + * called on it, true otherwise. + */ +goog.testing.events.fireMouseOutEvent = function(target, relatedTarget, + opt_coords) { + var mouseout = + new goog.testing.events.Event(goog.events.EventType.MOUSEOUT, target); + mouseout.relatedTarget = relatedTarget; + goog.testing.events.setEventClientXY_(mouseout, opt_coords); + return goog.testing.events.fireBrowserEvent(mouseout); +}; + + +/** + * Simulates a mousedown event on the given target. + * @param {EventTarget} target The target for the event. + * @param {goog.events.BrowserEvent.MouseButton=} opt_button Mouse button; + * defaults to {@code goog.events.BrowserEvent.MouseButton.LEFT}. + * @param {goog.math.Coordinate=} opt_coords Mouse position. Defaults to event's + * target's position (if available), otherwise (0, 0). + * @param {Object=} opt_eventProperties Event properties to be mixed into the + * BrowserEvent. + * @return {boolean} The returnValue of the event: false if preventDefault() was + * called on it, true otherwise. + */ +goog.testing.events.fireMouseDownEvent = + function(target, opt_button, opt_coords, opt_eventProperties) { + + var button = opt_button || goog.events.BrowserEvent.MouseButton.LEFT; + button = !goog.events.BrowserFeature.HAS_W3C_BUTTON ? + goog.events.BrowserEvent.IEButtonMap[button] : button; + return goog.testing.events.fireMouseButtonEvent_( + goog.events.EventType.MOUSEDOWN, target, button, opt_coords, + opt_eventProperties); +}; + + +/** + * Simulates a mouseup event on the given target. + * @param {EventTarget} target The target for the event. + * @param {goog.events.BrowserEvent.MouseButton=} opt_button Mouse button; + * defaults to {@code goog.events.BrowserEvent.MouseButton.LEFT}. + * @param {goog.math.Coordinate=} opt_coords Mouse position. Defaults to event's + * target's position (if available), otherwise (0, 0). + * @param {Object=} opt_eventProperties Event properties to be mixed into the + * BrowserEvent. + * @return {boolean} The returnValue of the event: false if preventDefault() was + * called on it, true otherwise. + */ +goog.testing.events.fireMouseUpEvent = + function(target, opt_button, opt_coords, opt_eventProperties) { + var button = opt_button || goog.events.BrowserEvent.MouseButton.LEFT; + button = !goog.events.BrowserFeature.HAS_W3C_BUTTON ? + goog.events.BrowserEvent.IEButtonMap[button] : button; + return goog.testing.events.fireMouseButtonEvent_( + goog.events.EventType.MOUSEUP, target, button, opt_coords, + opt_eventProperties); +}; + + +/** + * Simulates a click event on the given target. IE only supports click with + * the left mouse button. + * @param {EventTarget} target The target for the event. + * @param {goog.events.BrowserEvent.MouseButton=} opt_button Mouse button; + * defaults to {@code goog.events.BrowserEvent.MouseButton.LEFT}. + * @param {goog.math.Coordinate=} opt_coords Mouse position. Defaults to event's + * target's position (if available), otherwise (0, 0). + * @param {Object=} opt_eventProperties Event properties to be mixed into the + * BrowserEvent. + * @return {boolean} The returnValue of the event: false if preventDefault() was + * called on it, true otherwise. + */ +goog.testing.events.fireClickEvent = + function(target, opt_button, opt_coords, opt_eventProperties) { + return goog.testing.events.fireMouseButtonEvent_(goog.events.EventType.CLICK, + target, opt_button, opt_coords, opt_eventProperties); +}; + + +/** + * Simulates a double-click event on the given target. Always double-clicks + * with the left mouse button since no browser supports double-clicking with + * any other buttons. + * @param {EventTarget} target The target for the event. + * @param {goog.math.Coordinate=} opt_coords Mouse position. Defaults to event's + * target's position (if available), otherwise (0, 0). + * @param {Object=} opt_eventProperties Event properties to be mixed into the + * BrowserEvent. + * @return {boolean} The returnValue of the event: false if preventDefault() was + * called on it, true otherwise. + */ +goog.testing.events.fireDoubleClickEvent = + function(target, opt_coords, opt_eventProperties) { + return goog.testing.events.fireMouseButtonEvent_( + goog.events.EventType.DBLCLICK, target, + goog.events.BrowserEvent.MouseButton.LEFT, opt_coords, + opt_eventProperties); +}; + + +/** + * Helper function to fire a mouse event. + * with the left mouse button since no browser supports double-clicking with + * any other buttons. + * @param {string} type The event type. + * @param {EventTarget} target The target for the event. + * @param {number=} opt_button Mouse button; defaults to + * {@code goog.events.BrowserEvent.MouseButton.LEFT}. + * @param {goog.math.Coordinate=} opt_coords Mouse position. Defaults to event's + * target's position (if available), otherwise (0, 0). + * @param {Object=} opt_eventProperties Event properties to be mixed into the + * BrowserEvent. + * @return {boolean} The returnValue of the event: false if preventDefault() was + * called on it, true otherwise. + * @private + */ +goog.testing.events.fireMouseButtonEvent_ = + function(type, target, opt_button, opt_coords, opt_eventProperties) { + var e = + new goog.testing.events.Event(type, target); + e.button = opt_button || goog.events.BrowserEvent.MouseButton.LEFT; + goog.testing.events.setEventClientXY_(e, opt_coords); + if (opt_eventProperties) { + goog.object.extend(e, opt_eventProperties); + } + return goog.testing.events.fireBrowserEvent(e); +}; + + +/** + * Simulates a contextmenu event on the given target. + * @param {EventTarget} target The target for the event. + * @param {goog.math.Coordinate=} opt_coords Mouse position. Defaults to event's + * target's position (if available), otherwise (0, 0). + * @return {boolean} The returnValue of the event: false if preventDefault() was + * called on it, true otherwise. + */ +goog.testing.events.fireContextMenuEvent = function(target, opt_coords) { + var button = (goog.userAgent.MAC && goog.userAgent.WEBKIT) ? + goog.events.BrowserEvent.MouseButton.LEFT : + goog.events.BrowserEvent.MouseButton.RIGHT; + var contextmenu = + new goog.testing.events.Event(goog.events.EventType.CONTEXTMENU, target); + contextmenu.button = !goog.events.BrowserFeature.HAS_W3C_BUTTON ? + goog.events.BrowserEvent.IEButtonMap[button] : button; + contextmenu.ctrlKey = goog.userAgent.MAC; + goog.testing.events.setEventClientXY_(contextmenu, opt_coords); + return goog.testing.events.fireBrowserEvent(contextmenu); +}; + + +/** + * Simulates a mousedown, contextmenu, and the mouseup on the given event + * target, with the right mouse button. + * @param {EventTarget} target The target for the event. + * @param {goog.math.Coordinate=} opt_coords Mouse position. Defaults to event's + * target's position (if available), otherwise (0, 0). + * @return {boolean} The returnValue of the sequence: false if preventDefault() + * was called on any of the events, true otherwise. + */ +goog.testing.events.fireContextMenuSequence = function(target, opt_coords) { + var props = goog.userAgent.MAC ? {ctrlKey: true} : {}; + var button = (goog.userAgent.MAC && goog.userAgent.WEBKIT) ? + goog.events.BrowserEvent.MouseButton.LEFT : + goog.events.BrowserEvent.MouseButton.RIGHT; + + var result = goog.testing.events.fireMouseDownEvent(target, + button, opt_coords, props); + if (goog.userAgent.WINDOWS) { + // All browsers are consistent on Windows. + result &= goog.testing.events.fireMouseUpEvent(target, + button, opt_coords) & + goog.testing.events.fireContextMenuEvent(target, opt_coords); + } else { + result &= goog.testing.events.fireContextMenuEvent(target, opt_coords); + + // GECKO on Mac and Linux always fires the mouseup after the contextmenu. + + // WEBKIT is really weird. + // + // On Linux, it sometimes fires mouseup, but most of the time doesn't. + // It's really hard to reproduce consistently. I think there's some + // internal race condition. If contextmenu is preventDefaulted, then + // mouseup always fires. + // + // On Mac, it always fires mouseup and then fires a click. + result &= goog.testing.events.fireMouseUpEvent(target, + button, opt_coords, props); + + if (goog.userAgent.WEBKIT && goog.userAgent.MAC) { + result &= goog.testing.events.fireClickEvent( + target, button, opt_coords, props); + } + } + return !!result; +}; + + +/** + * Simulates a popstate event on the given target. + * @param {EventTarget} target The target for the event. + * @param {Object} state History state object. + * @return {boolean} The returnValue of the event: false if preventDefault() was + * called on it, true otherwise. + */ +goog.testing.events.firePopStateEvent = function(target, state) { + var e = new goog.testing.events.Event(goog.events.EventType.POPSTATE, target); + e.state = state; + return goog.testing.events.fireBrowserEvent(e); +}; + + +/** + * Simulate a focus event on the given target. + * @param {EventTarget} target The target for the event. + * @return {boolean} The value returned by firing the focus browser event, + * which returns false iff 'preventDefault' was invoked. + */ +goog.testing.events.fireFocusEvent = function(target) { + var e = new goog.testing.events.Event( + goog.events.EventType.FOCUS, target); + return goog.testing.events.fireBrowserEvent(e); +}; + + +/** + * Simulates an event's capturing and bubbling phases. + * @param {Event} event A simulated native event. It will be wrapped in a + * normalized BrowserEvent and dispatched to Closure listeners on all + * ancestors of its target (inclusive). + * @return {boolean} The returnValue of the event: false if preventDefault() was + * called on it, true otherwise. + */ +goog.testing.events.fireBrowserEvent = function(event) { + event.returnValue_ = true; + + // generate a list of ancestors + var ancestors = []; + for (var current = event.target; current; current = current.parentNode) { + ancestors.push(current); + } + + // dispatch capturing listeners + for (var j = ancestors.length - 1; + j >= 0 && !event.propagationStopped_; + j--) { + goog.events.fireListeners(ancestors[j], event.type, true, + new goog.events.BrowserEvent(event, ancestors[j])); + } + + // dispatch bubbling listeners + for (var j = 0; + j < ancestors.length && !event.propagationStopped_; + j++) { + goog.events.fireListeners(ancestors[j], event.type, false, + new goog.events.BrowserEvent(event, ancestors[j])); + } + + return event.returnValue_; +}; diff --git a/contexts/data/lib/closure-library/closure/goog/testing/events/events_test.html b/contexts/data/lib/closure-library/closure/goog/testing/events/events_test.html new file mode 100644 index 0000000..fd28121 --- /dev/null +++ b/contexts/data/lib/closure-library/closure/goog/testing/events/events_test.html @@ -0,0 +1,434 @@ +<!-- +Copyright 2008 The Closure Library Authors. All Rights Reserved. + +Use of this source code is governed by the Apache License, Version 2.0. +See the COPYING file for details. +--> +<!DOCTYPE html> +<html lang="en" dir="ltr"> +<head> +<meta http-equiv="X-UA-Compatible" content="IE=edge"> + <!-- + + Author: nicksantos@google.com (Nick Santos) + --> + <title>Closure Unit Tests - goog.testing.events</title> + <script src="../../base.js"></script> + <script> + goog.require('goog.array'); + goog.require('goog.dom'); + goog.require('goog.math.Coordinate'); + goog.require('goog.string'); + goog.require('goog.testing.PropertyReplacer'); + goog.require('goog.testing.events'); + goog.require('goog.testing.jsunit'); + goog.require('goog.userAgent'); + + + </script> +</head> +<body> +<div id="root"></div> +<input id='testButton' type='input' value='Click Me' /> +<div id='input'>Prevent Default these events:<br/></div> +<div id='log' style='position:absolute;right:0;top:0'>Logged events:</div> +<script type="text/javascript"> + var firedEventTypes; + var firedEventCoordinates; + var firedScreenCoordinates; + var firedShiftKeys; + var firedKeyCodes; + var root = goog.dom.getElement('root'); + var log = goog.dom.getElement('log'); + var input = goog.dom.getElement('input'); + var testButton = goog.dom.getElement('testButton'); + var coordinate = new goog.math.Coordinate(123, 456); + var stubs = new goog.testing.PropertyReplacer(); + + function setUp() { + stubs.reset(); + goog.events.removeAll(); + root.innerHTML = ''; + firedEventTypes = []; + firedEventCoordinates = []; + firedScreenCoordinates = []; + firedShiftKeys = []; + firedKeyCodes = []; + + for (var key in goog.events.EventType) { + goog.events.listen(root, goog.events.EventType[key], function(e) { + firedEventTypes.push(e.type); + var coord = new goog.math.Coordinate(e.clientX, e.clientY); + firedEventCoordinates.push(coord); + + firedScreenCoordinates.push( + new goog.math.Coordinate(e.screenX, e.screenY)); + + firedShiftKeys.push(!!e.shiftKey); + firedKeyCodes.push(e.keyCode); + }); + } + } + + function tearDownPage() { + for (var key in goog.events.EventType) { + var type = goog.events.EventType[key]; + if (type == 'mousemove' || type == 'mouseout' || type == 'mouseover') { + continue; + } + goog.dom.appendChild(input, + goog.dom.createDom('label', null, + goog.dom.createDom('input', + {'id': type, 'type': 'checkbox'}), + type, + goog.dom.createDom('br'))); + goog.events.listen(testButton, type, function(e) { + if (goog.dom.getElement(e.type).checked) { + e.preventDefault(); + } + + log.innerHTML += goog.string.subs('<br/>%s (%s, %s)', + e.type, e.clientX, e.clientY); + }); + } + } + + function testMouseOver() { + goog.testing.events.fireMouseOverEvent(root, null); + goog.testing.events.fireMouseOverEvent(root, null, coordinate); + assertEventTypes(['mouseover', 'mouseover']); + assertCoordinates([goog.style.getClientPosition(root), coordinate]); + } + + function testMouseOut() { + goog.testing.events.fireMouseOutEvent(root, null); + goog.testing.events.fireMouseOutEvent(root, null, coordinate); + assertEventTypes(['mouseout', 'mouseout']); + assertCoordinates([goog.style.getClientPosition(root), coordinate]); + } + + function testClickSequence() { + assertTrue(goog.testing.events.fireClickSequence(root)); + assertEventTypes(['mousedown', 'mouseup', 'click']); + var rootPosition = goog.style.getClientPosition(root); + assertCoordinates([rootPosition, rootPosition, rootPosition]); + } + + function testClickSequenceWithCoordinate() { + assertTrue(goog.testing.events.fireClickSequence(root, null, coordinate)); + assertCoordinates([coordinate, coordinate, coordinate]); + assertArrayEquals([false, false, false], firedShiftKeys); + } + + function testClickSequenceWithEventProperty() { + assertTrue(goog.testing.events.fireClickSequence( + root, null, undefined, { shiftKey: true })); + assertArrayEquals([true, true, true], firedShiftKeys); + } + + function testClickSequenceCancellingMousedown() { + preventDefaultEventType('mousedown'); + assertFalse(goog.testing.events.fireClickSequence(root)); + assertEventTypes(['mousedown', 'mouseup', 'click']); + } + + function testClickSequenceCancellingMousedownWithCoordinate() { + preventDefaultEventType('mousedown'); + assertFalse(goog.testing.events.fireClickSequence(root, null, coordinate)); + assertCoordinates([coordinate, coordinate, coordinate]); + } + + function testClickSequenceCancellingMouseup() { + preventDefaultEventType('mouseup'); + assertFalse(goog.testing.events.fireClickSequence(root)); + assertEventTypes(['mousedown', 'mouseup', 'click']); + } + + function testClickSequenceCancellingMouseupWithCoordinate() { + preventDefaultEventType('mouseup'); + assertFalse(goog.testing.events.fireClickSequence(root, null, coordinate)); + assertCoordinates([coordinate, coordinate, coordinate]); + } + + function testClickSequenceCancellingClick() { + preventDefaultEventType('click'); + assertFalse(goog.testing.events.fireClickSequence(root)); + assertEventTypes(['mousedown', 'mouseup', 'click']); + } + + function testClickSequenceCancellingClickWithCoordinate() { + preventDefaultEventType('click'); + assertFalse(goog.testing.events.fireClickSequence(root, null, coordinate)); + assertCoordinates([coordinate, coordinate, coordinate]); + } + + // For a double click, IE fires selectstart instead of the second mousedown, + // but we don't simulate selectstart. Also, IE doesn't fire the second click. + var DBLCLICK_SEQ = (goog.userAgent.IE ? + ['mousedown', + 'mouseup', + 'click', + 'mouseup', + 'dblclick'] : + ['mousedown', + 'mouseup', + 'click', + 'mousedown', + 'mouseup', + 'click', + 'dblclick']); + + + var DBLCLICK_SEQ_COORDS = goog.array.repeat(coordinate, DBLCLICK_SEQ.length); + + function testDoubleClickSequence() { + assertTrue(goog.testing.events.fireDoubleClickSequence(root)); + assertEventTypes(DBLCLICK_SEQ); + } + + function testDoubleClickSequenceWithCoordinate() { + assertTrue(goog.testing.events.fireDoubleClickSequence(root, coordinate)); + assertCoordinates(DBLCLICK_SEQ_COORDS); + } + + function testDoubleClickSequenceCancellingMousedown() { + preventDefaultEventType('mousedown'); + assertFalse(goog.testing.events.fireDoubleClickSequence(root)); + assertEventTypes(DBLCLICK_SEQ); + } + + function testDoubleClickSequenceCancellingMousedownWithCoordinate() { + preventDefaultEventType('mousedown'); + assertFalse(goog.testing.events.fireDoubleClickSequence(root, coordinate)); + assertCoordinates(DBLCLICK_SEQ_COORDS); + } + + function testDoubleClickSequenceCancellingMouseup() { + preventDefaultEventType('mouseup'); + assertFalse(goog.testing.events.fireDoubleClickSequence(root)); + assertEventTypes(DBLCLICK_SEQ); + } + + function testDoubleClickSequenceCancellingMouseupWithCoordinate() { + preventDefaultEventType('mouseup'); + assertFalse(goog.testing.events.fireDoubleClickSequence(root, coordinate)); + assertCoordinates(DBLCLICK_SEQ_COORDS); + } + + function testDoubleClickSequenceCancellingClick() { + preventDefaultEventType('click'); + assertFalse(goog.testing.events.fireDoubleClickSequence(root)); + assertEventTypes(DBLCLICK_SEQ); + } + + function testDoubleClickSequenceCancellingClickWithCoordinate() { + preventDefaultEventType('click'); + assertFalse(goog.testing.events.fireDoubleClickSequence(root, coordinate)); + assertCoordinates(DBLCLICK_SEQ_COORDS); + } + + function testDoubleClickSequenceCancellingDoubleClick() { + preventDefaultEventType('dblclick'); + assertFalse(goog.testing.events.fireDoubleClickSequence(root)); + assertEventTypes(DBLCLICK_SEQ); + } + + function testDoubleClickSequenceCancellingDoubleClickWithCoordinate() { + preventDefaultEventType('dblclick'); + assertFalse(goog.testing.events.fireDoubleClickSequence(root, coordinate)); + assertCoordinates(DBLCLICK_SEQ_COORDS); + } + + function testKeySequence() { + assertTrue(goog.testing.events.fireKeySequence( + root, goog.events.KeyCodes.ZERO)); + assertEventTypes(['keydown', 'keypress', 'keyup']); + } + + function testKeySequenceCancellingKeydown() { + preventDefaultEventType('keydown'); + assertFalse(goog.testing.events.fireKeySequence( + root, goog.events.KeyCodes.ZERO)); + if (goog.userAgent.IE) { + assertEventTypes(['keydown', 'keyup']); + } else { + assertEventTypes(['keydown', 'keypress', 'keyup']); + } + } + + function testKeySequenceCancellingKeypress() { + preventDefaultEventType('keypress'); + assertFalse(goog.testing.events.fireKeySequence( + root, goog.events.KeyCodes.ZERO)); + assertEventTypes(['keydown', 'keypress', 'keyup']); + } + + function testKeySequenceCancellingKeyup() { + preventDefaultEventType('keyup'); + assertFalse(goog.testing.events.fireKeySequence( + root, goog.events.KeyCodes.ZERO)); + assertEventTypes(['keydown', 'keypress', 'keyup']); + } + + function testKeySequenceWithEscapeKey() { + assertTrue(goog.testing.events.fireKeySequence( + root, goog.events.KeyCodes.ESC)); + if (goog.userAgent.WEBKIT && goog.userAgent.isVersion('525')) { + assertEventTypes(['keydown', 'keyup']); + } else { + assertEventTypes(['keydown', 'keypress', 'keyup']); + } + } + + function testKeySequenceForMacActionKeysNegative() { + stubs.set(goog.userAgent, 'GECKO', false); + goog.testing.events.fireKeySequence( + root, goog.events.KeyCodes.C, {'metaKey': true}); + assertEventTypes(['keydown', 'keypress', 'keyup']); + } + + function testKeySequenceForMacActionKeysPositive() { + stubs.set(goog.userAgent, 'GECKO', true); + stubs.set(goog.userAgent, 'MAC', true); + goog.testing.events.fireKeySequence( + root, goog.events.KeyCodes.C, {'metaKey': true}); + assertEventTypes(['keypress', 'keyup']); + } + + function testKeySequenceForOptionKeysOnMac() { + // Mac uses an option (or alt) key to type non-ASCII characters. This test + // verifies we can emulate key events sent when typing such non-ASCII + // characters. + stubs.set(goog.userAgent, 'WEBKIT', true); + stubs.set(goog.userAgent, 'MAC', true); + + var optionKeyCodes = [ + [0xc0, 0x00e6], // option+' + [0xbc, 0x2264], // option+, + [0xbd, 0x2013], // option+- + [0xbe, 0x2265], // option+. + [0xbf, 0x00f7], // option+/ + [0x30, 0x00ba], // option+0 + [0x31, 0x00a1], // option+1 + [0x32, 0x2122], // option+2 + [0x33, 0x00a3], // option+3 + [0x34, 0x00a2], // option+4 + [0x35, 0x221e], // option+5 + [0x36, 0x00a7], // option+6 + [0x37, 0x00b6], // option+7 + [0x38, 0x2022], // option+8 + [0x39, 0x00aa], // option+9 + [0xba, 0x2026], // option+; + [0xbb, 0x2260], // option+= + [0xdb, 0x201c], // option+[ + [0xdc, 0x00ab], // option+\ + [0xdd, 0x2018], // option+] + [0x41, 0x00e5], // option+a + [0x42, 0x222b], // option+b + [0x43, 0x00e7], // option+c + [0x44, 0x2202], // option+d + [0x45, 0x00b4], // option+e + [0x46, 0x0192], // option+f + [0x47, 0x00a9], // option+g + [0x48, 0x02d9], // option+h + [0x49, 0x02c6], // option+i + [0x4a, 0x2206], // option+j + [0x4b, 0x02da], // option+k + [0x4c, 0x00ac], // option+l + [0x4d, 0x00b5], // option+m + [0x4e, 0x02dc], // option+n + [0x4f, 0x00f8], // option+o + [0x50, 0x03c0], // option+p + [0x51, 0x0153], // option+q + [0x52, 0x00ae], // option+r + [0x53, 0x00df], // option+s + [0x54, 0x2020], // option+t + [0x56, 0x221a], // option+v + [0x57, 0x2211], // option+w + [0x58, 0x2248], // option+x + [0x59, 0x00a5], // option+y + [0x5a, 0x03a9] // option+z + ]; + + for (var i = 0; i < optionKeyCodes.length; ++i) { + firedEventTypes = []; + firedKeyCodes = []; + var keyCode = optionKeyCodes[i][0]; + var keyPressKeyCode = optionKeyCodes[i][1]; + goog.testing.events.fireNonAsciiKeySequence( + root, keyCode, keyPressKeyCode, {'altKey': true}); + assertEventTypes(['keydown', 'keypress', 'keyup']); + assertArrayEquals([keyCode, keyPressKeyCode, keyCode], firedKeyCodes); + } + } + + var CONTEXTMENU_SEQ = + goog.userAgent.WINDOWS ? ['mousedown', 'mouseup', 'contextmenu'] : + goog.userAgent.GECKO ? ['mousedown', 'contextmenu', 'mouseup'] : + goog.userAgent.WEBKIT && goog.userAgent.MAC ? + ['mousedown', 'contextmenu', 'mouseup', 'click'] : + ['mousedown', 'contextmenu', 'mouseup']; + + function testContextMenuSequence() { + assertTrue(goog.testing.events.fireContextMenuSequence(root)); + assertEventTypes(CONTEXTMENU_SEQ); + } + + function testContextMenuSequenceWithCoordinate() { + assertTrue(goog.testing.events.fireContextMenuSequence(root, coordinate)); + assertEventTypes(CONTEXTMENU_SEQ); + assertCoordinates(goog.array.repeat(coordinate, CONTEXTMENU_SEQ.length)); + } + + function testContextMenuSequenceCancellingMousedown() { + preventDefaultEventType('mousedown'); + assertFalse(goog.testing.events.fireContextMenuSequence(root)); + assertEventTypes(CONTEXTMENU_SEQ); + } + + function testContextMenuSequenceCancellingMouseup() { + preventDefaultEventType('mouseup'); + assertFalse(goog.testing.events.fireContextMenuSequence(root)); + assertEventTypes(CONTEXTMENU_SEQ); + } + + function testContextMenuSequenceCancellingContextMenu() { + preventDefaultEventType('contextmenu'); + assertFalse(goog.testing.events.fireContextMenuSequence(root)); + assertEventTypes(CONTEXTMENU_SEQ); + } + + function testContextMenuSequenceFakeMacWebkit() { + stubs.set(goog.userAgent, 'WINDOWS', false); + stubs.set(goog.userAgent, 'MAC', true); + stubs.set(goog.userAgent, 'WEBKIT', true); + assertTrue(goog.testing.events.fireContextMenuSequence(root)); + assertEventTypes(['mousedown', 'contextmenu', 'mouseup', 'click']); + } + + /** + * Assert that the list of events given was fired, in that order. + */ + function assertEventTypes(list) { + assertArrayEquals(list, firedEventTypes); + } + + /** + * Assert that the list of event coordinates given was caught, in that order. + */ + function assertCoordinates(list) { + assertArrayEquals(list, firedEventCoordinates); + assertArrayEquals(list, firedScreenCoordinates); + } + + /** Prevent default the event of the given type on the root element. */ + function preventDefaultEventType(type) { + goog.events.listen(root, type, preventDefault); + } + + function preventDefault(e) { + e.preventDefault(); + } +</script> +</body> +</html> diff --git a/contexts/data/lib/closure-library/closure/goog/testing/events/matchers.js b/contexts/data/lib/closure-library/closure/goog/testing/events/matchers.js new file mode 100644 index 0000000..2566cab --- /dev/null +++ b/contexts/data/lib/closure-library/closure/goog/testing/events/matchers.js @@ -0,0 +1,41 @@ +// Copyright 2009 The Closure Library Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Mock matchers for event related arguments. + */ + +goog.provide('goog.testing.events.EventMatcher'); + +goog.require('goog.events.Event'); +goog.require('goog.testing.mockmatchers.ArgumentMatcher'); + + + +/** + * A matcher that verifies that an argument is a {@code goog.events.Event} of a + * particular type. + * @param {string} type The single type the event argument must be of. + * @constructor + * @extends {goog.testing.mockmatchers.ArgumentMatcher} + */ +goog.testing.events.EventMatcher = function(type) { + goog.testing.mockmatchers.ArgumentMatcher.call(this, + function(obj) { + return obj instanceof goog.events.Event && + obj.type == type; + }, 'isEventOfType(' + type + ')'); +}; +goog.inherits(goog.testing.events.EventMatcher, + goog.testing.mockmatchers.ArgumentMatcher); diff --git a/contexts/data/lib/closure-library/closure/goog/testing/events/matchers_test.html b/contexts/data/lib/closure-library/closure/goog/testing/events/matchers_test.html new file mode 100644 index 0000000..90c1819 --- /dev/null +++ b/contexts/data/lib/closure-library/closure/goog/testing/events/matchers_test.html @@ -0,0 +1,40 @@ +<!DOCTYPE html> +<html> +<!-- +Copyright 2009 The Closure Library Authors. All Rights Reserved. + +Use of this source code is governed by the Apache License, Version 2.0. +See the COPYING file for details. +--> +<head> +<meta http-equiv="X-UA-Compatible" content="IE=edge"> + <!-- + + --> + <title>Closure Unit Tests - goog.testing.events.EventMatcher</title> + <script src="../../base.js"></script> + <script> + goog.require('goog.testing.events.EventMatcher'); + goog.require('goog.testing.jsunit'); + </script> +</head> +<body> +<script> + function testEventMatcher() { + var matcher = new goog.testing.events.EventMatcher('foo'); + assertFalse(matcher.matches(undefined)); + assertFalse(matcher.matches(null)); + assertFalse(matcher.matches({type: 'foo'})); + assertFalse(matcher.matches(new goog.events.Event('bar'))); + + assertTrue(matcher.matches(new goog.events.Event('foo'))); + var FooEvent = function() { + goog.events.Event.call(this, 'foo'); + }; + goog.inherits(FooEvent, goog.events.Event); + assertTrue(matcher.matches(new FooEvent())); + } +</script> +</body> +</html> + |