diff --git a/modules/ecs6-class/line.js b/modules/ecs6-class/line.js index 826c675..0b6777b 100644 --- a/modules/ecs6-class/line.js +++ b/modules/ecs6-class/line.js @@ -2,6 +2,26 @@ const Point = require("./point"); class Line { constructor({ point1 = new Point(), point2 = new Point(), n = undefined, slope = undefined }) { + if (typeof(slope) !== "undefined" && typeof(slope) !== "number") { + throw new Error("slope is not valid!") + } + + if (typeof(n) !== "undefined" && typeof(n) !== "number") { + throw new Error("n is not valid!") + } + + if ((!(point1 instanceof Point))&& (!(point2 instanceof Point))) { + throw new Error("point1 and point2 not instance of 'Point'!") + } + + if (!(point1 instanceof Point)) { + throw new Error("point1 not instance of 'Point'!") + } + + if ( !(point2 instanceof Point)) { + throw new Error("point2 not instance of 'Point'!") + } + this.point1 = point1; this.point2 = point2; this.slope = slope; @@ -26,11 +46,25 @@ class Line { getPointByX(x) { + if (x === undefined) { + throw new Error('x is undefined!') + } + if (typeof (x) !== "number") { + throw new Error("x is not a number!") + } + let y = this.slope * x + this.n return new Point({ x, y }) } getPointByY(y) { + if (y === undefined) { + throw new Error('y is undefined!') + } + if (typeof (y) !== "number") { + throw new Error("y is not a number!") + } + let x = (y - this.n) / this.slope; return new Point({ x, y }) } diff --git a/modules/ecs6-class/point.js b/modules/ecs6-class/point.js index e81b4a4..308ffb0 100644 --- a/modules/ecs6-class/point.js +++ b/modules/ecs6-class/point.js @@ -1,12 +1,30 @@ class Point { - constructor({x=0, y=0}={}) { + constructor({ x = 0, y = 0 } = {}) { + if(typeof(x)!=="number"){ + throw new Error('x is not a number!') + } + if(typeof(y)!=="number"){ + throw new Error('y is not a number!') + } this.x = x; this.y = y; } moveVertical(value) { + if (value === undefined) { + throw new Error('the value is undefined!') + } + if (typeof (value) != "number") { + throw new Error("the value is not a number!") + } this.y += value; } moveHorizontal(value) { + if (value === undefined) { + throw new Error('the value is undefined!') + } + if (typeof (value) != "number") { + throw new Error("the value is not a number!") + } this.x += value; } } diff --git a/modules/geometry-calculation.js b/modules/geometry-calculation.js index 6e11643..bea8c49 100644 --- a/modules/geometry-calculation.js +++ b/modules/geometry-calculation.js @@ -1,13 +1,45 @@ -const Line = require('./ecs6-class/line') +const Line = require('./ecs6-class/line'); +const Point = require('./ecs6-class/point'); const calculateDistance = (point1, point2) => { + if(point1===undefined && point2===undefined ){ + throw new Error('the function must get an arguments: point1 and point2!') + } + + if((!(point1 instanceof Point))&&(!(point2 instanceof Point))){ + throw new Error("the arguments: point1 and point2 are not instance of 'Point'!") + } + if(!(point1 instanceof Point)){ + throw new Error("point1 is not instance of 'Point'!") + } + if(!(point2 instanceof Point)){ + throw new Error("point2 is not instance of 'Point'!") + } let distanceX = (point2.x - point1.x) ** 2; - let distanceY = (point2.y - point2.y) ** 2; + let distanceY = (point2.y - point1.y) ** 2; const distance = Math.sqrt(distanceX + distanceY); return distance; } const calculateJunctionPoint = (line1, line2) => { + if(line1===undefined || line2===undefined ){ + throw new Error('the function must get an arguments:line1 and line2!') + } + if((!(line1 instanceof Line))&&(!(line2 instanceof Line))){ + throw new Error("line1 and line2 are not instance of 'Line'!") + } + if(!(line1 instanceof Line)){ + throw new Error("line1 is not instance of 'Line'!") + } + if(!(line2 instanceof Line)){ + throw new Error("line2 is not instance of 'Line'!") + } + if(line1.slope===undefined || line2.slope===undefined){ + throw new Error('slope is undefined!') + } + if(line1.n===undefined || line2.n===undefined){ + throw new Error('n is undefined!') + } if (line1.slope === line2.slope) { if (line1.n === line2.n) { return true @@ -22,8 +54,19 @@ const calculateJunctionPoint = (line1, line2) => { return junctionPoint } } - const isPointOnLine = (line, point) => { + if(line===undefined || point===undefined){ + throw new Error('the function must get an arguments: line and point!') + } + if((!(line instanceof Line))&&(!(point instanceof Point))){ + throw new Error("line and point are not instance of 'Line' and 'Point!") + } + if(!(line instanceof Line)){ + throw new Error("line is not instance of 'Line'!") + } + if(!(point instanceof Point)){ + throw new Error("point is not instance of 'Point!") + } const proxyLine = new Line({ point1: line.point1, point2: point }) proxyLine.calculateSlope() if (line.slope === proxyLine.slope) { @@ -39,4 +82,4 @@ module.exports = { calculateDistance, calculateJunctionPoint, isPointOnLine -} +} \ No newline at end of file diff --git a/package.json b/package.json index 56bf17b..24bf4cd 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,8 @@ "description": "practice unit tests in javascript", "main": "index.js", "scripts": { - "test": "jest" + "test": "jest", + "coverage":"npm run test -- --coverage" }, "dependencies": { "jest": "^29.7.0" @@ -19,5 +20,4 @@ "homepage": "https://github.com/gemtechd/build-tests#readme", "author": "gemtechd", "license": "ISC" - } diff --git a/test/modules/ecs6-class/line.test.js b/test/modules/ecs6-class/line.test.js new file mode 100644 index 0000000..33a8508 --- /dev/null +++ b/test/modules/ecs6-class/line.test.js @@ -0,0 +1,107 @@ +const Line = require("../../../modules/ecs6-class/line") +const Point = require("../../../modules/ecs6-class/point") +let point1 = new Point({ x: 3, y: 4 }) +let point2 = new Point({ x: 1, y: 2 }) +let line = new Line({ point1, point2 }) +let line1 = new Line({ point1, point2 }) +const myline = new Line({}) + +describe('LINE_CONSTRUCTOR', () => { + + it('should check the line object', () => { + expect(line1.point1.x).toBe(3) + expect(line1.point1.y).toBe(4) + expect(line1.point2.x).toBe(1) + expect(line1.point2.y).toBe(2) + expect(line1.n).toBe(undefined) + expect(line1.slope).toBe(undefined) + }) + + describe('ERROR_LINE_CONSTRUCTOR', () => { + it('should throw error if the line not valid', () => { + expect(() => new Line({ point1: new Line({}) })).toThrow("point1 not instance of 'Point'!") + expect(() => new Line({ point1: [1, 2, 3] })).toThrow("point1 not instance of 'Point'!") + expect(() => new Line({ point1: 'aaa' })).toThrow("point1 not instance of 'Point'!") + expect(() => new Line({ point2: new Line({}) })).toThrow("point2 not instance of 'Point'!") + expect(() => new Line({ point1: false })).toThrow("point1 not instance of 'Point'!") + expect(() => new Line({ n: 'hello' })).toThrow("n is not valid!") + expect(() => new Line({ slope: 'iii' })).toThrow("slope is not valid!") + expect(() => new Line({ point1: 'hello' , point2: 'hello' })).toThrow("point1 and point2 not instance of 'Point'!") + expect(() => new Line( {point1: 111 , point2: 222 })).toThrow("point1 and point2 not instance of 'Point'!") + }) + }) +}) + +describe('CALCULATE_SLOPE', () => { + it('should calculate the slope', () => { + line.calculateSlope() + expect(line.slope).toBe(1) + }) +}) + +describe('CALCULATE_N_LINE_FUNCTION', () => { + it('should calculate the n', () => { + line.calculateNOfLineFunction() + expect(line.n).toBe(1) + }) +}) + +describe('RETURN_THE_POINT_ON_X_ASIS', () => { + it('should return a point on x axis', () => { + expect(line.getPointOnXAsis()).toEqual({ x: -1, y: 0 }) + }) + it('mock function on getPointOnXAsis function', () => { + jest.spyOn(line1, 'getPointByY').mockImplementation((y) => { + return { x: 0, y }; + }); + const points = line.getPointOnYAsis(); + expect(points).toEqual({ x: 0, y: 1 }); + }) +}) + +describe('RETURN_THE_POINT_ON_Y_ASIS', () => { + it('should return a point on y axis', () => { + expect(line.getPointOnYAsis()).toEqual({ x: 0, y: 1 }) + }) + it('mock function on getPointOnYAsis function', () => { + jest.spyOn(line1, 'getPointByX').mockImplementation((x) => { + return { x, y: 0 }; + }); + const points = line.getPointOnXAsis(); + expect(points).toEqual({ x: -1, y: 0 }); + }) +}) + +describe('GET_POINT_BY_X', () => { + it('should return y by x', () => { + expect(line.getPointByX(2)).toEqual({ x: 2, y: 3 }) + }) + describe('ERROR', () => { + it('should throw error if the function:"getPointByX" not get/get not valid arguments', () => { + expect(() => line.getPointByX()).toThrow('x is undefined!') + expect(() => line.getPointByX(true)).toThrow('x is not a number!') + expect(() => line.getPointByX(() => false)).toThrow('x is not a number!') + expect(() => line.getPointByX([1, 2, 3, 4])).toThrow('x is not a number!') + expect(() => line.getPointByX({ x: 1, y: 2 })).toThrow('x is not a number!') + }) + }) +}) + +describe('GET_POINT_BY_Y', () => { + it('should return x by y', () => { + expect(line.getPointByY(9)).toEqual({ x: 8, y: 9 }) + }) + describe('ERROR', () => { + it('should throw error if the function:"getPointByY" not get/get not valid arguments', () => { + expect(() => line.getPointByY()).toThrow('y is undefined!') + expect(() => line.getPointByY(true)).toThrow('y is not a number!') + expect(() => line.getPointByY(() => false)).toThrow('y is not a number!') + expect(() => line.getPointByY([1, 2, 3, 4])).toThrow('y is not a number!') + expect(() => line.getPointByY({ x: 1, y: 2 })).toThrow('y is not a number!') + }) + }) +}) + + + + diff --git a/test/modules/ecs6-class/point.test.js b/test/modules/ecs6-class/point.test.js new file mode 100644 index 0000000..ad552de --- /dev/null +++ b/test/modules/ecs6-class/point.test.js @@ -0,0 +1,81 @@ +const Point = require('../../../modules/ecs6-class/point') + +describe('POINT_CONSTRUCTOR', () => { + let mypoint = new Point() + it('should check the point object', () => { + expect(mypoint.x).toBe(0) + expect(mypoint.y).toBe(0) + }) + describe('CONSTRUCTOR_POINT_ERROR', () => { + it('should throw error if the point not valid', () => { + expect(() => new Point({ x: 'x', y: 'y' })).toThrow('x is not a number!') + expect(() => new Point({ x: 'x' })).toThrow('x is not a number!') + expect(() => new Point({ y: 'y' })).toThrow('y is not a number!') + expect(() => new Point({ x: true })).toThrow('x is not a number!') + expect(() => new Point({ y: false })).toThrow('y is not a number!') + expect(() => new Point({ x: ['a', 'b'] })).toThrow('x is not a number!') + expect(() => new Point({ y: ['c', 'd'] })).toThrow('y is not a number!') + expect(() => new Point({ x: ['a', 'b'], y: ['c', 'd'] })).toThrow('x is not a number!') + expect(() => new Point({ x: [true, true, false] })).toThrow('x is not a number!') + expect(() => new Point({ y: [false, true] })).toThrow('y is not a number!') + expect(() => new Point({ x: [true, false], y: [false, true] })).toThrow('x is not a number!') + expect(() => new Point({ x: () => true })).toThrow('x is not a number!') + expect(() => new Point({ y: () => false })).toThrow('y is not a number!') + expect(() => new Point({ x: () => { }, y: () => true })).toThrow('x is not a number!') + }) + }) +}) + +describe('MOVE_VERTICAL', () => { + it('should add to this.y the value', () => { + let point = new Point({}) + point.moveVertical(6) + expect(point).toEqual({ x: 0, y: 6 }); + }) + + it('should add to this.y the value', () => { + let point = new Point({ x: 2, y: 3 }) + point.moveVertical(6) + expect(point).toEqual({ x: 2, y: 9 }); + }) + + describe('ERROR', () => { + let mypoint = new Point() + it('should throw error if the function not get/get a valid argument', () => { + expect(() => mypoint.moveVertical(a => (a))).toThrow('the value is not a number!') + expect(() => mypoint.moveVertical(true)).toThrow('the value is not a number!') + expect(() => mypoint.moveVertical('aaa')).toThrow('the value is not a number!') + expect(() => mypoint.moveVertical(['aaa', 'bbb'])).toThrow('the value is not a number!') + expect(() => mypoint.moveVertical()).toThrow('the value is undefined!') + }) + }) +}) + +describe('MOVE_HORIZONTAL', () => { + + it('should add to this.x the value', () => { + let point = new Point({}) + point.moveHorizontal(6) + expect(point).toEqual({ x: 6, y: 0 }); + }) + + it('should add to this.x the value', () => { + let point = new Point({ x: 5, y: 2 }) + point.moveHorizontal(6) + expect(point).toEqual({ x: 11, y: 2 }); + }) + + describe('ERROR', () => { + let mypoint = new Point() + it('should throw error if the function not get/get a valid argument', () => { + expect(() => mypoint.moveHorizontal(v => (v))).toThrow('the value is not a number!') + expect(() => mypoint.moveHorizontal(true)).toThrow('the value is not a number!') + expect(() => mypoint.moveHorizontal('aaa')).toThrow('the value is not a number!') + expect(() => mypoint.moveHorizontal(['aaa', 'bbb'])).toThrow('the value is not a number!') + expect(() => mypoint.moveHorizontal()).toThrow('the value is undefined!') + }) + }) +}) + + + diff --git a/test/modules/geometry-calculation.test.js b/test/modules/geometry-calculation.test.js new file mode 100644 index 0000000..7e34436 --- /dev/null +++ b/test/modules/geometry-calculation.test.js @@ -0,0 +1,140 @@ +const Line = require("../../modules/ecs6-class/line") +const Point = require("../../modules/ecs6-class/point") +const { calculateDistance, calculateJunctionPoint, isPointOnLine } = require("../../modules/geometry-calculation") + + + +describe('CALCULATE_DISTANCE', () => { + let point1 = new Point({ x: 4, y: 3 }) + let point2 = new Point({ x: 3, y: 2 }) + let point3 = new Point({ x: 2, y: 2 }) + let point4 = new Point({ x: 2, y: 1 }) + let line1 = new Line({ point1, point2, slope: 2, n: 3 }) + let line2 = new Line({ point3, point4, slope: 2, n: 5 }) + it(' should return the distance between two points', () => { + expect(calculateDistance(point1, point2)).toBe(1.4142135623730951) + }) + describe('ERROR', () => { + it('shold throw error if the function "calculateDistance" not get/get not valid arguments', () => { + expect(() => calculateDistance()).toThrow('the function must get an arguments: point1 and point2!') + expect(() => calculateDistance(new Line({}), new Point({}))).toThrow("point1 is not instance of 'Point'!") + expect(() => calculateDistance(new Point({}), new Line({}))).toThrow("point2 is not instance of 'Point'!") + expect(() => calculateDistance('wow')).toThrow("the arguments: point1 and point2 are not instance of 'Point'!") + expect(() => calculateDistance(['a', 'b'])).toThrow("the arguments: point1 and point2 are not instance of 'Point'!") + expect(() => calculateDistance(new Line({}))).toThrow("the arguments: point1 and point2 are not instance of 'Point'!") + expect(() => calculateDistance(true)).toThrow("the arguments: point1 and point2 are not instance of 'Point'!") + expect(() => calculateDistance({})).toThrow("the arguments: point1 and point2 are not instance of 'Point'!") + expect(() => calculateDistance(line1, line2)).toThrow("the arguments: point1 and point2 are not instance of 'Point'!") + expect(() => calculateDistance(new Line({}), new Line({}))).toThrow("the arguments: point1 and point2 are not instance of 'Point'!") + expect(() => calculateDistance([], [])).toThrow("the arguments: point1 and point2 are not instance of 'Point'!") + expect(() => calculateDistance('a', 'b')).toThrow("the arguments: point1 and point2 are not instance of 'Point'!") + expect(() => calculateDistance(1, 2)).toThrow("the arguments: point1 and point2 are not instance of 'Point'!") + }) + }) +}) + +describe('CALCULATE_JUNCTION_POINT', () => { + let point1 = new Point({ x: 4, y: 3 }) + let point2 = new Point({ x: 3, y: 2 }) + let point3 = new Point({ x: 2, y: 2 }) + let point4 = new Point({ x: 2, y: 1 }) + let point5 = new Point({ x: 2, y: 2 }) + let line1 = new Line({ point1, point2, slope: 2, n: 3 }) + let line2 = new Line({ point3, point4, slope: 2, n: 5 }) + let line3 = new Line({ point3, point4, slope: 4, n: 3 }) + let line6 = new Line({ point5, point4, slope: 1, n: 3 }) + + it('should return true when both lines are the same', () => { + expect(calculateJunctionPoint(line1, line1)).toBe(true) + }) + it('should return false if both lines are parallel', () => { + expect(calculateJunctionPoint(line1, line2)).toBe(false) + }) + + it('should return the junction point', () => { + expect(calculateJunctionPoint(line2, line3)).toEqual({ x: 1, y: 7 }) + }) + it('mock function on calculateJunctionPoint function', () => { + jest.spyOn(line1, 'getPointByX').mockImplementation((y) => { + return { x: 0, y }; + }); + + const lines = calculateJunctionPoint(line6, line6); + + expect(lines).toEqual(true); + }) + describe('ERROR', () => { + it('shold throw error if the function "calculateJunctionPoint" not get/get not valid arguments', () => { + expect(() => calculateJunctionPoint()).toThrow('the function must get an arguments:line1 and line2!') + expect(() => calculateJunctionPoint(new Point({}), new Line({}))).toThrow("line1 is not instance of 'Line'!") + expect(() => calculateJunctionPoint(new Line({}), new Point({}))).toThrow("line2 is not instance of 'Line'!") + expect(() => calculateJunctionPoint(new Line({ point3, point3, n: 3, slope: undefined }), new Line({ point3, point3, slope: undefined }))).toThrow("slope is undefined!") + expect(() => calculateJunctionPoint(new Line({ point3, point3, n: undefined, slope: 2 }), new Line({ point3, point3, n: undefined, slope: 2 }))).toThrow("n is undefined!") + expect(() => calculateJunctionPoint('wow')).toThrow('the function must get an arguments:line1 and line2!') + expect(() => calculateJunctionPoint(['a', 'b'])).toThrow('the function must get an arguments:line1 and line2!') + expect(() => calculateJunctionPoint(new Line({}))).toThrow('the function must get an arguments:line1 and line2!') + expect(() => calculateJunctionPoint(true)).toThrow('the function must get an arguments:line1 and line2!') + expect(() => calculateJunctionPoint({})).toThrow('the function must get an arguments:line1 and line2!') + expect(() => calculateJunctionPoint(point1, point2)).toThrow("line1 and line2 are not instance of 'Line'!") + expect(() => calculateJunctionPoint(new Point({}), new Point({}))).toThrow("line1 and line2 are not instance of 'Line'!") + expect(() => calculateJunctionPoint([], [])).toThrow("line1 and line2 are not instance of 'Line'!") + expect(() => calculateJunctionPoint('a', 'b')).toThrow("line1 and line2 are not instance of 'Line'!") + expect(() => calculateJunctionPoint(1, 2)).toThrow("line1 and line2 are not instance of 'Line'!") + }) + }) +}) + +describe('IS_POINT_ON_LINE', () => { + let point1 = new Point({ x: 4, y: 3 }) + let point2 = new Point({ x: 3, y: 2 }) + let point3 = new Point({ x: 2, y: 2 }) + let point4 = new Point({ x: 2, y: 1 }) + let point5 = new Point({ x: 2, y: 2 }) + let point6 = new Point({ x: 1, y: 1 }) + let line1 = new Line({ point1, point2, slope: 2, n: 3 }) + let line2 = new Line({ point3, point4, slope: 2, n: 5 }) + let line4 = new Line({ point5, point6, slope: 1, n: 0 }) + let line5 = new Line({ point5, point4, slope: 1, n: 3 }) + let line6 = new Line({ point5, point4, slope: 1, n: 3 }) + it('should return true if the point on line', () => { + expect(isPointOnLine(line4, point6)).toBe(true) + }) + + it('should return false if the point on line', () => { + expect(isPointOnLine(line5, point6)).toBe(false) + }) + it('should return false if the point on line', () => { + expect(isPointOnLine(line1, point1)).toBe(false) + }) + + it('mock function on "isPointOnLine" function', () => { + jest.spyOn(line6, 'calculateSlope').mockImplementation((x) => { + return { x, y: 0 }; + }); + jest.spyOn(line6, 'calculateNOfLineFunction').mockImplementation((x) => { + return { x, y: 0 }; + }); + const points = isPointOnLine(line6, point6); + expect(points).toEqual(false); + }) + + describe('ERROR', () => { + it('shold throw error if the function "isPointOnLine" not get/get not valid arguments', () => { + expect(() => isPointOnLine()).toThrow('the function must get an arguments: line and point!') + expect(() => isPointOnLine(new Point({}), new Line({}))).toThrow("line and point are not instance of 'Line' and 'Point!") + expect(() => isPointOnLine('wow')).toThrow('the function must get an arguments: line and point!') + expect(() => isPointOnLine(['a', 'b'])).toThrow('the function must get an arguments: line and point!') + expect(() => isPointOnLine(new Line({}))).toThrow('the function must get an arguments: line and point!') + expect(() => isPointOnLine(true)).toThrow('the function must get an arguments: line and point!') + expect(() => isPointOnLine({})).toThrow('the function must get an arguments: line and point!') + expect(() => isPointOnLine(point1, point2)).toThrow("line is not instance of 'Line'") + expect(() => isPointOnLine(line1, line2)).toThrow("point is not instance of 'Point!") + expect(() => isPointOnLine(new Line({ point1: new Line({}) }), new Line({}))).toThrow("point1 not instance of 'Point'!") + expect(() => isPointOnLine(new Point({}), new Point({}))).toThrow("line is not instance of 'Line'!") + expect(() => isPointOnLine(point1, line1)).toThrow("line and point are not instance of 'Line' and 'Point!") + expect(() => isPointOnLine([], [])).toThrow("line and point are not instance of 'Line' and 'Point!") + expect(() => isPointOnLine('a', 'b')).toThrow("line and point are not instance of 'Line' and 'Point!") + expect(() => isPointOnLine(1, 2)).toThrow("line and point are not instance of 'Line' and 'Point!") + }) + }) +})