From f95c08cde82e9ff2c129e2fd6bdd72a72e019c0e Mon Sep 17 00:00:00 2001 From: "R. Viangurt" Date: Mon, 9 Sep 2024 16:27:50 +0300 Subject: [PATCH] build tests --- modules/ecs6-class/line.js | 20 ++++++- modules/ecs6-class/point.js | 15 +++++ modules/geometry-calculation.js | 29 +++++++++- package.json | 3 +- tests/geometry-calculation.test.js | 90 ++++++++++++++++++++++++++++++ tests/line.test.js | 76 +++++++++++++++++++++++++ tests/point.test.js | 68 ++++++++++++++++++++++ 7 files changed, 297 insertions(+), 4 deletions(-) create mode 100644 tests/geometry-calculation.test.js create mode 100644 tests/line.test.js create mode 100644 tests/point.test.js diff --git a/modules/ecs6-class/line.js b/modules/ecs6-class/line.js index 826c675..b4d9d24 100644 --- a/modules/ecs6-class/line.js +++ b/modules/ecs6-class/line.js @@ -1,7 +1,13 @@ const Point = require("./point"); class Line { - constructor({ point1 = new Point(), point2 = new Point(), n = undefined, slope = undefined }) { + constructor({ point1 = new Point(), point2 = new Point(), n = undefined, slope = undefined }={}) { + if (!(point1 instanceof Point) || !(point2 instanceof Point)) { + throw new Error('the point must be point type') + } + if ((typeof (n) != "number" && typeof (n) != 'undefined') || (typeof (slope) != "number" && typeof (slope) != 'undefined')) { + throw new Error('the n and slope must be number type') + } this.point1 = point1; this.point2 = point2; this.slope = slope; @@ -26,11 +32,23 @@ class Line { getPointByX(x) { + if (!x && x != 0 ) { + throw new Error('not data') + } + if (typeof (x) != 'number') { + throw new Error('the parameter must be number type') + } let y = this.slope * x + this.n return new Point({ x, y }) } getPointByY(y) { + if (!y && y!=0) { + throw new Error('not data') + } + if (typeof (y) != 'number') { + throw new Error('the parameter must be number type') + } 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..f67b526 100644 --- a/modules/ecs6-class/point.js +++ b/modules/ecs6-class/point.js @@ -1,12 +1,27 @@ class Point { constructor({x=0, y=0}={}) { + if(typeof(x)!='number' || typeof(y)!='number'){ + throw new Error('the parameter must be number type') + } this.x = x; this.y = y; } moveVertical(value) { + if(!value){ + throw new Error('not data') + } + if(typeof(value)!='number'){ + throw new Error('the parameter must be number type') + } this.y += value; } moveHorizontal(value) { + if(!value){ + throw new Error('not data') + } + if(typeof(value)!='number'){ + throw new Error('the parameter must be number type') + } this.x += value; } } diff --git a/modules/geometry-calculation.js b/modules/geometry-calculation.js index 6e11643..8694b83 100644 --- a/modules/geometry-calculation.js +++ b/modules/geometry-calculation.js @@ -1,13 +1,26 @@ -const Line = require('./ecs6-class/line') +const Line = require('./ecs6-class/line'); +const Point = require('./ecs6-class/point'); const calculateDistance = (point1, point2) => { + if(!point2 || !point1){ + throw new Error('Not enough data'); + } + if(!(point1 instanceof Point) || !(point2 instanceof Point)){ + throw new Error('The argument must be type 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 || !line2){ + throw new Error('Not enough data') + } + if(!(line1 instanceof Line) || !(line2 instanceof Line)){ + throw new Error('The argument must be type line') + } if (line1.slope === line2.slope) { if (line1.n === line2.n) { return true @@ -24,6 +37,18 @@ const calculateJunctionPoint = (line1, line2) => { } const isPointOnLine = (line, point) => { + if(!line || !point){ + throw new Error('Not enough data') + } + if(!(line instanceof Line) && !(point instanceof Point)){ + throw new Error('The arguments must be type line and point') + } + if(!(line instanceof Line)){ + throw new Error('The argument must be type line') + } + if(!(point instanceof Point)){ + throw new Error('The argument must be type point') + } const proxyLine = new Line({ point1: line.point1, point2: point }) proxyLine.calculateSlope() if (line.slope === proxyLine.slope) { diff --git a/package.json b/package.json index 56bf17b..355814a 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", + "test:coverage":"jest --coverage" }, "dependencies": { "jest": "^29.7.0" diff --git a/tests/geometry-calculation.test.js b/tests/geometry-calculation.test.js new file mode 100644 index 0000000..acb265e --- /dev/null +++ b/tests/geometry-calculation.test.js @@ -0,0 +1,90 @@ +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', () => { + it('should return true if the arguments is true', () => { + const result = calculateDistance(new Point({ x: 0, y: 5 }), new Point({ x: 0, y: 8 })) + expect(result).toBe(3) + expect(calculateDistance(new Point({ x: 1, y: 5 }), new Point({ x: 5, y: 8 }))).toBe(5) + }) + + describe('ERRORS', () => { + test('should throw error if the parameters is false', () => { + expect(() => calculateDistance()).toThrow('Not enough data') + expect(() => calculateDistance(new Point({ x: 0, y: 5 }))).toThrow('Not enough data') + expect(() => calculateDistance({ x: 0, y: 5 }, new Point({ x: 0, y: 5 }))).toThrow('The argument must be type point') + expect(() => calculateDistance(2, 3)).toThrow('The argument must be type point') + }) + }) +}) + +describe('CALCULATE_JUCTION_POINT', () => { + test('should return true if the points is equals', () => { + let line1 = new Line({ point1: new Point({ x: 5, y: 8 }), point2: new Point({ x: 4, y: 7 }), n: 3, slope: 1 }) + let line2 = new Line({ point1: new Point({ x: 5, y: 8 }), point2: new Point({ x: 4, y: 7 }), n: 3, slope: 1 }) + const result = calculateJunctionPoint(line1, line2) + expect(result).toEqual(true) + }) + test('should return false if the lines is parallel lines', () => { + let line1 = new Line({ point1: new Point({ x: 2, y: 10 }), point2: new Point({ x: 3, y: 11 }), slope: 1 }) + line1.calculateNOfLineFunction() + let line2 = new Line({ point1: new Point({ x: 5, y: 8 }), point2: new Point({ x: 4, y: 7 }), n: 3, slope: 1 }) + const result = calculateJunctionPoint(line1, line2) + expect(result).toEqual(false) + }) + test('should return juction point', () => { + let line1 = new Line({ point1: new Point({ x: 5, y: 9 }), point2: new Point({ x: 3, y: 11 })}) + line1.calculateSlope() + line1.calculateNOfLineFunction() + let line2 = new Line({ point1: new Point({ x: 5, y: 8 }), point2: new Point({ x: 4, y: 7 }), n: 3, slope: 1 }) + const result = calculateJunctionPoint(line1, line2) + expect(result).toEqual({"x": 5.5, "y": 8.5}) + }) + + describe('ERRORS', () => { + test('should throw error if the parameters is false', () => { + let line1=new Line({ point1: new Point({ x: 5, y: 8 }), point2: new Point({ x: 4, y: 7 })}) + expect(() => calculateJunctionPoint()).toThrow('Not enough data') + expect(() => calculateJunctionPoint(line1)).toThrow('Not enough data') + expect(() => calculateJunctionPoint(2, 3)).toThrow('The argument must be type line') + expect(() => calculateJunctionPoint({point1: new Point({ x: 5, y: 8 }), point2: new Point({ x: 4, y: 7 })}, line1)).toThrow('The argument must be type line') + }) + }) +}) + +describe('IS_POINT_ON LINE_FUNCTION',()=>{ + test('should return true if the point on line',()=>{ + const p=new Point({x:5,y:6}) + const l=new Line({point1:new Point({x:4,y:5}),point2:new Point({x:6,y:7})}) + l.calculateSlope() + l.calculateNOfLineFunction() + expect(isPointOnLine(l,p)).toBe(true) + }) + + test('should return false if the point not on line',()=>{ + const p=new Point({x:5,y:6}) + const l=new Line({point1:new Point({x:4,y:7}),point2:new Point({x:6,y:5}),n:6}) + l.calculateSlope() + expect(isPointOnLine(l,p)).toBe(false) + }) + + test('should return false if the point not on line',()=>{ + const p=new Point({x:7,y:6}) + const l=new Line({point1:new Point({x:4,y:5}),point2:new Point({x:6,y:7}),slope:1}) + l.calculateNOfLineFunction() + expect(isPointOnLine(l,p)).toBe(false) + }) + + describe('ERRORS',()=>{ + test('should throw error if the parameters is false',()=>{ + expect(()=>isPointOnLine()).toThrow('Not enough data') + expect(()=>isPointOnLine(new Point())).toThrow('Not enough data') + expect(()=>isPointOnLine(2,3)).toThrow('The arguments must be type line and point') + expect(()=>isPointOnLine(2,new Point())).toThrow('The argument must be type line') + expect(()=>isPointOnLine({point1:new Point(),point2:new Point()},new Point())).toThrow('The argument must be type line') + expect(()=>isPointOnLine(new Line(),3)).toThrow('The argument must be type point') + expect(()=>isPointOnLine(new Line(),{x:1,y:4})).toThrow('The argument must be type point') + }) + }) +}) \ No newline at end of file diff --git a/tests/line.test.js b/tests/line.test.js new file mode 100644 index 0000000..2b2b99d --- /dev/null +++ b/tests/line.test.js @@ -0,0 +1,76 @@ +const Point = require("../modules/ecs6-class/point") +const Line = require("../modules/ecs6-class/line") + +describe('LINE', () => { + const l =new Line({point1:new Point({ x: 5, y: 8 }),point2:new Point({ x: 4, y: 7 })}) + describe('CONSTRACTOR',()=>{ + test('should build a line with the entered values', () => { + const l1 = new Line({point1:new Point({ x: 5,y:8 }),point2:new Point({ x: 3,y:5 }),n:4,slope:8}) + expect(l1).toMatchObject({"point1":{ "x": 5, "y": 8 },"point2":{ "x": 3, "y": 5 },"n":4,"slope":8}) + }) + test('should build a line with default parameters if not entered values',()=>{ + const l1=new Line() + expect(l1).toMatchObject({"point1":{ "x": 0, "y": 0 },"point2":{ "x": 0, "y": 0 },"n":undefined,"slope":undefined}) + }) + }) + test('should calculate true of slope',()=>{ + l.calculateSlope() + expect(l).toMatchObject({"slope":1}) + }) + test('should calculate true of n of line',()=>{ + l.calculateNOfLineFunction() + expect(l).toMatchObject({"n":3}) + }) + test('should return a correct Y value for X',()=>{ + const result=l.getPointByX(3) + expect(result).toEqual({"x":3,"y":6}) + }) + test('should return a correct X value for Y',()=>{ + const result=l.getPointByY(6) + expect(result).toEqual({"x":3,"y":6}) + }) + test('should return a correct Y value for x=0',()=>{ + const result=l.getPointOnYAsis() + expect(result).toEqual({"x":0,"y":3}) + }) + test('should return a correct X value for y=0',()=>{ + const result=l.getPointOnXAsis() + expect(result).toEqual({"x":-3,"y":0}) + }) + + describe('ERRORS',()=>{ + describe('CONSTRACTOR',()=>{ + test('should throw error if the parameters of wrong type',()=>{ + expect(()=>new Line({point1:{ x: 5, y: 8 }})).toThrow('the point must be point type') + expect(()=>new Line({point2:4})).toThrow('the point must be point type') + expect(()=>new Line({point2:"x:2,y:4"})).toThrow('the point must be point type') + expect(()=>new Line({n:"3"})).toThrow('the n and slope must be number type') + expect(()=>new Line({slope:true})).toThrow('the n and slope must be number type') + expect(()=>new Line({slope:{slope:5}})).toThrow('the n and slope must be number type') + expect(()=>new Line({slope:()=>{}})).toThrow('the n and slope must be number type') + }) + }) + describe('GET_POINT_BY_X FUNCTION',()=>{ + test('should throw error if not data',()=>{ + expect(()=>l.getPointByX()).toThrow('not data') + }) + test('should throw error if the parameter of wrong type',()=>{ + expect(()=>l.getPointByX("5")).toThrow('the parameter must be number type') + expect(()=>l.getPointByX(true)).toThrow('the parameter must be number type') + expect(()=>l.getPointByX(()=>{})).toThrow('the parameter must be number type') + expect(()=>l.getPointByX({x:5})).toThrow('the parameter must be number type') + }) + }) + describe('GET_POINT_BY_Y FUNCTION',()=>{ + test('should throw error if not data',()=>{ + expect(()=>l.getPointByY()).toThrow('not data') + }) + test('should throw error if the parameter of wrong type',()=>{ + expect(()=>l.getPointByY("5")).toThrow('the parameter must be number type') + expect(()=>l.getPointByY(true)).toThrow('the parameter must be number type') + expect(()=>l.getPointByY(()=>{})).toThrow('the parameter must be number type') + expect(()=>l.getPointByY({x:5})).toThrow('the parameter must be number type') + }) + }) + }) +}) \ No newline at end of file diff --git a/tests/point.test.js b/tests/point.test.js new file mode 100644 index 0000000..9d2e352 --- /dev/null +++ b/tests/point.test.js @@ -0,0 +1,68 @@ +const Point = require("../modules/ecs6-class/point") + +describe('POINT', () => { + const p = new Point({ x: 5, y: 8 }) + describe('CONSTRACTOR',()=>{ + it('should build a point with the entered values', () => { + const p1 = new Point({ x: 5, y: 8 }) + expect(p1).toEqual({ "x": 5, "y": 8 }) + }) + it('A point with the value 0 should be built if there is not enough data', () => { + const p1 = new Point({ x: 5 }) + expect(p1).toEqual({ "x": 5, "y": 0 }) + const p2 = new Point({ y: 5 }) + expect(p2).toEqual({ "x": 0, "y": 5 }) + const p3 = new Point({}) + expect(p3).toEqual({ "x": 0, "y": 0 }) + const p4 = new Point() + expect(p4).toEqual({ "x": 0, "y": 0 }) + }) + }) + describe('MOVE_POINT_HORIZONTAL', () => { + it('The point should be moved according to the entered value', () => { + const p1 = new Point({ x: 5, y: 8 }) + p1.moveHorizontal(5) + expect(p1).toEqual({ "x": 10, "y": 8 }) + }) + }) + describe('MOVE_POINT_VERTICAL', () => { + it('The point should be moved according to the entered value', () => { + const p1 = new Point({ x: 5, y: 8 }) + p1.moveVertical(5) + expect(p1).toEqual({ "x": 5, "y": 13 }) + }) + }) + + describe('ERRORS',()=>{ + describe('CONSTRACTOR',()=>{ + test('should throw error if the parameters not of number type',()=>{ + expect(()=>new Point({x:'5'})).toThrow('the parameter must be number type') + expect(()=>new Point({x:()=>{}})).toThrow('the parameter must be number type') + expect(()=>new Point({x:true})).toThrow('the parameter must be number type') + expect(()=>new Point({x:{x:5}})).toThrow('the parameter must be number type') + }) + }) + describe('MOVE_POINT_HORIZONTAL',()=>{ + test('should throw error if no data entered',()=>{ + expect(()=>p.moveHorizontal()).toThrow('not data') + }) + test('should throw error if the parameter not of number type',()=>{ + expect(()=>p.moveHorizontal('5')).toThrow('the parameter must be number type') + expect(()=>p.moveHorizontal(()=>{})).toThrow('the parameter must be number type') + expect(()=>p.moveHorizontal(true)).toThrow('the parameter must be number type') + expect(()=>p.moveHorizontal({x:5})).toThrow('the parameter must be number type') + }) + }) + describe('MOVE_POINT_VERTICAL',()=>{ + test('should throw error if no data entered',()=>{ + expect(()=>p.moveVertical()).toThrow('not data') + }) + test('should throw error if the parameter not of number type',()=>{ + expect(()=>p.moveVertical('5')).toThrow('the parameter must be number type') + expect(()=>p.moveVertical(()=>{})).toThrow('the parameter must be number type') + expect(()=>p.moveVertical(true)).toThrow('the parameter must be number type') + expect(()=>p.moveVertical({x:5})).toThrow('the parameter must be number type') + }) + }) + }) +}) \ No newline at end of file