From 0646e25e49d6c2632fe0ed0d38d71993888b2170 Mon Sep 17 00:00:00 2001 From: Rudi-Np Date: Thu, 18 Jul 2024 16:24:20 +0300 Subject: [PATCH] full coverage for the geometry-calculation project --- modules/ecs6-class/line.js | 16 +++- modules/ecs6-class/point.js | 11 +++ modules/geometry-calculation.js | 31 ++++++- package-lock.json | 18 ++-- package.json | 3 +- test/modules/ecs6-class/line.test.js | 79 +++++++++++++++++ test/modules/ecs6-class/point.test.js | 54 ++++++++++++ test/modules/geometry-calculation.test.js | 101 ++++++++++++++++++++++ 8 files changed, 297 insertions(+), 16 deletions(-) create mode 100644 test/modules/ecs6-class/line.test.js create mode 100644 test/modules/ecs6-class/point.test.js create mode 100644 test/modules/geometry-calculation.test.js diff --git a/modules/ecs6-class/line.js b/modules/ecs6-class/line.js index b3bf0f7..06e113c 100644 --- a/modules/ecs6-class/line.js +++ b/modules/ecs6-class/line.js @@ -9,8 +9,12 @@ class Line { } calculateSlope = () => { - this.slope = (this.point1.y - this.point2.y) / (this.point1.x - this.point2.x) - } + if ((this.point1.x - this.point2.x)===0) + throw new Error('error division by 0'); + + this.slope = (this.point1.y - this.point2.y) / (this.point1.x - this.point2.x); + } + calculateNOfLineFunction = () => { this.n = this.point1.y - this.slope * this.point1.x @@ -30,10 +34,14 @@ class Line { return new Point({ x, y }) } + getPointByY(y) { - let x = (y - this.slope) / this.n; + if (this.slope === 0) + throw new Error("don't divide by 0") + let x = (y - this.n) / this.slope; return new Point({ x, y }) } -} + +} module.exports = Line \ No newline at end of file diff --git a/modules/ecs6-class/point.js b/modules/ecs6-class/point.js index e81b4a4..b1569eb 100644 --- a/modules/ecs6-class/point.js +++ b/modules/ecs6-class/point.js @@ -1,14 +1,25 @@ class Point { constructor({x=0, y=0}={}) { + if (!(typeof (x) === "number") || !(typeof (y) === "number")) + throw new Error('x and y must be of the number type') this.x = x; this.y = y; } moveVertical(value) { + if (typeof value !== 'number') { + throw new Error('Invalid input. value should be a number.'); + } this.y += value; } moveHorizontal(value) { + if (typeof value !== 'number') { + throw new Error('Invalid input. value should be a number.'); + } this.x += value; } } + + + module.exports = Point \ No newline at end of file diff --git a/modules/geometry-calculation.js b/modules/geometry-calculation.js index 66856dc..44abe1d 100644 --- a/modules/geometry-calculation.js +++ b/modules/geometry-calculation.js @@ -1,13 +1,27 @@ const Line = require('./ecs6-class/line') +const Point=require('./ecs6-class/point') const calculateDistance = (point1, point2) => { + if(!(point1 instanceof Point)&&!(point2 instanceof Point)) + throw new Error('point1 and point2 must be of the Point type') + if (!(point1 instanceof Point)) + throw new Error('point1 must be of the Point type') + if (!(point2 instanceof Point)) + throw new Error('point2 must be of the Point type') 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 instanceof Line)&&!(line2 instanceof Line)) + throw new Error('line1 and line2 must be of the Line type') + if (!(line1 instanceof Line)) + throw new Error('line1 must be of the Line type') + if (!(line2 instanceof Line)) + throw new Error('line2 must be of the Line type') if (line1.slope === line2.slope) { if (line1.n === line2.n) { return true @@ -23,18 +37,27 @@ const calculateJunctionPoint = (line1, line2) => { } } + const isPointOnLine = (line, point) => { - const proxyLine = new Line(line.point1, point) + if (!(line instanceof Line)&&!(point instanceof Point)) { + throw new Error("The object line should be of the Line type and object point must be of the Point type") + } + if (!(line instanceof Line)) { + throw new Error("The object line should be of the Line type") + } + if (!(point instanceof Point)) { + throw new Error("The object point should be of the Point type") + } + const proxyLine = new Line({ point1: line.point1, point2: point }) proxyLine.calculateSlope() if (line.slope === proxyLine.slope) { proxyLine.calculateNOfLineFunction() - if (line.n === proxyLine.n2) { + if (line.n === proxyLine.n) { return true } } return false } - module.exports = { calculateDistance, calculateJunctionPoint, diff --git a/package-lock.json b/package-lock.json index 61f4a09..e6f6f63 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1053,10 +1053,11 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "license": "MIT", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -1401,8 +1402,9 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "license": "MIT", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -1586,7 +1588,8 @@ }, "node_modules/is-number": { "version": "7.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "engines": { "node": ">=0.12.0" } @@ -2803,7 +2806,8 @@ }, "node_modules/to-regex-range": { "version": "5.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dependencies": { "is-number": "^7.0.0" }, diff --git a/package.json b/package.json index 56bf17b..7b41f03 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":"npm run test -- --coverage" }, "dependencies": { "jest": "^29.7.0" diff --git a/test/modules/ecs6-class/line.test.js b/test/modules/ecs6-class/line.test.js new file mode 100644 index 0000000..3e43def --- /dev/null +++ b/test/modules/ecs6-class/line.test.js @@ -0,0 +1,79 @@ + const Line =require('../../../modules/ecs6-class/line') + const Point = require('../../../modules/ecs6-class/point') +const{calculateSlope}=require('../../../modules/ecs6-class/line') + +const mockConstructor1=jest.fn(constructor) +const mockConstructor=jest.fn(constructor) +const mockCalculateSlope=jest.fn(calculateSlope) + + describe('constructor tests',()=>{ + + it('should create a Line instance with correct slope, and n values',()=>{ + const l=new Line({n:4,slope:7}) + expect(l.slope).toBe(7) + expect(l.n).toBe(4) + + }) +it('should throw an error for invalid input types',()=>{ + const l=new Line({n:true,slope:7}) + expect(()=>l.toThrow('Invalid input should be numbers')) + }) +}) + describe('calculacalculateSlope function test',()=>{ + it('calculacalculateSlope should throw an error when dividing by zeroteSlope',()=>{ + const p1=mockConstructor(new Point({x:5,y:6})) + const p2=mockConstructor(new Point({x:5,y:3})) + const line=mockConstructor1(new Line({point1:p1,point2:p2})) + expect(()=>line.calculateSlope()).toThrowError('error division by 0') + + }) + it('should return 2',()=>{ + const line=mockConstructor1(new Line({point1:new Point({x:4,y:8}),point2:new Point({x:5,y:10})})) + line.calculateSlope() + expect(line.slope).toBe(2) + + }) + }) + describe(' getPointByY',()=>{ + it('should return new point acoording the y value',()=>{ + const line=mockConstructor1(new Line({point1:new Point({x:0,y:4}),n:6,slope:2})); + const l=line.getPointByY(line.point1.y) + expect(l).toEqual(new Point({x:-1,y:4})) + }) + it('shuold throw error when divison by zero',()=>{ + const line=mockConstructor1(new Line({point1:new Point({x:0,y:4}),point2:new Point({x:0,y:6}),slope:0})); + expect(()=>line.getPointByY(line.point1.y)).toThrow("don't divide by 0") + }) + }) + describe('getPointByX tests',()=>{ + it('check if the function return the currect value of y',()=>{ + const line=mockConstructor1(new Line({point1:new Point({x:8,y:0}),n:7,slope:5})) + const l=line.getPointByX(line.point1.x) + expect(l).toEqual(new Point({x:8,y:47})) + }) + }) + + describe('getPointOnXAsis tests', () => { + it('should return the point on the x-axis with y-coordinate 0', () => { + const line =mockConstructor1(new Line({ point1: new Point({ x: 8, y: 0 }), n: 7, slope: 5 })) + const pointOnXAxis = line.getPointOnXAsis(); + expect(pointOnXAxis).toEqual(new Point({ x: -1.4, y: 0 })); + }); + }); + describe('getPointOnYAsis tests', () => { + it('should return the point on the y-axis with x-coordinate 0', () => { + const line =mockConstructor1(new Line({ point1: new Point({ x: 0, y: 6 }), n: 7, slope: 5 })) ; + const pointOnYAxis = line.getPointOnYAsis(); + expect(pointOnYAxis).toEqual(new Point({ x: 0, y: 7 })); + }); + }); + + describe('calculateNOfLineFunction tests',()=>{ + it('should update the n with the corrent value',()=>{ + const l=mockConstructor1(new Line({point1:new Point({x:0,y:0}),point2:new Point({x:2,y:2}),slope:5})) + mockCalculateSlope(l.calculateSlope()) + l.calculateNOfLineFunction() + expect(l.n).toEqual(0) + }) + }) + \ No newline at end of file diff --git a/test/modules/ecs6-class/point.test.js b/test/modules/ecs6-class/point.test.js new file mode 100644 index 0000000..0d8b581 --- /dev/null +++ b/test/modules/ecs6-class/point.test.js @@ -0,0 +1,54 @@ + +const Point = require('../../../modules/ecs6-class/point'); + + +const mockConstructor = jest.fn(constructor); + +describe('Constructor tests', () => { + it ('check if the constructor get variable' ,()=>{ + const point=new Point({x:1,y:2}) + expect(point.x).toBe(1) + expect(point.y).toBe(2) +}) + +it('should throw an error for invalid input types', () => { + expect(() => new Point({ x:"rudi",y:'5'})).toThrowError('x and y must be of the number type'); +}) +it('should throw error when the values is not number type', () => { + expect(() => new Point({ x: "#", y: 4 })).toThrowError('x and y must be of the number type'); +}) +it('should throw error when the values is not number type', () => { + expect(() => new Point({ x: 2, y: false })).toThrowError('x and y must be of the number type'); +}) +it('Point constructor should set default values if no parameters are provided', () => { + const point=new Point() + expect(point.x).toBe(0) + expect(point.y).toBe(0) + +}) + +}); + describe('check the function moveVertical',()=>{ + it('moveVertical should update the y coordinate correctly',()=>{ + const point = mockConstructor(new Point({ x: 1, y: 2 })) + point.moveVertical(3); + expect(point.y).toBe(5); + }) + it('moveVertical should only accept a number as input',()=>{ + const point = mockConstructor(new Point({ x: 0, y: 8 })) + expect(() => point.moveVertical('5')).toThrow('Invalid input. value should be a number.'); + }) + }) + describe('check the function moveHorizontal',()=>{ + it('moveHorizontal should update the y coordinate correctly',()=>{ + const point=mockConstructor(new Point(0,0)); + point.moveHorizontal(6) + expect(point.x).toBe(6) + + }) + it('moveHorizontal should only accept a number as input',()=>{ + const point=mockConstructor(new Point({x:4,y:5})) + expect(() => point.moveHorizontal('invalid')).toThrow('Invalid input. value should be a number.'); + }) + +}) diff --git a/test/modules/geometry-calculation.test.js b/test/modules/geometry-calculation.test.js new file mode 100644 index 0000000..2fc11ba --- /dev/null +++ b/test/modules/geometry-calculation.test.js @@ -0,0 +1,101 @@ +const Line = require('../../modules/ecs6-class/line') +const Point = require('../../modules/ecs6-class/point') +const {calculateDistance,calculateJunctionPoint,isPointOnLine}=require('../../modules/geometry-calculation') + +const mockConstructor=jest.fn(constructor) +const mockConstructor1=jest.fn(constructor) + +describe('calculateDistance tests',()=>{ + it('should return the distance',()=>{ + const line=mockConstructor1(new Line({point1:new Point({x:0,y:0}),point2:new Point({x:0,y:0})})) + const dis=calculateDistance(line.point1,line.point2) + expect(dis).toBe(0) + }) + it('should throw error when the function calculateDistance get values that not from point type',()=>{ + const point1=mockConstructor1(new Line({n:7,slope:4})) + const point2=mockConstructor1(new Line({n:7,slope:4})) + expect(()=>calculateDistance(point1,point2)).toThrowError('point1 and point2 must be of the Point type') + }) + it('should throw error when point1 is not of point type',()=>{ + const point1=mockConstructor1(new Line({n:7,slope:4})) + const point2=mockConstructor(new Point({x:5,y:9})) + expect(()=>calculateDistance(point1,point2)).toThrowError('point1 must be of the Point type') + }) + it('should throw error when point2 is not of point type',()=>{ + const point1=mockConstructor(new Point({x:5,y:9})) + const point2= mockConstructor1(new Line({n:7,slope:4})) + expect(()=>calculateDistance(point1,point2)).toThrowError('point2 must be of the Point type') + }) +}) +describe('calculateJunctionPoint tests',()=>{ + it('should throw error when line1 and line2 is not of line type',()=>{ + const line1=mockConstructor(new Point({x:1,y:2})) + const line2=mockConstructor(new Point({x:1,y:2})) + expect(()=>calculateJunctionPoint(line1,line2)).toThrowError('line1 and line2 must be of the Line type') + }) + it('should throw error when line1 is not of line type',()=>{ + const line1=mockConstructor(new Point({x:1,y:2})) + const line2=mockConstructor1(new Line({point1:new Point({x:1,y:2})})) + expect(()=>calculateJunctionPoint(line1,line2)).toThrowError('line1 must be of the Line type') + }) + it('should throw error when line2 is not of line type',()=>{ + const line1=mockConstructor1(new Line({point1:new Point({x:1,y:2})})) + const line2=mockConstructor(new Point({x:1,y:2})) + expect(()=>calculateJunctionPoint(line1,line2)).toThrowError('line2 must be of the Line type') + }) + + it('',()=>{ + const line1=new Line({n:8,slope:7}) + const line2=new Line({n:8,slope:7}) + const t=calculateJunctionPoint(line1,line2) + expect(t).toBe(true) + }) + it('',()=>{ + const line1=new Line({n:8,slope:7}) + const line2=new Line({n:5,slope:7}) + const t=calculateJunctionPoint(line1,line2) + expect(t).toBe(false) + }) + it('',()=>{ + const line1=new Line({n:8,slope:9}) + const line2=new Line({n:5,slope:7}) + const t=calculateJunctionPoint(line1,line2) + expect(t).toEqual(new Point({x:-1.5,y:-5.5})) + }) +}) +describe('isPointOnLine tests',()=>{ + it('should throw error when line is not of line type &point is not of point type ',()=>{ + const line=mockConstructor1(new Point({x:4,y:6})) + const point=mockConstructor(new Line({n:1,slope:8})) + expect(()=>isPointOnLine(line,point)).toThrowError("The object line should be of the Line type and object point must be of the Point type") + }) + it('should throw error when line is not of line type',()=>{ + const line=mockConstructor1(new Point({x:4,y:6})) + const point=mockConstructor(new Point({x:1,y:8})) + expect(()=>isPointOnLine(line,point)).toThrowError("The object line should be of the Line type") + }) + it('should throw error when point is not of point type',()=>{ + const line=mockConstructor1(new Line({n:4,slope:6})) + const point=mockConstructor(new Line({n:1,slope:8})) + expect(()=>isPointOnLine(line,point)).toThrowError("The object point should be of the Point type") + }) + it('',()=>{ + const line=new Line({point1:new Point({x:7,y:10}),slope:1}) + const point=new Point({x:4,y:8}) + const result=isPointOnLine(line,point) + expect(result).toBe(false) + }) + it('',()=>{ + const line=new Line({point1:new Point({x:7,y:10}),slope:1,n:4}) + const point=new Point({x:6,y:9}) + const result=isPointOnLine(line,point) + expect(result).toBe(false) + }) + it('',()=>{ + const line=new Line({point1:new Point({x:7,y:10}),slope:1,n:3}) + const point=new Point({x:6,y:9}) + const result=isPointOnLine(line,point) + expect(result).toBe(true) + }) + +})