sku-pg
Version:
Skulpt is a Javascript implementation of Python 2.x. Python that runs in your browser!
660 lines (527 loc) • 19.9 kB
HTML
<html>
<!--
Copyright 2006 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.events</title>
<script src="../base.js"></script>
<script>
goog.require('goog.debug.EntryPointMonitor');
goog.require('goog.debug.ErrorHandler');
goog.require('goog.debug.ErrorHandler.ProtectedFunctionError');
goog.require('goog.events');
goog.require('goog.events.EventTarget');
goog.require('goog.events.EventType');
goog.require('goog.events.Listenable');
goog.require('goog.functions');
goog.require('goog.testing.PropertyReplacer');
goog.require('goog.testing.jsunit');
goog.require('goog.testing.recordFunction');
</script>
</head>
<body>
<script>
var originalHandleBrowserEvent = goog.events.handleBrowserEvent_;
var propertyReplacer;
var et1, et2, et3;
function setUp() {
et1 = new goog.events.EventTarget();
et2 = new goog.events.EventTarget();
et3 = new goog.events.EventTarget();
propertyReplacer = new goog.testing.PropertyReplacer();
}
function tearDown() {
goog.events.handleBrowserEvent_ = originalHandleBrowserEvent;
goog.disposeAll(et1, et2, et3);
goog.events.removeAllNativeListeners();
propertyReplacer.reset();
}
function testProtectBrowserEventEntryPoint() {
var errorHandlerCallbackCalled = false;
var errorHandler = new goog.debug.ErrorHandler(function() {
errorHandlerCallbackCalled = true;
});
goog.events.protectBrowserEventEntryPoint(errorHandler);
var protectedHandleBrowserEvent_ = goog.events.handleBrowserEvent_;
goog.events.handleBrowserEvent_ = function(evt) {
try {
protectedHandleBrowserEvent_(evt);
} catch (e) {
assertTrue(
e instanceof goog.debug.ErrorHandler.ProtectedFunctionError);
}
};
var bodyEl = document.body;
goog.events.listen(bodyEl, goog.events.EventType.CLICK, function(e){
throw Error;
});
triggerClickEvent(bodyEl);
assertTrue('Error handler callback should be called.',
errorHandlerCallbackCalled);
}
function triggerClickEvent(element) {
if (document.createEvent) {
var event = document.createEvent("MouseEvents");
event.initMouseEvent("click", true, true, window,
0, 0, 0, 0, 0, false, false, false, false, 0, null);
element.dispatchEvent(event);
} else {
element.fireEvent('onclick', element.ownerDocument.createEventObject());
}
}
function testSelfRemove() {
var callback = function() {
// This listener removes itself during event dispatching, so it
// is marked as 'removed' but not actually removed until after event
// dispatching ends.
goog.events.removeAll(et1, 'click');
// Test that goog.events.getListener ignores events marked as 'removed'.
assertNull(goog.events.getListener(et1, 'click', callback));
};
var key = goog.events.listen(et1, 'click', callback);
goog.events.dispatchEvent(et1, 'click');
}
function testHasListener() {
var div = document.createElement('div');
assertFalse(goog.events.hasListener(div));
var key = goog.events.listen(div, 'click', function(){});
assertTrue(goog.events.hasListener(div));
assertTrue(goog.events.hasListener(div, 'click'));
assertTrue(goog.events.hasListener(div, 'click', false));
assertTrue(goog.events.hasListener(div, undefined, false));
assertFalse(goog.events.hasListener(div, 'click', true));
assertFalse(goog.events.hasListener(div, undefined, true));
assertFalse(goog.events.hasListener(div, 'mouseup'));
// Test that hasListener returns false when all listeners are removed.
goog.events.unlistenByKey(key);
assertFalse(goog.events.hasListener(div));
}
function testHasListenerWithEventTarget() {
assertFalse(goog.events.hasListener(et1));
function callback() {};
goog.events.listen(et1, 'test', callback, true);
assertTrue(goog.events.hasListener(et1));
assertTrue(goog.events.hasListener(et1, 'test'));
assertTrue(goog.events.hasListener(et1, 'test', true));
assertTrue(goog.events.hasListener(et1, undefined, true));
assertFalse(goog.events.hasListener(et1, 'click'));
assertFalse(goog.events.hasListener(et1, 'test', false));
goog.events.unlisten(et1, 'test', callback, true);
assertFalse(goog.events.hasListener(et1));
}
function testHasListenerWithMultipleTargets() {
function callback() {};
goog.events.listen(et1, 'test1', callback, true);
goog.events.listen(et2, 'test2', callback, true);
assertTrue(goog.events.hasListener(et1));
assertTrue(goog.events.hasListener(et2));
assertTrue(goog.events.hasListener(et1, 'test1'));
assertTrue(goog.events.hasListener(et2, 'test2'));
assertFalse(goog.events.hasListener(et1, 'et2'));
assertFalse(goog.events.hasListener(et2, 'et1'));
goog.events.removeAll(et1);
goog.events.removeAll(et2);
}
function testBubbleSingle() {
et1.setParentEventTarget(et2);
et2.setParentEventTarget(et3);
var count = 0;
function callback() {
count++;
}
goog.events.listen(et3, 'test', callback, false);
et1.dispatchEvent('test');
assertEquals(1, count);
goog.events.removeAll(et1);
goog.events.removeAll(et2);
goog.events.removeAll(et3);
}
function testCaptureSingle() {
et1.setParentEventTarget(et2);
et2.setParentEventTarget(et3);
var count = 0;
function callback() {
count++;
}
goog.events.listen(et3, 'test', callback, true);
et1.dispatchEvent('test');
assertEquals(1, count);
goog.events.removeAll(et1);
goog.events.removeAll(et2);
goog.events.removeAll(et3);
}
function testCaptureAndBubble() {
et1.setParentEventTarget(et2);
et2.setParentEventTarget(et3);
var count = 0;
function callbackCapture1() {
count++;
assertEquals(3, count);
}
function callbackBubble1() {
count++;
assertEquals(4, count);
}
function callbackCapture2() {
count++;
assertEquals(2, count);
}
function callbackBubble2() {
count++;
assertEquals(5, count);
}
function callbackCapture3() {
count++;
assertEquals(1, count);
}
function callbackBubble3() {
count++;
assertEquals(6, count);
}
goog.events.listen(et1, 'test', callbackCapture1, true);
goog.events.listen(et1, 'test', callbackBubble1, false);
goog.events.listen(et2, 'test', callbackCapture2, true);
goog.events.listen(et2, 'test', callbackBubble2, false);
goog.events.listen(et3, 'test', callbackCapture3, true);
goog.events.listen(et3, 'test', callbackBubble3, false);
et1.dispatchEvent('test');
assertEquals(6, count);
goog.events.removeAll(et1);
goog.events.removeAll(et2);
goog.events.removeAll(et3);
}
function testCapturingRemovesBubblingListener() {
var bubbleCount = 0;
function callbackBubble() {
bubbleCount++;
}
var captureCount = 0;
function callbackCapture() {
captureCount++;
goog.events.removeAll(et1);
}
goog.events.listen(et1, 'test', callbackCapture, true);
goog.events.listen(et1, 'test', callbackBubble, false);
et1.dispatchEvent('test');
assertEquals(1, captureCount);
assertEquals(0, bubbleCount);
}
function dispatchClick(target) {
if (target.click) {
target.click();
} else {
var e = document.createEvent('MouseEvents');
e.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false,
false, false, false, 0, null);
target.dispatchEvent(e);
}
}
function testHandleBrowserEventBubblingListener() {
var count = 0;
var body = document.body;
goog.events.listen(body, 'click', function() {
count++;
});
dispatchClick(body);
assertEquals(1, count);
}
function testHandleBrowserEventCapturingListener() {
var count = 0;
var body = document.body;
goog.events.listen(body, 'click', function() {
count++;
}, true);
dispatchClick(body);
assertEquals(1, count);
}
function testHandleBrowserEventCapturingAndBubblingListener() {
var count = 1;
var body = document.body;
goog.events.listen(body, 'click', function() {
count += 3;
}, true);
goog.events.listen(body, 'click', function() {
count *= 5;
}, false);
dispatchClick(body);
assertEquals(20, count);
}
function testHandleBrowserEventCapturingRemovesBubblingListener() {
var body = document.body;
var bubbleCount = 0;
function callbackBubble() {
bubbleCount++;
}
var captureCount = 0;
function callbackCapture() {
captureCount++;
goog.events.removeAll(body);
}
goog.events.listen(body, 'click', callbackCapture, true);
goog.events.listen(body, 'click', callbackBubble, false);
dispatchClick(body);
assertEquals(1, captureCount);
assertEquals(0, bubbleCount);
}
function testHandleEventPropagationOnParentElement() {
var count = 1;
goog.events.listen(document.documentElement, 'click',
function() {
count += 3;
}, true);
goog.events.listen(document.documentElement, 'click', function() {
count *= 5;
}, false);
dispatchClick(document.body);
assertEquals(20, count);
}
function testEntryPointRegistry() {
var monitor = new goog.debug.EntryPointMonitor();
var replacement = function() {};
monitor.wrap = goog.testing.recordFunction(
goog.functions.constant(replacement));
goog.debug.entryPointRegistry.monitorAll(monitor);
assertTrue(monitor.wrap.getCallCount() >= 1);
assertEquals(replacement, goog.events.handleBrowserEvent_);
}
// Fixes bug http://b/6434926
function testListenOnceHandlerDispatchCausingInfiniteLoop() {
var handleFoo = goog.testing.recordFunction(function() {
et1.dispatchEvent('foo');
});
goog.events.listenOnce(et1, 'foo', handleFoo);
et1.dispatchEvent('foo');
assertEquals('Handler should be called only once.',
1, handleFoo.getCallCount());
}
function testCreationStack() {
if (!new Error().stack)
return;
propertyReplacer.replace(goog.events.Listener, 'ENABLE_MONITORING', true);
var div = document.createElement('div');
var key = goog.events.listen(
div, goog.events.EventType.CLICK, goog.nullFunction);
var listenerStack = key.creationStack;
// Check that the name of this test function occurs in the stack trace.
assertContains('testCreationStack', listenerStack);
goog.events.unlistenByKey(key);
}
/**
* The behavior of goog.events when a UID changes is undefined.
* We just want to make sure we don't throw an exception.
*/
function testUidDisappearanceJsTargets() {
var listener = goog.testing.recordFunction();
goog.events.listenOnce(et1, 'foo', listener, false);
goog.removeUid(et1);
et1.dispatchEvent('foo');
assertEquals(1, listener.getCallCount());
}
/**
* The behavior of goog.events when a UID changes is undefined.
* We just want to make sure we don't throw an exception.
*/
function testUidDisappearanceBrowserTargets() {
var listener = goog.testing.recordFunction();
var body = document.body;
goog.events.listenOnce(body, 'click', listener);
goog.removeUid(body);
dispatchClick(body);
assertEquals(1, listener.getCallCount());
// Make sure that dispatching again doesn't fire the listener.
dispatchClick(body);
assertEquals(1, listener.getCallCount());
}
function testListenOnceAfterListenDoesNotChangeExistingListener() {
var listener = goog.testing.recordFunction();
goog.events.listen(document.body, 'click', listener);
goog.events.listenOnce(document.body, 'click', listener);
dispatchClick(document.body);
dispatchClick(document.body);
dispatchClick(document.body);
assertEquals(3, listener.getCallCount());
}
function testListenOnceAfterListenOnceDoesNotChangeExistingListener() {
var listener = goog.testing.recordFunction();
goog.events.listenOnce(document.body, 'click', listener);
goog.events.listenOnce(document.body, 'click', listener);
dispatchClick(document.body);
dispatchClick(document.body);
dispatchClick(document.body);
assertEquals(1, listener.getCallCount());
}
function testListenAfterListenOnceRemoveOnceness() {
var listener = goog.testing.recordFunction();
goog.events.listenOnce(document.body, 'click', listener);
goog.events.listen(document.body, 'click', listener);
dispatchClick(document.body);
dispatchClick(document.body);
dispatchClick(document.body);
assertEquals(3, listener.getCallCount());
}
function testUnlistenAfterListenOnce() {
var listener = goog.testing.recordFunction();
goog.events.listenOnce(document.body, 'click', listener);
goog.events.unlisten(document.body, 'click', listener);
dispatchClick(document.body);
goog.events.listenOnce(document.body, 'click', listener);
goog.events.listen(document.body, 'click', listener);
goog.events.unlisten(document.body, 'click', listener);
dispatchClick(document.body);
goog.events.listen(document.body, 'click', listener);
goog.events.listenOnce(document.body, 'click', listener);
goog.events.unlisten(document.body, 'click', listener);
dispatchClick(document.body);
goog.events.listenOnce(document.body, 'click', listener);
goog.events.listenOnce(document.body, 'click', listener);
goog.events.unlisten(document.body, 'click', listener);
dispatchClick(document.body);
assertEquals(0, listener.getCallCount());
}
function testRemoveAll() {
var listener = goog.testing.recordFunction();
var div = document.createElement('div');
goog.events.listenOnce(document.body, 'click', listener);
goog.events.listen(document.body, 'click', listener);
goog.events.listenOnce(div, 'click', listener);
goog.events.listen(div, 'click', listener);
goog.events.removeAllNativeListeners();
dispatchClick(document.body);
dispatchClick(div);
assertEquals(0, listener.getCallCount());
}
function testEventBubblingWithReentrantDispatch_bubbling() {
runEventPropogationWithReentrantDispatch(false);
}
function testEventBubblingWithReentrantDispatch_capture() {
runEventPropogationWithReentrantDispatch(true);
}
function runEventPropogationWithReentrantDispatch(useCapture) {
var eventType = 'test-event-type';
var child = et1;
var parent = et2;
child.setParentEventTarget(parent);
var firstTarget = useCapture ? parent : child;
var secondTarget = useCapture ? child : parent;
var firstListener = function(evt) {
if (evt.isFirstEvent) {
// Fires another event of the same type the first time it is invoked.
child.dispatchEvent(new goog.events.Event(eventType));
}
};
goog.events.listen(firstTarget, eventType, firstListener, useCapture);
var secondListener = goog.testing.recordFunction();
goog.events.listen(secondTarget, eventType, secondListener, useCapture);
// Fire the first event.
var firstEvent = new goog.events.Event(eventType);
firstEvent.isFirstEvent = true;
child.dispatchEvent(firstEvent);
assertEquals(2, secondListener.getCallCount());
}
function testEventPropogationWhenListenerRemoved_bubbling() {
runEventPropogationWhenListenerRemoved(false);
}
function testEventPropogationWhenListenerRemoved_capture() {
runEventPropogationWhenListenerRemoved(true);
}
function runEventPropogationWhenListenerRemoved(useCapture) {
var eventType = 'test-event-type';
var child = et1;
var parent = et2;
child.setParentEventTarget(parent);
var firstTarget = useCapture ? parent : child;
var secondTarget = useCapture ? child : parent;
var firstListener = goog.testing.recordFunction();
var secondListener = goog.testing.recordFunction();
goog.events.listenOnce(firstTarget, eventType, firstListener, useCapture);
goog.events.listen(secondTarget, eventType, secondListener, useCapture);
child.dispatchEvent(new goog.events.Event(eventType));
assertEquals(1, secondListener.getCallCount());
}
function testEventPropogationWhenListenerAdded_bubbling() {
runEventPropogationWhenListenerAdded(false);
}
function testEventPropogationWhenListenerAdded_capture() {
runEventPropogationWhenListenerAdded(true);
}
function runEventPropogationWhenListenerAdded(useCapture) {
var eventType = 'test-event-type';
var child = et1;
var parent = et2;
child.setParentEventTarget(parent);
var firstTarget = useCapture ? parent : child;
var secondTarget = useCapture ? child : parent;
var firstListener = function() {
goog.events.listen(secondTarget, eventType, secondListener, useCapture);
};
var secondListener = goog.testing.recordFunction();
goog.events.listen(firstTarget, eventType, firstListener, useCapture);
child.dispatchEvent(new goog.events.Event(eventType));
assertEquals(1, secondListener.getCallCount());
}
function testEventPropogationWhenListenerAddedAndRemoved_bubbling() {
runEventPropogationWhenListenerAddedAndRemoved(false);
}
function testEventPropogationWhenListenerAddedAndRemoved_capture() {
runEventPropogationWhenListenerAddedAndRemoved(true);
}
function runEventPropogationWhenListenerAddedAndRemoved(useCapture) {
var eventType = 'test-event-type';
var child = et1;
var parent = et2;
child.setParentEventTarget(parent);
var firstTarget = useCapture ? parent : child;
var secondTarget = useCapture ? child : parent;
var firstListener = function() {
goog.events.listen(secondTarget, eventType, secondListener, useCapture);
};
var secondListener = goog.testing.recordFunction();
goog.events.listenOnce(firstTarget, eventType, firstListener, useCapture);
child.dispatchEvent(new goog.events.Event(eventType));
assertEquals(1, secondListener.getCallCount());
}
function testAssertWhenUsedWithUninitializedCustomEventTarget() {
var SubClass = function() { /* does not call superclass ctor */ };
goog.inherits(SubClass, goog.events.EventTarget);
var instance = new SubClass();
var e;
e = assertThrows(function() {
goog.events.listen(instance, 'test1', function() {});
});
assertTrue(e instanceof goog.asserts.AssertionError);
e = assertThrows(function() {
goog.events.dispatchEvent(instance, 'test1');
});
assertTrue(e instanceof goog.asserts.AssertionError);
e = assertThrows(function() {
instance.dispatchEvent('test1');
});
assertTrue(e instanceof goog.asserts.AssertionError);
}
function testAssertWhenDispatchEventIsUsedWithNonCustomEventTarget() {
var obj = {};
e = assertThrows(function() {
goog.events.dispatchEvent(obj, 'test1');
});
assertTrue(e instanceof goog.asserts.AssertionError);
}
function testRemoveAllNativeListeners() {
var handler = goog.testing.recordFunction();
var bodyEl = document.body;
var div = document.createElement('div');
var et = new goog.events.EventTarget();
goog.events.listen(bodyEl, goog.events.EventType.CLICK, handler);
goog.events.listen(div, goog.events.EventType.CLICK, handler);
goog.events.listen(et, 'test', handler);
goog.events.removeAllNativeListeners();
assertFalse(goog.events.hasListener(bodyEl));
assertFalse(goog.events.hasListener(div));
assertTrue(goog.events.hasListener(et));
}
</script>
</body>
</html>