const { Ticker, shared, UPDATE_PRIORITY } = require('../');
describe('PIXI.ticker.Ticker', function ()
{
before(function ()
{
this.length = (ticker) =>
{
ticker = ticker || shared;
if (!ticker._head || !ticker._head.next)
{
return 0;
}
let listener = ticker._head.next;
let i = 0;
while (listener)
{
listener = listener.next;
i++;
}
return i;
};
});
it('should be available', function ()
{
expect(Ticker).to.be.a.function;
expect(shared).to.be.an.instanceof(Ticker);
});
it('should create a new ticker and destroy it', function ()
{
const ticker = new Ticker();
ticker.start();
const listener = sinon.spy();
expect(this.length(ticker)).to.equal(0);
ticker.add(listener);
expect(this.length(ticker)).to.equal(1);
ticker.destroy();
expect(ticker._head).to.be.null;
expect(ticker.started).to.be.false;
expect(this.length(ticker)).to.equal(0);
});
it('should protect destroying shared ticker', function ()
{
const listener = sinon.spy();
shared.add(listener); // needed to autoStart
shared.destroy();
expect(shared._head).to.not.be.null;
expect(shared.started).to.be.true;
});
it('should add and remove listener', function ()
{
const listener = sinon.spy();
const length = this.length();
shared.add(listener);
expect(this.length()).to.equal(length + 1);
shared.remove(listener);
expect(this.length()).to.equal(length);
});
it('should update a listener', function ()
{
const listener = sinon.spy();
shared.add(listener);
shared.update();
expect(listener.calledOnce).to.be.true;
shared.remove(listener);
shared.update();
expect(listener.calledOnce).to.be.true;
});
it('should update a listener twice and remove once', function ()
{
const listener = sinon.spy();
const length = this.length();
shared.add(listener).add(listener);
shared.update();
expect(listener.calledTwice).to.be.true;
expect(this.length()).to.equal(length + 2);
shared.remove(listener);
shared.update();
expect(listener.calledTwice).to.be.true;
expect(this.length()).to.equal(length);
});
it('should respect priority order', function ()
{
const length = this.length();
const listener1 = sinon.spy();
const listener2 = sinon.spy();
const listener3 = sinon.spy();
const listener4 = sinon.spy();
shared.add(listener1, null, UPDATE_PRIORITY.LOW)
.add(listener4, null, UPDATE_PRIORITY.INTERACTION)
.add(listener3, null, UPDATE_PRIORITY.HIGH)
.add(listener2, null, UPDATE_PRIORITY.NORMAL);
shared.update();
expect(this.length()).to.equal(length + 4);
sinon.assert.callOrder(listener4, listener3, listener2, listener1);
shared.remove(listener1)
.remove(listener2)
.remove(listener3)
.remove(listener4);
expect(this.length()).to.equal(length);
});
it('should auto-remove once listeners', function ()
{
const length = this.length();
const listener = sinon.spy();
shared.addOnce(listener);
shared.update();
expect(listener.calledOnce).to.be.true;
expect(this.length()).to.equal(length);
});
it('should call when adding same priority', function ()
{
const length = this.length();
const listener1 = sinon.spy();
const listener2 = sinon.spy();
const listener3 = sinon.spy();
shared.add(listener1)
.add(listener2)
.add(listener3);
shared.update();
expect(this.length()).to.equal(length + 3);
sinon.assert.callOrder(listener1, listener2, listener3);
shared.remove(listener1)
.remove(listener2)
.remove(listener3);
expect(this.length()).to.equal(length);
});
it('should remove once listener in a stack', function ()
{
const length = this.length();
const listener1 = sinon.spy();
const listener2 = sinon.spy();
const listener3 = sinon.spy();
shared.add(listener1, null, UPDATE_PRIORITY.HIGH);
shared.addOnce(listener2, null, UPDATE_PRIORITY.NORMAL);
shared.add(listener3, null, UPDATE_PRIORITY.LOW);
shared.update();
expect(this.length()).to.equal(length + 2);
shared.update();
expect(listener1.calledTwice).to.be.true;
expect(listener2.calledOnce).to.be.true;
expect(listener3.calledTwice).to.be.true;
shared.remove(listener1).remove(listener3);
expect(this.length()).to.equal(length);
});
it('should call inserted item with a lower priority', function ()
{
const length = this.length();
const lowListener = sinon.spy();
const highListener = sinon.spy();
const mainListener = sinon.spy(() =>
{
shared.add(highListener, null, UPDATE_PRIORITY.HIGH);
shared.add(lowListener, null, UPDATE_PRIORITY.LOW);
});
shared.add(mainListener, null, UPDATE_PRIORITY.NORMAL);
shared.update();
expect(this.length()).to.equal(length + 3);
expect(mainListener.calledOnce).to.be.true;
expect(lowListener.calledOnce).to.be.true;
expect(highListener.calledOnce).to.be.false;
shared.remove(mainListener)
.remove(highListener)
.remove(lowListener);
expect(this.length()).to.equal(length);
});
it('should remove emit low-priority item during emit', function ()
{
const length = this.length();
const listener2 = sinon.spy();
const listener1 = sinon.spy(() =>
{
shared.add(listener2, null, UPDATE_PRIORITY.LOW);
});
shared.add(listener1, null, UPDATE_PRIORITY.NORMAL);
shared.update();
expect(this.length()).to.equal(length + 2);
expect(listener2.calledOnce).to.be.true;
expect(listener1.calledOnce).to.be.true;
shared.remove(listener1)
.remove(listener2);
expect(this.length()).to.equal(length);
});
it('should remove itself on emit after adding new item', function ()
{
const length = this.length();
const listener2 = sinon.spy();
const listener1 = sinon.spy(() =>
{
shared.add(listener2, null, UPDATE_PRIORITY.LOW);
shared.remove(listener1);
// listener is removed right away
expect(this.length()).to.equal(length + 1);
});
shared.add(listener1, null, UPDATE_PRIORITY.NORMAL);
shared.update();
expect(this.length()).to.equal(length + 1);
expect(listener2.calledOnce).to.be.true;
expect(listener1.calledOnce).to.be.true;
shared.remove(listener2);
expect(this.length()).to.equal(length);
});
it('should remove itself before, still calling new item', function ()
{
const length = this.length();
const listener2 = sinon.spy();
const listener1 = sinon.spy(() =>
{
shared.remove(listener1);
shared.add(listener2, null, UPDATE_PRIORITY.LOW);
// listener is removed right away
expect(this.length()).to.equal(length + 1);
});
shared.add(listener1, null, UPDATE_PRIORITY.NORMAL);
shared.update();
expect(this.length()).to.equal(length + 1);
expect(listener2.calledOnce).to.be.true;
expect(listener1.calledOnce).to.be.true;
shared.remove(listener2);
expect(this.length()).to.equal(length);
});
it('should remove items before and after current priority', function ()
{
const length = this.length();
const listener2 = sinon.spy();
const listener3 = sinon.spy();
const listener4 = sinon.spy();
shared.add(listener2, null, UPDATE_PRIORITY.HIGH);
shared.add(listener3, null, UPDATE_PRIORITY.LOW);
shared.add(listener4, null, UPDATE_PRIORITY.LOW);
const listener1 = sinon.spy(() =>
{
shared.remove(listener2)
.remove(listener3);
// listener is removed right away
expect(this.length()).to.equal(length + 2);
});
shared.add(listener1, null, UPDATE_PRIORITY.NORMAL);
shared.update();
expect(this.length()).to.equal(length + 2);
expect(listener2.calledOnce).to.be.true;
expect(listener3.calledOnce).to.be.false;
expect(listener4.calledOnce).to.be.true;
expect(listener1.calledOnce).to.be.true;
shared.update();
expect(listener2.calledOnce).to.be.true;
expect(listener3.calledOnce).to.be.false;
expect(listener4.calledTwice).to.be.true;
expect(listener1.calledTwice).to.be.true;
shared.remove(listener1)
.remove(listener4);
expect(this.length()).to.equal(length);
});
it('should destroy on listener', function (done)
{
const ticker = new Ticker();
const listener2 = sinon.spy();
const listener = sinon.spy(() =>
{
ticker.destroy();
setTimeout(() =>
{
expect(listener2.called).to.be.false;
expect(listener.calledOnce).to.be.true;
done();
}, 0);
});
ticker.add(listener);
ticker.add(listener2, null, UPDATE_PRIORITY.LOW);
ticker.start();
});
});