Skip to content

Commit

Permalink
feat(point): factory functions for correct types
Browse files Browse the repository at this point in the history
  • Loading branch information
MrTelanie committed Apr 18, 2019
1 parent dedcc9a commit a7314ec
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 63 deletions.
2 changes: 1 addition & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export { Point, IPoint };

/**
* @param {() => number} alg
* @return {Vector | Victor | IVector | Point | Ipoint | number}
* @return {(Vector | Victor | IVector | Point | IPoint) & number}
*/
export function calc(alg) {
return operatorCalc(alg);
Expand Down
102 changes: 66 additions & 36 deletions src/point.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @ts-nocheck
import {
cachedMethod,
cachedGetter,
Expand Down Expand Up @@ -43,7 +44,8 @@ function square(val) {
}

/**
* @extends {number}
* @typedef {APoint & number} APointType
* @abstract
*/
class APoint {
/**
Expand All @@ -69,15 +71,15 @@ class APoint {
}

/**
* @returns {APoint}
* @returns {APointType}
*/
normalize() {
const { length } = this;
return new this.constructor(this.x / length, this.y / length);
}

/**
* @returns {APoint}
* @returns {APointType}
*/
norm() {
return this.normalize();
Expand Down Expand Up @@ -195,6 +197,38 @@ class APoint {
return this.length;
}

/**
*
* @returns {number}
*/
get x() {
return this[AXES][X];
}

/**
*
* @throws SetNotImplementedError
*/
set x(_) {
throw new Error('set x() not implemented');
}

/**
*
* @returns {number}
*/
get y() {
return this[AXES][Y];
}

/**
*
* @throws SetNotImplementedError
*/
set y(_) {
throw new Error('set y() not implemented');
}

/**
*
* @throws GetNotImplementedError
Expand Down Expand Up @@ -222,6 +256,9 @@ cachedMethod(APoint, 'getRad');
cachedGetter(APoint, 'length');
cachedGetter(APoint, 'lengthSq');

/**
* @typedef {Point & number} PointType
*/
export class Point extends APoint {
/**
*
Expand Down Expand Up @@ -256,64 +293,57 @@ export class Point extends APoint {
}

/**
* @param {() => number} alg
* @param {(point: PointType) => number} alg
* @returns {this}
*/
calc(alg) {
return operatorCalc(alg, this);
}

/**
*
* @returns {Point}
*/
clone() {
return new Point(this.x, this.y);
}
}

/**
* @typedef {IPoint & number} IPointType
*/
export class IPoint extends APoint {
/**
*
* @returns {number}
*/
get x() {
return this[AXES][X];
}

/**
*
* @throws SetNotImplementedError
* @returns {PointType}
*/
set x(_) {
throw new Error('set x() not implemented');
}

/**
*
* @returns {number}
*/
get y() {
return this[AXES][Y];
}

/**
*
* @throws SetNotImplementedError
*/
set y(_) {
throw new Error('set y() not implemented');
}

toPoint() {
return new Point(this.x, this.y);
}
}

/**
* @param {() => number} alg
* @return {Point | IPoint | number}
* @return {PointType | IPointType}
*/
export function calc(alg) {
return operatorCalc(alg);
}

/**
* @typedef {(x: number, y: number) => PointType} point
* @param {number} x
* @param {number} y
* @return {PointType}
*/
export function point(x, y) {
return new Point(x, y);
}

/**
* @typedef {(x: number, y: number) => IPointType} ipoint
* @param {number} x
* @param {number} y
* @return {IPointType}
*/
export function ipoint(x, y) {
return new IPoint(x, y);
}
51 changes: 25 additions & 26 deletions test/point.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,37 @@
import { assert } from 'chai';
import { Point, IPoint, calc } from '../src/point';

const pointTest = (Vec2) => {
import {
Point, IPoint, point, ipoint, calc
} from '../src/point';

/**
* @param {ipoint | point} vec2
* @param {(typeof Point) | (typeof IPoint)} Vec2
*/
const pointTest = (vec2, Vec2) => {
it('should create x y values', () => {
const pos = new Vec2(5, 6);
const pos = vec2(5, 6);
assert.equal(pos.x, 5);
assert.equal(pos.y, 6);
});

it('should be calculated by assigned statement', () => {
const pos = new Vec2(5, 6);
const dir = new Vec2(1, 0);
const scale = new Vec2(() => dir * pos);
const pos = vec2(5, 6);
const dir = vec2(1, 0);
const scale = calc(() => dir * pos);

assert.equal(scale.x, 5);
assert.equal(scale.y, 0);
});

it('should be calculated by assigned statement with only numbers', () => {
const vec = new Vec2(() => 2 * 2 + 3);
const vec = calc(() => 2 * 2 + 3);

assert.equal(vec.x, 7);
assert.equal(vec.y, 7);
});

it('calling of calc should automatically detect assigned Point types', () => {
const pos = new Vec2(2, 2);
const pos = vec2(2, 2);
const vec = calc(() => 2 * pos + 3);

assert.instanceOf(vec, Vec2);
Expand All @@ -34,8 +40,8 @@ const pointTest = (Vec2) => {
});

it('should compares lengths of point.', () => {
const pos = new Vec2(1, 1);
const dir = new Vec2(2, 2);
const pos = vec2(1, 1);
const dir = vec2(2, 2);

assert.isTrue(dir > pos, `${dir} should be longer than ${pos}`);
assert.isTrue(dir.len > pos.len, `${dir} should be longer than ${pos}`);
Expand All @@ -44,22 +50,22 @@ const pointTest = (Vec2) => {
});

it('should change length to 1 when calling normalize', () => {
const pos = new Vec2(5, 6);
const pos = vec2(5, 6);
const dir = pos.normalize();

const length = dir.length;
assert(length > 0.99 && length < 1.01, `${dir} should have length 1, but is ${length}`);
});

it('should create polar coordinates when calling toAngles()', () => {
const dir1 = new Vec2(0, 1).normalize();
const dir1 = vec2(0, 1).normalize();
const rad = dir1.getRad();
assert.closeTo(rad, 1.57, 0.1);
});

it('should calculate correct angle between to points indepenetend of their lengths', () => {
const dir1 = new Vec2(0, 10);
const dir2 = new Vec2(-12, 0);
const dir1 = vec2(0, 10);
const dir2 = vec2(-12, 0);

const angle1 = dir1.angleTo(dir2);
const angle2 = dir1.normalize().angleTo(dir2.normalize());
Expand All @@ -69,7 +75,7 @@ const pointTest = (Vec2) => {
});

it('should create an array with x y values', () => {
const dir1 = new Vec2(7, 10);
const dir1 = vec2(7, 10);
const arr = dir1.toArray();

assert.closeTo(arr[0], 7, 0.1);
Expand All @@ -78,11 +84,11 @@ const pointTest = (Vec2) => {
};

describe('standard Point test.', () => {
pointTest(Point);
pointTest(point, Point);
});

describe('standard IPoint test.', () => {
pointTest(IPoint);
pointTest(ipoint, IPoint);
});

describe('special IPoint test.', () => {
Expand All @@ -107,7 +113,7 @@ describe('special IPoint test.', () => {

describe('special Point test.', () => {
it('should change x y values when setting directly', () => {
const pos = new Point(5, 6, 7);
const pos = new Point(5, 6);

pos.x = 27;
assert.equal(pos.x, 27);
Expand All @@ -124,10 +130,3 @@ describe('special Point test.', () => {
assert.equal(pos.y, 150);
});
});

describe('calc test.', () => {
it('calling of calc should generate only numbers if no point is in use', () => {
const vec = calc(() => 2 * 2 + 3);
assert.equal(vec, 7);
});
});

0 comments on commit a7314ec

Please sign in to comment.