phaser
Version:
A fast, free and fun HTML5 Game Framework for Desktop and Mobile web browsers from the team at Phaser Studio Inc.
559 lines (496 loc) • 19.4 kB
JavaScript
var EllipseCurve = require('../../src/curves/EllipseCurve');
describe('Ellipse', function ()
{
describe('Constructor', function ()
{
it('should create an ellipse curve with default values', function ()
{
var curve = new EllipseCurve(0, 0, 0);
expect(curve.x).toBe(0);
expect(curve.y).toBe(0);
expect(curve.xRadius).toBe(0);
expect(curve.yRadius).toBe(0);
expect(curve.startAngle).toBe(0);
expect(curve.endAngle).toBe(360);
expect(curve.clockwise).toBe(false);
expect(curve.rotation).toBe(0);
});
it('should create an ellipse curve with given positional arguments', function ()
{
var curve = new EllipseCurve(100, 200, 50, 30, 0, 360, false, 0);
expect(curve.x).toBe(100);
expect(curve.y).toBe(200);
expect(curve.xRadius).toBe(50);
expect(curve.yRadius).toBe(30);
expect(curve.startAngle).toBe(0);
expect(curve.endAngle).toBe(360);
expect(curve.clockwise).toBe(false);
});
it('should default yRadius to xRadius when not provided', function ()
{
var curve = new EllipseCurve(0, 0, 40);
expect(curve.xRadius).toBe(40);
expect(curve.yRadius).toBe(40);
});
it('should create an ellipse curve from a config object', function ()
{
var curve = new EllipseCurve({
x: 10,
y: 20,
xRadius: 100,
yRadius: 50,
startAngle: 45,
endAngle: 270,
clockwise: true,
rotation: 90
});
expect(curve.x).toBe(10);
expect(curve.y).toBe(20);
expect(curve.xRadius).toBe(100);
expect(curve.yRadius).toBe(50);
expect(curve.startAngle).toBeCloseTo(45);
expect(curve.endAngle).toBeCloseTo(270);
expect(curve.clockwise).toBe(true);
expect(curve.angle).toBeCloseTo(90);
});
it('should default yRadius to xRadius when config object omits yRadius', function ()
{
var curve = new EllipseCurve({ xRadius: 75 });
expect(curve.xRadius).toBe(75);
expect(curve.yRadius).toBe(75);
});
it('should have the correct curve type', function ()
{
var curve = new EllipseCurve();
expect(curve.type).toBe('EllipseCurve');
});
it('should store startAngle and endAngle as radians internally', function ()
{
var curve = new EllipseCurve(0, 0, 50, 50, 90, 180);
expect(curve._startAngle).toBeCloseTo(Math.PI / 2);
expect(curve._endAngle).toBeCloseTo(Math.PI);
});
});
describe('getStartPoint', function ()
{
it('should return a Vector2 at t=0', function ()
{
var curve = new EllipseCurve(0, 0, 100, 100, 0, 360, false, 0);
var point = curve.getStartPoint();
expect(point.x).toBeCloseTo(100);
expect(point.y).toBeCloseTo(0);
});
it('should write into the provided out vector', function ()
{
var curve = new EllipseCurve(0, 0, 50, 50, 0, 360, false, 0);
var out = { x: 0, y: 0, set: function (x, y) { this.x = x; this.y = y; return this; } };
var result = curve.getStartPoint(out);
expect(result).toBe(out);
expect(out.x).toBeCloseTo(50);
expect(out.y).toBeCloseTo(0);
});
it('should respect a non-zero start angle', function ()
{
var curve = new EllipseCurve(0, 0, 100, 100, 90, 360, false, 0);
var point = curve.getStartPoint();
expect(point.x).toBeCloseTo(0);
expect(point.y).toBeCloseTo(100);
});
});
describe('getResolution', function ()
{
it('should return double the divisions value', function ()
{
var curve = new EllipseCurve();
expect(curve.getResolution(10)).toBe(20);
});
it('should return zero for zero divisions', function ()
{
var curve = new EllipseCurve();
expect(curve.getResolution(0)).toBe(0);
});
it('should return double the value for any input', function ()
{
var curve = new EllipseCurve();
expect(curve.getResolution(1)).toBe(2);
expect(curve.getResolution(5)).toBe(10);
expect(curve.getResolution(100)).toBe(200);
});
});
describe('getPoint', function ()
{
it('should return t=0 at the start angle', function ()
{
var curve = new EllipseCurve(0, 0, 100, 100, 0, 360, false, 0);
var point = curve.getPoint(0);
expect(point.x).toBeCloseTo(100);
expect(point.y).toBeCloseTo(0);
});
it('should return t=1 at the end angle for a full circle', function ()
{
var curve = new EllipseCurve(0, 0, 100, 100, 0, 360, false, 0);
var point = curve.getPoint(1);
expect(point.x).toBeCloseTo(100);
expect(point.y).toBeCloseTo(0);
});
it('should return t=0.5 at the opposite side of a full circle', function ()
{
var curve = new EllipseCurve(0, 0, 100, 100, 0, 360, false, 0);
var point = curve.getPoint(0.5);
expect(point.x).toBeCloseTo(-100);
expect(point.y).toBeCloseTo(0);
});
it('should offset by center position', function ()
{
var curve = new EllipseCurve(50, 50, 100, 100, 0, 360, false, 0);
var point = curve.getPoint(0);
expect(point.x).toBeCloseTo(150);
expect(point.y).toBeCloseTo(50);
});
it('should respect different x and y radii', function ()
{
var curve = new EllipseCurve(0, 0, 100, 50, 0, 360, false, 0);
var point = curve.getPoint(0);
expect(point.x).toBeCloseTo(100);
expect(point.y).toBeCloseTo(0);
var point2 = curve.getPoint(0.25);
expect(point2.x).toBeCloseTo(0);
expect(point2.y).toBeCloseTo(50);
});
it('should create a new Vector2 when out is not provided', function ()
{
var curve = new EllipseCurve(0, 0, 100, 100);
var point = curve.getPoint(0);
expect(point).toBeDefined();
expect(typeof point.x).toBe('number');
expect(typeof point.y).toBe('number');
});
it('should write into the provided out vector', function ()
{
var curve = new EllipseCurve(0, 0, 100, 100, 0, 360, false, 0);
var out = { x: 0, y: 0, set: function (x, y) { this.x = x; this.y = y; return this; } };
var result = curve.getPoint(0, out);
expect(result).toBe(out);
});
it('should handle clockwise direction', function ()
{
var ccw = new EllipseCurve(0, 0, 100, 100, 0, 360, false, 0);
var cw = new EllipseCurve(0, 0, 100, 100, 0, 360, true, 0);
var ccwPoint = ccw.getPoint(0.25);
var cwPoint = cw.getPoint(0.25);
// CCW at 0.25 of 360 deg => 90 deg => (0, 100)
expect(ccwPoint.x).toBeCloseTo(0);
expect(ccwPoint.y).toBeCloseTo(100);
// CW at 0.25 of 360 deg => -90 deg => (0, -100)
expect(cwPoint.x).toBeCloseTo(0);
expect(cwPoint.y).toBeCloseTo(-100);
});
it('should apply rotation', function ()
{
var curve = new EllipseCurve(0, 0, 100, 100, 0, 360, false, 90);
var point = curve.getPoint(0);
// start point at angle 0 rotated by 90 degrees
// original: (100, 0), after 90deg rotation: (0, 100) -- but rotation is in degrees here via setter
// Actually setRotation takes radians, but constructor takes degrees converted via DegToRad
// After 90 deg rotation: x=0, y=100
expect(point.x).toBeCloseTo(0);
expect(point.y).toBeCloseTo(100);
});
it('should handle a partial arc at t=0.5 for a 180-degree arc', function ()
{
var curve = new EllipseCurve(0, 0, 100, 100, 0, 180, false, 0);
var point = curve.getPoint(0.5);
// midpoint of 0..180 => 90 deg => (0, 100)
expect(point.x).toBeCloseTo(0);
expect(point.y).toBeCloseTo(100);
});
});
describe('setXRadius', function ()
{
it('should set the horizontal radius and return the curve', function ()
{
var curve = new EllipseCurve(0, 0, 10, 10);
var result = curve.setXRadius(200);
expect(curve.xRadius).toBe(200);
expect(result).toBe(curve);
});
it('should accept zero', function ()
{
var curve = new EllipseCurve(0, 0, 50, 50);
curve.setXRadius(0);
expect(curve.xRadius).toBe(0);
});
it('should accept negative values', function ()
{
var curve = new EllipseCurve(0, 0, 50, 50);
curve.setXRadius(-10);
expect(curve.xRadius).toBe(-10);
});
});
describe('setYRadius', function ()
{
it('should set the vertical radius and return the curve', function ()
{
var curve = new EllipseCurve(0, 0, 10, 10);
var result = curve.setYRadius(300);
expect(curve.yRadius).toBe(300);
expect(result).toBe(curve);
});
it('should accept zero', function ()
{
var curve = new EllipseCurve(0, 0, 50, 50);
curve.setYRadius(0);
expect(curve.yRadius).toBe(0);
});
});
describe('setWidth', function ()
{
it('should set xRadius to half the given width and return the curve', function ()
{
var curve = new EllipseCurve();
var result = curve.setWidth(200);
expect(curve.xRadius).toBe(100);
expect(result).toBe(curve);
});
it('should work with odd values', function ()
{
var curve = new EllipseCurve();
curve.setWidth(100);
expect(curve.xRadius).toBe(50);
});
it('should work with zero', function ()
{
var curve = new EllipseCurve(0, 0, 50, 50);
curve.setWidth(0);
expect(curve.xRadius).toBe(0);
});
});
describe('setHeight', function ()
{
it('should set yRadius to half the given height and return the curve', function ()
{
var curve = new EllipseCurve();
var result = curve.setHeight(400);
expect(curve.yRadius).toBe(200);
expect(result).toBe(curve);
});
it('should work with zero', function ()
{
var curve = new EllipseCurve(0, 0, 50, 50);
curve.setHeight(0);
expect(curve.yRadius).toBe(0);
});
});
describe('setStartAngle', function ()
{
it('should set the start angle in degrees and return the curve', function ()
{
var curve = new EllipseCurve();
var result = curve.setStartAngle(90);
expect(curve.startAngle).toBeCloseTo(90);
expect(result).toBe(curve);
});
it('should store the value internally as radians', function ()
{
var curve = new EllipseCurve();
curve.setStartAngle(180);
expect(curve._startAngle).toBeCloseTo(Math.PI);
});
it('should accept zero', function ()
{
var curve = new EllipseCurve(0, 0, 50, 50, 90);
curve.setStartAngle(0);
expect(curve.startAngle).toBeCloseTo(0);
});
});
describe('setEndAngle', function ()
{
it('should set the end angle in degrees and return the curve', function ()
{
var curve = new EllipseCurve();
var result = curve.setEndAngle(180);
expect(curve.endAngle).toBeCloseTo(180);
expect(result).toBe(curve);
});
it('should store the value internally as radians', function ()
{
var curve = new EllipseCurve();
curve.setEndAngle(270);
expect(curve._endAngle).toBeCloseTo(3 * Math.PI / 2);
});
});
describe('setClockwise', function ()
{
it('should set clockwise to true and return the curve', function ()
{
var curve = new EllipseCurve();
var result = curve.setClockwise(true);
expect(curve.clockwise).toBe(true);
expect(result).toBe(curve);
});
it('should set clockwise to false', function ()
{
var curve = new EllipseCurve(0, 0, 50, 50, 0, 360, true);
curve.setClockwise(false);
expect(curve.clockwise).toBe(false);
});
});
describe('setRotation', function ()
{
it('should set rotation in radians and return the curve', function ()
{
var curve = new EllipseCurve();
var result = curve.setRotation(Math.PI / 2);
expect(curve.rotation).toBeCloseTo(Math.PI / 2);
expect(result).toBe(curve);
});
it('should accept zero', function ()
{
var curve = new EllipseCurve(0, 0, 50, 50, 0, 360, false, 45);
curve.setRotation(0);
expect(curve.rotation).toBeCloseTo(0);
});
it('should accept negative values', function ()
{
var curve = new EllipseCurve();
curve.setRotation(-Math.PI);
expect(curve.rotation).toBeCloseTo(-Math.PI);
});
});
describe('toJSON', function ()
{
it('should return an object with the correct type', function ()
{
var curve = new EllipseCurve();
var json = curve.toJSON();
expect(json.type).toBe('EllipseCurve');
});
it('should serialize all properties correctly', function ()
{
var curve = new EllipseCurve(10, 20, 50, 30, 45, 270, true, 90);
var json = curve.toJSON();
expect(json.x).toBe(10);
expect(json.y).toBe(20);
expect(json.xRadius).toBe(50);
expect(json.yRadius).toBe(30);
expect(json.startAngle).toBeCloseTo(45);
expect(json.endAngle).toBeCloseTo(270);
expect(json.clockwise).toBe(true);
expect(json.rotation).toBeCloseTo(90);
});
it('should serialize default values', function ()
{
var curve = new EllipseCurve(0, 0, 0, 0);
var json = curve.toJSON();
expect(json.x).toBe(0);
expect(json.y).toBe(0);
expect(json.xRadius).toBe(0);
expect(json.yRadius).toBe(0);
expect(json.startAngle).toBeCloseTo(0);
expect(json.endAngle).toBeCloseTo(360);
expect(json.clockwise).toBe(false);
expect(json.rotation).toBeCloseTo(0);
});
it('should be usable with fromJSON to reconstruct the curve', function ()
{
var original = new EllipseCurve(5, 15, 80, 40, 30, 300, false, 45);
var json = original.toJSON();
var restored = EllipseCurve.fromJSON(json);
expect(restored.x).toBe(original.x);
expect(restored.y).toBe(original.y);
expect(restored.xRadius).toBe(original.xRadius);
expect(restored.yRadius).toBe(original.yRadius);
expect(restored.startAngle).toBeCloseTo(original.startAngle);
expect(restored.endAngle).toBeCloseTo(original.endAngle);
expect(restored.clockwise).toBe(original.clockwise);
expect(restored.angle).toBeCloseTo(original.angle);
});
});
describe('fromJSON', function ()
{
it('should create a curve from a JSON object', function ()
{
var json = {
type: 'EllipseCurve',
x: 0,
y: 0,
xRadius: 100,
yRadius: 50,
startAngle: 0,
endAngle: 360,
clockwise: false,
rotation: 0
};
var curve = EllipseCurve.fromJSON(json);
expect(curve.xRadius).toBe(100);
expect(curve.yRadius).toBe(50);
});
});
describe('property accessors', function ()
{
it('should get and set x via the accessor', function ()
{
var curve = new EllipseCurve(10, 20, 50);
expect(curve.x).toBe(10);
curve.x = 99;
expect(curve.x).toBe(99);
expect(curve.p0.x).toBe(99);
});
it('should get and set y via the accessor', function ()
{
var curve = new EllipseCurve(10, 20, 50);
expect(curve.y).toBe(20);
curve.y = 77;
expect(curve.y).toBe(77);
expect(curve.p0.y).toBe(77);
});
it('should get and set xRadius via the accessor', function ()
{
var curve = new EllipseCurve(0, 0, 50, 50);
expect(curve.xRadius).toBe(50);
curve.xRadius = 120;
expect(curve.xRadius).toBe(120);
});
it('should get and set yRadius via the accessor', function ()
{
var curve = new EllipseCurve(0, 0, 50, 50);
expect(curve.yRadius).toBe(50);
curve.yRadius = 80;
expect(curve.yRadius).toBe(80);
});
it('should get and set startAngle in degrees via the accessor', function ()
{
var curve = new EllipseCurve(0, 0, 50, 50, 0);
curve.startAngle = 45;
expect(curve.startAngle).toBeCloseTo(45);
expect(curve._startAngle).toBeCloseTo(Math.PI / 4);
});
it('should get and set endAngle in degrees via the accessor', function ()
{
var curve = new EllipseCurve();
curve.endAngle = 180;
expect(curve.endAngle).toBeCloseTo(180);
expect(curve._endAngle).toBeCloseTo(Math.PI);
});
it('should get and set clockwise via the accessor', function ()
{
var curve = new EllipseCurve();
expect(curve.clockwise).toBe(false);
curve.clockwise = true;
expect(curve.clockwise).toBe(true);
});
it('should get and set rotation in radians via the accessor', function ()
{
var curve = new EllipseCurve();
curve.rotation = Math.PI;
expect(curve.rotation).toBeCloseTo(Math.PI);
});
it('should get and set angle in degrees via the angle accessor', function ()
{
var curve = new EllipseCurve();
curve.angle = 90;
expect(curve.angle).toBeCloseTo(90);
expect(curve._rotation).toBeCloseTo(Math.PI / 2);
});
});
});