Skip to content

Commit 6327ac5

Browse files
committed
feat: add geometry kite
1 parent 9010481 commit 6327ac5

File tree

2 files changed

+193
-0
lines changed

2 files changed

+193
-0
lines changed

Geometry/Kite.js

+119
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
/**
2+
* This class represents a Kite and provides methods to calculate its area and perimeter.
3+
* @see {@link https://en.wikipedia.org/wiki/Kite_(geometry)}
4+
* @class
5+
*/
6+
export default class Kite {
7+
/** @private */
8+
#sideA
9+
10+
/** @private */
11+
#sideB
12+
13+
/** @private */
14+
#diagonal1
15+
16+
/** @private */
17+
#diagonal2
18+
19+
/**
20+
* Creates a kite instance.
21+
* @constructor
22+
* @param {number} sideA - The length of one pair of equal sides.
23+
* @param {number} sideB - The length of the other pair of equal sides.
24+
* @param {number} diagonal1 - The length of the first diagonal.
25+
* @param {number} diagonal2 - The length of the second diagonal.
26+
* @throws {Error} Will throw an error if any dimension is invalid.
27+
*/
28+
constructor(sideA, sideB, diagonal1, diagonal2) {
29+
this.#validateDimension(sideA, 'sideA')
30+
this.#validateDimension(sideB, 'sideB')
31+
this.#validateDimension(diagonal1, 'diagonal1')
32+
this.#validateDimension(diagonal2, 'diagonal2')
33+
34+
this.#sideA = sideA
35+
this.#sideB = sideB
36+
this.#diagonal1 = diagonal1
37+
this.#diagonal2 = diagonal2
38+
}
39+
40+
/**
41+
* Validates that a dimension is a positive number.
42+
* @private
43+
* @param {number} value - The value to validate.
44+
* @param {string} name - The name of the dimension (for error reporting).
45+
* @throws {Error} Will throw an error if the value is not a positive number.
46+
*/
47+
#validateDimension(value, name) {
48+
if (typeof value !== 'number' || isNaN(value) || value <= 0) {
49+
throw new Error(`${name} must be a positive number.`)
50+
}
51+
}
52+
53+
/**
54+
* Calculates the area of the kite.
55+
* @public
56+
* @returns {number} The area of the kite.
57+
*/
58+
area() {
59+
return (this.#diagonal1 * this.#diagonal2) / 2
60+
}
61+
62+
/**
63+
* Calculates the perimeter of the kite.
64+
* @public
65+
* @returns {number} The perimeter of the kite.
66+
*/
67+
perimeter() {
68+
return 2 * (this.#sideA + this.#sideB)
69+
}
70+
71+
/**
72+
* Returns a string representation of the kite.
73+
* @public
74+
* @returns {string} A string describing the kite's dimensions and area/perimeter.
75+
*/
76+
toString() {
77+
return (
78+
`Kite: sideA = ${this.#sideA}, sideB = ${this.#sideB}, ` +
79+
`diagonal1 = ${this.#diagonal1}, diagonal2 = ${this.#diagonal2}, ` +
80+
`area = ${this.area()}, perimeter = ${this.perimeter()}`
81+
)
82+
}
83+
84+
/**
85+
* Gets the length of side A of the kite.
86+
* @public
87+
* @returns {number} The length of side A.
88+
*/
89+
get sideA() {
90+
return this.#sideA
91+
}
92+
93+
/**
94+
* Gets the length of side B of the kite.
95+
* @public
96+
* @returns {number} The length of side B.
97+
*/
98+
get sideB() {
99+
return this.#sideB
100+
}
101+
102+
/**
103+
* Gets the length of diagonal 1 of the kite.
104+
* @public
105+
* @returns {number} The length of diagonal 1.
106+
*/
107+
get diagonal1() {
108+
return this.#diagonal1
109+
}
110+
111+
/**
112+
* Gets the length of diagonal 2 of the kite.
113+
* @public
114+
* @returns {number} The length of diagonal 2.
115+
*/
116+
get diagonal2() {
117+
return this.#diagonal2
118+
}
119+
}

Geometry/Test/Kite.test.js

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import Kite from '../Kite'
2+
3+
describe('Kite', () => {
4+
describe('Constructor', () => {
5+
test('creates a kite with valid dimensions', () => {
6+
const kite = new Kite(5, 7, 10, 12)
7+
expect(kite).toBeInstanceOf(Kite)
8+
expect(kite.sideA).toBe(5)
9+
expect(kite.sideB).toBe(7)
10+
expect(kite.diagonal1).toBe(10)
11+
expect(kite.diagonal2).toBe(12)
12+
})
13+
14+
test('throws an error if any dimension is invalid', () => {
15+
expect(() => new Kite(-5, 7, 10, 12)).toThrow(
16+
'sideA must be a positive number.'
17+
)
18+
expect(() => new Kite(5, -7, -10, null)).toThrow(
19+
'sideB must be a positive number.'
20+
)
21+
expect(() => new Kite(5, 7, null, null)).toThrow(
22+
'diagonal1 must be a positive number.'
23+
)
24+
expect(() => new Kite(5, 7, 10, undefined)).toThrow(
25+
'diagonal2 must be a positive number.'
26+
)
27+
})
28+
})
29+
30+
describe('Area Calculation', () => {
31+
test('calculates area correctly', () => {
32+
const kite = new Kite(5, 7, 10, 12)
33+
expect(kite.area()).toBe(60) // Area = (10 * 12) / 2
34+
})
35+
})
36+
37+
describe('Perimeter Calculation', () => {
38+
test('calculates perimeter correctly', () => {
39+
const kite = new Kite(5, 7, 10, 12)
40+
expect(kite.perimeter()).toBe(24) // Perimeter = 2 * (5 + 7)
41+
})
42+
})
43+
44+
describe('Getters', () => {
45+
test('sideA getter returns correct value', () => {
46+
const kite = new Kite(5, 7, 10, 12)
47+
expect(kite.sideA).toBe(5)
48+
})
49+
50+
test('sideB getter returns correct value', () => {
51+
const kite = new Kite(5, 7, 10, 12)
52+
expect(kite.sideB).toBe(7)
53+
})
54+
55+
test('diagonal1 getter returns correct value', () => {
56+
const kite = new Kite(5, 7, 10, 12)
57+
expect(kite.diagonal1).toBe(10)
58+
})
59+
60+
test('diagonal2 getter returns correct value', () => {
61+
const kite = new Kite(5, 7, 10, 12)
62+
expect(kite.diagonal2).toBe(12)
63+
})
64+
})
65+
66+
describe('String Representation', () => {
67+
test('returns correct string representation', () => {
68+
const kite = new Kite(5, 7, 10, 12)
69+
expect(kite.toString()).toBe(
70+
'Kite: sideA = 5, sideB = 7, diagonal1 = 10, diagonal2 = 12, area = 60, perimeter = 24'
71+
)
72+
})
73+
})
74+
})

0 commit comments

Comments
 (0)