From 6327ac5d53cc379197560e91ee25610c6e3bf50d Mon Sep 17 00:00:00 2001 From: saahil-mahato Date: Tue, 1 Oct 2024 12:46:47 +0545 Subject: [PATCH] feat: add geometry kite --- Geometry/Kite.js | 119 +++++++++++++++++++++++++++++++++++++ Geometry/Test/Kite.test.js | 74 +++++++++++++++++++++++ 2 files changed, 193 insertions(+) create mode 100644 Geometry/Kite.js create mode 100644 Geometry/Test/Kite.test.js diff --git a/Geometry/Kite.js b/Geometry/Kite.js new file mode 100644 index 0000000000..0cc314006c --- /dev/null +++ b/Geometry/Kite.js @@ -0,0 +1,119 @@ +/** + * This class represents a Kite and provides methods to calculate its area and perimeter. + * @see {@link https://en.wikipedia.org/wiki/Kite_(geometry)} + * @class + */ +export default class Kite { + /** @private */ + #sideA + + /** @private */ + #sideB + + /** @private */ + #diagonal1 + + /** @private */ + #diagonal2 + + /** + * Creates a kite instance. + * @constructor + * @param {number} sideA - The length of one pair of equal sides. + * @param {number} sideB - The length of the other pair of equal sides. + * @param {number} diagonal1 - The length of the first diagonal. + * @param {number} diagonal2 - The length of the second diagonal. + * @throws {Error} Will throw an error if any dimension is invalid. + */ + constructor(sideA, sideB, diagonal1, diagonal2) { + this.#validateDimension(sideA, 'sideA') + this.#validateDimension(sideB, 'sideB') + this.#validateDimension(diagonal1, 'diagonal1') + this.#validateDimension(diagonal2, 'diagonal2') + + this.#sideA = sideA + this.#sideB = sideB + this.#diagonal1 = diagonal1 + this.#diagonal2 = diagonal2 + } + + /** + * Validates that a dimension is a positive number. + * @private + * @param {number} value - The value to validate. + * @param {string} name - The name of the dimension (for error reporting). + * @throws {Error} Will throw an error if the value is not a positive number. + */ + #validateDimension(value, name) { + if (typeof value !== 'number' || isNaN(value) || value <= 0) { + throw new Error(`${name} must be a positive number.`) + } + } + + /** + * Calculates the area of the kite. + * @public + * @returns {number} The area of the kite. + */ + area() { + return (this.#diagonal1 * this.#diagonal2) / 2 + } + + /** + * Calculates the perimeter of the kite. + * @public + * @returns {number} The perimeter of the kite. + */ + perimeter() { + return 2 * (this.#sideA + this.#sideB) + } + + /** + * Returns a string representation of the kite. + * @public + * @returns {string} A string describing the kite's dimensions and area/perimeter. + */ + toString() { + return ( + `Kite: sideA = ${this.#sideA}, sideB = ${this.#sideB}, ` + + `diagonal1 = ${this.#diagonal1}, diagonal2 = ${this.#diagonal2}, ` + + `area = ${this.area()}, perimeter = ${this.perimeter()}` + ) + } + + /** + * Gets the length of side A of the kite. + * @public + * @returns {number} The length of side A. + */ + get sideA() { + return this.#sideA + } + + /** + * Gets the length of side B of the kite. + * @public + * @returns {number} The length of side B. + */ + get sideB() { + return this.#sideB + } + + /** + * Gets the length of diagonal 1 of the kite. + * @public + * @returns {number} The length of diagonal 1. + */ + get diagonal1() { + return this.#diagonal1 + } + + /** + * Gets the length of diagonal 2 of the kite. + * @public + * @returns {number} The length of diagonal 2. + */ + get diagonal2() { + return this.#diagonal2 + } +} diff --git a/Geometry/Test/Kite.test.js b/Geometry/Test/Kite.test.js new file mode 100644 index 0000000000..7a5060873c --- /dev/null +++ b/Geometry/Test/Kite.test.js @@ -0,0 +1,74 @@ +import Kite from '../Kite' + +describe('Kite', () => { + describe('Constructor', () => { + test('creates a kite with valid dimensions', () => { + const kite = new Kite(5, 7, 10, 12) + expect(kite).toBeInstanceOf(Kite) + expect(kite.sideA).toBe(5) + expect(kite.sideB).toBe(7) + expect(kite.diagonal1).toBe(10) + expect(kite.diagonal2).toBe(12) + }) + + test('throws an error if any dimension is invalid', () => { + expect(() => new Kite(-5, 7, 10, 12)).toThrow( + 'sideA must be a positive number.' + ) + expect(() => new Kite(5, -7, -10, null)).toThrow( + 'sideB must be a positive number.' + ) + expect(() => new Kite(5, 7, null, null)).toThrow( + 'diagonal1 must be a positive number.' + ) + expect(() => new Kite(5, 7, 10, undefined)).toThrow( + 'diagonal2 must be a positive number.' + ) + }) + }) + + describe('Area Calculation', () => { + test('calculates area correctly', () => { + const kite = new Kite(5, 7, 10, 12) + expect(kite.area()).toBe(60) // Area = (10 * 12) / 2 + }) + }) + + describe('Perimeter Calculation', () => { + test('calculates perimeter correctly', () => { + const kite = new Kite(5, 7, 10, 12) + expect(kite.perimeter()).toBe(24) // Perimeter = 2 * (5 + 7) + }) + }) + + describe('Getters', () => { + test('sideA getter returns correct value', () => { + const kite = new Kite(5, 7, 10, 12) + expect(kite.sideA).toBe(5) + }) + + test('sideB getter returns correct value', () => { + const kite = new Kite(5, 7, 10, 12) + expect(kite.sideB).toBe(7) + }) + + test('diagonal1 getter returns correct value', () => { + const kite = new Kite(5, 7, 10, 12) + expect(kite.diagonal1).toBe(10) + }) + + test('diagonal2 getter returns correct value', () => { + const kite = new Kite(5, 7, 10, 12) + expect(kite.diagonal2).toBe(12) + }) + }) + + describe('String Representation', () => { + test('returns correct string representation', () => { + const kite = new Kite(5, 7, 10, 12) + expect(kite.toString()).toBe( + 'Kite: sideA = 5, sideB = 7, diagonal1 = 10, diagonal2 = 12, area = 60, perimeter = 24' + ) + }) + }) +})