UNPKG

phaser

Version:

A fast, free and fun HTML5 Game Framework for Desktop and Mobile web browsers from the team at Phaser Studio Inc.

380 lines (306 loc) 10.7 kB
var AtlasXML = require('../../../src/textures/parsers/AtlasXML'); describe('Phaser.Textures.Parsers.AtlasXML', function () { var texture; var addedFrames; function makeMockTexture (sourceWidth, sourceHeight) { addedFrames = []; return { source: [ { width: sourceWidth || 512, height: sourceHeight || 512 } ], add: function (name, sourceIndex, x, y, width, height) { var frame = { name: name, sourceIndex: sourceIndex, x: x, y: y, width: width, height: height, trimmed: false, setTrim: function (w, h, fx, fy, fw, fh) { this.trimmed = true; this.realWidth = w; this.realHeight = h; this.trimX = fx; this.trimY = fy; this.trimWidth = fw; this.trimHeight = fh; } }; addedFrames.push(frame); return frame; } }; } function makeAttr (value) { return { value: String(value) }; } function makeMockXml (subTextures) { var elements = (subTextures || []).map(function (st) { var attrs = { name: makeAttr(st.name), x: makeAttr(st.x), y: makeAttr(st.y), width: makeAttr(st.width), height: makeAttr(st.height) }; if (st.frameX !== undefined) { attrs.frameX = makeAttr(st.frameX); attrs.frameY = makeAttr(st.frameY); attrs.frameWidth = makeAttr(st.frameWidth); attrs.frameHeight = makeAttr(st.frameHeight); } return { attributes: attrs }; }); return { getElementsByTagName: function (tag) { if (tag === 'TextureAtlas') { return [{}]; } if (tag === 'SubTexture') { return elements; } return []; } }; } function makeMalformedXml () { return { getElementsByTagName: function () { return null; } }; } beforeEach(function () { texture = makeMockTexture(512, 256); }); it('should return undefined for malformed XML without TextureAtlas element', function () { var xml = makeMalformedXml(); var result = AtlasXML(texture, 0, xml); expect(result).toBeUndefined(); }); it('should not add any frames for malformed XML', function () { var xml = makeMalformedXml(); AtlasXML(texture, 0, xml); expect(addedFrames.length).toBe(0); }); it('should return the texture object on success', function () { var xml = makeMockXml([]); var result = AtlasXML(texture, 0, xml); expect(result).toBe(texture); }); it('should add a __BASE frame using the source dimensions', function () { var xml = makeMockXml([]); AtlasXML(texture, 0, xml); var base = addedFrames[0]; expect(base.name).toBe('__BASE'); expect(base.x).toBe(0); expect(base.y).toBe(0); expect(base.width).toBe(512); expect(base.height).toBe(256); }); it('should add __BASE with correct sourceIndex', function () { texture = makeMockTexture(512, 512); texture.source.push({ width: 256, height: 128 }); var xml = makeMockXml([]); AtlasXML(texture, 1, xml); var base = addedFrames[0]; expect(base.sourceIndex).toBe(1); expect(base.width).toBe(256); expect(base.height).toBe(128); }); it('should add a frame for each SubTexture element', function () { var xml = makeMockXml([ { name: 'frame1', x: 0, y: 0, width: 64, height: 64 }, { name: 'frame2', x: 64, y: 0, width: 32, height: 32 }, { name: 'frame3', x: 96, y: 0, width: 16, height: 16 } ]); AtlasXML(texture, 0, xml); // 1 for __BASE + 3 frames expect(addedFrames.length).toBe(4); }); it('should parse frame name correctly', function () { var xml = makeMockXml([ { name: 'explosion_01', x: 0, y: 0, width: 64, height: 64 } ]); AtlasXML(texture, 0, xml); expect(addedFrames[1].name).toBe('explosion_01'); }); it('should parse frame x and y as integers', function () { var xml = makeMockXml([ { name: 'sprite', x: 128, y: 64, width: 32, height: 32 } ]); AtlasXML(texture, 0, xml); var frame = addedFrames[1]; expect(frame.x).toBe(128); expect(frame.y).toBe(64); }); it('should parse frame width and height as integers', function () { var xml = makeMockXml([ { name: 'sprite', x: 0, y: 0, width: 100, height: 200 } ]); AtlasXML(texture, 0, xml); var frame = addedFrames[1]; expect(frame.width).toBe(100); expect(frame.height).toBe(200); }); it('should not call setTrim when frameX attribute is absent', function () { var xml = makeMockXml([ { name: 'sprite', x: 0, y: 0, width: 64, height: 64 } ]); AtlasXML(texture, 0, xml); expect(addedFrames[1].trimmed).toBe(false); }); it('should call setTrim when frameX attribute is present', function () { var xml = makeMockXml([ { name: 'trimmed_sprite', x: 10, y: 10, width: 50, height: 50, frameX: -5, frameY: -8, frameWidth: 60, frameHeight: 66 } ]); AtlasXML(texture, 0, xml); expect(addedFrames[1].trimmed).toBe(true); }); it('should pass correct values to setTrim', function () { var xml = makeMockXml([ { name: 'trimmed_sprite', x: 10, y: 10, width: 50, height: 50, frameX: -5, frameY: -8, frameWidth: 60, frameHeight: 66 } ]); AtlasXML(texture, 0, xml); var frame = addedFrames[1]; // setTrim(actualWidth, actualHeight, destX, destY, destWidth, destHeight) // - actualWidth / actualHeight → the ORIGINAL (untrimmed) sprite size, // stored as frame.realWidth / realHeight // - destX / destY → the trim offset within the source // - destWidth / destHeight → the TRIMMED (in-atlas) size that was // packed into the texture, captured here as trimWidth / trimHeight expect(frame.realWidth).toBe(60); expect(frame.realHeight).toBe(66); expect(frame.trimX).toBe(5); expect(frame.trimY).toBe(8); expect(frame.trimWidth).toBe(50); expect(frame.trimHeight).toBe(50); }); it('should use Math.abs for frameX and frameY values', function () { var xml = makeMockXml([ { name: 'sprite', x: 0, y: 0, width: 40, height: 40, frameX: -10, frameY: -20, frameWidth: 50, frameHeight: 60 } ]); AtlasXML(texture, 0, xml); var frame = addedFrames[1]; expect(frame.trimX).toBe(10); expect(frame.trimY).toBe(20); }); it('should use Math.abs for positive frameX and frameY values too', function () { var xml = makeMockXml([ { name: 'sprite', x: 0, y: 0, width: 40, height: 40, frameX: 10, frameY: 20, frameWidth: 50, frameHeight: 60 } ]); AtlasXML(texture, 0, xml); var frame = addedFrames[1]; expect(frame.trimX).toBe(10); expect(frame.trimY).toBe(20); }); it('should handle an atlas with no SubTexture elements', function () { var xml = makeMockXml([]); var result = AtlasXML(texture, 0, xml); expect(result).toBe(texture); expect(addedFrames.length).toBe(1); // only __BASE }); it('should handle string number values in attributes (parseInt)', function () { var xml = makeMockXml([ { name: 'frame', x: '7', y: '13', width: '32', height: '48' } ]); AtlasXML(texture, 0, xml); var frame = addedFrames[1]; expect(frame.x).toBe(7); expect(frame.y).toBe(13); expect(frame.width).toBe(32); expect(frame.height).toBe(48); }); it('should add each frame with the correct sourceIndex', function () { var xml = makeMockXml([ { name: 'a', x: 0, y: 0, width: 16, height: 16 }, { name: 'b', x: 16, y: 0, width: 16, height: 16 } ]); AtlasXML(texture, 0, xml); expect(addedFrames[1].sourceIndex).toBe(0); expect(addedFrames[2].sourceIndex).toBe(0); }); it('should process multiple trimmed frames independently', function () { var xml = makeMockXml([ { name: 'a', x: 0, y: 0, width: 30, height: 30, frameX: -2, frameY: -4, frameWidth: 34, frameHeight: 38 }, { name: 'b', x: 30, y: 0, width: 20, height: 20, frameX: -1, frameY: -3, frameWidth: 22, frameHeight: 26 } ]); AtlasXML(texture, 0, xml); var frameA = addedFrames[1]; var frameB = addedFrames[2]; // realWidth / realHeight are the ORIGINAL (untrimmed) sprite dimensions; // trimWidth / trimHeight are the TRIMMED in-atlas dimensions (the 5th and // 6th arguments passed to setTrim). expect(frameA.realWidth).toBe(34); expect(frameA.realHeight).toBe(38); expect(frameA.trimX).toBe(2); expect(frameA.trimY).toBe(4); expect(frameA.trimWidth).toBe(30); expect(frameA.trimHeight).toBe(30); expect(frameB.realWidth).toBe(22); expect(frameB.realHeight).toBe(26); expect(frameB.trimX).toBe(1); expect(frameB.trimY).toBe(3); expect(frameB.trimWidth).toBe(20); expect(frameB.trimHeight).toBe(20); }); });