Adding mapbox-gl branch
This commit is contained in:
@@ -0,0 +1,307 @@
|
||||
// Copyright 2005 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 Implements the disposable interface. The dispose method is used
|
||||
* to clean up references and resources.
|
||||
* @author arv@google.com (Erik Arvidsson)
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.Disposable');
|
||||
/** @suppress {extraProvide} */
|
||||
goog.provide('goog.dispose');
|
||||
/** @suppress {extraProvide} */
|
||||
goog.provide('goog.disposeAll');
|
||||
|
||||
goog.require('goog.disposable.IDisposable');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Class that provides the basic implementation for disposable objects. If your
|
||||
* class holds one or more references to COM objects, DOM nodes, or other
|
||||
* disposable objects, it should extend this class or implement the disposable
|
||||
* interface (defined in goog.disposable.IDisposable).
|
||||
* @constructor
|
||||
* @implements {goog.disposable.IDisposable}
|
||||
*/
|
||||
goog.Disposable = function() {
|
||||
if (goog.Disposable.MONITORING_MODE != goog.Disposable.MonitoringMode.OFF) {
|
||||
if (goog.Disposable.INCLUDE_STACK_ON_CREATION) {
|
||||
this.creationStack = new Error().stack;
|
||||
}
|
||||
goog.Disposable.instances_[goog.getUid(this)] = this;
|
||||
}
|
||||
// Support sealing
|
||||
this.disposed_ = this.disposed_;
|
||||
this.onDisposeCallbacks_ = this.onDisposeCallbacks_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @enum {number} Different monitoring modes for Disposable.
|
||||
*/
|
||||
goog.Disposable.MonitoringMode = {
|
||||
/**
|
||||
* No monitoring.
|
||||
*/
|
||||
OFF: 0,
|
||||
/**
|
||||
* Creating and disposing the goog.Disposable instances is monitored. All
|
||||
* disposable objects need to call the {@code goog.Disposable} base
|
||||
* constructor. The PERMANENT mode must be switched on before creating any
|
||||
* goog.Disposable instances.
|
||||
*/
|
||||
PERMANENT: 1,
|
||||
/**
|
||||
* INTERACTIVE mode can be switched on and off on the fly without producing
|
||||
* errors. It also doesn't warn if the disposable objects don't call the
|
||||
* {@code goog.Disposable} base constructor.
|
||||
*/
|
||||
INTERACTIVE: 2
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @define {number} The monitoring mode of the goog.Disposable
|
||||
* instances. Default is OFF. Switching on the monitoring is only
|
||||
* recommended for debugging because it has a significant impact on
|
||||
* performance and memory usage. If switched off, the monitoring code
|
||||
* compiles down to 0 bytes.
|
||||
*/
|
||||
goog.define('goog.Disposable.MONITORING_MODE', 0);
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether to attach creation stack to each created disposable
|
||||
* instance; This is only relevant for when MonitoringMode != OFF.
|
||||
*/
|
||||
goog.define('goog.Disposable.INCLUDE_STACK_ON_CREATION', true);
|
||||
|
||||
|
||||
/**
|
||||
* Maps the unique ID of every undisposed {@code goog.Disposable} object to
|
||||
* the object itself.
|
||||
* @type {!Object<number, !goog.Disposable>}
|
||||
* @private
|
||||
*/
|
||||
goog.Disposable.instances_ = {};
|
||||
|
||||
|
||||
/**
|
||||
* @return {!Array<!goog.Disposable>} All {@code goog.Disposable} objects that
|
||||
* haven't been disposed of.
|
||||
*/
|
||||
goog.Disposable.getUndisposedObjects = function() {
|
||||
var ret = [];
|
||||
for (var id in goog.Disposable.instances_) {
|
||||
if (goog.Disposable.instances_.hasOwnProperty(id)) {
|
||||
ret.push(goog.Disposable.instances_[Number(id)]);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Clears the registry of undisposed objects but doesn't dispose of them.
|
||||
*/
|
||||
goog.Disposable.clearUndisposedObjects = function() {
|
||||
goog.Disposable.instances_ = {};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Whether the object has been disposed of.
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
goog.Disposable.prototype.disposed_ = false;
|
||||
|
||||
|
||||
/**
|
||||
* Callbacks to invoke when this object is disposed.
|
||||
* @type {Array<!Function>}
|
||||
* @private
|
||||
*/
|
||||
goog.Disposable.prototype.onDisposeCallbacks_;
|
||||
|
||||
|
||||
/**
|
||||
* If monitoring the goog.Disposable instances is enabled, stores the creation
|
||||
* stack trace of the Disposable instance.
|
||||
* @const {string}
|
||||
*/
|
||||
goog.Disposable.prototype.creationStack;
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the object has been disposed of.
|
||||
* @override
|
||||
*/
|
||||
goog.Disposable.prototype.isDisposed = function() {
|
||||
return this.disposed_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the object has been disposed of.
|
||||
* @deprecated Use {@link #isDisposed} instead.
|
||||
*/
|
||||
goog.Disposable.prototype.getDisposed = goog.Disposable.prototype.isDisposed;
|
||||
|
||||
|
||||
/**
|
||||
* Disposes of the object. If the object hasn't already been disposed of, calls
|
||||
* {@link #disposeInternal}. Classes that extend {@code goog.Disposable} should
|
||||
* override {@link #disposeInternal} in order to delete references to COM
|
||||
* objects, DOM nodes, and other disposable objects. Reentrant.
|
||||
*
|
||||
* @return {void} Nothing.
|
||||
* @override
|
||||
*/
|
||||
goog.Disposable.prototype.dispose = function() {
|
||||
if (!this.disposed_) {
|
||||
// Set disposed_ to true first, in case during the chain of disposal this
|
||||
// gets disposed recursively.
|
||||
this.disposed_ = true;
|
||||
this.disposeInternal();
|
||||
if (goog.Disposable.MONITORING_MODE != goog.Disposable.MonitoringMode.OFF) {
|
||||
var uid = goog.getUid(this);
|
||||
if (goog.Disposable.MONITORING_MODE ==
|
||||
goog.Disposable.MonitoringMode.PERMANENT &&
|
||||
!goog.Disposable.instances_.hasOwnProperty(uid)) {
|
||||
throw Error(this + ' did not call the goog.Disposable base ' +
|
||||
'constructor or was disposed of after a clearUndisposedObjects ' +
|
||||
'call');
|
||||
}
|
||||
delete goog.Disposable.instances_[uid];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Associates a disposable object with this object so that they will be disposed
|
||||
* together.
|
||||
* @param {goog.disposable.IDisposable} disposable that will be disposed when
|
||||
* this object is disposed.
|
||||
*/
|
||||
goog.Disposable.prototype.registerDisposable = function(disposable) {
|
||||
this.addOnDisposeCallback(goog.partial(goog.dispose, disposable));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Invokes a callback function when this object is disposed. Callbacks are
|
||||
* invoked in the order in which they were added. If a callback is added to
|
||||
* an already disposed Disposable, it will be called immediately.
|
||||
* @param {function(this:T):?} callback The callback function.
|
||||
* @param {T=} opt_scope An optional scope to call the callback in.
|
||||
* @template T
|
||||
*/
|
||||
goog.Disposable.prototype.addOnDisposeCallback = function(callback, opt_scope) {
|
||||
if (this.disposed_) {
|
||||
callback.call(opt_scope);
|
||||
return;
|
||||
}
|
||||
if (!this.onDisposeCallbacks_) {
|
||||
this.onDisposeCallbacks_ = [];
|
||||
}
|
||||
|
||||
this.onDisposeCallbacks_.push(
|
||||
goog.isDef(opt_scope) ? goog.bind(callback, opt_scope) : callback);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Deletes or nulls out any references to COM objects, DOM nodes, or other
|
||||
* disposable objects. Classes that extend {@code goog.Disposable} should
|
||||
* override this method.
|
||||
* Not reentrant. To avoid calling it twice, it must only be called from the
|
||||
* subclass' {@code disposeInternal} method. Everywhere else the public
|
||||
* {@code dispose} method must be used.
|
||||
* For example:
|
||||
* <pre>
|
||||
* mypackage.MyClass = function() {
|
||||
* mypackage.MyClass.base(this, 'constructor');
|
||||
* // Constructor logic specific to MyClass.
|
||||
* ...
|
||||
* };
|
||||
* goog.inherits(mypackage.MyClass, goog.Disposable);
|
||||
*
|
||||
* mypackage.MyClass.prototype.disposeInternal = function() {
|
||||
* // Dispose logic specific to MyClass.
|
||||
* ...
|
||||
* // Call superclass's disposeInternal at the end of the subclass's, like
|
||||
* // in C++, to avoid hard-to-catch issues.
|
||||
* mypackage.MyClass.base(this, 'disposeInternal');
|
||||
* };
|
||||
* </pre>
|
||||
* @protected
|
||||
*/
|
||||
goog.Disposable.prototype.disposeInternal = function() {
|
||||
if (this.onDisposeCallbacks_) {
|
||||
while (this.onDisposeCallbacks_.length) {
|
||||
this.onDisposeCallbacks_.shift()();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns True if we can verify the object is disposed.
|
||||
* Calls {@code isDisposed} on the argument if it supports it. If obj
|
||||
* is not an object with an isDisposed() method, return false.
|
||||
* @param {*} obj The object to investigate.
|
||||
* @return {boolean} True if we can verify the object is disposed.
|
||||
*/
|
||||
goog.Disposable.isDisposed = function(obj) {
|
||||
if (obj && typeof obj.isDisposed == 'function') {
|
||||
return obj.isDisposed();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Calls {@code dispose} on the argument if it supports it. If obj is not an
|
||||
* object with a dispose() method, this is a no-op.
|
||||
* @param {*} obj The object to dispose of.
|
||||
*/
|
||||
goog.dispose = function(obj) {
|
||||
if (obj && typeof obj.dispose == 'function') {
|
||||
obj.dispose();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Calls {@code dispose} on each member of the list that supports it. (If the
|
||||
* member is an ArrayLike, then {@code goog.disposeAll()} will be called
|
||||
* recursively on each of its members.) If the member is not an object with a
|
||||
* {@code dispose()} method, then it is ignored.
|
||||
* @param {...*} var_args The list.
|
||||
*/
|
||||
goog.disposeAll = function(var_args) {
|
||||
for (var i = 0, len = arguments.length; i < len; ++i) {
|
||||
var disposable = arguments[i];
|
||||
if (goog.isArrayLike(disposable)) {
|
||||
goog.disposeAll.apply(null, disposable);
|
||||
} else {
|
||||
goog.dispose(disposable);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,26 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<!-- Author: attila@google.com (Attila Bodis) -->
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<title>
|
||||
Closure Unit Tests - goog.Disposable
|
||||
</title>
|
||||
<script src="../base.js">
|
||||
</script>
|
||||
<script>
|
||||
goog.require('goog.DisposableTest');
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="someElement">
|
||||
Hello!
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,313 @@
|
||||
// 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.
|
||||
|
||||
goog.provide('goog.DisposableTest');
|
||||
goog.setTestOnly('goog.DisposableTest');
|
||||
|
||||
goog.require('goog.Disposable');
|
||||
goog.require('goog.testing.jsunit');
|
||||
goog.require('goog.testing.recordFunction');
|
||||
var d1, d2;
|
||||
|
||||
// Sample subclass of goog.Disposable.
|
||||
|
||||
function DisposableTest() {
|
||||
goog.Disposable.call(this);
|
||||
this.element = document.getElementById('someElement');
|
||||
}
|
||||
goog.inherits(DisposableTest, goog.Disposable);
|
||||
|
||||
DisposableTest.prototype.disposeInternal = function() {
|
||||
DisposableTest.superClass_.disposeInternal.call(this);
|
||||
delete this.element;
|
||||
};
|
||||
|
||||
// Class that doesn't inherit from goog.Disposable, but implements the
|
||||
// disposable interface via duck typing.
|
||||
|
||||
function DisposableDuck() {
|
||||
this.element = document.getElementById('someElement');
|
||||
}
|
||||
|
||||
DisposableDuck.prototype.dispose = function() {
|
||||
delete this.element;
|
||||
};
|
||||
|
||||
// Class which calls dispose recursively.
|
||||
|
||||
function RecursiveDisposable() {
|
||||
this.disposedCount = 0;
|
||||
}
|
||||
goog.inherits(RecursiveDisposable, goog.Disposable);
|
||||
|
||||
RecursiveDisposable.prototype.disposeInternal = function() {
|
||||
++this.disposedCount;
|
||||
assertEquals('Disposed too many times', 1, this.disposedCount);
|
||||
this.dispose();
|
||||
};
|
||||
|
||||
// Test methods.
|
||||
|
||||
function setUp() {
|
||||
d1 = new goog.Disposable();
|
||||
d2 = new DisposableTest();
|
||||
}
|
||||
|
||||
function tearDown() {
|
||||
goog.Disposable.MONITORING_MODE = goog.Disposable.MonitoringMode.OFF;
|
||||
goog.Disposable.INCLUDE_STACK_ON_CREATION = true;
|
||||
goog.Disposable.instances_ = {};
|
||||
d1.dispose();
|
||||
d2.dispose();
|
||||
}
|
||||
|
||||
function testConstructor() {
|
||||
assertFalse(d1.isDisposed());
|
||||
assertFalse(d2.isDisposed());
|
||||
assertEquals(document.getElementById('someElement'), d2.element);
|
||||
}
|
||||
|
||||
function testDispose() {
|
||||
assertFalse(d1.isDisposed());
|
||||
d1.dispose();
|
||||
assertTrue('goog.Disposable instance should have been disposed of',
|
||||
d1.isDisposed());
|
||||
|
||||
assertFalse(d2.isDisposed());
|
||||
d2.dispose();
|
||||
assertTrue('goog.DisposableTest instance should have been disposed of',
|
||||
d2.isDisposed());
|
||||
}
|
||||
|
||||
function testDisposeInternal() {
|
||||
assertNotUndefined(d2.element);
|
||||
d2.dispose();
|
||||
assertUndefined('goog.DisposableTest.prototype.disposeInternal should ' +
|
||||
'have deleted the element reference', d2.element);
|
||||
}
|
||||
|
||||
function testDisposeAgain() {
|
||||
d2.dispose();
|
||||
assertUndefined('goog.DisposableTest.prototype.disposeInternal should ' +
|
||||
'have deleted the element reference', d2.element);
|
||||
// Manually reset the element to a non-null value, and call dispose().
|
||||
// Because the object is already marked disposed, disposeInternal won't
|
||||
// be called again.
|
||||
d2.element = document.getElementById('someElement');
|
||||
d2.dispose();
|
||||
assertNotUndefined('disposeInternal should not be called again if the ' +
|
||||
'object has already been marked disposed', d2.element);
|
||||
}
|
||||
|
||||
function testDisposeWorksRecursively() {
|
||||
new RecursiveDisposable().dispose();
|
||||
}
|
||||
|
||||
function testStaticDispose() {
|
||||
assertFalse(d1.isDisposed());
|
||||
goog.dispose(d1);
|
||||
assertTrue('goog.Disposable instance should have been disposed of',
|
||||
d1.isDisposed());
|
||||
|
||||
assertFalse(d2.isDisposed());
|
||||
goog.dispose(d2);
|
||||
assertTrue('goog.DisposableTest instance should have been disposed of',
|
||||
d2.isDisposed());
|
||||
|
||||
var duck = new DisposableDuck();
|
||||
assertNotUndefined(duck.element);
|
||||
goog.dispose(duck);
|
||||
assertUndefined('goog.dispose should have disposed of object that ' +
|
||||
'implements the disposable interface', duck.element);
|
||||
}
|
||||
|
||||
function testStaticDisposeOnNonDisposableType() {
|
||||
// Call goog.dispose() with various types and make sure no errors are
|
||||
// thrown.
|
||||
goog.dispose(true);
|
||||
goog.dispose(false);
|
||||
goog.dispose(null);
|
||||
goog.dispose(undefined);
|
||||
goog.dispose('');
|
||||
goog.dispose([]);
|
||||
goog.dispose({});
|
||||
|
||||
function A() {}
|
||||
goog.dispose(new A());
|
||||
}
|
||||
|
||||
function testMonitoringFailure() {
|
||||
function BadDisposable() {};
|
||||
goog.inherits(BadDisposable, goog.Disposable);
|
||||
|
||||
goog.Disposable.MONITORING_MODE =
|
||||
goog.Disposable.MonitoringMode.PERMANENT;
|
||||
|
||||
var badDisposable = new BadDisposable;
|
||||
assertArrayEquals('no disposable objects registered', [],
|
||||
goog.Disposable.getUndisposedObjects());
|
||||
assertThrows('the base ctor should have been called',
|
||||
goog.bind(badDisposable.dispose, badDisposable));
|
||||
}
|
||||
|
||||
function testGetUndisposedObjects() {
|
||||
goog.Disposable.MONITORING_MODE =
|
||||
goog.Disposable.MonitoringMode.PERMANENT;
|
||||
|
||||
var d1 = new DisposableTest();
|
||||
var d2 = new DisposableTest();
|
||||
assertSameElements('the undisposed instances', [d1, d2],
|
||||
goog.Disposable.getUndisposedObjects());
|
||||
|
||||
d1.dispose();
|
||||
assertSameElements('1 undisposed instance left', [d2],
|
||||
goog.Disposable.getUndisposedObjects());
|
||||
|
||||
d1.dispose();
|
||||
assertSameElements('second disposal of the same object is no-op', [d2],
|
||||
goog.Disposable.getUndisposedObjects());
|
||||
|
||||
d2.dispose();
|
||||
assertSameElements('all objects have been disposed of', [],
|
||||
goog.Disposable.getUndisposedObjects());
|
||||
}
|
||||
|
||||
function testClearUndisposedObjects() {
|
||||
goog.Disposable.MONITORING_MODE =
|
||||
goog.Disposable.MonitoringMode.PERMANENT;
|
||||
|
||||
var d1 = new DisposableTest();
|
||||
var d2 = new DisposableTest();
|
||||
d2.dispose();
|
||||
goog.Disposable.clearUndisposedObjects();
|
||||
assertSameElements('no undisposed object in the registry', [],
|
||||
goog.Disposable.getUndisposedObjects());
|
||||
|
||||
assertThrows('disposal after clearUndisposedObjects()', function() {
|
||||
d1.dispose();
|
||||
});
|
||||
|
||||
// d2 is already disposed of, the redisposal shouldn't throw error.
|
||||
d2.dispose();
|
||||
}
|
||||
|
||||
function testRegisterDisposable() {
|
||||
var d1 = new DisposableTest();
|
||||
var d2 = new DisposableTest();
|
||||
|
||||
d1.registerDisposable(d2);
|
||||
d1.dispose();
|
||||
|
||||
assertTrue('d2 should be disposed when d1 is disposed', d2.isDisposed());
|
||||
}
|
||||
|
||||
function testDisposeAll() {
|
||||
var d1 = new DisposableTest();
|
||||
var d2 = new DisposableTest();
|
||||
|
||||
goog.disposeAll(d1, d2);
|
||||
|
||||
assertTrue('d1 should be disposed', d1.isDisposed());
|
||||
assertTrue('d2 should be disposed', d2.isDisposed());
|
||||
}
|
||||
|
||||
function testDisposeAllRecursive() {
|
||||
var d1 = new DisposableTest();
|
||||
var d2 = new DisposableTest();
|
||||
var d3 = new DisposableTest();
|
||||
var d4 = new DisposableTest();
|
||||
|
||||
goog.disposeAll(d1, [[d2], d3, d4]);
|
||||
|
||||
assertTrue('d1 should be disposed', d1.isDisposed());
|
||||
assertTrue('d2 should be disposed', d2.isDisposed());
|
||||
assertTrue('d3 should be disposed', d3.isDisposed());
|
||||
assertTrue('d4 should be disposed', d4.isDisposed());
|
||||
}
|
||||
|
||||
function testCreationStack() {
|
||||
if (!new Error().stack)
|
||||
return;
|
||||
goog.Disposable.MONITORING_MODE =
|
||||
goog.Disposable.MonitoringMode.PERMANENT;
|
||||
var disposableStack = new DisposableTest().creationStack;
|
||||
// Check that the name of this test function occurs in the stack trace.
|
||||
assertNotEquals(-1, disposableStack.indexOf('testCreationStack'));
|
||||
}
|
||||
|
||||
function testMonitoredWithoutCreationStack() {
|
||||
if (!new Error().stack)
|
||||
return;
|
||||
goog.Disposable.MONITORING_MODE =
|
||||
goog.Disposable.MonitoringMode.PERMANENT;
|
||||
goog.Disposable.INCLUDE_STACK_ON_CREATION = false;
|
||||
var d1 = new DisposableTest();
|
||||
|
||||
// Check that it is tracked, but not with a creation stack.
|
||||
assertUndefined(d1.creationStack);
|
||||
assertSameElements('the undisposed instance', [d1],
|
||||
goog.Disposable.getUndisposedObjects());
|
||||
}
|
||||
|
||||
function testOnDisposeCallback() {
|
||||
var callback = goog.testing.recordFunction();
|
||||
d1.addOnDisposeCallback(callback);
|
||||
assertEquals('callback called too early', 0, callback.getCallCount());
|
||||
d1.dispose();
|
||||
assertEquals('callback should be called once on dispose',
|
||||
1, callback.getCallCount());
|
||||
}
|
||||
|
||||
function testOnDisposeCallbackOrder() {
|
||||
var invocations = [];
|
||||
var callback = function(str) {
|
||||
invocations.push(str);
|
||||
};
|
||||
d1.addOnDisposeCallback(goog.partial(callback, 'a'));
|
||||
d1.addOnDisposeCallback(goog.partial(callback, 'b'));
|
||||
goog.dispose(d1);
|
||||
assertArrayEquals('callbacks should be called in chronological order',
|
||||
['a', 'b'], invocations);
|
||||
}
|
||||
|
||||
function testAddOnDisposeCallbackAfterDispose() {
|
||||
var callback = goog.testing.recordFunction();
|
||||
var scope = {};
|
||||
goog.dispose(d1);
|
||||
d1.addOnDisposeCallback(callback, scope);
|
||||
assertEquals('Callback should be immediately called if already disposed', 1,
|
||||
callback.getCallCount());
|
||||
assertEquals('Callback scope should be respected', scope,
|
||||
callback.getLastCall().getThis());
|
||||
}
|
||||
|
||||
function testInteractiveMonitoring() {
|
||||
var d1 = new DisposableTest();
|
||||
goog.Disposable.MONITORING_MODE =
|
||||
goog.Disposable.MonitoringMode.INTERACTIVE;
|
||||
var d2 = new DisposableTest();
|
||||
|
||||
assertSameElements('only 1 undisposed instance tracked', [d2],
|
||||
goog.Disposable.getUndisposedObjects());
|
||||
|
||||
// No errors should be thrown.
|
||||
d1.dispose();
|
||||
|
||||
assertSameElements('1 undisposed instance left', [d2],
|
||||
goog.Disposable.getUndisposedObjects());
|
||||
|
||||
d2.dispose();
|
||||
assertSameElements('all disposed', [],
|
||||
goog.Disposable.getUndisposedObjects());
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
// Copyright 2011 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 Definition of the disposable interface. A disposable object
|
||||
* has a dispose method to to clean up references and resources.
|
||||
* @author nnaze@google.com (Nathan Naze)
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.disposable.IDisposable');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Interface for a disposable object. If a instance requires cleanup
|
||||
* (references COM objects, DOM notes, or other disposable objects), it should
|
||||
* implement this interface (it may subclass goog.Disposable).
|
||||
* @interface
|
||||
*/
|
||||
goog.disposable.IDisposable = function() {};
|
||||
|
||||
|
||||
/**
|
||||
* Disposes of the object and its resources.
|
||||
* @return {void} Nothing.
|
||||
*/
|
||||
goog.disposable.IDisposable.prototype.dispose = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the object has been disposed of.
|
||||
*/
|
||||
goog.disposable.IDisposable.prototype.isDisposed = goog.abstractMethod;
|
||||
Reference in New Issue
Block a user