phaser
Version:
A fast, free and fun HTML5 Game Framework for Desktop and Mobile web browsers from the team at Phaser Studio Inc.
575 lines (470 loc) • 19.4 kB
JavaScript
// Phaser's device detection modules access browser globals at require-time.
// Stub the minimum needed for Node.js.
if (typeof window === 'undefined')
{
global.window = {
cordova: undefined,
ejecta: undefined,
devicePixelRatio: 1,
Worker: undefined,
URL: undefined,
webkitURL: undefined,
mozURL: undefined,
msURL: undefined,
addEventListener: function () {}
};
}
if (typeof navigator === 'undefined')
{
global.navigator = {
userAgent: '',
appVersion: '',
maxTouchPoints: 0,
standalone: false,
getUserMedia: undefined,
webkitGetUserMedia: undefined,
mozGetUserMedia: undefined,
msGetUserMedia: undefined,
oGetUserMedia: undefined,
vibrate: undefined,
msPointerEnabled: false,
pointerEnabled: false,
getGamepads: undefined
};
}
if (typeof document === 'undefined')
{
var mockContext = {
fillStyle: '',
globalCompositeOperation: '',
globalAlpha: 1,
fillRect: function () {},
drawImage: function () {},
getImageData: function () { return { data: [ 0, 0, 0, 0 ] }; },
putImageData: function () {},
createImageData: function () { return { data: [] }; },
clearRect: function () {},
save: function () {},
restore: function () {}
};
var mockCanvas = {
getContext: function () { return mockContext; },
width: 1,
height: 1,
style: {}
};
global.document = {
documentElement: {},
pointerLockElement: undefined,
mozPointerLockElement: undefined,
webkitPointerLockElement: undefined,
createElement: function (tag)
{
if (tag === 'canvas') { return mockCanvas; }
return { style: {} };
},
addEventListener: function () {}
};
}
if (typeof Image === 'undefined')
{
global.Image = function ()
{
this.onload = null;
this.src = '';
};
}
if (typeof HTMLCanvasElement === 'undefined')
{
global.HTMLCanvasElement = function () {};
}
var TilemapLayerBase = require('../../src/tilemaps/TilemapLayerBase');
var TilemapComponents = require('../../src/tilemaps/components');
var GameObject = require('../../src/gameobjects/GameObject');
function createMockLayer ()
{
return {
alpha: 1,
width: 10,
height: 8,
tilemapLayer: null,
data: []
};
}
function createMockTilemap (layer)
{
return {
tileWidth: 32,
tileHeight: 32,
layers: [ layer ],
tileToWorldX: vi.fn().mockReturnValue(64),
tileToWorldY: vi.fn().mockReturnValue(96),
tileToWorldXY: vi.fn().mockReturnValue({ x: 64, y: 96 }),
getTileCorners: vi.fn().mockReturnValue([]),
worldToTileX: vi.fn().mockReturnValue(2),
worldToTileY: vi.fn().mockReturnValue(3),
worldToTileXY: vi.fn().mockReturnValue({ x: 2, y: 3 }),
removeLayer: vi.fn()
};
}
function createMockObject (overrides)
{
var layer = createMockLayer();
var tilemap = createMockTilemap(layer);
var base = {
layer: layer,
tilemap: tilemap,
tempVec: { x: 0, y: 0 },
scene: {
sys: {
updateList: {
add: vi.fn(),
remove: vi.fn()
}
}
},
updateTimer: vi.fn(),
getTileAt: vi.fn().mockReturnValue({ index: 3 })
};
if (overrides)
{
for (var key in overrides)
{
base[key] = overrides[key];
}
}
return base;
}
describe('TilemapLayerBase', function ()
{
beforeEach(function ()
{
vi.spyOn(TilemapComponents, 'CalculateFacesAt').mockImplementation(function () {});
vi.spyOn(TilemapComponents, 'CalculateFacesWithin').mockImplementation(function () {});
vi.spyOn(TilemapComponents, 'CreateFromTiles').mockReturnValue([]);
vi.spyOn(TilemapComponents, 'Copy').mockImplementation(function () {});
vi.spyOn(TilemapComponents, 'Fill').mockImplementation(function () {});
vi.spyOn(TilemapComponents, 'FilterTiles').mockReturnValue([ { index: 1 } ]);
vi.spyOn(TilemapComponents, 'FindByIndex').mockReturnValue({ index: 5 });
vi.spyOn(TilemapComponents, 'FindTile').mockReturnValue(null);
vi.spyOn(TilemapComponents, 'ForEachTile').mockImplementation(function () {});
vi.spyOn(TilemapComponents, 'GetTileAt').mockReturnValue({ index: 3 });
vi.spyOn(TilemapComponents, 'GetTileAtWorldXY').mockReturnValue({ index: 2 });
vi.spyOn(TilemapComponents, 'GetTilesWithin').mockReturnValue([]);
vi.spyOn(TilemapComponents, 'GetTilesWithinShape').mockReturnValue([]);
vi.spyOn(TilemapComponents, 'GetTilesWithinWorldXY').mockReturnValue([]);
vi.spyOn(TilemapComponents, 'HasTileAt').mockReturnValue(true);
vi.spyOn(TilemapComponents, 'HasTileAtWorldXY').mockReturnValue(false);
vi.spyOn(TilemapComponents, 'IsometricWorldToTileXY').mockImplementation(function () {});
vi.spyOn(TilemapComponents, 'PutTileAt').mockReturnValue({ index: 7 });
vi.spyOn(TilemapComponents, 'PutTileAtWorldXY').mockReturnValue({ index: 8 });
vi.spyOn(TilemapComponents, 'PutTilesAt').mockImplementation(function () {});
vi.spyOn(TilemapComponents, 'Randomize').mockImplementation(function () {});
vi.spyOn(TilemapComponents, 'RemoveTileAt').mockReturnValue({ index: 1 });
vi.spyOn(TilemapComponents, 'RemoveTileAtWorldXY').mockReturnValue({ index: 2 });
vi.spyOn(TilemapComponents, 'RenderDebug').mockImplementation(function () {});
vi.spyOn(TilemapComponents, 'ReplaceByIndex').mockImplementation(function () {});
vi.spyOn(TilemapComponents, 'SetCollision').mockImplementation(function () {});
vi.spyOn(TilemapComponents, 'SetCollisionBetween').mockImplementation(function () {});
vi.spyOn(TilemapComponents, 'SetCollisionByProperty').mockImplementation(function () {});
vi.spyOn(TilemapComponents, 'SetCollisionByExclusion').mockImplementation(function () {});
vi.spyOn(TilemapComponents, 'SetCollisionFromCollisionGroup').mockImplementation(function () {});
vi.spyOn(TilemapComponents, 'SetTileIndexCallback').mockImplementation(function () {});
vi.spyOn(TilemapComponents, 'SetTileLocationCallback').mockImplementation(function () {});
vi.spyOn(TilemapComponents, 'Shuffle').mockImplementation(function () {});
vi.spyOn(TilemapComponents, 'SwapByIndex').mockImplementation(function () {});
vi.spyOn(TilemapComponents, 'WeightedRandomize').mockImplementation(function () {});
});
afterEach(function ()
{
vi.restoreAllMocks();
});
it('should be importable', function ()
{
expect(TilemapLayerBase).toBeDefined();
});
describe('addedToScene', function ()
{
it('should add this to the scene update list', function ()
{
var mock = createMockObject();
TilemapLayerBase.prototype.addedToScene.call(mock);
expect(mock.scene.sys.updateList.add).toHaveBeenCalledWith(mock);
});
});
describe('removedFromScene', function ()
{
it('should remove this from the scene update list', function ()
{
var mock = createMockObject();
TilemapLayerBase.prototype.removedFromScene.call(mock);
expect(mock.scene.sys.updateList.remove).toHaveBeenCalledWith(mock);
});
});
describe('preUpdate', function ()
{
it('should call updateTimer with time and delta', function ()
{
var mock = createMockObject();
TilemapLayerBase.prototype.preUpdate.call(mock, 1000, 16);
expect(mock.updateTimer).toHaveBeenCalledWith(1000, 16);
});
});
describe('calculateFacesAt', function ()
{
it('should delegate to TilemapComponents with tileX, tileY, and layer', function ()
{
var mock = createMockObject();
TilemapLayerBase.prototype.calculateFacesAt.call(mock, 3, 5);
expect(TilemapComponents.CalculateFacesAt).toHaveBeenCalledWith(3, 5, mock.layer);
});
it('should return this for chaining', function ()
{
var mock = createMockObject();
var result = TilemapLayerBase.prototype.calculateFacesAt.call(mock, 0, 0);
expect(result).toBe(mock);
});
});
describe('calculateFacesWithin', function ()
{
it('should delegate to TilemapComponents and return this', function ()
{
var mock = createMockObject();
var result = TilemapLayerBase.prototype.calculateFacesWithin.call(mock, 0, 0, 5, 5);
expect(TilemapComponents.CalculateFacesWithin).toHaveBeenCalledWith(0, 0, 5, 5, mock.layer);
expect(result).toBe(mock);
});
});
describe('fill', function ()
{
it('should delegate to TilemapComponents with all arguments', function ()
{
var mock = createMockObject();
TilemapLayerBase.prototype.fill.call(mock, 2, 1, 1, 4, 4, true);
expect(TilemapComponents.Fill).toHaveBeenCalledWith(2, 1, 1, 4, 4, true, mock.layer);
});
it('should return this for chaining', function ()
{
var mock = createMockObject();
var result = TilemapLayerBase.prototype.fill.call(mock, 1, 0, 0, 3, 3);
expect(result).toBe(mock);
});
});
describe('filterTiles', function ()
{
it('should delegate to TilemapComponents and return the result', function ()
{
var mock = createMockObject();
var cb = function (tile) { return tile.index > 0; };
var result = TilemapLayerBase.prototype.filterTiles.call(mock, cb, null, 0, 0, 5, 5, null);
expect(TilemapComponents.FilterTiles).toHaveBeenCalledWith(cb, null, 0, 0, 5, 5, null, mock.layer);
expect(Array.isArray(result)).toBe(true);
});
});
describe('findByIndex', function ()
{
it('should delegate to TilemapComponents and return the tile', function ()
{
var mock = createMockObject();
var result = TilemapLayerBase.prototype.findByIndex.call(mock, 5, 0, false);
expect(TilemapComponents.FindByIndex).toHaveBeenCalledWith(5, 0, false, mock.layer);
expect(result).toEqual({ index: 5 });
});
});
describe('getTileAt', function ()
{
it('should delegate to TilemapComponents and return the tile', function ()
{
var mock = createMockObject();
var result = TilemapLayerBase.prototype.getTileAt.call(mock, 2, 3, false);
expect(TilemapComponents.GetTileAt).toHaveBeenCalledWith(2, 3, false, mock.layer);
expect(result).toEqual({ index: 3 });
});
});
describe('hasTileAt', function ()
{
it('should delegate to TilemapComponents and return boolean true', function ()
{
var mock = createMockObject();
var result = TilemapLayerBase.prototype.hasTileAt.call(mock, 1, 2);
expect(TilemapComponents.HasTileAt).toHaveBeenCalledWith(1, 2, mock.layer);
expect(result).toBe(true);
});
it('should return boolean false when HasTileAtWorldXY returns false', function ()
{
var mock = createMockObject();
var result = TilemapLayerBase.prototype.hasTileAtWorldXY.call(mock, 64, 96, null);
expect(TilemapComponents.HasTileAtWorldXY).toHaveBeenCalledWith(64, 96, null, mock.layer);
expect(result).toBe(false);
});
});
describe('putTileAt', function ()
{
it('should delegate to TilemapComponents and return the tile', function ()
{
var mock = createMockObject();
var result = TilemapLayerBase.prototype.putTileAt.call(mock, 7, 2, 3, true);
expect(TilemapComponents.PutTileAt).toHaveBeenCalledWith(7, 2, 3, true, mock.layer);
expect(result).toEqual({ index: 7 });
});
});
describe('putTilesAt', function ()
{
it('should delegate to TilemapComponents and return this', function ()
{
var mock = createMockObject();
var tiles = [ 1, 2, 3 ];
var result = TilemapLayerBase.prototype.putTilesAt.call(mock, tiles, 0, 0, true);
expect(TilemapComponents.PutTilesAt).toHaveBeenCalledWith(tiles, 0, 0, true, mock.layer);
expect(result).toBe(mock);
});
});
describe('replaceByIndex', function ()
{
it('should delegate to TilemapComponents and return this', function ()
{
var mock = createMockObject();
var result = TilemapLayerBase.prototype.replaceByIndex.call(mock, 1, 2, 0, 0, 5, 5);
expect(TilemapComponents.ReplaceByIndex).toHaveBeenCalledWith(1, 2, 0, 0, 5, 5, mock.layer);
expect(result).toBe(mock);
});
});
describe('setCollision', function ()
{
it('should delegate to TilemapComponents and return this', function ()
{
var mock = createMockObject();
var result = TilemapLayerBase.prototype.setCollision.call(mock, [ 1, 2, 3 ], true, true, true);
expect(TilemapComponents.SetCollision).toHaveBeenCalledWith([ 1, 2, 3 ], true, true, mock.layer, true);
expect(result).toBe(mock);
});
});
describe('setCollisionBetween', function ()
{
it('should delegate to TilemapComponents and return this', function ()
{
var mock = createMockObject();
var result = TilemapLayerBase.prototype.setCollisionBetween.call(mock, 1, 5, true, true);
expect(TilemapComponents.SetCollisionBetween).toHaveBeenCalledWith(1, 5, true, true, mock.layer);
expect(result).toBe(mock);
});
});
describe('shuffle', function ()
{
it('should delegate to TilemapComponents and return this', function ()
{
var mock = createMockObject();
var result = TilemapLayerBase.prototype.shuffle.call(mock, 0, 0, 4, 4);
expect(TilemapComponents.Shuffle).toHaveBeenCalledWith(0, 0, 4, 4, mock.layer);
expect(result).toBe(mock);
});
});
describe('swapByIndex', function ()
{
it('should delegate to TilemapComponents and return this', function ()
{
var mock = createMockObject();
var result = TilemapLayerBase.prototype.swapByIndex.call(mock, 1, 2, 0, 0, 3, 3);
expect(TilemapComponents.SwapByIndex).toHaveBeenCalledWith(1, 2, 0, 0, 3, 3, mock.layer);
expect(result).toBe(mock);
});
});
describe('tileToWorldX', function ()
{
it('should delegate to tilemap.tileToWorldX and return the result', function ()
{
var mock = createMockObject();
var camera = {};
var result = TilemapLayerBase.prototype.tileToWorldX.call(mock, 2, camera);
expect(mock.tilemap.tileToWorldX).toHaveBeenCalledWith(2, camera, mock);
expect(result).toBe(64);
});
});
describe('tileToWorldY', function ()
{
it('should delegate to tilemap.tileToWorldY and return the result', function ()
{
var mock = createMockObject();
var camera = {};
var result = TilemapLayerBase.prototype.tileToWorldY.call(mock, 3, camera);
expect(mock.tilemap.tileToWorldY).toHaveBeenCalledWith(3, camera, mock);
expect(result).toBe(96);
});
});
describe('worldToTileX', function ()
{
it('should delegate to tilemap.worldToTileX and return the result', function ()
{
var mock = createMockObject();
var camera = {};
var result = TilemapLayerBase.prototype.worldToTileX.call(mock, 64, true, camera);
expect(mock.tilemap.worldToTileX).toHaveBeenCalledWith(64, true, camera, mock);
expect(result).toBe(2);
});
});
describe('worldToTileY', function ()
{
it('should delegate to tilemap.worldToTileY and return the result', function ()
{
var mock = createMockObject();
var camera = {};
var result = TilemapLayerBase.prototype.worldToTileY.call(mock, 96, true, camera);
expect(mock.tilemap.worldToTileY).toHaveBeenCalledWith(96, true, camera, mock);
expect(result).toBe(3);
});
});
describe('destroy', function ()
{
it('should do nothing if tilemap is already undefined', function ()
{
var mock = createMockObject();
mock.tilemap = undefined;
var goDestroySpy = vi.spyOn(GameObject.prototype, 'destroy').mockImplementation(function () {});
expect(function ()
{
TilemapLayerBase.prototype.destroy.call(mock);
}).not.toThrow();
goDestroySpy.mockRestore();
});
it('should unlink layer.tilemapLayer when it references this', function ()
{
var mock = createMockObject();
mock.layer.tilemapLayer = mock;
var goDestroySpy = vi.spyOn(GameObject.prototype, 'destroy').mockImplementation(function () {});
TilemapLayerBase.prototype.destroy.call(mock);
expect(mock.layer).toBeUndefined();
goDestroySpy.mockRestore();
});
it('should call tilemap.removeLayer by default', function ()
{
var mock = createMockObject();
mock.layer.tilemapLayer = mock;
var goDestroySpy = vi.spyOn(GameObject.prototype, 'destroy').mockImplementation(function () {});
TilemapLayerBase.prototype.destroy.call(mock);
expect(mock.tilemap).toBeUndefined();
goDestroySpy.mockRestore();
});
it('should not call removeLayer when removeFromTilemap is false', function ()
{
var layer = createMockLayer();
var tilemap = createMockTilemap(layer);
var mock = createMockObject();
mock.layer = layer;
mock.tilemap = tilemap;
mock.layer.tilemapLayer = mock;
var goDestroySpy = vi.spyOn(GameObject.prototype, 'destroy').mockImplementation(function () {});
TilemapLayerBase.prototype.destroy.call(mock, false);
expect(tilemap.removeLayer).not.toHaveBeenCalled();
goDestroySpy.mockRestore();
});
it('should set tilemap to undefined after destroy', function ()
{
var mock = createMockObject();
mock.layer.tilemapLayer = mock;
var goDestroySpy = vi.spyOn(GameObject.prototype, 'destroy').mockImplementation(function () {});
TilemapLayerBase.prototype.destroy.call(mock);
expect(mock.tilemap).toBeUndefined();
goDestroySpy.mockRestore();
});
});
});