diff --git a/projects/002-polygon-area-calculator/js/index.js b/projects/002-polygon-area-calculator/js/index.js index e69de29..6489191 100644 --- a/projects/002-polygon-area-calculator/js/index.js +++ b/projects/002-polygon-area-calculator/js/index.js @@ -0,0 +1,23 @@ +const shapeCalculator = require( './shapeCalculator.js' ); // For CommonJS environment + +function init(){ + const rect = new shapeCalculator.Rectangle(10, 5); + console.log(rect.getArea()); + rect.setHeight(3); + console.log(rect.getPerimeter()); + console.log(shapeCalculator.Rectangle.str(rect)); + console.log(rect.getPicture()); + + const sq = new shapeCalculator.Square(9); + console.log(sq.getArea()); + sq.setSide(4); + console.log(sq.getDiagonal()); + console.log(shapeCalculator.Square.str(sq)); + console.log(sq.getPicture()); + + rect.setHeight(8); + rect.setWidth(16); + console.log(rect.getAmountInside(sq)); +} + +init(); \ No newline at end of file diff --git a/projects/002-polygon-area-calculator/js/index.test.js b/projects/002-polygon-area-calculator/js/index.test.js new file mode 100644 index 0000000..078578b --- /dev/null +++ b/projects/002-polygon-area-calculator/js/index.test.js @@ -0,0 +1,168 @@ +const shapeCalculator = require( './shapeCalculator.js' ); // For CommonJS environment + +let rect, sq; + +beforeEach(() => { + rect = new shapeCalculator.Rectangle(3, 6); + sq = new shapeCalculator.Square(5) +}); + +test('Expected Square class to be a subclass of the Rectangle class.', () => { + const actual = shapeCalculator.Square.prototype instanceof shapeCalculator.Rectangle; + const expected = true; + expect(actual).toBe(expected); +}); + +test('Expected Square class to be a distinct class from the Rectangle class.', () => { + const actual = Object.getPrototypeOf(shapeCalculator.Square) !== Object.getPrototypeOf(shapeCalculator.Rectangle); + const expected = true; + expect(actual).toBe(expected); +}); + +test('Expected square object to be an instance of the Square class and the Rectangle class.', () => { + const actual = sq instanceof shapeCalculator.Square && sq instanceof shapeCalculator.Rectangle; + const expected = true; + expect(actual).toBe(expected); +}); + +test('Expected string representation of rectangle to be "Rectangle(width=3, height=6)"', () => { + const actual = shapeCalculator.Rectangle.str(rect); + const expected = "Rectangle(width=3, height=6)"; + expect(actual).toEqual(expected); +}); + +test('Expected string representation of square to be "Square(side=5)"', () => { + const actual = shapeCalculator.Square.str(sq); + const expected = "Square(side=5)"; + expect(actual).toEqual(expected); +}); + +describe('Expected area of ', () => { + let actual, expected; + + test('rectangle to be 18', () => { + actual = rect.getArea(); + expected = 18; + expect(actual).toEqual(expected); + }); + + test('square to be 25', () => { + actual = sq.getArea(); + expected = 25; + expect(actual).toEqual(expected); + }); +}); + +describe('Expected perimeter of ', () => { + let actual, expected; + + test('rectangle to be 18', () => { + actual = rect.getPerimeter(); + expected = 18; + expect(actual).toEqual(expected); + }); + + test('square to be 20', () => { + actual = sq.getPerimeter(); + expected = 20; + expect(actual).toEqual(expected); + }); +}); + + +describe('Expected diagonal of ', () => { + let actual, expected; + + test('rectangle to be 6.708203932499369', () => { + actual = rect.getDiagonal(); + expected = 6.708203932499369; + expect(actual).toEqual(expected); + }); + + test('square to be 7.0710678118654755', () => { + actual = sq.getDiagonal(); + expected = 7.0710678118654755; + expect(actual).toEqual(expected); + }); +}); + +describe('Expected string representation of ', () => { + let actual, expected; + + beforeEach(() => { + rect.setWidth(7) + rect.setHeight(8) + sq.setSide(2) + }); + + test('rectangle after setting new values to be "Rectangle(width=7, height=8)"', () => { + actual = shapeCalculator.Rectangle.str(rect); + expected = "Rectangle(width=7, height=8)"; + expect(actual).toEqual(expected); + }); + + test('square after setting new values to be "Square(side=2)"', () => { + actual = shapeCalculator.Square.str(sq); + expected = "Square(side=2)"; + expect(actual).toEqual(expected); + }); + + test('square after setting width to be "Square(side=4)"', () => { + sq.setWidth(4); + actual = shapeCalculator.Square.str(sq); + expected = "Square(side=4)"; + expect(actual).toEqual(expected); + }); + + test('square after setting height to be "Square(side=8)"', () => { + sq.setHeight(8); + actual = shapeCalculator.Square.str(sq); + expected = "Square(side=8)"; + expect(actual).toEqual(expected); + }); +}); + +test('Expected rectangle picture to be different.', () => { + rect.setWidth(7); + rect.setHeight(3); + const actual = rect.getPicture(); + const expected = "*******\n*******\n*******\n"; + expect(actual).toEqual(expected); +}); + +test('Expected square picture to be different.', () => { + sq.setSide(2); + const actual = sq.getPicture(); + const expected = "**\n**\n"; + expect(actual).toEqual(expected); +}); + +test('Expected message: "Too big for picture."', () => { + rect.setWidth(51); + rect.setHeight(3); + const actual = rect.getPicture(); + const expected = "Too big for picture."; + expect(actual).toEqual(expected); +}); + +test('Expected `getAmountInside` to return 6.', () => { + rect.setHeight(10); + rect.setWidth(15); + const actual = rect.getAmountInside(sq); + const expected = 6; + expect(actual).toEqual(expected); +}); + +test('Expected `getAmountInside` to return 1.', () => { + const rect2 = new shapeCalculator.Rectangle(4, 8); + const actual = rect2.getAmountInside(rect); + const expected = 1; + expect(actual).toEqual(expected); +}); + +test('Expected `getAmountInside` to return 0.', () => { + const rect2 = new shapeCalculator.Rectangle(2, 3); + const actual = rect2.getAmountInside(rect); + const expected = 0; + expect(actual).toEqual(expected); +}); \ No newline at end of file diff --git a/projects/002-polygon-area-calculator/js/shapeCalculator.js b/projects/002-polygon-area-calculator/js/shapeCalculator.js new file mode 100644 index 0000000..88d2f1d --- /dev/null +++ b/projects/002-polygon-area-calculator/js/shapeCalculator.js @@ -0,0 +1,124 @@ +/** Class representing a Rectangle. */ +class Rectangle { + /** + * Creates a rectangle as wide as the width parameter and as long as the height parameter. + * @param {number} width + * @param {number} height + */ + constructor(width, height){ + this.width = width; + this.height = height; + } + /** + * Sets the width of the rectangle + * @param {number} value - The width + */ + setWidth(value){ + this.width = value; + } + /** + * Sets the height of the rectangle + * @param {number} value - The height + */ + setHeight(value){ + this.height = value; + } + /** + * Returns the area of the rectangle + * @returns {number} The area + */ + getArea(){ + return this.width * this.height; + } + /** + * Returns the perimeter of the rectangle + * @returns {number} The perimeter + */ + getPerimeter(){ + return 2 * this.width + 2 * this.height; + } + /** + * Returns the diagonal of the rectangle + * @returns {number} The diagonal + */ + getDiagonal(){ + return (this.width ** 2 + this.height ** 2) ** .5; + } + /** + * Returns a string that represents the shape of the rectangle using lines of "*" + * @returns {string} The picture + */ + getPicture(){ + if(this.width > 50 || this.height > 50) + return 'Too big for picture.'; + + let picture = ''; + for (let i = 0; i < this.height; i++) { + picture += `${'*'.repeat(this.width)}\n`; + } + + return picture; + } + /** + * + * @param {number} shape + * @returns + */ + getAmountInside(shape){ + return Math.trunc(this.width / shape.width) * Math.trunc(this.height / shape.height); + } + /** + * A static method that returns the relevant data of the rectangle, i.e.: the name, the width and the height + * @param {Rectangle} rectangle - The rectangle to be processed + * @returns {string} The relevant data of the category + */ + static str(rectangle){ + return `Rectangle(width=${rectangle.width}, height=${rectangle.height})`; + } +} +/** Class representing a Square, derived by Rectangle Class. */ +class Square extends Rectangle { + /** + * Creates a square whose side is as long as the side parameter + * @param {*} side + */ + constructor(side){ + super(side, side); + } + /** + * Sets the side of the square + * @param {number} value - The side + */ + setSide(value){ + this.width = value; + this.height = value; + } + /** + * Sets the width of the square + * @param {number} value - The width + */ + setWidth(value){ + this.setSide(value); + } + /** + * Sets the height of the square + * @param {number} value - The height + */ + setHeight(value){ + this.setSide(value); + } + /** + * A static method that returns the relevant data of the square, i.e.: the name and the side + * @param {Square} square - The rectangle to be processed + * @returns {string} The relevant data of the category + */ + static str(square){ + return `Square(side=${square.width})`; + } +} + +module.exports = { // For CommonJS environment +// export { // For ES module environment. In addition for Visual Studio Code two package.json files must be created, one in this file folder, the other one in the application file folder, they must contain the following code { "type": "module" } + Rectangle, + Square +}; \ No newline at end of file