UNPKG

@rawify/vector3

Version:

The RAW JavaScript 3D Vector library

823 lines (643 loc) 19.1 kB
var expect = require('chai').expect; var Victor = require('../index'); describe('static methods', function () { describe('new Victor', function () { var x, y, vec1, vec2; before(function () { x = 100; y = 200; vec1 = new Victor(x, y); vec2 = Victor(x, y); }); it('should be an instance of Victor', function () { expect(vec1).to.be.an.instanceof(Victor); expect(vec2).to.be.an.instanceof(Victor); }); it('should have axis from arguments', function () { expect(vec1).to.have.property('x', x); expect(vec1).to.have.property('y', y); expect(vec2).to.have.property('x', x); expect(vec2).to.have.property('y', y); }); }); describe('#fromArray()', function () { var arr, vec; before(function () { arr = [100, 200]; vec = Victor.fromArray(arr); }); it('should return an instance of Victor', function () { expect(vec).to.be.an.instanceof(Victor); }); it('should have axis from array', function () { expect(vec).to.have.property('x', arr[0]); expect(vec).to.have.property('y', arr[1]); }); }); describe('#fromObject()', function () { var obj, vec; before(function () { obj = { x: 100, y: 200 }; vec = Victor.fromObject(obj); }); it('should return an instance of Victor', function () { expect(vec).to.be.an.instanceof(Victor); }); it('should have axis from object', function () { expect(vec).to.have.property('x', obj.x); expect(vec).to.have.property('y', obj.y); }); }); }); describe('chainable instance methods', function () { describe('#addX()', function () { var vec1, vec2, ret; before(function () { vec1 = new Victor(20, 40); vec2 = new Victor(30, 20); ret = vec1.addX(vec2); }); it('should be chainable', function () { expect(ret).to.equal(vec1); }); it('should add only the X axis of a vector', function () { expect(vec1).to.have.property('x', 50); expect(vec1).to.have.property('y', 40); }); }); describe('#addY()', function () { var vec1, vec2, ret; before(function () { vec1 = new Victor(20, 40); vec2 = new Victor(30, 20); ret = vec1.addY(vec2); }); it('should be chainable', function () { expect(ret).to.equal(vec1); }); it('should add only the Y axis of a vector', function () { expect(vec1).to.have.property('x', 20); expect(vec1).to.have.property('y', 60); }); }); describe('#add()', function () { var vec1, vec2, ret; before(function () { vec1 = new Victor(20, 40); vec2 = new Victor(30, 20); ret = vec1.add(vec2); }); it('should be chainable', function () { expect(ret).to.equal(vec1); }); it('should add a vector', function () { expect(vec1).to.have.property('x', 50); expect(vec1).to.have.property('y', 60); }); }); describe('#subtractX()', function () { var vec1, vec2, ret; before(function () { vec1 = new Victor(30, 20); vec2 = new Victor(20, 40); ret = vec1.subtractX(vec2); }); it('should be chainable', function () { expect(ret).to.equal(vec1); }); it('should subtract only the X axis of a vector', function () { expect(vec1).to.have.property('x', 10); expect(vec1).to.have.property('y', 20); }); }); describe('#subtractY()', function () { var vec1, vec2, ret; before(function () { vec1 = new Victor(30, 20); vec2 = new Victor(20, 40); ret = vec1.subtractY(vec2); }); it('should be chainable', function () { expect(ret).to.equal(vec1); }); it('should subtract only the Y axis of a vector', function () { expect(vec1).to.have.property('x', 30); expect(vec1).to.have.property('y', -20); }); }); describe('#subtract()', function () { var vec1, vec2, ret; before(function () { vec1 = new Victor(30, 20); vec2 = new Victor(20, 40); ret = vec1.subtract(vec2); }); it('should be chainable', function () { expect(ret).to.equal(vec1); }); it('should subtract a vector', function () { expect(vec1).to.have.property('x', 10); expect(vec1).to.have.property('y', -20); }); }); describe('#divideX()', function () { var vec, vec2, ret; before(function () { vec = new Victor(30, 20); vec2 = new Victor(2, 2); ret = vec.divideX(vec2); }); it('should be chainable', function () { expect(ret).to.equal(vec); }); it('should divide the X axis by 2', function () { expect(vec).to.have.property('x', 15); expect(vec).to.have.property('y', 20); }); }); describe('#divideY()', function () { var vec, vec2, ret; before(function () { vec = new Victor(30, 20); vec2 = new Victor(2, 2); ret = vec.divideY(vec2); }); it('should be chainable', function () { expect(ret).to.equal(vec); }); it('should divide the Y axis by 2', function () { expect(vec).to.have.property('x', 30); expect(vec).to.have.property('y', 10); }); }); describe('#divide()', function () { var vec, vec2, ret; before(function () { vec = new Victor(30, 20); vec2 = new Victor(2, 2); ret = vec.divide(vec2); }); it('should be chainable', function () { expect(ret).to.equal(vec); }); it('should divide both vector axis by 2', function () { expect(vec).to.have.property('x', 15); expect(vec).to.have.property('y', 10); }); }); describe('#multiplyX()', function () { var vec, vec2, ret; before(function () { vec = new Victor(30, 20); vec2 = new Victor(2, 2); ret = vec.multiplyX(vec2); }); it('should be chainable', function () { expect(ret).to.equal(vec); }); it('should multiply the X axis by 2', function () { expect(vec).to.have.property('x', 60); expect(vec).to.have.property('y', 20); }); }); describe('#multiplyY()', function () { var vec, vec2, ret; before(function () { vec = new Victor(30, 20); vec2 = new Victor(2, 2); ret = vec.multiplyY(vec2); }); it('should be chainable', function () { expect(ret).to.equal(vec); }); it('should multiply the Y axis by 2', function () { expect(vec).to.have.property('x', 30); expect(vec).to.have.property('y', 40); }); }); describe('#multiply()', function () { var vec, vec2, ret; before(function () { vec = new Victor(30, 20); vec2 = new Victor(2, 2); ret = vec.multiply(vec2); }); it('should be chainable', function () { expect(ret).to.equal(vec); }); it('should multiply both vector axis by 2', function () { expect(vec).to.have.property('x', 60); expect(vec).to.have.property('y', 40); }); }); describe('#norm()', function () { var vec, ret; before(function () { vec = new Victor(13.37, 42.42); ret = vec.norm(); }); it('should be chainable', function () { expect(ret).to.equal(vec); }); it.skip('should?', function () { expect(vec).to.have.property('x'); expect(vec).to.have.property('y'); }); }); describe('#limit()', function () { var vec, ret; before(function () { vec = new Victor(30, 20); ret = vec.limit(20, 0.5); }); it('should be chainable', function () { expect(ret).to.equal(vec); }); it('should limit both vector axis by limit', function () { expect(vec).to.have.property('x', 15); expect(vec).to.have.property('y', 20); }); }); describe('#randomize()', function () { var topLeft = new Victor(-50, 100); var bottomRight = new Victor(300, -500); it('should be chainable', function () { var vec = new Victor(30, 20); expect(vec.randomize(topLeft, bottomRight)).to.equal(vec); }); it('should randomize both vector axis and respect the boundaries', function () { var i, count = 100; var vec = new Victor(30, 20); var minX = Math.min(topLeft.x, bottomRight.x); var maxX = Math.max(topLeft.x, bottomRight.x); var minY = Math.min(topLeft.y, bottomRight.y); var maxY = Math.max(topLeft.y, bottomRight.y); for (i = 0; i < count; i++) { vec.randomize(topLeft, bottomRight); expect(vec.x).to.be.within(minX, maxX); expect(vec.y).to.be.within(minY, maxY); } }); }); describe('#randomizeX()', function () { var topLeft = new Victor(-50, 100); var bottomRight = new Victor(300, -500); it('should be chainable', function () { var vec = new Victor(30, 20); expect(vec.randomizeX(topLeft, bottomRight)).to.equal(vec); }); it('should randomize only the X axis and respect the boundaries', function () { var i, count = 100; var vec = new Victor(30, 20); var y = vec.y; var minX = Math.min(topLeft.x, bottomRight.x); var maxX = Math.max(topLeft.x, bottomRight.x); for (i = 0; i < count; i++) { vec.randomizeX(topLeft, bottomRight); expect(vec).to.have.property('x') .that.is.within(minX, maxX); expect(vec).to.have.property('y', y); } }); }); describe('#randomizeY()', function () { var topLeft = new Victor(-50, 100); var bottomRight = new Victor(300, -500); it('should be chainable', function () { var vec = new Victor(30, 20); expect(vec.randomizeY(topLeft, bottomRight)).to.equal(vec); }); it('should randomize only the X axis and respect the boundaries', function () { var i, count = 100; var vec = new Victor(30, 20); var x = vec.x; var minY = Math.min(topLeft.y, bottomRight.y); var maxY = Math.max(topLeft.y, bottomRight.y); for (i = 0; i < count; i++) { vec.randomizeY(topLeft, bottomRight); expect(vec).to.have.property('y') .that.is.within(minY, maxY); expect(vec).to.have.property('x', x); } }); }); describe('#randomizeAny()', function () { var topLeft = new Victor(100, 100); var bottomRight = new Victor(300, 300); it('should be chainable', function () { var vec = new Victor(30, 20); expect(vec.randomizeAny(topLeft, bottomRight)).to.equal(vec); }); it('should randomize only one vector axis and respect the boundaries', function () { var vec, i, count = 100, originX = 50, originY = 50; var minX = Math.min(topLeft.x, bottomRight.x); var maxX = Math.max(topLeft.x, bottomRight.x); var minY = Math.min(topLeft.y, bottomRight.y); var maxY = Math.max(topLeft.y, bottomRight.y); for (i = 0; i < count; i++) { vec = new Victor(originX, originY); vec.randomizeAny(topLeft, bottomRight); if (vec.x !== originX) { expect(vec).to.have.property('x') .that.is.within(minX, maxX); expect(vec).to.have.property('y', originY); } else { expect(vec).to.have.property('y') .that.is.within(minY, maxY); expect(vec).to.have.property('x', originX); } } }); }); describe('#unfloat()', function () { var vec, ret; before(function () { vec = new Victor(30.333, 20.666); ret = vec.unfloat(); }); it('should be chainable', function () { expect(ret).to.equal(vec); }); it('should round both vector axis to integers', function () { expect(vec).to.have.property('x', 30); expect(vec).to.have.property('y', 21); }); }); describe('#mixX()', function () { var vec1, vec2, ret; before(function () { vec1 = new Victor(100, 100); vec2 = new Victor(200, 200); ret = vec1.mixX(vec2, 0.5); }); it('should be chainable', function () { expect(ret).to.equal(vec1); }); it('should interpolate the X axis half way', function () { expect(vec1).to.have.property('x', 150); expect(vec1).to.have.property('y', 100); }); }); describe('#mixY()', function () { var vec1, vec2, ret; before(function () { vec1 = new Victor(100, 100); vec2 = new Victor(200, 200); ret = vec1.mixY(vec2, 0.5); }); it('should be chainable', function () { expect(ret).to.equal(vec1); }); it('should interpolate the Y axis half way', function () { expect(vec1).to.have.property('x', 100); expect(vec1).to.have.property('y', 150); }); }); describe('#mix()', function () { var vec1, vec2, ret; before(function () { vec1 = new Victor(100, 100); vec2 = new Victor(200, 200); ret = vec1.mix(vec2, 0.5); }); it('should be chainable', function () { expect(ret).to.equal(vec1); }); it('should interpolate half way', function () { expect(vec1).to.have.property('x', 150); expect(vec1).to.have.property('y', 150); }); }); describe('#zero()', function () { var vec, ret; before(function () { vec = new Victor(100, 100); ret = vec.zero(); }); it('should be chainable', function () { expect(ret).to.equal(vec); }); it('should interpolate half way', function () { expect(vec).to.have.property('x', 0); expect(vec).to.have.property('y', 0); }); }); describe('#rotate()', function () { var vec, ret; before(function () { vec = new Victor(100, 100); ret = vec.rotate(90 * Math.PI / 180); }); it('should be chainable', function () { expect(ret).to.equal(vec); }); it('should set the rotation angle', function () { expect(vec).to.have.property('x', -100); expect(vec).to.have.property('y', 100); }); }); describe('#rotateDeg()', function () { var vec, ret; before(function () { vec = new Victor(100, 100); ret = vec.rotateDeg(90); }); it('should be chainable', function () { expect(ret).to.equal(vec); }); it('should set the rotation angle in degrees', function () { expect(vec).to.have.property('x', -100); expect(vec).to.have.property('y', 100); }); }); describe('#rotateBy()', function () { var vec, ret; before(function () { vec = new Victor(100, 100); ret = vec.rotateBy(45 * Math.PI / 180); }); it('should be chainable', function () { expect(ret).to.equal(vec); }); it('should rotate by the given angle', function () { expect(vec).to.have.property('x', -100); expect(vec).to.have.property('y', 100); }); }); describe('#rotateByDeg()', function () { var vec, ret; before(function () { vec = new Victor(100, 100); ret = vec.rotateByDeg(45); }); it('should be chainable', function () { expect(ret).to.equal(vec); }); it('should rotate by the given angle in degrees', function () { expect(vec).to.have.property('x', -100); expect(vec).to.have.property('y', 100); }); }); describe('#projectOnto()', function () { var vec1, vec2, var3, selfRet, perpRet, paraRet, middleRet; before(function () { vec1 = new Victor(100, 0); vec2 = new Victor(100, 100); vec3 = new Victor(0,100); vec4 = new Victor(200,0); selfRet = vec1.projectOnto(vec1); perpRet = vec1.clone().projectOnto(vec3); paraRet = vec1.clone().projectOnto(vec4); middleRet = vec1.clone().projectOnto(vec2); }); it('should be chainable', function () { expect(selfRet).to.equal(vec1); }); it('should project same vector onto itself without change', function() { expect(selfRet).to.have.property('x',100); expect(selfRet).to.have.property('y',0); }); it('should project orthogonal vectors into a zero-length vector', function () { expect(perpRet).to.have.property('x',0); expect(perpRet).to.have.property('y',0); }); it('shuld project parallel vectors into a vector of same direction and magnitude', function () { expect(paraRet).to.have.property('x', 100); expect(paraRet).to.have.property('y', 0); }); it('should project non-orthogonal non-parallel vectors correctly', function () { expect(middleRet).to.have.property('x', 50); expect(middleRet).to.have.property('y', 50); }); }); }); describe('regular instance methods', function () { describe('#clone()', function () { var vec1, vec2; before(function () { vec1 = new Victor(42, 21); vec2 = vec1.clone(); }); it('should return a clone of a vector', function () { expect(vec2).to.be.an.instanceof(Victor); expect(vec2).to.not.equal(vec1); }); it('should have the same values as the original', function () { expect(vec1.x).to.equal(vec2.x); expect(vec1.y).to.equal(vec2.y); }); }); describe('#dot()', function () { var vec1, vec2, ret; before(function () { vec1 = new Victor(42, 21); vec2 = new Victor(44, 42); ret = vec1.dot(vec2); }); it('should return the dot product of 2 vectors', function () { expect(ret).to.equal(2730); }); }); describe('#distanceX()', function () { var vec1, vec2, ret; before(function () { vec1 = new Victor(42, 21); vec2 = new Victor(44, 42); ret = vec1.distanceX(vec2); }); it('should return the distance between the X axis of 2 vectors', function () { expect(ret).to.equal(-2); }); }); describe('#distanceY()', function () { var vec1, vec2, ret; before(function () { vec1 = new Victor(42, 21); vec2 = new Victor(44, 42); ret = vec1.distanceY(vec2); }); it('should return the distance between the Y axis of 2 vectors', function () { expect(ret).to.equal(-21); }); }); describe.skip('#distance()', function () { var vec1, vec2, ret; before(function () { vec1 = new Victor(100, 100); vec2 = new Victor(200, 100); ret = vec1.distance(vec2); }); it('should return the euclidean distance between 2 vectors', function () { expect(ret).to.equal(-21); }); }); describe('#length()', function () { var vec, ret; before(function () { vec = new Victor(100, 100); ret = vec.length(); }); it('should return the length of the vector', function () { expect(Math.round(ret)).to.equal(141); }); }); describe('#isZero()', function () { var vec; before(function () { vec = new Victor(100, 100); vec.zero(); }); it('should return true if the vector is zero', function () { expect(vec.isZero()).to.equal(true); }); }); describe('#isEqualTo()', function () { var vec1, vec2, vec3; before(function () { vec1 = new Victor(100, 100); vec2 = new Victor(100, 120); vec3 = new Victor(100, 120); }); it('should return false if the vectors are not the same', function () { expect(vec1.isEqualTo(vec2)).to.equal(false); }); it('should return true if the vectors are the same', function () { expect(vec2.isEqualTo(vec3)).to.equal(true); }); }); }); describe('utility methods', function () { describe('#toString()', function () { var vec, ret; before(function () { vec = new Victor(100, 200); ret = vec.toString(); }); it('should return a string representation of the vector', function () { expect(ret).to.be.a('string'); expect(ret).to.have.string('x:100, y:200'); }); }); describe('#toArray()', function () { var vec, ret; before(function () { vec = new Victor(100, 200); ret = vec.toArray(); }); it('should return an array representation of the vector', function () { expect(ret).to.be.instanceof(Array); expect(ret).to.eql([ 100, 200 ]); }); }); describe('#toObject()', function () { var vec, ret; before(function () { vec = new Victor(100, 200); ret = vec.toObject(); }); it('should return an object representation of the vector', function () { expect(ret).to.be.instanceof(Object); expect(ret).to.eql({ x: 100, y: 200 }); }); }); });