'use strict';
const MockPointer = require('./MockPointer');
describe('PIXI.interaction.InteractionManager', function ()
{
afterEach(function ()
{
// if we made a MockPointer for the test, clean it up
if (this.pointer)
{
this.pointer.cleanUp();
this.pointer = null;
}
});
describe('event basics', function ()
{
it('should call mousedown handler', function ()
{
const stage = new PIXI.Container();
const graphics = new PIXI.Graphics();
const eventSpy = sinon.spy();
const pointer = this.pointer = new MockPointer(stage);
stage.addChild(graphics);
graphics.beginFill(0xFFFFFF);
graphics.drawRect(0, 0, 50, 50);
graphics.interactive = true;
graphics.on('mousedown', eventSpy);
pointer.mousedown(10, 10);
expect(eventSpy).to.have.been.calledOnce;
});
it('should call mouseup handler', function ()
{
const stage = new PIXI.Container();
const graphics = new PIXI.Graphics();
const eventSpy = sinon.spy();
const pointer = this.pointer = new MockPointer(stage);
stage.addChild(graphics);
graphics.beginFill(0xFFFFFF);
graphics.drawRect(0, 0, 50, 50);
graphics.interactive = true;
graphics.on('mouseup', eventSpy);
pointer.click(10, 10);
expect(eventSpy).to.have.been.called;
});
it('should call mouseupoutside handler', function ()
{
const stage = new PIXI.Container();
const graphics = new PIXI.Graphics();
const eventSpy = sinon.spy();
const pointer = this.pointer = new MockPointer(stage);
stage.addChild(graphics);
graphics.beginFill(0xFFFFFF);
graphics.drawRect(0, 0, 50, 50);
graphics.interactive = true;
graphics.on('mouseupoutside', eventSpy);
pointer.mousedown(10, 10);
pointer.mouseup(60, 60);
expect(eventSpy).to.have.been.called;
});
it('should call mouseover handler', function ()
{
const stage = new PIXI.Container();
const graphics = new PIXI.Graphics();
const eventSpy = sinon.spy();
const pointer = this.pointer = new MockPointer(stage);
stage.addChild(graphics);
graphics.beginFill(0xFFFFFF);
graphics.drawRect(0, 0, 50, 50);
graphics.interactive = true;
graphics.on('mouseover', eventSpy);
pointer.mousemove(10, 10);
expect(eventSpy).to.have.been.called;
});
it('should call mouseout handler', function ()
{
const stage = new PIXI.Container();
const graphics = new PIXI.Graphics();
const eventSpy = sinon.spy();
const pointer = this.pointer = new MockPointer(stage);
stage.addChild(graphics);
graphics.beginFill(0xFFFFFF);
graphics.drawRect(0, 0, 50, 50);
graphics.interactive = true;
graphics.on('mouseout', eventSpy);
pointer.mousemove(10, 10);
pointer.mousemove(60, 60);
expect(eventSpy).to.have.been.called;
});
});
describe('add/remove events', function ()
{
let stub;
before(function ()
{
stub = sinon.stub(PIXI.interaction.InteractionManager.prototype, 'setTargetElement');
});
after(function ()
{
stub.restore();
});
it('should add and remove pointer events to document', function ()
{
const manager = new PIXI.interaction.InteractionManager(sinon.stub());
const addSpy = sinon.spy(window.document, 'addEventListener');
const removeSpy = sinon.spy(window.document, 'removeEventListener');
manager.interactionDOMElement = { style: {}, addEventListener: sinon.stub(), removeEventListener: sinon.stub() };
manager.supportsPointerEvents = true;
manager.addEvents();
expect(addSpy).to.have.been.calledOnce;
expect(addSpy).to.have.been.calledWith('pointermove');
manager.removeEvents();
expect(removeSpy).to.have.been.calledOnce;
expect(removeSpy).to.have.been.calledWith('pointermove');
addSpy.restore();
removeSpy.restore();
});
it('should add and remove pointer events to window', function ()
{
const manager = new PIXI.interaction.InteractionManager(sinon.stub());
const addSpy = sinon.spy(window, 'addEventListener');
const removeSpy = sinon.spy(window, 'removeEventListener');
manager.interactionDOMElement = { style: {}, addEventListener: sinon.stub(), removeEventListener: sinon.stub() };
manager.supportsPointerEvents = true;
manager.addEvents();
expect(addSpy).to.have.been.calledTwice;
expect(addSpy).to.have.been.calledWith('pointercancel');
expect(addSpy).to.have.been.calledWith('pointerup');
manager.removeEvents();
expect(removeSpy).to.have.been.calledTwice;
expect(removeSpy).to.have.been.calledWith('pointercancel');
expect(removeSpy).to.have.been.calledWith('pointerup');
addSpy.restore();
removeSpy.restore();
});
it('should add and remove pointer events to element', function ()
{
const manager = new PIXI.interaction.InteractionManager(sinon.stub());
const element = { style: {}, addEventListener: sinon.stub(), removeEventListener: sinon.stub() };
manager.interactionDOMElement = element;
manager.supportsPointerEvents = true;
manager.addEvents();
expect(element.addEventListener).to.have.been.calledThrice;
expect(element.addEventListener).to.have.been.calledWith('pointerdown');
expect(element.addEventListener).to.have.been.calledWith('pointerleave');
expect(element.addEventListener).to.have.been.calledWith('pointerover');
manager.removeEvents();
expect(element.removeEventListener).to.have.been.calledThrice;
expect(element.removeEventListener).to.have.been.calledWith('pointerdown');
expect(element.removeEventListener).to.have.been.calledWith('pointerleave');
expect(element.removeEventListener).to.have.been.calledWith('pointerover');
});
it('should add and remove mouse events to document', function ()
{
const manager = new PIXI.interaction.InteractionManager(sinon.stub());
const addSpy = sinon.spy(window.document, 'addEventListener');
const removeSpy = sinon.spy(window.document, 'removeEventListener');
manager.interactionDOMElement = { style: {}, addEventListener: sinon.stub(), removeEventListener: sinon.stub() };
manager.supportsPointerEvents = false;
manager.addEvents();
expect(addSpy).to.have.been.calledOnce;
expect(addSpy).to.have.been.calledWith('mousemove');
manager.removeEvents();
expect(removeSpy).to.have.been.calledOnce;
expect(removeSpy).to.have.been.calledWith('mousemove');
addSpy.restore();
removeSpy.restore();
});
it('should add and remove mouse events to window', function ()
{
const manager = new PIXI.interaction.InteractionManager(sinon.stub());
const addSpy = sinon.spy(window, 'addEventListener');
const removeSpy = sinon.spy(window, 'removeEventListener');
manager.interactionDOMElement = { style: {}, addEventListener: sinon.stub(), removeEventListener: sinon.stub() };
manager.supportsPointerEvents = false;
manager.addEvents();
expect(addSpy).to.have.been.calledOnce;
expect(addSpy).to.have.been.calledWith('mouseup');
manager.removeEvents();
expect(removeSpy).to.have.been.calledOnce;
expect(removeSpy).to.have.been.calledWith('mouseup');
addSpy.restore();
removeSpy.restore();
});
it('should add and remove mouse events to element', function ()
{
const manager = new PIXI.interaction.InteractionManager(sinon.stub());
const element = { style: {}, addEventListener: sinon.stub(), removeEventListener: sinon.stub() };
manager.interactionDOMElement = element;
manager.supportsPointerEvents = false;
manager.supportsTouchEvents = false;
manager.addEvents();
expect(element.addEventListener).to.have.been.calledThrice;
expect(element.addEventListener).to.have.been.calledWith('mousedown');
expect(element.addEventListener).to.have.been.calledWith('mouseout');
expect(element.addEventListener).to.have.been.calledWith('mouseover');
manager.removeEvents();
expect(element.removeEventListener).to.have.been.calledThrice;
expect(element.removeEventListener).to.have.been.calledWith('mousedown');
expect(element.removeEventListener).to.have.been.calledWith('mouseout');
expect(element.removeEventListener).to.have.been.calledWith('mouseover');
});
it('should add and remove touch events to element', function ()
{
const manager = new PIXI.interaction.InteractionManager(sinon.stub());
const element = { style: {}, addEventListener: sinon.stub(), removeEventListener: sinon.stub() };
manager.interactionDOMElement = element;
manager.supportsPointerEvents = false;
manager.supportsTouchEvents = true;
manager.addEvents();
expect(element.addEventListener).to.have.been.calledWith('touchstart');
expect(element.addEventListener).to.have.been.calledWith('touchcancel');
expect(element.addEventListener).to.have.been.calledWith('touchend');
expect(element.addEventListener).to.have.been.calledWith('touchmove');
manager.removeEvents();
expect(element.removeEventListener).to.have.been.calledWith('touchstart');
expect(element.removeEventListener).to.have.been.calledWith('touchcancel');
expect(element.removeEventListener).to.have.been.calledWith('touchend');
expect(element.removeEventListener).to.have.been.calledWith('touchmove');
});
});
describe('onClick', function ()
{
it('should call handler when inside', function ()
{
const stage = new PIXI.Container();
const graphics = new PIXI.Graphics();
const clickSpy = sinon.spy();
const pointer = this.pointer = new MockPointer(stage);
stage.addChild(graphics);
graphics.beginFill(0xFFFFFF);
graphics.drawRect(0, 0, 50, 50);
graphics.interactive = true;
graphics.on('click', clickSpy);
pointer.click(10, 10);
expect(clickSpy).to.have.been.calledOnce;
});
it('should not call handler when outside', function ()
{
const stage = new PIXI.Container();
const graphics = new PIXI.Graphics();
const clickSpy = sinon.spy();
const pointer = this.pointer = new MockPointer(stage);
stage.addChild(graphics);
graphics.beginFill(0xFFFFFF);
graphics.drawRect(0, 0, 50, 50);
graphics.interactive = true;
graphics.on('click', clickSpy);
pointer.click(60, 60);
expect(clickSpy).to.not.have.been.called;
});
it('should not call handler when mousedown not received', function ()
{
const stage = new PIXI.Container();
const graphics = new PIXI.Graphics();
const clickSpy = sinon.spy();
const pointer = new MockPointer(stage);
stage.addChild(graphics);
graphics.beginFill(0xFFFFFF);
graphics.drawRect(0, 0, 50, 50);
graphics.interactive = true;
graphics.on('click', clickSpy);
pointer.mouseup(10, 10);
expect(clickSpy).to.not.have.been.called;
});
});
describe('onTap', function ()
{
it('should call handler when inside', function ()
{
const stage = new PIXI.Container();
const graphics = new PIXI.Graphics();
const clickSpy = sinon.spy();
const pointer = this.pointer = new MockPointer(stage);
stage.addChild(graphics);
graphics.beginFill(0xFFFFFF);
graphics.drawRect(0, 0, 50, 50);
graphics.interactive = true;
graphics.on('tap', clickSpy);
pointer.tap(10, 10);
expect(clickSpy).to.have.been.calledOnce;
});
it('should not call handler when outside', function ()
{
const stage = new PIXI.Container();
const graphics = new PIXI.Graphics();
const clickSpy = sinon.spy();
const pointer = this.pointer = new MockPointer(stage);
stage.addChild(graphics);
graphics.beginFill(0xFFFFFF);
graphics.drawRect(0, 0, 50, 50);
graphics.interactive = true;
graphics.on('tap', clickSpy);
pointer.tap(60, 60);
expect(clickSpy).to.not.have.been.called;
});
});
describe('overlapping children', function ()
{
function getScene(callbackEventName)
{
const behindChild = new PIXI.Graphics();
const frontChild = new PIXI.Graphics();
const parent = new PIXI.Container();
const behindChildCallback = sinon.spy();
const frontChildCallback = sinon.spy();
const parentCallback = sinon.spy();
behindChild.beginFill(0xFF);
behindChild.drawRect(0, 0, 50, 50);
behindChild.on(callbackEventName, behindChildCallback);
frontChild.beginFill(0x00FF);
frontChild.drawRect(0, 0, 50, 50);
frontChild.on(callbackEventName, frontChildCallback);
parent.addChild(behindChild, frontChild);
parent.on(callbackEventName, parentCallback);
return {
behindChild,
frontChild,
parent,
behindChildCallback,
frontChildCallback,
parentCallback,
};
}
describe('when parent is non-interactive', function ()
{
describe('when both children are interactive', function ()
{
it('should callback front child when clicking front child', function ()
{
const stage = new PIXI.Container();
const pointer = this.pointer = new MockPointer(stage);
const scene = getScene('click');
scene.behindChild.interactive = true;
scene.behindChild.x = 25;
scene.frontChild.interactive = true;
stage.addChild(scene.parent);
pointer.click(10, 10);
expect(scene.behindChildCallback).to.not.have.been.called;
expect(scene.frontChildCallback).to.have.been.calledOnce;
expect(scene.parentCallback).to.not.have.been.called;
});
it('should callback front child when clicking overlap', function ()
{
const stage = new PIXI.Container();
const pointer = this.pointer = new MockPointer(stage);
const scene = getScene('click');
scene.behindChild.interactive = true;
scene.behindChild.x = 25;
scene.frontChild.interactive = true;
stage.addChild(scene.parent);
pointer.click(40, 10);
expect(scene.behindChildCallback).to.not.have.been.called;
expect(scene.frontChildCallback).to.have.been.calledOnce;
expect(scene.parentCallback).to.not.have.been.called;
});
it('should callback behind child when clicking behind child', function ()
{
const stage = new PIXI.Container();
const pointer = this.pointer = new MockPointer(stage);
const scene = getScene('click');
scene.behindChild.interactive = true;
scene.behindChild.x = 25;
scene.frontChild.interactive = true;
stage.addChild(scene.parent);
pointer.click(60, 10);
expect(scene.frontChildCallback).to.not.have.been.called;
expect(scene.behindChildCallback).to.have.been.calledOnce;
expect(scene.parentCallback).to.not.have.been.called;
});
});
describe('when front child is non-interactive', function ()
{
it('should not callback when clicking front child', function ()
{
const stage = new PIXI.Container();
const pointer = this.pointer = new MockPointer(stage);
const scene = getScene('click');
scene.behindChild.interactive = true;
scene.behindChild.x = 25;
stage.addChild(scene.parent);
pointer.click(10, 10);
expect(scene.behindChildCallback).to.not.have.been.called;
expect(scene.frontChildCallback).to.not.have.been.called;
expect(scene.parentCallback).to.not.have.been.called;
});
it('should callback behind child when clicking overlap', function ()
{
const stage = new PIXI.Container();
const pointer = this.pointer = new MockPointer(stage);
const scene = getScene('click');
scene.behindChild.interactive = true;
scene.behindChild.x = 25;
stage.addChild(scene.parent);
pointer.click(40, 10);
expect(scene.behindChildCallback).to.have.been.calledOnce;
expect(scene.frontChildCallback).to.not.have.been.called;
expect(scene.parentCallback).to.not.have.been.called;
});
it('should callback behind child when clicking behind child', function ()
{
const stage = new PIXI.Container();
const pointer = this.pointer = new MockPointer(stage);
const scene = getScene('click');
scene.behindChild.interactive = true;
scene.behindChild.x = 25;
stage.addChild(scene.parent);
pointer.click(60, 10);
expect(scene.frontChildCallback).to.not.have.been.called;
expect(scene.behindChildCallback).to.have.been.calledOnce;
expect(scene.parentCallback).to.not.have.been.called;
});
});
describe('when behind child is non-interactive', function ()
{
it('should callback front child when clicking front child', function ()
{
const stage = new PIXI.Container();
const pointer = this.pointer = new MockPointer(stage);
const scene = getScene('click');
scene.behindChild.x = 25;
scene.frontChild.interactive = true;
stage.addChild(scene.parent);
pointer.click(10, 10);
expect(scene.behindChildCallback).to.not.have.been.called;
expect(scene.frontChildCallback).to.have.been.calledOnce;
expect(scene.parentCallback).to.not.have.been.called;
});
it('should callback front child when clicking overlap', function ()
{
const stage = new PIXI.Container();
const pointer = this.pointer = new MockPointer(stage);
const scene = getScene('click');
scene.behindChild.x = 25;
scene.frontChild.interactive = true;
stage.addChild(scene.parent);
pointer.click(40, 10);
expect(scene.behindChildCallback).to.not.have.been.called;
expect(scene.frontChildCallback).to.have.been.calledOnce;
expect(scene.parentCallback).to.not.have.been.called;
});
it('should not callback when clicking behind child', function ()
{
const stage = new PIXI.Container();
const pointer = this.pointer = new MockPointer(stage);
const scene = getScene('click');
scene.behindChild.x = 25;
scene.frontChild.interactive = true;
stage.addChild(scene.parent);
pointer.click(60, 10);
expect(scene.frontChildCallback).to.not.have.been.called;
expect(scene.behindChildCallback).to.not.have.been.called;
expect(scene.parentCallback).to.not.have.been.called;
});
});
});
describe('when parent is interactive', function ()
{
describe('when both children are interactive', function ()
{
it('should callback parent and front child when clicking front child', function ()
{
const stage = new PIXI.Container();
const pointer = this.pointer = new MockPointer(stage);
const scene = getScene('click');
scene.behindChild.interactive = true;
scene.behindChild.x = 25;
scene.frontChild.interactive = true;
scene.parent.interactive = true;
stage.addChild(scene.parent);
pointer.click(10, 10);
expect(scene.behindChildCallback).to.not.have.been.called;
expect(scene.frontChildCallback).to.have.been.calledOnce;
expect(scene.parentCallback).to.have.been.calledOnce;
});
it('should callback parent and front child when clicking overlap', function ()
{
const stage = new PIXI.Container();
const pointer = this.pointer = new MockPointer(stage);
const scene = getScene('click');
scene.behindChild.interactive = true;
scene.behindChild.x = 25;
scene.frontChild.interactive = true;
scene.parent.interactive = true;
stage.addChild(scene.parent);
pointer.click(40, 10);
expect(scene.behindChildCallback).to.not.have.been.called;
expect(scene.frontChildCallback).to.have.been.calledOnce;
expect(scene.parentCallback).to.have.been.calledOnce;
});
it('should callback parent and behind child when clicking behind child', function ()
{
const stage = new PIXI.Container();
const pointer = this.pointer = new MockPointer(stage);
const scene = getScene('click');
scene.behindChild.interactive = true;
scene.behindChild.x = 25;
scene.frontChild.interactive = true;
scene.parent.interactive = true;
stage.addChild(scene.parent);
pointer.click(60, 10);
expect(scene.frontChildCallback).to.not.have.been.called;
expect(scene.behindChildCallback).to.have.been.calledOnce;
expect(scene.parentCallback).to.have.been.calledOnce;
});
});
describe('when front child is non-interactive', function ()
{
it('should callback parent when clicking front child', function ()
{
const stage = new PIXI.Container();
const pointer = this.pointer = new MockPointer(stage);
const scene = getScene('click');
scene.behindChild.interactive = true;
scene.behindChild.x = 25;
scene.parent.interactive = true;
stage.addChild(scene.parent);
pointer.click(10, 10);
expect(scene.behindChildCallback).to.not.have.been.called;
expect(scene.frontChildCallback).to.not.have.been.called;
expect(scene.parentCallback).to.have.been.calledOnce;
});
it('should callback parent and behind child when clicking overlap', function ()
{
const stage = new PIXI.Container();
const pointer = this.pointer = new MockPointer(stage);
const scene = getScene('click');
scene.behindChild.interactive = true;
scene.behindChild.x = 25;
scene.parent.interactive = true;
stage.addChild(scene.parent);
pointer.click(40, 10);
expect(scene.behindChildCallback).to.have.been.calledOnce;
expect(scene.frontChildCallback).to.not.have.been.called;
expect(scene.parentCallback).to.have.been.calledOnce;
});
it('should callback parent and behind child when clicking behind child', function ()
{
const stage = new PIXI.Container();
const pointer = this.pointer = new MockPointer(stage);
const scene = getScene('click');
scene.behindChild.interactive = true;
scene.behindChild.x = 25;
scene.parent.interactive = true;
stage.addChild(scene.parent);
pointer.click(60, 10);
expect(scene.frontChildCallback).to.not.have.been.called;
expect(scene.behindChildCallback).to.have.been.calledOnce;
expect(scene.parentCallback).to.have.been.calledOnce;
});
});
describe('when behind child is non-interactive', function ()
{
it('should callback parent and front child when clicking front child', function ()
{
const stage = new PIXI.Container();
const pointer = this.pointer = new MockPointer(stage);
const scene = getScene('click');
scene.behindChild.x = 25;
scene.frontChild.interactive = true;
scene.parent.interactive = true;
stage.addChild(scene.parent);
pointer.click(10, 10);
expect(scene.behindChildCallback).to.not.have.been.called;
expect(scene.frontChildCallback).to.have.been.calledOnce;
expect(scene.parentCallback).to.have.been.calledOnce;
});
it('should callback parent and front child when clicking overlap', function ()
{
const stage = new PIXI.Container();
const pointer = this.pointer = new MockPointer(stage);
const scene = getScene('click');
scene.behindChild.x = 25;
scene.frontChild.interactive = true;
scene.parent.interactive = true;
stage.addChild(scene.parent);
pointer.click(40, 10);
expect(scene.behindChildCallback).to.not.have.been.called;
expect(scene.frontChildCallback).to.have.been.calledOnce;
expect(scene.parentCallback).to.have.been.calledOnce;
});
it('should callback parent when clicking behind child', function ()
{
const stage = new PIXI.Container();
const pointer = this.pointer = new MockPointer(stage);
const scene = getScene('click');
scene.behindChild.x = 25;
scene.frontChild.interactive = true;
scene.parent.interactive = true;
stage.addChild(scene.parent);
pointer.click(60, 10);
expect(scene.frontChildCallback).to.not.have.been.called;
expect(scene.behindChildCallback).to.not.have.been.called;
expect(scene.parentCallback).to.have.been.calledOnce;
});
});
});
});
describe('cursor changes', function ()
{
it('cursor should be the cursor of interactive item', function ()
{
const stage = new PIXI.Container();
const graphics = new PIXI.Graphics();
const pointer = this.pointer = new MockPointer(stage);
stage.addChild(graphics);
graphics.beginFill(0xFFFFFF);
graphics.drawRect(0, 0, 50, 50);
graphics.interactive = true;
graphics.cursor = 'help';
pointer.interaction.cursorStyles.help = 'help';
pointer.mousemove(10, 10);
expect(pointer.renderer.view.style.cursor).to.equal('help');
});
it('should return cursor to default on mouseout', function ()
{
const stage = new PIXI.Container();
const graphics = new PIXI.Graphics();
const pointer = this.pointer = new MockPointer(stage);
stage.addChild(graphics);
graphics.beginFill(0xFFFFFF);
graphics.drawRect(0, 0, 50, 50);
graphics.interactive = true;
graphics.cursor = 'help';
pointer.interaction.cursorStyles.help = 'help';
pointer.mousemove(10, 10);
pointer.mousemove(60, 60);
expect(pointer.renderer.view.style.cursor).to.equal(pointer.interaction.cursorStyles.default);
});
it('should still be the over cursor after a click', function ()
{
const stage = new PIXI.Container();
const graphics = new PIXI.Graphics();
const pointer = this.pointer = new MockPointer(stage);
stage.addChild(graphics);
graphics.beginFill(0xFFFFFF);
graphics.drawRect(0, 0, 50, 50);
graphics.interactive = true;
graphics.cursor = 'help';
pointer.interaction.cursorStyles.help = 'help';
pointer.mousemove(10, 10);
pointer.click(10, 10);
expect(pointer.renderer.view.style.cursor).to.equal('help');
});
it('should return cursor to default when mouse leaves renderer', function ()
{
const stage = new PIXI.Container();
const graphics = new PIXI.Graphics();
const pointer = this.pointer = new MockPointer(stage);
stage.addChild(graphics);
graphics.beginFill(0xFFFFFF);
graphics.drawRect(0, 0, 50, 50);
graphics.interactive = true;
graphics.cursor = 'help';
pointer.interaction.cursorStyles.help = 'help';
pointer.mousemove(10, 10);
pointer.mousemove(-10, 60);
expect(pointer.renderer.view.style.cursor).to.equal(pointer.interaction.cursorStyles.default);
});
it('cursor callback should be called', function ()
{
const stage = new PIXI.Container();
const graphics = new PIXI.Graphics();
const overSpy = sinon.spy();
const defaultSpy = sinon.spy();
const pointer = this.pointer = new MockPointer(stage);
stage.addChild(graphics);
graphics.beginFill(0xFFFFFF);
graphics.drawRect(0, 0, 50, 50);
graphics.interactive = true;
graphics.cursor = 'help';
pointer.interaction.cursorStyles.help = overSpy;
pointer.interaction.cursorStyles.default = defaultSpy;
pointer.mousemove(10, 10);
pointer.mousemove(60, 60);
expect(overSpy).to.have.been.called;
expect(defaultSpy).to.have.been.called;
});
it('cursor callback should only be called if the cursor actually changed', function ()
{
const stage = new PIXI.Container();
const graphics = new PIXI.Graphics();
const defaultSpy = sinon.spy();
const pointer = this.pointer = new MockPointer(stage);
stage.addChild(graphics);
graphics.beginFill(0xFFFFFF);
graphics.drawRect(0, 0, 50, 50);
graphics.interactive = true;
graphics.cursor = null;
pointer.interaction.cursorStyles.default = defaultSpy;
pointer.mousemove(10, 10);
pointer.mousemove(20, 20);
expect(defaultSpy).to.have.been.calledOnce;
});
it('cursor style object should be fully applied', function ()
{
const stage = new PIXI.Container();
const graphics = new PIXI.Graphics();
const pointer = this.pointer = new MockPointer(stage);
stage.addChild(graphics);
graphics.beginFill(0xFFFFFF);
graphics.drawRect(0, 0, 50, 50);
graphics.interactive = true;
graphics.cursor = 'help';
pointer.interaction.cursorStyles.help = {
cursor: 'none',
display: 'none',
};
pointer.mousemove(10, 10);
expect(pointer.renderer.view.style.cursor).to.equal('none');
expect(pointer.renderer.view.style.display).to.equal('none');
});
it('should not change cursor style if no cursor style provided', function ()
{
const stage = new PIXI.Container();
const graphics = new PIXI.Graphics();
const pointer = this.pointer = new MockPointer(stage);
stage.addChild(graphics);
graphics.beginFill(0xFFFFFF);
graphics.drawRect(0, 0, 50, 50);
graphics.interactive = true;
graphics.cursor = 'pointer';
pointer.interaction.cursorStyles.pointer = null;
pointer.interaction.cursorStyles.default = null;
pointer.mousemove(10, 10);
expect(pointer.renderer.view.style.cursor).to.equal('');
pointer.mousemove(60, 60);
expect(pointer.renderer.view.style.cursor).to.equal('');
});
});
describe('recursive hitTesting', function ()
{
function getScene()
{
const stage = new PIXI.Container();
const behindChild = new PIXI.Graphics();
const middleChild = new PIXI.Graphics();
const frontChild = new PIXI.Graphics();
behindChild.beginFill(0xFF);
behindChild.drawRect(0, 0, 50, 50);
middleChild.beginFill(0xFF00);
middleChild.drawRect(0, 0, 50, 50);
frontChild.beginFill(0xFF0000);
frontChild.drawRect(0, 0, 50, 50);
stage.addChild(behindChild, middleChild, frontChild);
return {
behindChild,
middleChild,
frontChild,
stage,
};
}
describe('when frontChild is interactive', function ()
{
it('should stop hitTesting after first hit', function ()
{
const scene = getScene();
const pointer = this.pointer = new MockPointer(scene.stage);
const frontHitTest = sinon.spy(scene.frontChild, 'containsPoint');
const middleHitTest = sinon.spy(scene.middleChild, 'containsPoint');
const behindHitTest = sinon.spy(scene.behindChild, 'containsPoint');
scene.frontChild.interactive = true;
scene.middleChild.interactive = true;
scene.behindChild.interactive = true;
pointer.mousedown(25, 25);
expect(frontHitTest).to.have.been.calledOnce;
expect(middleHitTest).to.not.have.been.called;
expect(behindHitTest).to.not.have.been.called;
});
});
describe('when frontChild is not interactive', function ()
{
it('should stop hitTesting after first hit', function ()
{
const scene = getScene();
const pointer = this.pointer = new MockPointer(scene.stage);
const frontHitTest = sinon.spy(scene.frontChild, 'containsPoint');
const middleHitTest = sinon.spy(scene.middleChild, 'containsPoint');
const behindHitTest = sinon.spy(scene.behindChild, 'containsPoint');
scene.frontChild.interactive = false;
scene.middleChild.interactive = true;
scene.behindChild.interactive = true;
pointer.mousedown(25, 25);
expect(frontHitTest).to.not.have.been.called;
expect(middleHitTest).to.have.been.calledOnce;
expect(behindHitTest).to.not.have.been.called;
});
});
});
describe('pointer handling', function ()
{
it('pointer event from mouse should use single mouse data', function ()
{
const stage = new PIXI.Container();
const graphics = new PIXI.Graphics();
const pointer = this.pointer = new MockPointer(stage, 100, 100, true);
stage.addChild(graphics);
graphics.beginFill(0xFFFFFF);
graphics.drawRect(0, 0, 50, 50);
graphics.interactive = true;
pointer.mousemove(20, 10, true);
expect(pointer.interaction.mouse.global.x).to.equal(20);
expect(pointer.interaction.mouse.global.y).to.equal(10);
});
});
});