@polymer/polymer
Version:
The Polymer library makes it easy to create your own web components. Give your element some markup and properties, and then use it on a site. Polymer provides features like dynamic templates and data binding to reduce the amount of boilerplate you need to
296 lines (253 loc) • 10.1 kB
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="../../../webcomponentsjs/webcomponents-lite.js"></script>
<script src="../../../web-component-tester/browser.js"></script>
<link rel="import" href="../../polymer.html">
</head>
<body>
<test-fixture id="basic">
<template>
<x-basic></x-basic>
</template>
</test-fixture>
<test-fixture id="another">
<template>
<x-basic></x-basic>
</template>
</test-fixture>
<script>
HTMLImports.whenReady(function() {
Polymer({is: 'x-basic'});
});
suite('enqueueDebouncer & flush', function() {
// NOTE: This is a regression test; the bug it fixed only occurred if the
// debouncer was flushed before any microtasks run, hence it should be
// first in this file
test('re-enqueue canceled debouncer', function() {
const cb = sinon.spy();
let db;
db = Polymer.Debouncer.debounce(null, Polymer.Async.microTask, cb);
Polymer.enqueueDebouncer(db);
db.cancel();
assert.equal(db.isActive(), false);
assert.equal(cb.callCount, 0);
db = Polymer.Debouncer.debounce(db, Polymer.Async.microTask, cb);
Polymer.enqueueDebouncer(db);
Polymer.flush();
assert.isTrue(cb.calledOnce);
});
test('flushDebouncers from enqueued debouncer', function(done) {
const cb = sinon.spy(() => Polymer.flush());
let db = Polymer.Debouncer.debounce(null, Polymer.Async.microTask, cb);
Polymer.enqueueDebouncer(db);
setTimeout(() => {
assert.isTrue(cb.calledOnce);
done();
});
});
const testEnqueue = (shouldFlush, done) => {
const actualOrder = [];
const enqueue = (type, {db, cb} = {}) => {
cb = cb || (() => actualOrder.push(cb));
db = Polymer.Debouncer.debounce(db, type, cb);
Polymer.enqueueDebouncer(db);
return {db, cb};
};
const db1 = enqueue(Polymer.Async.microTask);
const db2 = enqueue(Polymer.Async.microTask);
const db3 = enqueue(Polymer.Async.timeOut);
const db4 = enqueue(Polymer.Async.microTask);
enqueue(Polymer.Async.microTask, db2);
enqueue(Polymer.Async.microTask, db1);
if (shouldFlush) {
Polymer.flush();
assert.deepEqual(actualOrder, [db1.cb, db2.cb, db3.cb, db4.cb]);
done();
} else {
Polymer.Async.timeOut.run(() => {
assert.deepEqual(actualOrder, [db4.cb, db2.cb, db1.cb, db3.cb]);
done();
});
}
};
test('non-flushed', function(done) {
testEnqueue(false, done);
});
test('flushed', function(done) {
testEnqueue(true, done);
});
test('reentrant flush', function() {
const cb2 = sinon.spy();
let db2;
const cb1 = sinon.spy(() => {
Polymer.flush();
db2 = Polymer.Debouncer.debounce(null, Polymer.Async.microTask, cb2);
Polymer.enqueueDebouncer(db2);
});
const db1 = Polymer.Debouncer.debounce(null, Polymer.Async.microTask, cb1);
Polymer.enqueueDebouncer(db1);
Polymer.flush();
assert.isTrue(cb1.calledOnce);
assert.isTrue(cb2.calledOnce);
});
});
suite('debounce', function() {
var element;
setup(function() {
element = fixture('basic');
});
test('debounce (no-wait)', function(done) {
var called = 0;
var callback = function() {
called++;
};
element.debounce('job', callback);
element.debounce('job', callback);
element.debounce('job', callback);
setTimeout(function() {
assert.equal(called, 1, 'debounce should be called exactly once');
done();
}, 50);
});
test('debounce (wait)', function(done) {
var called = 0;
var now = Date.now();
var callback = function() {
called++;
};
element.debounce('job', callback);
element.debounce('job', callback, 100);
element.debounce('job', callback, 100);
setTimeout(function() {
assert.equal(called, 1, 'debounce should be called exactly once');
assert(Date.now() - now > 100, 'debounce should be called after at least 100ms');
done();
}, 200);
});
suite('debounce does not carry across multiple elements', function() {
var element1, element2;
setup(function() {
element1 = fixture('basic');
element2 = fixture('another');
});
test('debounce (no-wait)', function(done) {
var called = 0;
var callback = function() {
called++;
};
element1.debounce('job', callback);
element2.debounce('job', callback);
element1.debounce('job', callback);
element2.debounce('job', callback);
setTimeout(function() {
assert.equal(called, 2, 'debounce should be called exactly twice');
done();
}, 50);
});
});
suite('Polymer.Debouncer.debounce', function() {
test('same debouncer and multiple micro tasks', function(done) {
var callback = sinon.spy();
var job = Polymer.Debouncer.debounce(null, Polymer.Async.microTask, callback);
Polymer.Debouncer.debounce(job, Polymer.Async.microTask, callback);
setTimeout(function() {
assert.isTrue(callback.calledOnce, 'callback should be called once');
done();
});
});
test('flush debouncer', function(done) {
var callback = sinon.spy();
var job = Polymer.Debouncer.debounce(null, Polymer.Async.microTask, callback);
setTimeout(function() {
job.flush();
assert.isTrue(callback.calledOnce, 'callback should be called once');
done();
});
});
test('different debouncers and multiple micro tasks', function(done) {
var callback = sinon.spy();
var job1 = Polymer.Debouncer.debounce(null, Polymer.Async.microTask, callback);
Polymer.Debouncer.debounce(job1, Polymer.Async.microTask, callback);
var job2 = Polymer.Debouncer.debounce(null, Polymer.Async.microTask, callback);
Polymer.Debouncer.debounce(job2, Polymer.Async.microTask, callback);
setTimeout(function() {
assert.isTrue(callback.calledTwice, 'callback should be called twice');
done();
});
});
test('same debouncer and multiple timers', function(done) {
var callback = sinon.spy();
var job = Polymer.Debouncer.debounce(null, Polymer.Async.timeOut.after(10), callback);
Polymer.Debouncer.debounce(job, Polymer.Async.timeOut.after(10), callback);
setTimeout(function() {
assert.isTrue(callback.calledOnce, 'callback should be called once');
done();
}, 20);
});
test('different debouncers and multiple timers', function(done) {
var callback = sinon.spy();
var job1 = Polymer.Debouncer.debounce(null, Polymer.Async.timeOut.after(10), callback);
Polymer.Debouncer.debounce(job1, Polymer.Async.timeOut.after(10), callback);
var job2 = Polymer.Debouncer.debounce(null, Polymer.Async.timeOut.after(10), callback);
Polymer.Debouncer.debounce(job2, Polymer.Async.timeOut.after(10), callback);
setTimeout(function() {
assert.isTrue(callback.calledTwice, 'callback should be called twice');
done();
}, 20);
});
test('same debouncer and multiple animation frames', function(done) {
var callback = sinon.spy();
var job = Polymer.Debouncer.debounce(null, Polymer.Async.animationFrame, callback);
Polymer.Debouncer.debounce(job, Polymer.Async.animationFrame, callback);
requestAnimationFrame(function() {
assert.isTrue(callback.calledOnce, 'callback should be called once');
done();
});
});
test('different debouncer and multiple animation frames', function(done) {
var callback = sinon.spy();
var job1 = Polymer.Debouncer.debounce(null, Polymer.Async.animationFrame, callback);
Polymer.Debouncer.debounce(job1, Polymer.Async.animationFrame, callback);
var job2 = Polymer.Debouncer.debounce(null, Polymer.Async.animationFrame, callback);
Polymer.Debouncer.debounce(job2, Polymer.Async.animationFrame, callback);
requestAnimationFrame(function() {
assert.isTrue(callback.calledTwice, 'callback should be called twice');
done();
});
});
test('same debouncer and multiple idle callbacks', function(done) {
var callback = sinon.spy();
var job = Polymer.Debouncer.debounce(null, Polymer.Async.idlePeriod, callback);
Polymer.Debouncer.debounce(job, Polymer.Async.idlePeriod, callback);
Polymer.Async.idlePeriod.run(function() {
assert.isTrue(callback.calledOnce, 'callback should be called once');
done();
});
});
test('different debouncer and multiple idle callbacks', function(done) {
var callback = sinon.spy();
var job1 = Polymer.Debouncer.debounce(null, Polymer.Async.idlePeriod, callback);
Polymer.Debouncer.debounce(job1, Polymer.Async.idlePeriod, callback);
var job2 = Polymer.Debouncer.debounce(null, Polymer.Async.idlePeriod, callback);
Polymer.Debouncer.debounce(job2, Polymer.Async.idlePeriod, callback);
Polymer.Async.idlePeriod.run(function() {
assert.isTrue(callback.calledTwice, 'callback should be called twice');
done();
});
});
});
});
</script>
</body>
</html>