Files
polymer/test/unit/async.html
2018-04-19 18:19:39 -07:00

480 lines
13 KiB
HTML

<!doctype html>
<!--
@license
Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-->
<html>
<head>
<meta charset="utf-8">
<script src="../../node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
<script src="wct-browser-config.js"></script>
<script src="../../node_modules/wct-browser-legacy/browser.js"></script>
<script type="module" src="../../lib/utils/async.js"></script>
</head>
<body>
<script type="module">
import { microTask, timeOut, animationFrame, idlePeriod } from '../../lib/utils/async.js';
var capturedErrors = [];
var captureEnabled = false;
window.addEventListener('error', function(e) {
if (captureEnabled) {
capturedErrors.push(e);
e.stopImmediatePropagation();
e.preventDefault();
return true;
}
});
suite('Queueing micro tasks', function() {
test('The queued function runs.', function(done) {
var callCount = 0;
var callback = function() {
callCount++;
};
microTask.run(callback);
setTimeout(function() {
assert.equal(callCount, 1);
done();
});
});
test('Functions queued multiple times are run multiple times.',
function(done) {
var callCount = 0;
var callback = function() {
callCount++;
};
microTask.run(callback);
microTask.run(callback);
microTask.run(callback);
setTimeout(function() {
assert.equal(callCount, 3);
done();
});
});
test('All queued functions are run.', function(done) {
var callCount1 = 0;
var callCount2 = 0;
var callCount3 = 0;
var callback1 = function() {
callCount1++;
};
var callback2 = function() {
callCount2++;
};
var callback3 = function() {
callCount3++;
};
microTask.run(callback1);
microTask.run(callback2);
microTask.run(callback3);
setTimeout(function() {
assert.equal(callCount1, 1);
assert.equal(callCount2, 1);
assert.equal(callCount3, 1);
done();
});
});
test('Errors are thrown but the queue is continued', function(done) {
captureEnabled = true;
var callCount1 = 0;
var callCount2 = 0;
var callCount3 = 0;
var callCount4 = 0;
var callCount5 = 0;
var callback1 = function() {
callCount1++;
};
var callback2 = function() {
callCount2++;
throw new Error('intentional error 1');
};
var callback3 = function() {
callCount3++;
microTask.run(callback5);
throw new Error('intentional error 2');
};
var callback4 = function() {
callCount4++;
};
var callback5 = function() {
callCount5++;
};
microTask.run(callback1);
microTask.run(callback2);
microTask.run(callback3);
microTask.run(callback4);
// All callbacks have been called by the next task.
setTimeout(function() {
captureEnabled = false;
assert.equal(callCount1, 1);
assert.equal(callCount2, 1);
assert.equal(callCount3, 1);
assert.equal(callCount4, 1);
assert.equal(callCount5, 1);
assert.equal(capturedErrors.length, 2);
capturedErrors.length = 0;
done();
}, 100);
});
});
suite('Cancelling micro tasks', function() {
test('Queued functions are cancelable.', function(done) {
var callCount = 0;
var callback = function() {
callCount++;
};
var asyncRef = microTask.run(callback);
microTask.cancel(asyncRef);
setTimeout(function() {
assert.equal(callCount, 0);
done();
});
});
test('Multiple instances of the same queued function are cancelable.', function(done) {
var callCount = 0;
var callback = function() {
callCount++;
};
var asyncRefs = [];
asyncRefs.push(microTask.run(callback));
asyncRefs.push(microTask.run(callback));
asyncRefs.push(microTask.run(callback));
microTask.cancel(asyncRefs.pop());
microTask.cancel(asyncRefs.pop());
microTask.cancel(asyncRefs.pop());
setTimeout(function() {
assert.equal(callCount, 0);
done();
});
});
test('Multiple queued functions are individually cancelable.', function(done) {
var callCount1 = 0;
var callCount2 = 0;
var callCount3 = 0;
var callback1 = function() {
callCount1++;
};
var callback2 = function() {
callCount2++;
};
var callback3 = function() {
callCount3++;
};
var asyncRef1 = microTask.run(callback1);
microTask.run(callback2);
var asyncRef3 = microTask.run(callback3);
microTask.cancel(asyncRef1);
microTask.cancel(asyncRef3);
setTimeout(function() {
assert.equal(callCount1, 0);
assert.equal(callCount2, 1);
assert.equal(callCount3, 0);
done();
});
});
});
suite('Queueing timeouts with a wait time', function() {
test('The queued function runs.', function(done) {
var callCount = 0;
var callback = function() {
callCount++;
};
timeOut.run(callback, 50);
timeOut.after(50).run(callback);
setTimeout(function() {
assert.equal(callCount, 2);
done();
}, 100);
});
test('Functions queued multiple times are run multiple times.', function(done) {
var callCount = 0;
var callback = function() {
callCount++;
};
timeOut.run(callback, 50);
timeOut.after(50).run(callback);
timeOut.run(callback, 50);
timeOut.after(50).run(callback);
timeOut.run(callback, 200);
timeOut.after(200).run(callback);
setTimeout(function() {
assert.equal(callCount, 4);
done();
}, 100); // Only wait until the first two callbacks are called.
});
test('All queued functions are run.', function(done) {
var callCount1 = 0;
var callCount2 = 0;
var callCount3 = 0;
var callback1 = function() {
callCount1++;
};
var callback2 = function() {
callCount2++;
};
var callback3 = function() {
callCount3++;
};
timeOut.run(callback1, 50);
timeOut.run(callback2, 50);
timeOut.run(callback3, 200);
setTimeout(function() {
assert.equal(callCount1, 1);
assert.equal(callCount2, 1);
assert.equal(callCount3, 0);
done();
}, 100); // Only wait until the first two callbacks are called.
});
});
suite('Cancelling timers queued with a wait time', function() {
test('Queued functions are cancelable.', function(done) {
var callCount = 0;
var callback = function() {
callCount++;
};
var asyncRef = timeOut.run(callback, 50);
timeOut.cancel(asyncRef);
setTimeout(function() {
assert.equal(callCount, 0);
done();
}, 100);
});
test('Multiple instances of the same queued function are cancelable.', function(done) {
var callCount = 0;
var callback = function() {
callCount++;
};
var queue = [];
queue.push(timeOut.run(callback, 50));
queue.push(timeOut.run(callback, 50));
queue.push(timeOut.after(50).run(callback));
queue.push(timeOut.run(callback, 200));
while (queue.length > 0) {
timeOut.cancel(queue.pop());
}
setTimeout(function() {
assert.equal(callCount, 0);
done();
}, 250);
});
test('Multiple queued functions are individually cancelable.', function(done) {
var callCount1 = 0;
var callCount2 = 0;
var callCount3 = 0;
var callback1 = function() {
callCount1++;
};
var callback2 = function() {
callCount2++;
};
var callback3 = function() {
callCount3++;
};
var asyncRef1 = timeOut.run(callback1, 50);
microTask.run(callback2, 50);
var asyncRef3 = timeOut.run(callback3, 200);
timeOut.cancel(asyncRef1);
timeOut.cancel(asyncRef3);
setTimeout(function() {
assert.equal(callCount1, 0);
assert.equal(callCount2, 1);
assert.equal(callCount3, 0);
done();
}, 250);
});
});
suite('Queueing functions to run before the next paint', function() {
test('The queued function runs.', function(done) {
var callback = sinon.spy();
animationFrame.run(callback);
requestAnimationFrame(function() {
assert.isTrue(callback.calledOnce);
done();
});
});
test('Functions queued multiple times are run multiple times.', function(done) {
var callback = sinon.spy();
animationFrame.run(callback);
animationFrame.run(callback);
requestAnimationFrame(function() {
assert.isTrue(callback.calledTwice);
done();
});
});
test('All queued functions are run.', function(done) {
var callback1 = sinon.spy();
var callback2 = sinon.spy();
animationFrame.run(callback1);
animationFrame.run(callback2);
requestAnimationFrame(function() {
assert.isTrue(callback1.calledOnce);
assert.isTrue(callback2.calledOnce);
done();
});
});
});
suite('Cancelling functions queued to run before the next paint', function() {
test('Queued functions are cancelable.', function(done) {
var callback = sinon.spy();
var asyncRef = animationFrame.run(callback);
animationFrame.cancel(asyncRef);
requestAnimationFrame(function() {
assert.isFalse(callback.called);
done();
});
});
test('Multiple instances of the same queued function are cancelable.', function(done) {
var callback = sinon.spy();
var asyncRefs = [];
asyncRefs.push(animationFrame.run(callback));
asyncRefs.push(animationFrame.run(callback));
asyncRefs.push(animationFrame.run(callback));
animationFrame.cancel(asyncRefs.pop());
animationFrame.cancel(asyncRefs.pop());
animationFrame.cancel(asyncRefs.pop());
requestAnimationFrame(function() {
assert.isFalse(callback.called);
done();
});
});
test('Multiple queued functions are individually cancelable.', function(done) {
var callback1 = sinon.spy();
var callback2 = sinon.spy();
var callback3 = sinon.spy();
var asyncRef1 = animationFrame.run(callback1, 50);
animationFrame.run(callback2, 50);
var asyncRef3 = animationFrame.run(callback3, 200);
animationFrame.cancel(asyncRef1);
animationFrame.cancel(asyncRef3);
requestAnimationFrame(function() {
assert.isFalse(callback1.called);
assert.isTrue(callback2.calledOnce);
assert.isFalse(callback3.called);
done();
});
});
});
suite('Queueing functions to run during idle period', function() {
var whenIdle = window.requestIdleCallback ? window.requestIdleCallback : function(fn) { setTimeout(fn, 16); };
test('The queued function runs.', function(done) {
var callback = sinon.spy();
idlePeriod.run(callback);
whenIdle(function() {
assert.isTrue(callback.calledOnce);
done();
});
});
test('Functions queued multiple times are run multiple times.', function(done) {
var callback = sinon.spy();
idlePeriod.run(callback);
idlePeriod.run(callback);
whenIdle(function() {
assert.isTrue(callback.calledTwice);
done();
});
});
test('All queued functions are run.', function(done) {
var callback1 = sinon.spy();
var callback2 = sinon.spy();
idlePeriod.run(callback1);
idlePeriod.run(callback2);
whenIdle(function() {
assert.isTrue(callback1.calledOnce);
assert.isTrue(callback2.calledOnce);
done();
});
});
});
suite('Cancelling functions queued to run during idle period', function() {
var whenIdle = window.requestIdleCallback ? window.requestIdleCallback : function(fn) { setTimeout(fn, 16); };
test('Queued functions are cancelable.', function(done) {
var callback = sinon.spy();
var asyncRef = idlePeriod.run(callback);
idlePeriod.cancel(asyncRef);
whenIdle(function() {
assert.isFalse(callback.called);
done();
});
});
test('Multiple instances of the same queued function are cancelable.', function(done) {
var callback = sinon.spy();
var asyncRefs = [];
asyncRefs.push(idlePeriod.run(callback));
asyncRefs.push(idlePeriod.run(callback));
asyncRefs.push(idlePeriod.run(callback));
idlePeriod.cancel(asyncRefs.pop());
idlePeriod.cancel(asyncRefs.pop());
idlePeriod.cancel(asyncRefs.pop());
whenIdle(function() {
assert.isFalse(callback.called);
done();
});
});
test('Multiple queued functions are individually cancelable.', function(done) {
var callback1 = sinon.spy();
var callback2 = sinon.spy();
var callback3 = sinon.spy();
var asyncRef1 = idlePeriod.run(callback1, 50);
idlePeriod.run(callback2, 50);
var asyncRef3 = idlePeriod.run(callback3, 200);
idlePeriod.cancel(asyncRef1);
idlePeriod.cancel(asyncRef3);
whenIdle(function() {
assert.isFalse(callback1.called);
assert.isTrue(callback2.calledOnce);
assert.isFalse(callback3.called);
done();
});
});
});
</script>
</body>
</html>