├── README.md ├── 0x00-ES6_basic ├── README.md ├── 4-rest-parameter.js ├── 5-spread-operator.js ├── 3-default-parameter.js ├── 11-createEmployeesObject.js ├── 7-getBudgetObject.js ├── babel.config.js ├── 10-loops.js ├── 12-createReportObject.js ├── 101-iterateThroughObject.js ├── 100-createIteratorObject.js ├── 1-block-scoped.js ├── 2-arrow.js ├── 0-constants.js ├── 8-getBudgetCurrentYear.js ├── 9-getFullBudget.js ├── 6-string-interpolation.js ├── package.json └── .eslintrc.js ├── 0x04-TypeScript ├── README.md ├── task_4 │ ├── js │ │ ├── subjects │ │ │ ├── Teacher.ts │ │ │ ├── Subject.ts │ │ │ ├── Cpp.ts │ │ │ ├── Java.ts │ │ │ └── React.ts │ │ └── main.ts │ ├── tsconfig.json │ ├── .eslintrc.js │ ├── webpack.config.js │ └── package.json ├── task_3 │ ├── js │ │ ├── interface.ts │ │ ├── crud.d.ts │ │ ├── crud.js │ │ └── main.ts │ ├── tsconfig.json │ ├── .eslintrc.js │ ├── webpack.config.js │ └── package.json ├── task_0 │ ├── tsconfig.json │ ├── .eslintrc.js │ ├── webpack.config.js │ ├── package.json │ └── js │ │ └── main.ts ├── task_1 │ ├── tsconfig.json │ ├── .eslintrc.js │ ├── webpack.config.js │ ├── package.json │ └── js │ │ └── main.ts ├── task_2 │ ├── tsconfig.json │ ├── .eslintrc.js │ ├── webpack.config.js │ ├── package.json │ └── js │ │ └── main.ts └── task_5 │ ├── tsconfig.json │ ├── .eslintrc.js │ ├── js │ └── main.ts │ ├── webpack.config.js │ └── package.json ├── 0x01-ES6_promise ├── README.md ├── 0-promise.js ├── 4-user-promise.js ├── 5-photo-reject.js ├── 7-load_balancer.js ├── 8-try.js ├── babel.config.js ├── 2-then.js ├── utils.js ├── 9-try.js ├── 1-promise.js ├── 3-all.js ├── 100-await.js ├── 6-final-user.js ├── package.json └── .eslintrc.js ├── 0x02-ES6_classes ├── README.md ├── babel.config.js ├── 1-make_classrooms.js ├── 0-classroom.js ├── 6-sky_high.js ├── 7-airport.js ├── 100-evcar.js ├── 5-building.js ├── package.json ├── 3-currency.js ├── 8-hbtn_class.js ├── .eslintrc.js ├── 10-car.js ├── 4-pricing.js ├── 9-hoisting.js └── 2-hbtn_course.js ├── 0x05-Node_JS_basic ├── README.md ├── .babelrc ├── babel.config.js ├── 0-console.js ├── database.csv ├── full_server │ ├── server.js │ ├── controllers │ │ ├── AppController.js │ │ └── StudentsController.js │ ├── routes │ │ └── index.js │ └── utils.js ├── 6-http_express.js ├── 1-stdin.js ├── 4-http.js ├── .eslintrc.js ├── package.json ├── 2-read_file.js ├── 3-read_file_async.js ├── 7-http_express.js └── 5-http.js ├── 0x06-unittests_in_js ├── README.md ├── .babelrc ├── 0-calcul.js ├── babel.config.js ├── 6-payment_token.js ├── 3-payment.js ├── 4-payment.js ├── 5-payment.js ├── 8-api │ ├── api.js │ ├── api.test.js │ └── package.json ├── 1-calcul.js ├── 2-calcul_chai.js ├── utils.js ├── 6-payment_token.test.js ├── 9-api │ ├── api.js │ ├── package.json │ └── api.test.js ├── 3-payment.test.js ├── 7-skip.test.js ├── .eslintrc.js ├── 4-payment.test.js ├── 10-api │ ├── api.js │ ├── package.json │ └── api.test.js ├── 5-payment.test.js ├── 0-calcul.test.js ├── package.json ├── 2-calcul_chai.test.js └── 1-calcul.test.js └── 0x03-ES6_data_manipulation ├── README.md ├── 6-set.js ├── babel.config.js ├── 7-has_array_values.js ├── 9-groceries_list.js ├── 0-get_list_students.js ├── 1-get_list_student_ids.js ├── 10-update_uniq_items.js ├── 2-get_students_by_loc.js ├── 3-get_ids_sum.js ├── package.json ├── 5-typed_arrays.js ├── 100-weak.js ├── .eslintrc.js ├── 8-clean_set.js └── 4-update_grade_by_city.js /README.md: -------------------------------------------------------------------------------- 1 | # ALX Backend JavaScript -------------------------------------------------------------------------------- /0x00-ES6_basic/README.md: -------------------------------------------------------------------------------- 1 | # ES6 Basics -------------------------------------------------------------------------------- /0x04-TypeScript/README.md: -------------------------------------------------------------------------------- 1 | # TypeScript -------------------------------------------------------------------------------- /0x01-ES6_promise/README.md: -------------------------------------------------------------------------------- 1 | # ES6 Promises -------------------------------------------------------------------------------- /0x02-ES6_classes/README.md: -------------------------------------------------------------------------------- 1 | # ES6 Classes -------------------------------------------------------------------------------- /0x05-Node_JS_basic/README.md: -------------------------------------------------------------------------------- 1 | # 0x05-Node_JS_basic -------------------------------------------------------------------------------- /0x06-unittests_in_js/README.md: -------------------------------------------------------------------------------- 1 | # 0x06-unittests_in_js -------------------------------------------------------------------------------- /0x03-ES6_data_manipulation/README.md: -------------------------------------------------------------------------------- 1 | # ES6 Data Manipulation -------------------------------------------------------------------------------- /0x05-Node_JS_basic/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [["env", {"exclude": ["transform-regenerator"]}]] 3 | } 4 | -------------------------------------------------------------------------------- /0x06-unittests_in_js/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [["env", {"exclude": ["transform-regenerator"]}]] 3 | } 4 | -------------------------------------------------------------------------------- /0x01-ES6_promise/0-promise.js: -------------------------------------------------------------------------------- 1 | export default function getResponseFromAPI() { 2 | return new Promise(() => {}); 3 | } 4 | -------------------------------------------------------------------------------- /0x00-ES6_basic/4-rest-parameter.js: -------------------------------------------------------------------------------- 1 | export default function returnHowManyArguments(...args) { 2 | return args.length; 3 | } 4 | -------------------------------------------------------------------------------- /0x06-unittests_in_js/0-calcul.js: -------------------------------------------------------------------------------- 1 | const calculateNumber = (a, b) => Math.round(a) + Math.round(b); 2 | 3 | module.exports = calculateNumber; 4 | -------------------------------------------------------------------------------- /0x00-ES6_basic/5-spread-operator.js: -------------------------------------------------------------------------------- 1 | export default function concatArrays(array1, array2, string) { 2 | return [...array1, ...array2, ...string]; 3 | } 4 | -------------------------------------------------------------------------------- /0x01-ES6_promise/4-user-promise.js: -------------------------------------------------------------------------------- 1 | export default function signUpUser(firstName, lastName) { 2 | return Promise.resolve({ firstName, lastName }); 3 | } 4 | -------------------------------------------------------------------------------- /0x01-ES6_promise/5-photo-reject.js: -------------------------------------------------------------------------------- 1 | export default function uploadPhoto(filename) { 2 | return Promise.reject(new Error(`${filename} cannot be processed`)); 3 | } 4 | -------------------------------------------------------------------------------- /0x04-TypeScript/task_4/js/subjects/Teacher.ts: -------------------------------------------------------------------------------- 1 | namespace Subjects { 2 | export interface Teacher { 3 | firstName: string; 4 | lastName: string; 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /0x04-TypeScript/task_3/js/interface.ts: -------------------------------------------------------------------------------- 1 | export type RowID = number; 2 | 3 | export interface RowElement { 4 | firstName: string; 5 | lastName: string; 6 | age?: number; 7 | } 8 | -------------------------------------------------------------------------------- /0x00-ES6_basic/3-default-parameter.js: -------------------------------------------------------------------------------- 1 | export default function getSumOfHoods(initialNumber, expansion1989 = 89, expansion2019 = 19) { 2 | return initialNumber + expansion1989 + expansion2019; 3 | } 4 | -------------------------------------------------------------------------------- /0x01-ES6_promise/7-load_balancer.js: -------------------------------------------------------------------------------- 1 | export default function loadBalancer(chinaDownload, USDownload) { 2 | return Promise 3 | .race([chinaDownload, USDownload]) 4 | .then((res) => res); 5 | } 6 | -------------------------------------------------------------------------------- /0x00-ES6_basic/11-createEmployeesObject.js: -------------------------------------------------------------------------------- 1 | export default function createEmployeesObject(departmentName, employees) { 2 | return { 3 | [departmentName]: [ 4 | ...employees, 5 | ], 6 | }; 7 | } 8 | -------------------------------------------------------------------------------- /0x00-ES6_basic/7-getBudgetObject.js: -------------------------------------------------------------------------------- 1 | export default function getBudgetObject(income, gdp, capita) { 2 | const budget = { 3 | income, 4 | gdp, 5 | capita, 6 | }; 7 | 8 | return budget; 9 | } 10 | -------------------------------------------------------------------------------- /0x01-ES6_promise/8-try.js: -------------------------------------------------------------------------------- 1 | export default function divideFunction(numerator, denominator) { 2 | if (denominator === 0) { 3 | throw Error('cannot divide by 0'); 4 | } else { 5 | return numerator / denominator; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /0x03-ES6_data_manipulation/6-set.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Creates a set from an array. 3 | * @param {Array} array - The source array. 4 | * @returns {Set} 5 | */ 6 | export default function setFromArray(array) { 7 | return new Set(array); 8 | } 9 | -------------------------------------------------------------------------------- /0x00-ES6_basic/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | [ 4 | '@babel/preset-env', 5 | { 6 | targets: { 7 | node: 'current', 8 | }, 9 | }, 10 | ], 11 | ], 12 | }; 13 | -------------------------------------------------------------------------------- /0x01-ES6_promise/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | [ 4 | '@babel/preset-env', 5 | { 6 | targets: { 7 | node: 'current', 8 | }, 9 | }, 10 | ], 11 | ], 12 | }; 13 | -------------------------------------------------------------------------------- /0x02-ES6_classes/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | [ 4 | '@babel/preset-env', 5 | { 6 | targets: { 7 | node: 'current', 8 | }, 9 | }, 10 | ], 11 | ], 12 | }; 13 | -------------------------------------------------------------------------------- /0x00-ES6_basic/10-loops.js: -------------------------------------------------------------------------------- 1 | export default function appendToEachArrayValue(array, appendString) { 2 | const newArray = []; 3 | for (const value of array) { 4 | newArray.push(appendString + value); 5 | } 6 | 7 | return newArray; 8 | } 9 | -------------------------------------------------------------------------------- /0x05-Node_JS_basic/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | [ 4 | '@babel/preset-env', 5 | { 6 | targets: { 7 | node: 'current', 8 | }, 9 | }, 10 | ], 11 | ], 12 | }; 13 | -------------------------------------------------------------------------------- /0x06-unittests_in_js/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | [ 4 | '@babel/preset-env', 5 | { 6 | targets: { 7 | node: 'current', 8 | }, 9 | }, 10 | ], 11 | ], 12 | }; 13 | -------------------------------------------------------------------------------- /0x03-ES6_data_manipulation/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | [ 4 | '@babel/preset-env', 5 | { 6 | targets: { 7 | node: 'current', 8 | }, 9 | }, 10 | ], 11 | ], 12 | }; 13 | -------------------------------------------------------------------------------- /0x04-TypeScript/task_4/js/subjects/Subject.ts: -------------------------------------------------------------------------------- 1 | namespace Subjects { 2 | export class Subject { 3 | teacher: Subjects.Teacher; 4 | 5 | set setTeacher(teacher: Subjects.Teacher) { 6 | this.teacher = teacher; 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /0x05-Node_JS_basic/0-console.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Displays a message on the STDOUT. 3 | * @param {String} msg The message to display. 4 | */ 5 | const displayMessage = (msg) => { 6 | console.log(msg); 7 | }; 8 | 9 | module.exports = displayMessage; 10 | -------------------------------------------------------------------------------- /0x01-ES6_promise/2-then.js: -------------------------------------------------------------------------------- 1 | export default function handleResponseFromAPI(promise) { 2 | return promise 3 | .then(() => ({ status: 200, body: 'success' })) 4 | .catch(() => new Error()) 5 | .finally(() => console.log('Got a response from the API')); 6 | } 7 | -------------------------------------------------------------------------------- /0x06-unittests_in_js/6-payment_token.js: -------------------------------------------------------------------------------- 1 | const getPaymentTokenFromAPI = (success) => new Promise((resolve, _reject) => { 2 | if (success) { 3 | resolve({data: 'Successful response from the API'}); 4 | } 5 | }); 6 | 7 | module.exports = getPaymentTokenFromAPI; 8 | -------------------------------------------------------------------------------- /0x00-ES6_basic/12-createReportObject.js: -------------------------------------------------------------------------------- 1 | export default function createReportObject(employeesList) { 2 | return { 3 | allEmployees: employeesList, 4 | getNumberOfDepartments(employeesList) { 5 | return Object.keys(employeesList).length; 6 | }, 7 | }; 8 | } 9 | -------------------------------------------------------------------------------- /0x04-TypeScript/task_3/js/crud.d.ts: -------------------------------------------------------------------------------- 1 | import { RowID, RowElement } from './interface'; 2 | 3 | export function insertRow(row: RowElement): number; 4 | 5 | export function deleteRow(rowId: RowID): void; 6 | 7 | export function updateRow(rowId: RowID, row: RowElement): number; 8 | -------------------------------------------------------------------------------- /0x04-TypeScript/task_0/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "./dist/", 4 | "sourceMap": true, 5 | "noImplicitAny": true, 6 | "module": "es6", 7 | "target": "es5", 8 | "allowJs": true, 9 | "moduleResolution": "node" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /0x04-TypeScript/task_1/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "./dist/", 4 | "sourceMap": true, 5 | "noImplicitAny": true, 6 | "module": "es6", 7 | "target": "es5", 8 | "allowJs": true, 9 | "moduleResolution": "node" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /0x04-TypeScript/task_2/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "./dist/", 4 | "sourceMap": true, 5 | "noImplicitAny": true, 6 | "module": "es6", 7 | "target": "es5", 8 | "allowJs": true, 9 | "moduleResolution": "node" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /0x04-TypeScript/task_3/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "./dist/", 4 | "sourceMap": true, 5 | "noImplicitAny": true, 6 | "module": "es6", 7 | "target": "es5", 8 | "allowJs": true, 9 | "moduleResolution": "node" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /0x04-TypeScript/task_4/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "./dist/", 4 | "sourceMap": true, 5 | "noImplicitAny": true, 6 | "module": "es6", 7 | "target": "es5", 8 | "allowJs": true, 9 | "moduleResolution": "node" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /0x04-TypeScript/task_5/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "./dist/", 4 | "sourceMap": true, 5 | "noImplicitAny": true, 6 | "module": "es6", 7 | "target": "es5", 8 | "allowJs": true, 9 | "moduleResolution": "node" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /0x00-ES6_basic/101-iterateThroughObject.js: -------------------------------------------------------------------------------- 1 | export default function iterateThroughObject(reportWithIterator) { 2 | const employees = []; 3 | 4 | for (const employee of reportWithIterator) { 5 | employees.push(employee); 6 | } 7 | 8 | return employees.join(' | '); 9 | } 10 | -------------------------------------------------------------------------------- /0x01-ES6_promise/utils.js: -------------------------------------------------------------------------------- 1 | export function uploadPhoto() { 2 | return Promise.resolve({ 3 | status: 200, 4 | body: 'photo-profile-1', 5 | }); 6 | } 7 | 8 | export function createUser() { 9 | return Promise.resolve({ 10 | firstName: 'Guillaume', 11 | lastName: 'Salva', 12 | }); 13 | } 14 | -------------------------------------------------------------------------------- /0x00-ES6_basic/100-createIteratorObject.js: -------------------------------------------------------------------------------- 1 | export default function createIteratorObject(report) { 2 | return (function* _() { 3 | for (const department of Object.values(report.allEmployees)) { 4 | for (const employee of department) { 5 | yield employee; 6 | } 7 | } 8 | }()); 9 | } 10 | -------------------------------------------------------------------------------- /0x01-ES6_promise/9-try.js: -------------------------------------------------------------------------------- 1 | export default function guardrail(mathFunction) { 2 | const queue = []; 3 | 4 | try { 5 | queue.push(mathFunction()); 6 | } catch (err) { 7 | queue.push(String(err)); 8 | } finally { 9 | queue.push('Guardrail was processed'); 10 | } 11 | 12 | return queue; 13 | } 14 | -------------------------------------------------------------------------------- /0x05-Node_JS_basic/database.csv: -------------------------------------------------------------------------------- 1 | firstname,lastname,age,field 2 | Johann,Kerbrou,30,CS 3 | Guillaume,Salou,30,SWE 4 | Arielle,Salou,20,CS 5 | Jonathan,Benou,30,CS 6 | Emmanuel,Turlou,40,CS 7 | Guillaume,Plessous,35,CS 8 | Joseph,Crisou,34,SWE 9 | Paul,Schneider,60,SWE 10 | Tommy,Schoul,32,SWE 11 | Katie,Shirou,21,CS 12 | -------------------------------------------------------------------------------- /0x06-unittests_in_js/3-payment.js: -------------------------------------------------------------------------------- 1 | const Utils = require('./utils'); 2 | 3 | const sendPaymentRequestToApi = (totalAmount, totalShipping) => { 4 | const totalCost = Utils.calculateNumber('SUM', totalAmount, totalShipping); 5 | console.log(`The total is: ${totalCost}`); 6 | }; 7 | 8 | module.exports = sendPaymentRequestToApi; 9 | -------------------------------------------------------------------------------- /0x06-unittests_in_js/4-payment.js: -------------------------------------------------------------------------------- 1 | const Utils = require('./utils'); 2 | 3 | const sendPaymentRequestToApi = (totalAmount, totalShipping) => { 4 | const totalCost = Utils.calculateNumber('SUM', totalAmount, totalShipping); 5 | console.log(`The total is: ${totalCost}`); 6 | }; 7 | 8 | module.exports = sendPaymentRequestToApi; 9 | -------------------------------------------------------------------------------- /0x06-unittests_in_js/5-payment.js: -------------------------------------------------------------------------------- 1 | const Utils = require('./utils'); 2 | 3 | const sendPaymentRequestToApi = (totalAmount, totalShipping) => { 4 | const totalCost = Utils.calculateNumber('SUM', totalAmount, totalShipping); 5 | console.log(`The total is: ${totalCost}`); 6 | }; 7 | 8 | module.exports = sendPaymentRequestToApi; 9 | -------------------------------------------------------------------------------- /0x02-ES6_classes/1-make_classrooms.js: -------------------------------------------------------------------------------- 1 | import ClassRoom from './0-classroom'; 2 | 3 | /** 4 | * Creates an array of {@link ClassRoom}s with a specific size. 5 | * @returns An array of {@link ClassRoom}s. 6 | */ 7 | export default function initializeRooms() { 8 | return [19, 20, 34].map((size) => new ClassRoom(size)); 9 | } 10 | -------------------------------------------------------------------------------- /0x00-ES6_basic/1-block-scoped.js: -------------------------------------------------------------------------------- 1 | export default function taskBlock(trueOrFalse) { 2 | const task = false; 3 | const task2 = true; 4 | 5 | if (trueOrFalse) { 6 | const task = true; // eslint-disable-line no-unused-vars 7 | const task2 = false; // eslint-disable-line no-unused-vars 8 | } 9 | 10 | return [task, task2]; 11 | } 12 | -------------------------------------------------------------------------------- /0x05-Node_JS_basic/full_server/server.js: -------------------------------------------------------------------------------- 1 | import express from 'express'; 2 | import mapRoutes from './routes'; 3 | 4 | const app = express(); 5 | const PORT = 1245; 6 | 7 | mapRoutes(app); 8 | app.listen(PORT, () => { 9 | console.log(`Server listening on PORT ${PORT}`); 10 | }); 11 | 12 | export default app; 13 | module.exports = app; 14 | -------------------------------------------------------------------------------- /0x00-ES6_basic/2-arrow.js: -------------------------------------------------------------------------------- 1 | export default function getNeighborhoodsList() { 2 | this.sanFranciscoNeighborhoods = ['SOMA', 'Union Square']; 3 | 4 | const self = this; 5 | this.addNeighborhood = (newNeighborhood) => { 6 | self.sanFranciscoNeighborhoods.push(newNeighborhood); 7 | return self.sanFranciscoNeighborhoods; 8 | }; 9 | } 10 | -------------------------------------------------------------------------------- /0x05-Node_JS_basic/6-http_express.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | 3 | const app = express(); 4 | const PORT = 1245; 5 | 6 | app.get('/', (_, res) => { 7 | res.send('Hello Holberton School!'); 8 | }); 9 | 10 | app.listen(PORT, () => { 11 | console.log(`Server listening on PORT ${PORT}`); 12 | }); 13 | 14 | module.exports = app; 15 | -------------------------------------------------------------------------------- /0x05-Node_JS_basic/full_server/controllers/AppController.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Contains the miscellaneous route handlers. 3 | */ 4 | class AppController { 5 | static getHomepage(request, response) { 6 | response.status(200).send('Hello Holberton School!'); 7 | } 8 | } 9 | 10 | export default AppController; 11 | module.exports = AppController; 12 | -------------------------------------------------------------------------------- /0x00-ES6_basic/0-constants.js: -------------------------------------------------------------------------------- 1 | export function taskFirst() { 2 | const task = 'I prefer const when I can.'; 3 | return task; 4 | } 5 | 6 | export function getLast() { 7 | return ' is okay'; 8 | } 9 | 10 | export function taskNext() { 11 | let combination = 'But sometimes let'; 12 | combination += getLast(); 13 | 14 | return combination; 15 | } 16 | -------------------------------------------------------------------------------- /0x06-unittests_in_js/8-api/api.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | 3 | const app = express(); 4 | const PORT = 7865; 5 | 6 | app.get('/', (_, res) => { 7 | res.send('Welcome to the payment system'); 8 | }); 9 | 10 | app.listen(PORT, () => { 11 | console.log(`API available on localhost port ${PORT}`); 12 | }); 13 | 14 | module.exports = app; 15 | -------------------------------------------------------------------------------- /0x01-ES6_promise/1-promise.js: -------------------------------------------------------------------------------- 1 | export default function getFullResponseFromAPI(success) { 2 | return new Promise((resolve, reject) => { 3 | if (success) { 4 | resolve({ 5 | status: 200, 6 | body: 'Success', 7 | }); 8 | } else { 9 | reject(new Error('The fake API is not working currently')); 10 | } 11 | }); 12 | } 13 | -------------------------------------------------------------------------------- /0x03-ES6_data_manipulation/7-has_array_values.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Checks if a set contains each element in an array. 3 | * @param {Set} set - The collection of unique items. 4 | * @param {*} array - The array of items. 5 | * @returns {Boolean} 6 | */ 7 | export default function hasValuesFromArray(set, array) { 8 | return array.every((value) => set.has(value)); 9 | } 10 | -------------------------------------------------------------------------------- /0x04-TypeScript/task_0/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | parser: '@typescript-eslint/parser', 3 | extends: [ 4 | 'plugin:@typescript-eslint/recommended', // Uses the recommended rules from @typescript-eslint/eslint-plugin 5 | ], 6 | parserOptions: { 7 | ecmaVersion: 2018, 8 | sourceType: 'module', 9 | }, 10 | rules: { 11 | }, 12 | }; 13 | -------------------------------------------------------------------------------- /0x04-TypeScript/task_1/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | parser: '@typescript-eslint/parser', 3 | extends: [ 4 | 'plugin:@typescript-eslint/recommended', // Uses the recommended rules from @typescript-eslint/eslint-plugin 5 | ], 6 | parserOptions: { 7 | ecmaVersion: 2018, 8 | sourceType: 'module', 9 | }, 10 | rules: { 11 | }, 12 | }; 13 | -------------------------------------------------------------------------------- /0x04-TypeScript/task_2/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | parser: '@typescript-eslint/parser', 3 | extends: [ 4 | 'plugin:@typescript-eslint/recommended', // Uses the recommended rules from @typescript-eslint/eslint-plugin 5 | ], 6 | parserOptions: { 7 | ecmaVersion: 2018, 8 | sourceType: 'module', 9 | }, 10 | rules: { 11 | }, 12 | }; 13 | -------------------------------------------------------------------------------- /0x04-TypeScript/task_3/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | parser: '@typescript-eslint/parser', 3 | extends: [ 4 | 'plugin:@typescript-eslint/recommended', // Uses the recommended rules from @typescript-eslint/eslint-plugin 5 | ], 6 | parserOptions: { 7 | ecmaVersion: 2018, 8 | sourceType: 'module', 9 | }, 10 | rules: { 11 | }, 12 | }; 13 | -------------------------------------------------------------------------------- /0x04-TypeScript/task_4/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | parser: '@typescript-eslint/parser', 3 | extends: [ 4 | 'plugin:@typescript-eslint/recommended', // Uses the recommended rules from @typescript-eslint/eslint-plugin 5 | ], 6 | parserOptions: { 7 | ecmaVersion: 2018, 8 | sourceType: 'module', 9 | }, 10 | rules: { 11 | }, 12 | }; 13 | -------------------------------------------------------------------------------- /0x04-TypeScript/task_5/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | parser: '@typescript-eslint/parser', 3 | extends: [ 4 | 'plugin:@typescript-eslint/recommended', // Uses the recommended rules from @typescript-eslint/eslint-plugin 5 | ], 6 | parserOptions: { 7 | ecmaVersion: 2018, 8 | sourceType: 'module', 9 | }, 10 | rules: { 11 | }, 12 | }; 13 | -------------------------------------------------------------------------------- /0x01-ES6_promise/3-all.js: -------------------------------------------------------------------------------- 1 | import { uploadPhoto, createUser } from './utils'; 2 | 3 | export default function handleProfileSignup() { 4 | return Promise 5 | .all([uploadPhoto(), createUser()]) 6 | .then((res) => { 7 | console.log(`${res[0].body} ${res[1].firstName} ${res[1].lastName}`); 8 | }) 9 | .catch(() => console.log('Signup system offline')); 10 | } 11 | -------------------------------------------------------------------------------- /0x02-ES6_classes/0-classroom.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Represents a class room. 3 | */ 4 | export default class ClassRoom { 5 | /** 6 | * Creates a new @see {@link ClassRoom}. 7 | * @param {Number} maxStudentsSize - The maximum number of 8 | * students in the class. 9 | */ 10 | constructor(maxStudentsSize) { 11 | this._maxStudentsSize = maxStudentsSize; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /0x01-ES6_promise/100-await.js: -------------------------------------------------------------------------------- 1 | import { uploadPhoto, createUser } from './utils'; 2 | 3 | export default async function asyncUploadUser() { 4 | let res = {}; 5 | 6 | try { 7 | const photo = await uploadPhoto(); 8 | const user = await createUser(); 9 | res = { photo, user }; 10 | } catch (err) { 11 | res = { photo: null, user: null }; 12 | } 13 | return res; 14 | } 15 | -------------------------------------------------------------------------------- /0x03-ES6_data_manipulation/9-groceries_list.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Retrieves a map of grocery names and their quantity. 3 | * 4 | * @returns {Map} 5 | */ 6 | export default function groceriesList() { 7 | const values = [ 8 | ['Apples', 10], 9 | ['Tomatoes', 10], 10 | ['Pasta', 1], 11 | ['Rice', 1], 12 | ['Banana', 5], 13 | ]; 14 | return new Map(values); 15 | } 16 | -------------------------------------------------------------------------------- /0x04-TypeScript/task_3/js/crud.js: -------------------------------------------------------------------------------- 1 | export function insertRow(row) { 2 | console.log('Insert row', row); 3 | return Math.floor(Math.random() * Math.floor(1000)); 4 | } 5 | 6 | export function deleteRow(rowId) { 7 | console.log('Delete row id', rowId); 8 | return; 9 | } 10 | 11 | export function updateRow(rowId, row) { 12 | console.log(`Update row ${rowId}`, row); 13 | 14 | return rowId; 15 | } 16 | -------------------------------------------------------------------------------- /0x05-Node_JS_basic/1-stdin.js: -------------------------------------------------------------------------------- 1 | process.stdout.write('Welcome to Holberton School, what is your name?\n'); 2 | 3 | process.stdin.on('readable', () => { 4 | const chunk = process.stdin.read(); 5 | 6 | if (chunk) { 7 | process.stdout.write(`Your name is: ${chunk}`); 8 | } 9 | }); 10 | 11 | process.stdin.on('end', () => { 12 | process.stdout.write('This important software is now closing\n'); 13 | }); 14 | -------------------------------------------------------------------------------- /0x00-ES6_basic/8-getBudgetCurrentYear.js: -------------------------------------------------------------------------------- 1 | function getCurrentYear() { 2 | const date = new Date(); 3 | return date.getFullYear(); 4 | } 5 | 6 | export default function getBudgetForCurrentYear(income, gdp, capita) { 7 | const budget = { 8 | [`income-${getCurrentYear()}`]: income, 9 | [`gdp-${getCurrentYear()}`]: gdp, 10 | [`capita-${getCurrentYear()}`]: capita, 11 | }; 12 | 13 | return budget; 14 | } 15 | -------------------------------------------------------------------------------- /0x04-TypeScript/task_3/js/main.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import { RowID, RowElement } from './interface'; 3 | import * as CRUD from './crud'; 4 | 5 | const row: RowElement = { 6 | firstName: 'Guillaume', 7 | lastName: 'Salva', 8 | }; 9 | const newRowID: RowID = CRUD.insertRow(row); 10 | const updatedRow: RowElement = {...row, age: 23}; 11 | CRUD.updateRow(newRowID, updatedRow); 12 | CRUD.deleteRow(newRowID); 13 | -------------------------------------------------------------------------------- /0x06-unittests_in_js/1-calcul.js: -------------------------------------------------------------------------------- 1 | const calculateNumber = (type, a, b) => { 2 | if (type === 'SUM') { 3 | return Math.round(a) + Math.round(b); 4 | } 5 | if (type === 'SUBTRACT') { 6 | return Math.round(a) - Math.round(b); 7 | } 8 | if (type === 'DIVIDE') { 9 | return Math.round(b) === 0 ? 'Error' : Math.round(a) / Math.round(b); 10 | } 11 | return 0; 12 | }; 13 | 14 | module.exports = calculateNumber; 15 | -------------------------------------------------------------------------------- /0x06-unittests_in_js/2-calcul_chai.js: -------------------------------------------------------------------------------- 1 | const calculateNumber = (type, a, b) => { 2 | if (type === 'SUM') { 3 | return Math.round(a) + Math.round(b); 4 | } 5 | if (type === 'SUBTRACT') { 6 | return Math.round(a) - Math.round(b); 7 | } 8 | if (type === 'DIVIDE') { 9 | return Math.round(b) === 0 ? 'Error' : Math.round(a) / Math.round(b); 10 | } 11 | return 0; 12 | }; 13 | 14 | module.exports = calculateNumber; 15 | -------------------------------------------------------------------------------- /0x03-ES6_data_manipulation/0-get_list_students.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Retrieves a list of students. 3 | * @returns {{id: Number, firstName: String, location: String}[]} 4 | */ 5 | export default function getListStudents() { 6 | return [ 7 | { id: 1, firstName: 'Guillaume', location: 'San Francisco' }, 8 | { id: 2, firstName: 'James', location: 'Columbia' }, 9 | { id: 5, firstName: 'Serena', location: 'San Francisco' }, 10 | ]; 11 | } 12 | -------------------------------------------------------------------------------- /0x03-ES6_data_manipulation/1-get_list_student_ids.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Retrieves ids from a list of students. 3 | * @param {{ 4 | * id: Number, 5 | * firstName: String, 6 | * location: String 7 | * }[]} students - The list of students. 8 | * 9 | * @returns 10 | */ 11 | export default function getListStudentIds(students) { 12 | if (students instanceof Array) { 13 | return students.map((student) => student.id); 14 | } 15 | return []; 16 | } 17 | -------------------------------------------------------------------------------- /0x06-unittests_in_js/utils.js: -------------------------------------------------------------------------------- 1 | const Utils = { 2 | calculateNumber(type, a, b) { 3 | if (type === 'SUM') { 4 | return Math.round(a) + Math.round(b); 5 | } 6 | if (type === 'SUBTRACT') { 7 | return Math.round(a) - Math.round(b); 8 | } 9 | if (type === 'DIVIDE') { 10 | return Math.round(b) === 0 ? 'Error' : Math.round(a) / Math.round(b); 11 | } 12 | return 0; 13 | }, 14 | }; 15 | 16 | module.exports = Utils; 17 | -------------------------------------------------------------------------------- /0x00-ES6_basic/9-getFullBudget.js: -------------------------------------------------------------------------------- 1 | import getBudgetObject from './7-getBudgetObject'; 2 | 3 | export default function getFullBudgetObject(income, gdp, capita) { 4 | const budget = getBudgetObject(income, gdp, capita); 5 | const fullBudget = { 6 | ...budget, 7 | getIncomeInDollars(income) { 8 | return `$${income}`; 9 | }, 10 | getIncomeInEuros(income) { 11 | return `${income} euros`; 12 | }, 13 | }; 14 | 15 | return fullBudget; 16 | } 17 | -------------------------------------------------------------------------------- /0x06-unittests_in_js/6-payment_token.test.js: -------------------------------------------------------------------------------- 1 | const { expect } = require('chai'); 2 | const getPaymentTokenFromAPI = require('./6-payment_token'); 3 | 4 | describe('getPaymentTokenFromAPI', () => { 5 | it('getPaymentTokenFromAPI(success), where success == true', (done) => { 6 | getPaymentTokenFromAPI(true) 7 | .then((res) => { 8 | expect(res).to.deep.equal({data: 'Successful response from the API'}); 9 | done(); 10 | }); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /0x02-ES6_classes/6-sky_high.js: -------------------------------------------------------------------------------- 1 | import Building from './5-building'; 2 | 3 | export default class SkyHighBuilding extends Building { 4 | constructor(sqft, floors) { 5 | super(sqft); 6 | this.floors = floors; 7 | } 8 | 9 | get floors() { 10 | return this._floors; 11 | } 12 | 13 | set floors(value) { 14 | this._floors = value; 15 | } 16 | 17 | evacuationWarningMessage() { 18 | return `Evacuate slowly the ${this.floors} floors`; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /0x03-ES6_data_manipulation/10-update_uniq_items.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Changes the quantity of unique grocery items to 100. 3 | * @param {Map} map - A map of the name of a 4 | * grocery and its quantity. 5 | */ 6 | export default function updateUniqueItems(map) { 7 | if (!(map instanceof Map)) { 8 | throw new Error('Cannot process'); 9 | } 10 | map.forEach((value, key) => { 11 | if (value === 1) { 12 | map.set(key, 100); 13 | } 14 | }); 15 | } 16 | -------------------------------------------------------------------------------- /0x02-ES6_classes/7-airport.js: -------------------------------------------------------------------------------- 1 | export default class Airport { 2 | constructor(name, code) { 3 | this.name = name; 4 | this.code = code; 5 | } 6 | 7 | get name() { 8 | return this._name; 9 | } 10 | 11 | set name(value) { 12 | this._name = value; 13 | } 14 | 15 | get code() { 16 | return this._code; 17 | } 18 | 19 | set code(value) { 20 | this._code = value; 21 | } 22 | 23 | get [Symbol.toStringTag]() { 24 | return this._code; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /0x02-ES6_classes/100-evcar.js: -------------------------------------------------------------------------------- 1 | import Car from './10-car'; 2 | 3 | export default class EVCar extends Car { 4 | constructor(brand, motor, color, range) { 5 | super(brand, motor, color); 6 | this.range = range; 7 | } 8 | 9 | get range() { 10 | return this._range; 11 | } 12 | 13 | set range(value) { 14 | this._range = value; 15 | } 16 | 17 | cloneCar() { 18 | const Species = super.constructor[Symbol.species]; 19 | 20 | return new Species(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /0x06-unittests_in_js/8-api/api.test.js: -------------------------------------------------------------------------------- 1 | const request = require('request'); 2 | const { expect } = require('chai'); 3 | 4 | describe('API integration test', () => { 5 | const API_URL = 'http://localhost:7865'; 6 | 7 | it('GET / returns correct response', (done) => { 8 | request.get(`${API_URL}/`, (_err, res, body) => { 9 | expect(res.statusCode).to.be.equal(200); 10 | expect(body).to.be.equal('Welcome to the payment system'); 11 | done(); 12 | }); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /0x01-ES6_promise/6-final-user.js: -------------------------------------------------------------------------------- 1 | import signUpUser from './4-user-promise'; 2 | import uploadPhoto from './5-photo-reject'; 3 | 4 | export default async function handleProfileSignup(firstName, lastName, fileName) { 5 | return Promise 6 | .allSettled([signUpUser(firstName, lastName), uploadPhoto(fileName)]) 7 | .then((res) => ( 8 | res.map((o) => ({ 9 | status: o.status, 10 | value: o.status === 'fulfilled' ? o.value : String(o.reason), 11 | })) 12 | )); 13 | } 14 | -------------------------------------------------------------------------------- /0x06-unittests_in_js/9-api/api.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | 3 | const app = express(); 4 | const PORT = 7865; 5 | 6 | app.get('/', (_, res) => { 7 | res.send('Welcome to the payment system'); 8 | }); 9 | 10 | app.get('/cart/:id(\\d+)', (req, res) => { 11 | const id = req.params.id; 12 | 13 | res.send(`Payment methods for cart ${id}`); 14 | }); 15 | 16 | app.listen(PORT, () => { 17 | console.log(`API available on localhost port ${PORT}`); 18 | }); 19 | 20 | module.exports = app; 21 | -------------------------------------------------------------------------------- /0x00-ES6_basic/6-string-interpolation.js: -------------------------------------------------------------------------------- 1 | export default function getSanFranciscoDescription() { 2 | const year = 2017; 3 | const budget = { 4 | income: '$119,868', 5 | gdp: '$154.2 billion', 6 | capita: '$178,479', 7 | }; 8 | 9 | return `As of ${year}, it was the seventh-highest income county in the United States\ 10 | , with a per capita personal income of ${budget.income}. As of 2015, San Francisco \ 11 | proper had a GDP of ${budget.gdp}, and a GDP per capita of ${budget.capita}.`; 12 | } 13 | -------------------------------------------------------------------------------- /0x02-ES6_classes/5-building.js: -------------------------------------------------------------------------------- 1 | export default class Building { 2 | constructor(sqft) { 3 | this.sqft = sqft; 4 | if (this.constructor !== Building) { 5 | if (typeof this.evacuationWarningMessage !== 'function') { 6 | throw new Error( 7 | 'Class extending Building must override evacuationWarningMessage', 8 | ); 9 | } 10 | } 11 | } 12 | 13 | get sqft() { 14 | return this._sqft; 15 | } 16 | 17 | set sqft(value) { 18 | this._sqft = value; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /0x03-ES6_data_manipulation/2-get_students_by_loc.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Retrieves students in a given location. 3 | * @param {{ 4 | * id: Number, 5 | * firstName: String, 6 | * location: String 7 | * }[]} students - The list of students. 8 | * @param {String} city - The location. 9 | * 10 | * @returns 11 | */ 12 | export default function getStudentsByLocation(students, city) { 13 | if (students instanceof Array) { 14 | return students.filter((student) => student.location === city); 15 | } 16 | return []; 17 | } 18 | -------------------------------------------------------------------------------- /0x03-ES6_data_manipulation/3-get_ids_sum.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Retrieves the sum of ids of a list of students. 3 | * @param {{ 4 | * id: Number, 5 | * firstName: String, 6 | * location: String 7 | * }[]} students - The list of students. 8 | * 9 | * @returns {Number} 10 | */ 11 | export default function getStudentIdsSum(students) { 12 | if (students instanceof Array) { 13 | return students.reduce( 14 | (prevStudent, curStudent) => prevStudent.id || prevStudent + curStudent.id, 15 | 0, 16 | ); 17 | } 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /0x04-TypeScript/task_4/js/subjects/Cpp.ts: -------------------------------------------------------------------------------- 1 | namespace Subjects { 2 | export interface Teacher { 3 | experienceTeachingC?: number; 4 | } 5 | 6 | export class Cpp extends Subjects.Subject { 7 | getRequirements(): string { 8 | return 'Here is the list of requirements for Cpp'; 9 | } 10 | 11 | getAvailableTeacher(): string { 12 | if (!this.teacher || this.teacher.experienceTeachingC <= 0) { 13 | return 'No available teacher'; 14 | } 15 | return `Available Teacher: ${this.teacher.firstName}`; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /0x04-TypeScript/task_4/js/subjects/Java.ts: -------------------------------------------------------------------------------- 1 | namespace Subjects { 2 | export interface Teacher { 3 | experienceTeachingJava?: number; 4 | } 5 | 6 | export class Java extends Subjects.Subject { 7 | getRequirements(): string { 8 | return 'Here is the list of requirements for Java'; 9 | } 10 | 11 | getAvailableTeacher(): string { 12 | if (!this.teacher || this.teacher.experienceTeachingJava <= 0) { 13 | return 'No available teacher'; 14 | } 15 | return `Available Teacher: ${this.teacher.firstName}`; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /0x04-TypeScript/task_4/js/subjects/React.ts: -------------------------------------------------------------------------------- 1 | namespace Subjects { 2 | export interface Teacher { 3 | experienceTeachingReact?: number; 4 | } 5 | 6 | export class React extends Subjects.Subject { 7 | getRequirements(): string { 8 | return 'Here is the list of requirements for React'; 9 | } 10 | 11 | getAvailableTeacher(): string { 12 | if (!this.teacher || this.teacher.experienceTeachingReact <= 0) { 13 | return 'No available teacher'; 14 | } 15 | return `Available Teacher: ${this.teacher.firstName}`; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /0x00-ES6_basic/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "lint": "./node_modules/.bin/eslint", 4 | "check-lint": "lint [0-9]*.js", 5 | "dev": "npx babel-node", 6 | "test": "jest", 7 | "full-test": "./node_modules/.bin/eslint [0-9]*.js && jest" 8 | }, 9 | "devDependencies": { 10 | "@babel/core": "^7.6.0", 11 | "@babel/node": "^7.8.0", 12 | "@babel/preset-env": "^7.6.0", 13 | "eslint": "^6.4.0", 14 | "eslint-config-airbnb-base": "^14.0.0", 15 | "eslint-plugin-import": "^2.18.2", 16 | "eslint-plugin-jest": "^22.17.0", 17 | "jest": "^24.9.0" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /0x01-ES6_promise/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "lint": "./node_modules/.bin/eslint", 4 | "check-lint": "lint [0-9]*.js", 5 | "dev": "npx babel-node", 6 | "test": "jest", 7 | "full-test": "./node_modules/.bin/eslint [0-9]*.js && jest" 8 | }, 9 | "devDependencies": { 10 | "@babel/core": "^7.6.0", 11 | "@babel/node": "^7.8.0", 12 | "@babel/preset-env": "^7.6.0", 13 | "eslint": "^6.4.0", 14 | "eslint-config-airbnb-base": "^14.0.0", 15 | "eslint-plugin-import": "^2.18.2", 16 | "eslint-plugin-jest": "^22.17.0", 17 | "jest": "^24.9.0" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /0x02-ES6_classes/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "lint": "./node_modules/.bin/eslint", 4 | "check-lint": "lint [0-9]*.js", 5 | "dev": "npx babel-node", 6 | "test": "jest", 7 | "full-test": "./node_modules/.bin/eslint [0-9]*.js && jest" 8 | }, 9 | "devDependencies": { 10 | "@babel/core": "^7.6.0", 11 | "@babel/node": "^7.8.0", 12 | "@babel/preset-env": "^7.6.0", 13 | "eslint": "^6.4.0", 14 | "eslint-config-airbnb-base": "^14.0.0", 15 | "eslint-plugin-import": "^2.18.2", 16 | "eslint-plugin-jest": "^22.17.0", 17 | "jest": "^24.9.0" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /0x05-Node_JS_basic/4-http.js: -------------------------------------------------------------------------------- 1 | const http = require('http'); 2 | 3 | const PORT = 1245; 4 | const HOST = 'localhost'; 5 | const app = http.createServer(); 6 | 7 | app.on('request', (_, res) => { 8 | const responseText = 'Hello Holberton School!'; 9 | 10 | res.setHeader('Content-Type', 'text/plain'); 11 | res.setHeader('Content-Length', responseText.length); 12 | res.statusCode = 200; 13 | res.write(Buffer.from(responseText)); 14 | }); 15 | 16 | app.listen(PORT, HOST, () => { 17 | process.stdout.write(`Server listening at -> http://${HOST}:${PORT}\n`); 18 | }); 19 | 20 | module.exports = app; 21 | -------------------------------------------------------------------------------- /0x03-ES6_data_manipulation/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "lint": "./node_modules/.bin/eslint", 4 | "check-lint": "lint [0-9]*.js", 5 | "dev": "npx babel-node", 6 | "test": "jest", 7 | "full-test": "./node_modules/.bin/eslint [0-9]*.js && jest" 8 | }, 9 | "devDependencies": { 10 | "@babel/core": "^7.6.0", 11 | "@babel/node": "^7.8.0", 12 | "@babel/preset-env": "^7.6.0", 13 | "eslint": "^6.4.0", 14 | "eslint-config-airbnb-base": "^14.0.0", 15 | "eslint-plugin-import": "^2.18.2", 16 | "eslint-plugin-jest": "^22.17.0", 17 | "jest": "^24.9.0" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /0x04-TypeScript/task_5/js/main.ts: -------------------------------------------------------------------------------- 1 | export interface MajorCredits { 2 | credits: number & { __brand: 'MajorCredits.credits' }; 3 | } 4 | 5 | export interface MinorCredits { 6 | credits: number & { __brand: 'MinorCredits.credits' }; 7 | } 8 | 9 | export function sumMajorCredits(subject1: MajorCredits, subject2: MajorCredits): MajorCredits { 10 | return { credits: subject1.credits + subject2.credits } as MajorCredits; 11 | } 12 | 13 | export function sumMinorCredits(subject1: MinorCredits, subject2: MinorCredits): MinorCredits { 14 | return { credits: subject1.credits + subject2.credits } as MinorCredits; 15 | } 16 | -------------------------------------------------------------------------------- /0x02-ES6_classes/3-currency.js: -------------------------------------------------------------------------------- 1 | export default class Currency { 2 | constructor(code, name) { 3 | this.code = code; 4 | this.name = name; 5 | } 6 | 7 | get code() { 8 | return this._code; 9 | } 10 | 11 | set code(value) { 12 | this._code = value; 13 | } 14 | 15 | get name() { 16 | return this._name; 17 | } 18 | 19 | set name(value) { 20 | this._name = value; 21 | } 22 | 23 | /** 24 | * Creates the full string representation of this Currency. 25 | * @returns {String} 26 | */ 27 | displayFullCurrency() { 28 | return `${this.name} (${this.code})`; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /0x05-Node_JS_basic/full_server/routes/index.js: -------------------------------------------------------------------------------- 1 | import AppController from '../controllers/AppController'; 2 | import StudentsController from '../controllers/StudentsController'; 3 | 4 | /** 5 | * Binds the routes to the appropriate handler in the 6 | * given Express application. 7 | * @param {Express} app The Express application. 8 | */ 9 | const mapRoutes = (app) => { 10 | app.get('/', AppController.getHomepage); 11 | app.get('/students', StudentsController.getAllStudents); 12 | app.get('/students/:major', StudentsController.getAllStudentsByMajor); 13 | }; 14 | 15 | export default mapRoutes; 16 | module.exports = mapRoutes; 17 | -------------------------------------------------------------------------------- /0x03-ES6_data_manipulation/5-typed_arrays.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Creates a buffer array with a given position set to a given value. 3 | * @param {Number} length - The length of the buffer. 4 | * @param {Number} position - The position to modify. 5 | * @param {Number} value - The value to be stored in the position. 6 | * @returns {DataView} 7 | */ 8 | export default function createInt8TypedArray(length, position, value) { 9 | if (position >= length) { 10 | throw new Error('Position outside range'); 11 | } 12 | const buf = new DataView(new ArrayBuffer(length), 0, length); 13 | buf.setInt8(position, value); 14 | return buf; 15 | } 16 | -------------------------------------------------------------------------------- /0x06-unittests_in_js/3-payment.test.js: -------------------------------------------------------------------------------- 1 | const sinon = require('sinon'); 2 | const Utils = require('./utils'); 3 | const { expect } = require('chai'); 4 | const sendPaymentRequestToApi = require('./3-payment'); 5 | 6 | describe('sendPaymentRequestToApi', () => { 7 | it('sendPaymentRequestToApi uses the calculateNumber method of Utils', () => { 8 | const bigBrother = sinon.spy(Utils); 9 | 10 | sendPaymentRequestToApi(100, 20); 11 | expect(bigBrother.calculateNumber.calledWith('SUM', 100, 20)).to.be.true; 12 | expect(bigBrother.calculateNumber.callCount).to.be.equal(1); 13 | bigBrother.calculateNumber.restore(); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /0x02-ES6_classes/8-hbtn_class.js: -------------------------------------------------------------------------------- 1 | export default class HolbertonClass { 2 | constructor(size, location) { 3 | this.size = size; 4 | this.location = location; 5 | } 6 | 7 | get size() { 8 | return this._size; 9 | } 10 | 11 | set size(value) { 12 | this._size = value; 13 | } 14 | 15 | get location() { 16 | return this._location; 17 | } 18 | 19 | set location(value) { 20 | this._location = value; 21 | } 22 | 23 | [Symbol.toPrimitive](hint) { 24 | if (hint === 'number') { 25 | return this.size; 26 | } 27 | if (hint === 'string') { 28 | return this.location; 29 | } 30 | return this; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /0x00-ES6_basic/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: false, 4 | es6: true, 5 | jest: true, 6 | }, 7 | extends: ["airbnb-base", "plugin:jest/all"], 8 | globals: { 9 | Atomics: "readonly", 10 | SharedArrayBuffer: "readonly", 11 | }, 12 | parserOptions: { 13 | ecmaVersion: 2018, 14 | sourceType: "module", 15 | }, 16 | plugins: ["jest"], 17 | rules: { 18 | "no-console": "off", 19 | "no-shadow": "off", 20 | "no-restricted-syntax": ["error", "LabeledStatement", "WithStatement"], 21 | }, 22 | overrides: [ 23 | { 24 | files: ["*.js"], 25 | excludedFiles: "babel.config.js", 26 | }, 27 | ], 28 | }; 29 | -------------------------------------------------------------------------------- /0x01-ES6_promise/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: false, 4 | es6: true, 5 | jest: true, 6 | }, 7 | extends: ["airbnb-base", "plugin:jest/all"], 8 | globals: { 9 | Atomics: "readonly", 10 | SharedArrayBuffer: "readonly", 11 | }, 12 | parserOptions: { 13 | ecmaVersion: 2018, 14 | sourceType: "module", 15 | }, 16 | plugins: ["jest"], 17 | rules: { 18 | "no-console": "off", 19 | "no-shadow": "off", 20 | "no-restricted-syntax": ["error", "LabeledStatement", "WithStatement"], 21 | }, 22 | overrides: [ 23 | { 24 | files: ["*.js"], 25 | excludedFiles: "babel.config.js", 26 | }, 27 | ], 28 | }; 29 | -------------------------------------------------------------------------------- /0x02-ES6_classes/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: false, 4 | es6: true, 5 | jest: true, 6 | }, 7 | extends: ["airbnb-base", "plugin:jest/all"], 8 | globals: { 9 | Atomics: "readonly", 10 | SharedArrayBuffer: "readonly", 11 | }, 12 | parserOptions: { 13 | ecmaVersion: 2018, 14 | sourceType: "module", 15 | }, 16 | plugins: ["jest"], 17 | rules: { 18 | "max-classes-per-file": "off", 19 | "no-underscore-dangle": "off", 20 | "no-console": "off", 21 | "no-shadow": "off", 22 | "no-restricted-syntax": ["error", "LabeledStatement", "WithStatement"], 23 | }, 24 | overrides: [ 25 | { 26 | files: ["*.js"], 27 | excludedFiles: "babel.config.js", 28 | }, 29 | ], 30 | }; 31 | -------------------------------------------------------------------------------- /0x03-ES6_data_manipulation/100-weak.js: -------------------------------------------------------------------------------- 1 | /** 2 | * A weak map of endpoints and the number of calls made. 3 | */ 4 | export const weakMap = new WeakMap(); 5 | 6 | /** 7 | * The maximum number of calls for an endpoint. 8 | */ 9 | const MAX_ENDPOINT_CALLS = 5; 10 | 11 | /** 12 | * Tracks the number of calls made to an API's endpoint. 13 | * @param {{ 14 | * protocol: String, 15 | * name: String, 16 | * }} endpoint - The endpoint to make a request to. 17 | */ 18 | export function queryAPI(endpoint) { 19 | if (!weakMap.has(endpoint)) { 20 | weakMap.set(endpoint, 0); 21 | } 22 | weakMap.set(endpoint, weakMap.get(endpoint) + 1); 23 | if (weakMap.get(endpoint) >= MAX_ENDPOINT_CALLS) { 24 | throw new Error('Endpoint load is high'); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /0x02-ES6_classes/10-car.js: -------------------------------------------------------------------------------- 1 | export default class Car { 2 | constructor(brand, motor, color) { 3 | this.brand = brand; 4 | this.motor = motor; 5 | this.color = color; 6 | } 7 | 8 | get brand() { 9 | return this._brand; 10 | } 11 | 12 | set brand(value) { 13 | this._brand = value; 14 | } 15 | 16 | get motor() { 17 | return this._motor; 18 | } 19 | 20 | set motor(value) { 21 | this._motor = value; 22 | } 23 | 24 | get color() { 25 | return this._color; 26 | } 27 | 28 | set color(value) { 29 | this._color = value; 30 | } 31 | 32 | static get [Symbol.species]() { 33 | return this; 34 | } 35 | 36 | cloneCar() { 37 | const Species = this.constructor[Symbol.species]; 38 | 39 | return new Species(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /0x04-TypeScript/task_4/js/main.ts: -------------------------------------------------------------------------------- 1 | export const cpp: Subjects.Cpp = new Subjects.Cpp(); 2 | export const java: Subjects.Java = new Subjects.Java(); 3 | export const react: Subjects.React = new Subjects.React(); 4 | export const cTeacher: Subjects.Teacher = { 5 | firstName: 'Dennis', 6 | lastName: 'Ritchie', 7 | experienceTeachingC: 10, 8 | }; 9 | 10 | console.log('C++'); 11 | cpp.setTeacher = cTeacher; 12 | console.log(cpp.getRequirements()); 13 | console.log(cpp.getAvailableTeacher()); 14 | 15 | console.log('Java'); 16 | java.setTeacher = cTeacher; 17 | console.log(java.getRequirements()); 18 | console.log(java.getAvailableTeacher()); 19 | 20 | console.log('React'); 21 | react.setTeacher = cTeacher; 22 | console.log(react.getRequirements()); 23 | console.log(react.getAvailableTeacher()); 24 | -------------------------------------------------------------------------------- /0x06-unittests_in_js/7-skip.test.js: -------------------------------------------------------------------------------- 1 | const { expect } = require('chai'); 2 | 3 | describe('Testing numbers', () => { 4 | it('1 is equal to 1', () => { 5 | expect(1 === 1).to.be.true; 6 | }); 7 | 8 | it('2 is equal to 2', () => { 9 | expect(2 === 2).to.be.true; 10 | }); 11 | 12 | it.skip('1 is equal to 3', () => { 13 | expect(1 === 3).to.be.true; 14 | }); 15 | 16 | it('3 is equal to 3', () => { 17 | expect(3 === 3).to.be.true; 18 | }); 19 | 20 | it('4 is equal to 4', () => { 21 | expect(4 === 4).to.be.true; 22 | }); 23 | 24 | it('5 is equal to 5', () => { 25 | expect(5 === 5).to.be.true; 26 | }); 27 | 28 | it('6 is equal to 6', () => { 29 | expect(6 === 6).to.be.true; 30 | }); 31 | 32 | it('7 is equal to 7', () => { 33 | expect(7 === 7).to.be.true; 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /0x05-Node_JS_basic/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: false, 4 | es6: true, 5 | jest: true, 6 | }, 7 | extends: [ 8 | 'airbnb-base', 9 | 'plugin:jest/all', 10 | ], 11 | globals: { 12 | Atomics: 'readonly', 13 | SharedArrayBuffer: 'readonly', 14 | }, 15 | parserOptions: { 16 | ecmaVersion: 2018, 17 | sourceType: 'module', 18 | }, 19 | plugins: ['jest'], 20 | rules: { 21 | 'max-classes-per-file': 'off', 22 | 'no-underscore-dangle': 'off', 23 | 'no-console': 'off', 24 | 'no-shadow': 'off', 25 | 'no-restricted-syntax': [ 26 | 'error', 27 | 'LabeledStatement', 28 | 'WithStatement', 29 | ], 30 | }, 31 | overrides:[ 32 | { 33 | files: ['*.js'], 34 | excludedFiles: 'babel.config.js', 35 | } 36 | ] 37 | }; 38 | -------------------------------------------------------------------------------- /0x06-unittests_in_js/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: false, 4 | es6: true, 5 | jest: true, 6 | }, 7 | extends: [ 8 | 'airbnb-base', 9 | 'plugin:jest/all', 10 | ], 11 | globals: { 12 | Atomics: 'readonly', 13 | SharedArrayBuffer: 'readonly', 14 | }, 15 | parserOptions: { 16 | ecmaVersion: 2018, 17 | sourceType: 'module', 18 | }, 19 | plugins: ['jest'], 20 | rules: { 21 | 'max-classes-per-file': 'off', 22 | 'no-underscore-dangle': 'off', 23 | 'no-console': 'off', 24 | 'no-shadow': 'off', 25 | 'no-restricted-syntax': [ 26 | 'error', 27 | 'LabeledStatement', 28 | 'WithStatement', 29 | ], 30 | }, 31 | overrides:[ 32 | { 33 | files: ['*.js'], 34 | excludedFiles: 'babel.config.js', 35 | } 36 | ] 37 | }; 38 | -------------------------------------------------------------------------------- /0x03-ES6_data_manipulation/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: false, 4 | es6: true, 5 | jest: true, 6 | }, 7 | extends: [ 8 | 'airbnb-base', 9 | 'plugin:jest/all', 10 | ], 11 | globals: { 12 | Atomics: 'readonly', 13 | SharedArrayBuffer: 'readonly', 14 | }, 15 | parserOptions: { 16 | ecmaVersion: 2018, 17 | sourceType: 'module', 18 | }, 19 | plugins: ['jest'], 20 | rules: { 21 | 'max-classes-per-file': 'off', 22 | 'no-underscore-dangle': 'off', 23 | 'no-console': 'off', 24 | 'no-shadow': 'off', 25 | 'no-restricted-syntax': [ 26 | 'error', 27 | 'LabeledStatement', 28 | 'WithStatement', 29 | ], 30 | }, 31 | overrides:[ 32 | { 33 | files: ['*.js'], 34 | excludedFiles: 'babel.config.js', 35 | } 36 | ] 37 | }; 38 | -------------------------------------------------------------------------------- /0x06-unittests_in_js/4-payment.test.js: -------------------------------------------------------------------------------- 1 | const sinon = require('sinon'); 2 | const Utils = require('./utils'); 3 | const { expect } = require('chai'); 4 | const sendPaymentRequestToApi = require('./4-payment'); 5 | 6 | describe('sendPaymentRequestToApi', () => { 7 | it('sendPaymentRequestToApi calls console.log with the right arguments', () => { 8 | const bigBrother = sinon.spy(console); 9 | const dummy = sinon.stub(Utils, 'calculateNumber'); 10 | 11 | dummy.returns(10); 12 | sendPaymentRequestToApi(100, 20); 13 | expect(dummy.calledWith('SUM', 100, 20)).to.be.true; 14 | expect(dummy.callCount).to.be.equal(1); 15 | expect(bigBrother.log.calledWith('The total is: 10')).to.be.true; 16 | expect(bigBrother.log.callCount).to.be.equal(1); 17 | dummy.restore(); 18 | bigBrother.log.restore(); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /0x06-unittests_in_js/10-api/api.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | 3 | const app = express(); 4 | const PORT = 7865; 5 | 6 | app.use(express.json()); 7 | 8 | app.get('/', (_req, res) => { 9 | res.send('Welcome to the payment system'); 10 | }); 11 | 12 | app.get('/cart/:id(\\d+)', (req, res) => { 13 | const id = req.params.id; 14 | 15 | res.send(`Payment methods for cart ${id}`); 16 | }); 17 | 18 | app.get('/available_payments', (_req, res) => { 19 | res.json({ payment_methods: { credit_cards: true, paypal: false } }); 20 | }); 21 | 22 | app.post('/login', (req, res) => { 23 | let username = ''; 24 | 25 | if (req.body) { 26 | username = req.body.userName; 27 | } 28 | 29 | res.send(`Welcome ${username}`); 30 | }); 31 | 32 | app.listen(PORT, () => { 33 | console.log(`API available on localhost port ${PORT}`); 34 | }); 35 | 36 | module.exports = app; 37 | -------------------------------------------------------------------------------- /0x03-ES6_data_manipulation/8-clean_set.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Joins a set of strings with a dash after stripping the strings of 3 | * a leading sub string. 4 | * @param {Set} set - A collection of strings. 5 | * @param {String} startString - The string to strip from the beginning 6 | * of each item in the set. 7 | * @returns {String} 8 | */ 9 | export default function cleanSet(set, startString) { 10 | const parts = []; 11 | if (!set || !startString || !(set instanceof Set) || typeof startString !== 'string') { 12 | return ''; 13 | } 14 | for (const value of set.values()) { 15 | if (typeof value === 'string' && value.startsWith(startString)) { 16 | const valueSubStr = value.substring(startString.length); 17 | 18 | if (valueSubStr && valueSubStr !== value) { 19 | parts.push(valueSubStr); 20 | } 21 | } 22 | } 23 | return parts.join('-'); 24 | } 25 | -------------------------------------------------------------------------------- /0x04-TypeScript/task_0/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 3 | const { CleanWebpackPlugin } = require('clean-webpack-plugin'); 4 | const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); 5 | 6 | module.exports = { 7 | entry: "./js/main.ts", 8 | devtool: "inline-source-map", 9 | module: { 10 | rules: [ 11 | { 12 | test: /\.tsx?$/, 13 | loader: 'ts-loader', 14 | options: { 15 | transpileOnly: true 16 | } 17 | } 18 | ] 19 | }, 20 | resolve: { 21 | extensions: [".tsx", ".ts", ".js"] 22 | }, 23 | devServer: { 24 | contentBase: "./dist" 25 | }, 26 | plugins: [ 27 | new ForkTsCheckerWebpackPlugin(), 28 | new CleanWebpackPlugin(), 29 | new HtmlWebpackPlugin({ 30 | title: "Development" 31 | }) 32 | ], 33 | output: { 34 | filename: "bundle.js", 35 | path: path.resolve(__dirname, "dist") 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /0x04-TypeScript/task_1/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 3 | const { CleanWebpackPlugin } = require('clean-webpack-plugin'); 4 | const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); 5 | 6 | module.exports = { 7 | entry: "./js/main.ts", 8 | devtool: "inline-source-map", 9 | module: { 10 | rules: [ 11 | { 12 | test: /\.tsx?$/, 13 | loader: 'ts-loader', 14 | options: { 15 | transpileOnly: true 16 | } 17 | } 18 | ] 19 | }, 20 | resolve: { 21 | extensions: [".tsx", ".ts", ".js"] 22 | }, 23 | devServer: { 24 | contentBase: "./dist" 25 | }, 26 | plugins: [ 27 | new ForkTsCheckerWebpackPlugin(), 28 | new CleanWebpackPlugin(), 29 | new HtmlWebpackPlugin({ 30 | title: "Development" 31 | }) 32 | ], 33 | output: { 34 | filename: "bundle.js", 35 | path: path.resolve(__dirname, "dist") 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /0x04-TypeScript/task_2/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 3 | const { CleanWebpackPlugin } = require('clean-webpack-plugin'); 4 | const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); 5 | 6 | module.exports = { 7 | entry: "./js/main.ts", 8 | devtool: "inline-source-map", 9 | module: { 10 | rules: [ 11 | { 12 | test: /\.tsx?$/, 13 | loader: 'ts-loader', 14 | options: { 15 | transpileOnly: true 16 | } 17 | } 18 | ] 19 | }, 20 | resolve: { 21 | extensions: [".tsx", ".ts", ".js"] 22 | }, 23 | devServer: { 24 | contentBase: "./dist" 25 | }, 26 | plugins: [ 27 | new ForkTsCheckerWebpackPlugin(), 28 | new CleanWebpackPlugin(), 29 | new HtmlWebpackPlugin({ 30 | title: "Development" 31 | }) 32 | ], 33 | output: { 34 | filename: "bundle.js", 35 | path: path.resolve(__dirname, "dist") 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /0x04-TypeScript/task_3/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 3 | const { CleanWebpackPlugin } = require('clean-webpack-plugin'); 4 | const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); 5 | 6 | module.exports = { 7 | entry: "./js/main.ts", 8 | devtool: "inline-source-map", 9 | module: { 10 | rules: [ 11 | { 12 | test: /\.tsx?$/, 13 | loader: 'ts-loader', 14 | options: { 15 | transpileOnly: true 16 | } 17 | } 18 | ] 19 | }, 20 | resolve: { 21 | extensions: [".tsx", ".ts", ".js"] 22 | }, 23 | devServer: { 24 | contentBase: "./dist" 25 | }, 26 | plugins: [ 27 | new ForkTsCheckerWebpackPlugin(), 28 | new CleanWebpackPlugin(), 29 | new HtmlWebpackPlugin({ 30 | title: "Development" 31 | }) 32 | ], 33 | output: { 34 | filename: "bundle.js", 35 | path: path.resolve(__dirname, "dist") 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /0x04-TypeScript/task_4/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 3 | const { CleanWebpackPlugin } = require('clean-webpack-plugin'); 4 | const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); 5 | 6 | module.exports = { 7 | entry: "./js/main.ts", 8 | devtool: "inline-source-map", 9 | module: { 10 | rules: [ 11 | { 12 | test: /\.tsx?$/, 13 | loader: 'ts-loader', 14 | options: { 15 | transpileOnly: true 16 | } 17 | } 18 | ] 19 | }, 20 | resolve: { 21 | extensions: [".tsx", ".ts", ".js"] 22 | }, 23 | devServer: { 24 | contentBase: "./dist" 25 | }, 26 | plugins: [ 27 | new ForkTsCheckerWebpackPlugin(), 28 | new CleanWebpackPlugin(), 29 | new HtmlWebpackPlugin({ 30 | title: "Development" 31 | }) 32 | ], 33 | output: { 34 | filename: "bundle.js", 35 | path: path.resolve(__dirname, "dist") 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /0x04-TypeScript/task_5/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 3 | const { CleanWebpackPlugin } = require('clean-webpack-plugin'); 4 | const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); 5 | 6 | module.exports = { 7 | entry: "./js/main.ts", 8 | devtool: "inline-source-map", 9 | module: { 10 | rules: [ 11 | { 12 | test: /\.tsx?$/, 13 | loader: 'ts-loader', 14 | options: { 15 | transpileOnly: true 16 | } 17 | } 18 | ] 19 | }, 20 | resolve: { 21 | extensions: [".tsx", ".ts", ".js"] 22 | }, 23 | devServer: { 24 | contentBase: "./dist" 25 | }, 26 | plugins: [ 27 | new ForkTsCheckerWebpackPlugin(), 28 | new CleanWebpackPlugin(), 29 | new HtmlWebpackPlugin({ 30 | title: "Development" 31 | }) 32 | ], 33 | output: { 34 | filename: "bundle.js", 35 | path: path.resolve(__dirname, "dist") 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /0x06-unittests_in_js/8-api/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "8-api", 3 | "version": "1.0.0", 4 | "description": "A simple API for learning basic integration testing in NodeJS.", 5 | "main": "api.js", 6 | "author": "abdallah", 7 | "private": true, 8 | "license": "MIT", 9 | "scripts": { 10 | "test": "node ./node_modules/mocha/bin/mocha" 11 | }, 12 | "dependencies": { 13 | "express": "^4.17.1" 14 | }, 15 | "devDependencies": { 16 | "chai": "^4.2.0", 17 | "mocha": "^6.2.2", 18 | "request": "^2.88.0", 19 | "sinon": "^7.5.0" 20 | }, 21 | "repository": { 22 | "type": "git", 23 | "url": "https://github.com/B3zaleel/alx-backend-javascript" 24 | }, 25 | "bugs": { 26 | "url": "https://github.com/B3zaleel/alx-backend-javascript/issues" 27 | }, 28 | "homepage": "https://github.com/B3zaleel/alx-backend-javascript/tree/main/0x06-unittests_in_js/8-api", 29 | "engines": { 30 | "node": "16.x", 31 | "npm": "8.x", 32 | "yarn": "1.x" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /0x06-unittests_in_js/9-api/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "9-api", 3 | "version": "1.0.0", 4 | "description": "A simple API for learning basic integration testing in NodeJS.", 5 | "main": "api.js", 6 | "author": "abdallah", 7 | "private": true, 8 | "license": "MIT", 9 | "scripts": { 10 | "test": "node ./node_modules/mocha/bin/mocha" 11 | }, 12 | "dependencies": { 13 | "express": "^4.17.1" 14 | }, 15 | "devDependencies": { 16 | "chai": "^4.2.0", 17 | "mocha": "^6.2.2", 18 | "request": "^2.88.0", 19 | "sinon": "^7.5.0" 20 | }, 21 | "repository": { 22 | "type": "git", 23 | "url": "https://github.com/B3zaleel/alx-backend-javascript" 24 | }, 25 | "bugs": { 26 | "url": "https://github.com/B3zaleel/alx-backend-javascript/issues" 27 | }, 28 | "homepage": "https://github.com/B3zaleel/alx-backend-javascript/tree/main/0x06-unittests_in_js/9-api", 29 | "engines": { 30 | "node": "16.x", 31 | "npm": "8.x", 32 | "yarn": "1.x" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /0x06-unittests_in_js/10-api/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "10-api", 3 | "version": "1.0.0", 4 | "description": "A simple API for learning basic integration testing in NodeJS.", 5 | "main": "api.js", 6 | "author": "abdallah", 7 | "private": true, 8 | "license": "MIT", 9 | "scripts": { 10 | "test": "node ./node_modules/mocha/bin/mocha" 11 | }, 12 | "dependencies": { 13 | "express": "^4.17.1" 14 | }, 15 | "devDependencies": { 16 | "chai": "^4.2.0", 17 | "mocha": "^6.2.2", 18 | "request": "^2.88.0", 19 | "sinon": "^7.5.0" 20 | }, 21 | "repository": { 22 | "type": "git", 23 | "url": "https://github.com/B3zaleel/alx-backend-javascript" 24 | }, 25 | "bugs": { 26 | "url": "https://github.com/B3zaleel/alx-backend-javascript/issues" 27 | }, 28 | "homepage": "https://github.com/B3zaleel/alx-backend-javascript/tree/main/0x06-unittests_in_js/10-api", 29 | "engines": { 30 | "node": "16.x", 31 | "npm": "8.x", 32 | "yarn": "1.x" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /0x06-unittests_in_js/5-payment.test.js: -------------------------------------------------------------------------------- 1 | const sinon = require('sinon'); 2 | const { expect } = require('chai'); 3 | const sendPaymentRequestToApi = require('./5-payment'); 4 | 5 | describe('sendPaymentRequestToApi', () => { 6 | let bigBrother; 7 | 8 | beforeEach(() => { 9 | if (!bigBrother) { 10 | bigBrother = sinon.spy(console); 11 | } 12 | }); 13 | 14 | afterEach(() => { 15 | bigBrother.log.resetHistory(); 16 | }); 17 | 18 | it('sendPaymentRequestToApi(100, 20) logs "The total is: 120" to the console', () => { 19 | sendPaymentRequestToApi(100, 20); 20 | expect(bigBrother.log.calledWith('The total is: 120')).to.be.true; 21 | expect(bigBrother.log.calledOnce).to.be.true; 22 | }); 23 | 24 | it('sendPaymentRequestToApi(10, 10) logs "The total is: 20" to the console', () => { 25 | sendPaymentRequestToApi(10, 10); 26 | expect(bigBrother.log.calledWith('The total is: 20')).to.be.true; 27 | expect(bigBrother.log.calledOnce).to.be.true; 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /0x04-TypeScript/task_0/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript_dependencies", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start-dev": "webpack-dev-server --open", 8 | "build": "webpack", 9 | "test": "jest" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC", 14 | "devDependencies": { 15 | "@babel/plugin-proposal-export-default-from": "^7.5.2", 16 | "@babel/preset-typescript": "^7.7.2", 17 | "@types/jest": "^24.0.23", 18 | "@typescript-eslint/eslint-plugin": "^2.4.0", 19 | "@typescript-eslint/parser": "^2.4.0", 20 | "clean-webpack-plugin": "^3.0.0", 21 | "fork-ts-checker-webpack-plugin": "^1.5.1", 22 | "html-webpack-plugin": "^3.2.0", 23 | "jest": "^24.9.0", 24 | "source-map": "^0.7.3", 25 | "ts-jest": "^24.1.0", 26 | "ts-loader": "^6.2.0", 27 | "typescript": "^3.6.4", 28 | "webpack": "^4.41.2", 29 | "webpack-cli": "^3.3.9", 30 | "webpack-dev-server": "^3.8.2" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /0x04-TypeScript/task_1/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript_dependencies", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start-dev": "webpack-dev-server --open", 8 | "build": "webpack", 9 | "test": "jest" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC", 14 | "devDependencies": { 15 | "@babel/plugin-proposal-export-default-from": "^7.5.2", 16 | "@babel/preset-typescript": "^7.7.2", 17 | "@types/jest": "^24.0.23", 18 | "@typescript-eslint/eslint-plugin": "^2.4.0", 19 | "@typescript-eslint/parser": "^2.4.0", 20 | "clean-webpack-plugin": "^3.0.0", 21 | "fork-ts-checker-webpack-plugin": "^1.5.1", 22 | "html-webpack-plugin": "^3.2.0", 23 | "jest": "^24.9.0", 24 | "source-map": "^0.7.3", 25 | "ts-jest": "^24.1.0", 26 | "ts-loader": "^6.2.0", 27 | "typescript": "^3.6.4", 28 | "webpack": "^4.41.2", 29 | "webpack-cli": "^3.3.9", 30 | "webpack-dev-server": "^3.8.2" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /0x04-TypeScript/task_2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript_dependencies", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start-dev": "webpack-dev-server --open", 8 | "build": "webpack", 9 | "test": "jest" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC", 14 | "devDependencies": { 15 | "@babel/plugin-proposal-export-default-from": "^7.5.2", 16 | "@babel/preset-typescript": "^7.7.2", 17 | "@types/jest": "^24.0.23", 18 | "@typescript-eslint/eslint-plugin": "^2.4.0", 19 | "@typescript-eslint/parser": "^2.4.0", 20 | "clean-webpack-plugin": "^3.0.0", 21 | "fork-ts-checker-webpack-plugin": "^1.5.1", 22 | "html-webpack-plugin": "^3.2.0", 23 | "jest": "^24.9.0", 24 | "source-map": "^0.7.3", 25 | "ts-jest": "^24.1.0", 26 | "ts-loader": "^6.2.0", 27 | "typescript": "^3.6.4", 28 | "webpack": "^4.41.2", 29 | "webpack-cli": "^3.3.9", 30 | "webpack-dev-server": "^3.8.2" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /0x04-TypeScript/task_3/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript_dependencies", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start-dev": "webpack-dev-server --open", 8 | "build": "webpack", 9 | "test": "jest" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC", 14 | "devDependencies": { 15 | "@babel/plugin-proposal-export-default-from": "^7.5.2", 16 | "@babel/preset-typescript": "^7.7.2", 17 | "@types/jest": "^24.0.23", 18 | "@typescript-eslint/eslint-plugin": "^2.4.0", 19 | "@typescript-eslint/parser": "^2.4.0", 20 | "clean-webpack-plugin": "^3.0.0", 21 | "fork-ts-checker-webpack-plugin": "^1.5.1", 22 | "html-webpack-plugin": "^3.2.0", 23 | "jest": "^24.9.0", 24 | "source-map": "^0.7.3", 25 | "ts-jest": "^24.1.0", 26 | "ts-loader": "^6.2.0", 27 | "typescript": "^3.6.4", 28 | "webpack": "^4.41.2", 29 | "webpack-cli": "^3.3.9", 30 | "webpack-dev-server": "^3.8.2" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /0x04-TypeScript/task_5/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript_dependencies", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start-dev": "webpack-dev-server --open", 8 | "build": "webpack", 9 | "test": "jest" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC", 14 | "devDependencies": { 15 | "@babel/plugin-proposal-export-default-from": "^7.5.2", 16 | "@babel/preset-typescript": "^7.7.2", 17 | "@types/jest": "^24.0.23", 18 | "@typescript-eslint/eslint-plugin": "^2.4.0", 19 | "@typescript-eslint/parser": "^2.4.0", 20 | "clean-webpack-plugin": "^3.0.0", 21 | "fork-ts-checker-webpack-plugin": "^1.5.1", 22 | "html-webpack-plugin": "^3.2.0", 23 | "jest": "^24.9.0", 24 | "source-map": "^0.7.3", 25 | "ts-jest": "^24.1.0", 26 | "ts-loader": "^6.2.0", 27 | "typescript": "^3.6.4", 28 | "webpack": "^4.41.2", 29 | "webpack-cli": "^3.3.9", 30 | "webpack-dev-server": "^3.8.2" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /0x04-TypeScript/task_4/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "task_4", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start-dev": "webpack-dev-server --open", 8 | "build": "webpack", 9 | "test": "echo \"Error: no test specified\" && exit 1" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC", 14 | "devDependencies": { 15 | "@babel/plugin-proposal-export-default-from": "^7.5.2", 16 | "@babel/preset-typescript": "^7.7.2", 17 | "@types/jest": "^24.0.23", 18 | "@typescript-eslint/eslint-plugin": "^2.4.0", 19 | "@typescript-eslint/parser": "^2.4.0", 20 | "clean-webpack-plugin": "^3.0.0", 21 | "fork-ts-checker-webpack-plugin": "^1.5.1", 22 | "html-webpack-plugin": "^3.2.0", 23 | "jest": "^24.9.0", 24 | "source-map": "^0.7.3", 25 | "ts-jest": "^24.1.0", 26 | "ts-loader": "^6.2.0", 27 | "typescript": "^3.6.4", 28 | "webpack": "^4.41.2", 29 | "webpack-cli": "^3.3.9", 30 | "webpack-dev-server": "^3.8.2" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /0x03-ES6_data_manipulation/4-update_grade_by_city.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Updates the grades of a list of students in a given city. 3 | * @param {{ 4 | * id: Number, 5 | * firstName: String, 6 | * location: String 7 | * }[]} students - The list of students. 8 | * @param {*} city - The city of students. 9 | * @param {{ 10 | * studentId: Number, 11 | * grade: Number, 12 | * }[]} newGrades - The new grades to be given to a student. 13 | * @returns {{id: Number, firstName: String, location: String}[]} 14 | */ 15 | export default function updateStudentGradeByCity(students, city, newGrades) { 16 | const defaultGrade = { grade: 'N/A' }; 17 | 18 | if (students instanceof Array) { 19 | return students 20 | .filter((student) => student.location === city) 21 | .map((student) => ({ 22 | id: student.id, 23 | firstName: student.firstName, 24 | location: student.location, 25 | grade: (newGrades 26 | .filter((grade) => grade.studentId === student.id) 27 | .pop() || defaultGrade).grade, 28 | })); 29 | } 30 | return []; 31 | } 32 | -------------------------------------------------------------------------------- /0x02-ES6_classes/4-pricing.js: -------------------------------------------------------------------------------- 1 | import Currency from './3-currency'; 2 | 3 | export default class Pricing { 4 | constructor(amount, currency) { 5 | this.amount = amount; 6 | this.currency = currency; 7 | } 8 | 9 | get amount() { 10 | return this._amount; 11 | } 12 | 13 | set amount(value) { 14 | if (typeof value !== 'number') { 15 | throw new TypeError('amount must be a number'); 16 | } 17 | this._amount = value; 18 | } 19 | 20 | /** 21 | * @returns {Currency} 22 | */ 23 | get currency() { 24 | return this._currency; 25 | } 26 | 27 | /** 28 | * @param {Currency} value 29 | */ 30 | set currency(value) { 31 | if (!(value instanceof Currency)) { 32 | throw new TypeError('currency must be a Currency'); 33 | } 34 | this._currency = value; 35 | } 36 | 37 | displayFullPrice() { 38 | return `${this.amount} ${this.currency.name} (${this.currency.code})`; 39 | } 40 | 41 | static convertPrice(amount, conversionRate) { 42 | if (typeof amount !== 'number') { 43 | throw new TypeError('amount must be a number'); 44 | } 45 | if (typeof conversionRate !== 'number') { 46 | throw new TypeError('conversionRate must be a number'); 47 | } 48 | return amount * conversionRate; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /0x06-unittests_in_js/9-api/api.test.js: -------------------------------------------------------------------------------- 1 | const request = require('request'); 2 | const { expect } = require('chai'); 3 | 4 | describe('API integration test', () => { 5 | const API_URL = 'http://localhost:7865'; 6 | 7 | it('GET / returns correct response', (done) => { 8 | request.get(`${API_URL}/`, (_err, res, body) => { 9 | expect(res.statusCode).to.be.equal(200); 10 | expect(body).to.be.equal('Welcome to the payment system'); 11 | done(); 12 | }); 13 | }); 14 | 15 | it('GET /cart/:id returns correct response for valid :id', (done) => { 16 | request.get(`${API_URL}/cart/47`, (_err, res, body) => { 17 | expect(res.statusCode).to.be.equal(200); 18 | expect(body).to.be.equal('Payment methods for cart 47'); 19 | done(); 20 | }); 21 | }); 22 | 23 | it('GET /cart/:id returns 404 response for negative number values in :id', (done) => { 24 | request.get(`${API_URL}/cart/-47`, (_err, res, _body) => { 25 | expect(res.statusCode).to.be.equal(404); 26 | done(); 27 | }); 28 | }); 29 | 30 | it('GET /cart/:id returns 404 response for non-numeric values in :id', (done) => { 31 | request.get(`${API_URL}/cart/d200-44a5-9de6`, (_err, res, _body) => { 32 | expect(res.statusCode).to.be.equal(404); 33 | done(); 34 | }); 35 | }); 36 | }); 37 | -------------------------------------------------------------------------------- /0x06-unittests_in_js/0-calcul.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | const calculateNumber = require('./0-calcul'); 3 | 4 | describe('calculateNumber', () => { 5 | it('floating point whole numbers', () => { 6 | assert.strictEqual(calculateNumber(1.0, 2.0), 3); 7 | }); 8 | 9 | it('rounding down b\'s floating point fractional number', () => { 10 | assert.strictEqual(calculateNumber(1.0, 2.4), 3); 11 | }); 12 | 13 | it('rounding down a and b\'s floating point fractional number', () => { 14 | assert.strictEqual(calculateNumber(1.4, 2.4), 3); 15 | }); 16 | 17 | it('rounding down a\'s floating point fractional number', () => { 18 | assert.strictEqual(calculateNumber(1.4, 2.0), 3); 19 | }); 20 | 21 | it('rounding up b\'s floating point fractional numbers', () => { 22 | assert.strictEqual(calculateNumber(1.0, 2.5), 4); 23 | }); 24 | 25 | it('rounding up a and b\'s floating point fractional numbers', () => { 26 | assert.strictEqual(calculateNumber(2.6, 2.5), 6); 27 | }); 28 | 29 | it('rounding up a\'s floating point fractional numbers', () => { 30 | assert.strictEqual(calculateNumber(2.6, 2.0), 5); 31 | }); 32 | 33 | it('rounding down a and b floating point fractional numbers with trailing 9\'s', () => { 34 | assert.strictEqual(calculateNumber(2.499999, 3.499999), 5); 35 | }); 36 | }); 37 | -------------------------------------------------------------------------------- /0x04-TypeScript/task_1/js/main.ts: -------------------------------------------------------------------------------- 1 | export interface Teacher { 2 | readonly firstName: string; 3 | readonly lastName: string; 4 | fullTimeEmployee: boolean; 5 | yearsOfExperience?: number; 6 | location: string; 7 | [index:string]: any; 8 | } 9 | 10 | export interface Directors extends Teacher { 11 | numberOfReports: number; 12 | } 13 | 14 | export interface printTeacherFunction { 15 | (firstName: string, lastName: string): string; 16 | } 17 | 18 | export function printTeacher(firstName: string, lastName: string): string { 19 | return `${firstName[0]}. ${lastName}`; 20 | } 21 | 22 | export interface IStudentClassConstructor { 23 | new (firstName: string, lastName: string): IStudentClass; 24 | } 25 | 26 | export interface IStudentClass { 27 | workOnHomework(): string; 28 | displayName(): string; 29 | } 30 | 31 | export class StudentClass implements IStudentClass { 32 | private _firstName!: string; 33 | private _lastName!: string; 34 | 35 | constructor(firstName: string, lastName: string) { 36 | this._firstName = firstName; 37 | this._lastName = lastName; 38 | } 39 | 40 | workOnHomework() { 41 | return 'Currently working'; 42 | } 43 | 44 | displayName() { 45 | return this._firstName; 46 | } 47 | } 48 | 49 | export function createStudent(ctor: IStudentClassConstructor, firstName: string, lastName: string): IStudentClass { 50 | return new ctor(firstName, lastName); 51 | } 52 | -------------------------------------------------------------------------------- /0x02-ES6_classes/9-hoisting.js: -------------------------------------------------------------------------------- 1 | export class HolbertonClass { 2 | constructor(year, location) { 3 | this._year = year; 4 | this._location = location; 5 | } 6 | 7 | get year() { 8 | return this._year; 9 | } 10 | 11 | get location() { 12 | return this._location; 13 | } 14 | } 15 | 16 | export class StudentHolberton { 17 | constructor(firstName, lastName, holbertonClass) { 18 | this._firstName = firstName; 19 | this._lastName = lastName; 20 | this._holbertonClass = holbertonClass; 21 | } 22 | 23 | get fullName() { 24 | return `${this._firstName} ${this._lastName}`; 25 | } 26 | 27 | get holbertonClass() { 28 | return this._holbertonClass; 29 | } 30 | 31 | get fullStudentDescription() { 32 | return `${this._firstName} ${this._lastName} - \ 33 | ${this._holbertonClass.year} - ${this._holbertonClass.location}`; 34 | } 35 | } 36 | 37 | const class2019 = new HolbertonClass(2019, 'San Francisco'); 38 | const class2020 = new HolbertonClass(2020, 'San Francisco'); 39 | 40 | const student1 = new StudentHolberton('Guillaume', 'Salva', class2020); 41 | const student2 = new StudentHolberton('John', 'Doe', class2020); 42 | const student3 = new StudentHolberton('Albert', 'Clinton', class2019); 43 | const student4 = new StudentHolberton('Donald', 'Bush', class2019); 44 | const student5 = new StudentHolberton('Jason', 'Sandler', class2019); 45 | 46 | const listOfStudents = [student1, student2, student3, student4, student5]; 47 | 48 | export default listOfStudents; 49 | -------------------------------------------------------------------------------- /0x06-unittests_in_js/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "unittests_in_js", 3 | "version": "1.0.0", 4 | "description": "A project for learning the basics of unittests in Node.js.", 5 | "author": "abdallah", 6 | "private": true, 7 | "license": "MIT", 8 | "scripts": { 9 | "lint": "./node_modules/.bin/eslint", 10 | "lint-all": "./node_modules/.bin/eslint [0-9]*.js", 11 | "lint-fix-all": "./node_modules/.bin/eslint --fix [0-9]*.js", 12 | "test": "node ./node_modules/mocha/bin/mocha --require babel-register --exit", 13 | "dev": "nodemon --exec babel-node --presets babel-preset-env ./full_server/server.js ./database.csv" 14 | }, 15 | "dependencies": { 16 | "chai-http": "^4.3.0", 17 | "express": "^4.17.1" 18 | }, 19 | "devDependencies": { 20 | "babel-cli": "^6.26.0", 21 | "babel-preset-env": "^1.7.0", 22 | "nodemon": "^2.0.2", 23 | "eslint": "^6.4.0", 24 | "eslint-config-airbnb-base": "^14.0.0", 25 | "eslint-plugin-import": "^2.18.2", 26 | "eslint-plugin-jest": "^22.17.0", 27 | "chai": "^4.2.0", 28 | "mocha": "^6.2.2", 29 | "request": "^2.88.0", 30 | "sinon": "^7.5.0" 31 | }, 32 | "repository": { 33 | "type": "git", 34 | "url": "https://github.com/B3zaleel/alx-backend-javascript" 35 | }, 36 | "bugs": { 37 | "url": "https://github.com/B3zaleel/alx-backend-javascript/issues" 38 | }, 39 | "homepage": "https://github.com/B3zaleel/alx-backend-javascript/blob/main/0x06-unittests_in_js/README.md", 40 | "engines": { 41 | "node": "16.x", 42 | "npm": "8.x", 43 | "yarn": "1.x" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /0x05-Node_JS_basic/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node_js_basics", 3 | "version": "1.0.0", 4 | "description": "A simple project for learning the basics of Node.js for server-side apps.", 5 | "main": "index.js", 6 | "author": "abdallah", 7 | "private": true, 8 | "license": "MIT", 9 | "scripts": { 10 | "lint": "./node_modules/.bin/eslint", 11 | "check-lint": "lint [0-9]*.js", 12 | "lint-all": "./node_modules/.bin/eslint [0-9]*.js", 13 | "lint-fix-all": "./node_modules/.bin/eslint --fix [0-9]*.js", 14 | "test": "./node_modules/mocha/bin/mocha --require babel-register --exit", 15 | "dev": "nodemon --exec babel-node --presets babel-preset-env ./full_server/server.js ./database.csv" 16 | }, 17 | "dependencies": { 18 | "chai-http": "^4.3.0", 19 | "express": "^4.17.1" 20 | }, 21 | "devDependencies": { 22 | "babel-cli": "^6.26.0", 23 | "babel-preset-env": "^1.7.0", 24 | "nodemon": "^2.0.2", 25 | "eslint": "^6.4.0", 26 | "eslint-config-airbnb-base": "^14.0.0", 27 | "eslint-plugin-import": "^2.18.2", 28 | "eslint-plugin-jest": "^22.17.0", 29 | "chai": "^4.2.0", 30 | "mocha": "^6.2.2", 31 | "request": "^2.88.0", 32 | "sinon": "^7.5.0" 33 | }, 34 | "repository": { 35 | "type": "git", 36 | "url": "https://github.com/B3zaleel/alx-backend-javascript" 37 | }, 38 | "bugs": { 39 | "url": "https://github.com/B3zaleel/alx-backend-javascript/tree/main/0x05-Node_JS_basic" 40 | }, 41 | "homepage": "https://github.com/B3zaleel/alx-backend-javascript/blob/main/0x05-Node_JS_basic/README.md", 42 | "engines": { 43 | "node": "16.x", 44 | "npm": "8.x", 45 | "yarn": "1.x" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /0x05-Node_JS_basic/full_server/utils.js: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | 3 | /** 4 | * Reads the data of students in a CSV data file. 5 | * @param {String} dataPath The path to the CSV data file. 6 | * @returns {Promise<{ 7 | * String: {firstname: String, lastname: String, age: number}[] 8 | * }>} 9 | */ 10 | const readDatabase = (dataPath) => new Promise((resolve, reject) => { 11 | if (!dataPath) { 12 | reject(new Error('Cannot load the database')); 13 | } 14 | if (dataPath) { 15 | fs.readFile(dataPath, (err, data) => { 16 | if (err) { 17 | reject(new Error('Cannot load the database')); 18 | } 19 | if (data) { 20 | const fileLines = data 21 | .toString('utf-8') 22 | .trim() 23 | .split('\n'); 24 | const studentGroups = {}; 25 | const dbFieldNames = fileLines[0].split(','); 26 | const studentPropNames = dbFieldNames 27 | .slice(0, dbFieldNames.length - 1); 28 | 29 | for (const line of fileLines.slice(1)) { 30 | const studentRecord = line.split(','); 31 | const studentPropValues = studentRecord 32 | .slice(0, studentRecord.length - 1); 33 | const field = studentRecord[studentRecord.length - 1]; 34 | if (!Object.keys(studentGroups).includes(field)) { 35 | studentGroups[field] = []; 36 | } 37 | const studentEntries = studentPropNames 38 | .map((propName, idx) => [propName, studentPropValues[idx]]); 39 | studentGroups[field].push(Object.fromEntries(studentEntries)); 40 | } 41 | resolve(studentGroups); 42 | } 43 | }); 44 | } 45 | }); 46 | 47 | export default readDatabase; 48 | module.exports = readDatabase; 49 | -------------------------------------------------------------------------------- /0x05-Node_JS_basic/2-read_file.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | 3 | /** 4 | * Counts the students in a CSV data file. 5 | * @param {String} dataPath The path to the CSV data file. 6 | */ 7 | const countStudents = (dataPath) => { 8 | if (!fs.existsSync(dataPath)) { 9 | throw new Error('Cannot load the database'); 10 | } 11 | if (!fs.statSync(dataPath).isFile()) { 12 | throw new Error('Cannot load the database'); 13 | } 14 | const fileLines = fs 15 | .readFileSync(dataPath, 'utf-8') 16 | .toString('utf-8') 17 | .trim() 18 | .split('\n'); 19 | const studentGroups = {}; 20 | const dbFieldNames = fileLines[0].split(','); 21 | const studentPropNames = dbFieldNames.slice(0, dbFieldNames.length - 1); 22 | 23 | for (const line of fileLines.slice(1)) { 24 | const studentRecord = line.split(','); 25 | const studentPropValues = studentRecord.slice(0, studentRecord.length - 1); 26 | const field = studentRecord[studentRecord.length - 1]; 27 | if (!Object.keys(studentGroups).includes(field)) { 28 | studentGroups[field] = []; 29 | } 30 | const studentEntries = studentPropNames 31 | .map((propName, idx) => [propName, studentPropValues[idx]]); 32 | studentGroups[field].push(Object.fromEntries(studentEntries)); 33 | } 34 | 35 | const totalStudents = Object 36 | .values(studentGroups) 37 | .reduce((pre, cur) => (pre || []).length + cur.length); 38 | console.log(`Number of students: ${totalStudents}`); 39 | for (const [field, group] of Object.entries(studentGroups)) { 40 | const studentNames = group.map((student) => student.firstname).join(', '); 41 | console.log(`Number of students in ${field}: ${group.length}. List: ${studentNames}`); 42 | } 43 | }; 44 | 45 | module.exports = countStudents; 46 | -------------------------------------------------------------------------------- /0x04-TypeScript/task_2/js/main.ts: -------------------------------------------------------------------------------- 1 | export interface DirectorInterface { 2 | workFromHome(): string; 3 | getCoffeeBreak(): string; 4 | workDirectorTasks(): string; 5 | } 6 | 7 | export interface TeacherInterface { 8 | workFromHome(): string; 9 | getCoffeeBreak(): string; 10 | workTeacherTasks(): string; 11 | } 12 | 13 | export class Director implements DirectorInterface { 14 | workFromHome() { 15 | return 'Working from home'; 16 | } 17 | 18 | getCoffeeBreak() { 19 | return 'Getting a coffee break'; 20 | } 21 | 22 | workDirectorTasks() { 23 | return 'Getting to director tasks'; 24 | } 25 | } 26 | 27 | export class Teacher implements TeacherInterface { 28 | workFromHome() { 29 | return 'Cannot work from home'; 30 | } 31 | 32 | getCoffeeBreak() { 33 | return 'Cannot have a break'; 34 | } 35 | 36 | workTeacherTasks() { 37 | return 'Getting to work'; 38 | } 39 | } 40 | 41 | export function createEmployee(salary: (number | string)): (Director | Teacher) { 42 | if (typeof salary === 'number' && salary < 500) { 43 | return new Teacher(); 44 | } 45 | return new Director(); 46 | } 47 | 48 | export function isDirector(employee: (Director | Teacher)) { 49 | return employee instanceof Director; 50 | } 51 | 52 | export function executeWork(employee: (Director | Teacher)) { 53 | if (isDirector(employee)) { 54 | return (employee as Director).workDirectorTasks(); 55 | } 56 | return (employee as Teacher).workTeacherTasks(); 57 | } 58 | 59 | export type Subjects = ('Math' | 'History'); 60 | 61 | export function teachClass(todayClass: Subjects): string { 62 | if (todayClass === 'Math') { 63 | return 'Teaching Math'; 64 | } 65 | if (todayClass === 'History') { 66 | return 'Teaching History'; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /0x02-ES6_classes/2-hbtn_course.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Represents a Holberton Course. 3 | */ 4 | export default class HolbertonCourse { 5 | /** 6 | * Creates a new @see {@link HolbertonCourse}. 7 | * 8 | * @param {String} name - The name of the course. 9 | * @param {Number} length - How long the course is (in months). 10 | * @param {String[]} students - The names of students in the course. 11 | */ 12 | constructor(name, length, students) { 13 | this.name = name; 14 | this.length = length; 15 | this.students = students; 16 | } 17 | 18 | /** 19 | * Gets the name of this course. 20 | */ 21 | get name() { 22 | return this._name; 23 | } 24 | 25 | /** 26 | * Sets the name of this course. 27 | */ 28 | set name(value) { 29 | if (typeof value !== 'string') { 30 | throw new TypeError('Name must be a string'); 31 | } 32 | this._name = value; 33 | } 34 | 35 | /** 36 | * Gets the length of this course (in months). 37 | */ 38 | get length() { 39 | return this._length; 40 | } 41 | 42 | /** 43 | * Sets the length of this course (in months). 44 | */ 45 | set length(value) { 46 | if (typeof value !== 'number') { 47 | throw new TypeError('Length must be a number'); 48 | } 49 | this._length = value; 50 | } 51 | 52 | /** 53 | * Gets the names of students in this course. 54 | */ 55 | get students() { 56 | return this._students; 57 | } 58 | 59 | /** 60 | * Sets the names of students in this course. 61 | */ 62 | set students(value) { 63 | if (!(value instanceof Array)) { 64 | throw new TypeError('Students must be an array of strings'); 65 | } 66 | if (!value.every((student) => typeof student === 'string')) { 67 | throw new TypeError('Students must be an array of strings'); 68 | } 69 | this._students = value; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /0x05-Node_JS_basic/3-read_file_async.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | 3 | /** 4 | * Counts the students in a CSV data file. 5 | * @param {String} dataPath The path to the CSV data file. 6 | */ 7 | const countStudents = (dataPath) => new Promise((resolve, reject) => { 8 | fs.readFile(dataPath, 'utf-8', (err, data) => { 9 | if (err) { 10 | reject(new Error('Cannot load the database')); 11 | } 12 | if (data) { 13 | const fileLines = data 14 | .toString('utf-8') 15 | .trim() 16 | .split('\n'); 17 | const studentGroups = {}; 18 | const dbFieldNames = fileLines[0].split(','); 19 | const studentPropNames = dbFieldNames 20 | .slice(0, dbFieldNames.length - 1); 21 | 22 | for (const line of fileLines.slice(1)) { 23 | const studentRecord = line.split(','); 24 | const studentPropValues = studentRecord 25 | .slice(0, studentRecord.length - 1); 26 | const field = studentRecord[studentRecord.length - 1]; 27 | if (!Object.keys(studentGroups).includes(field)) { 28 | studentGroups[field] = []; 29 | } 30 | const studentEntries = studentPropNames 31 | .map((propName, idx) => [propName, studentPropValues[idx]]); 32 | studentGroups[field].push(Object.fromEntries(studentEntries)); 33 | } 34 | 35 | const totalStudents = Object 36 | .values(studentGroups) 37 | .reduce((pre, cur) => (pre || []).length + cur.length); 38 | console.log(`Number of students: ${totalStudents}`); 39 | for (const [field, group] of Object.entries(studentGroups)) { 40 | const studentNames = group.map((student) => student.firstname).join(', '); 41 | console.log(`Number of students in ${field}: ${group.length}. List: ${studentNames}`); 42 | } 43 | resolve(true); 44 | } 45 | }); 46 | }); 47 | 48 | module.exports = countStudents; 49 | -------------------------------------------------------------------------------- /0x06-unittests_in_js/10-api/api.test.js: -------------------------------------------------------------------------------- 1 | const request = require('request'); 2 | const { expect } = require('chai'); 3 | 4 | describe('API integration test', () => { 5 | const API_URL = 'http://localhost:7865'; 6 | 7 | it('GET / returns correct response', (done) => { 8 | request.get(`${API_URL}/`, (_err, res, body) => { 9 | expect(res.statusCode).to.be.equal(200); 10 | expect(body).to.be.equal('Welcome to the payment system'); 11 | done(); 12 | }); 13 | }); 14 | 15 | it('GET /cart/:id returns correct response for valid :id', (done) => { 16 | request.get(`${API_URL}/cart/47`, (_err, res, body) => { 17 | expect(res.statusCode).to.be.equal(200); 18 | expect(body).to.be.equal('Payment methods for cart 47'); 19 | done(); 20 | }); 21 | }); 22 | 23 | it('GET /cart/:id returns 404 response for negative number values in :id', (done) => { 24 | request.get(`${API_URL}/cart/-47`, (_err, res, _body) => { 25 | expect(res.statusCode).to.be.equal(404); 26 | done(); 27 | }); 28 | }); 29 | 30 | it('GET /cart/:id returns 404 response for non-numeric values in :id', (done) => { 31 | request.get(`${API_URL}/cart/d200-44a5-9de6`, (_err, res, _body) => { 32 | expect(res.statusCode).to.be.equal(404); 33 | done(); 34 | }); 35 | }); 36 | 37 | it('POST /login returns valid response', (done) => { 38 | request.post(`${API_URL}/login`, {json: {userName: 'Pinkbrook'}}, (_err, res, body) => { 39 | expect(res.statusCode).to.be.equal(200); 40 | expect(body).to.be.equal('Welcome Pinkbrook'); 41 | done(); 42 | }); 43 | }); 44 | 45 | it('GET /available_payments returns valid response', (done) => { 46 | request.get(`${API_URL}/available_payments`, (_err, res, body) => { 47 | expect(res.statusCode).to.be.equal(200); 48 | expect(JSON.parse(body)) 49 | .to.be.deep.equal({payment_methods: {credit_cards: true, paypal: false}}); 50 | done(); 51 | }); 52 | }); 53 | }); 54 | -------------------------------------------------------------------------------- /0x04-TypeScript/task_0/js/main.ts: -------------------------------------------------------------------------------- 1 | export interface Student { 2 | firstName: string; 3 | lastName: string; 4 | age: number; 5 | location: string; 6 | } 7 | const studentA: Student = { 8 | firstName: "Harry", 9 | lastName: "Yoon", 10 | age: 22, 11 | location: "Seoul, South Korea", 12 | }; 13 | const studentB: Student = { 14 | firstName: "Anjali", 15 | lastName: "Prajapati", 16 | age: 22, 17 | location: "Lodz, Poland", 18 | }; 19 | 20 | const studentsList: Array = [ 21 | studentA, 22 | studentB, 23 | ]; 24 | const styleSheet = ` 25 | html { 26 | margin: 0; 27 | height: 100%; 28 | } 29 | body { 30 | box-sizing: border-box; 31 | display: flex; 32 | align-items: center; 33 | justify-content: center; 34 | height: 80%; 35 | margin: 10%; 36 | } 37 | table { 38 | border-collapse: collapse; 39 | } 40 | thead { 41 | font-weight: bold; 42 | } 43 | td { 44 | padding: 10px; 45 | border: 1px solid gray; 46 | cursor: pointer; 47 | } 48 | td:hover { 49 | background: gainsboro; 50 | } 51 | 52 | td:nth-child(1) { 53 | text-align: center; 54 | } 55 | `; 56 | 57 | /** 58 | * Displays information about students in a table. 59 | * @param students The list of students to display. 60 | */ 61 | export const displayStudents = (students: Array): void => { 62 | const table = document.createElement('table'); 63 | const tableHead = document.createElement('thead'); 64 | const headRow = document.createElement('tr'); 65 | const tableBody = document.createElement('tbody'); 66 | headRow.insertAdjacentHTML('beforeend', 'FirstNameLocation${student.firstName}`); 73 | bodyRow.insertAdjacentHTML('beforeend', `${student.location}`); 74 | tableBody.insertAdjacentElement('beforeend', bodyRow); 75 | } 76 | 77 | table.insertAdjacentElement('beforeend', tableHead); 78 | table.insertAdjacentElement('beforeend', tableBody); 79 | document.body.insertAdjacentElement('beforeend', table); 80 | }; 81 | 82 | displayStudents(studentsList); 83 | const styleSheetElement = document.createElement('style'); 84 | styleSheetElement.innerHTML = styleSheet; 85 | document.head.insertAdjacentElement('beforeend', styleSheetElement); 86 | document.title = 'Task 0'; 87 | -------------------------------------------------------------------------------- /0x05-Node_JS_basic/full_server/controllers/StudentsController.js: -------------------------------------------------------------------------------- 1 | import readDatabase from '../utils'; 2 | 3 | /** 4 | * The list of supported majors. 5 | */ 6 | const VALID_MAJORS = ['CS', 'SWE']; 7 | 8 | /** 9 | * Contains the student-related route handlers. 10 | */ 11 | class StudentsController { 12 | static getAllStudents(request, response) { 13 | const dataPath = process.argv.length > 2 ? process.argv[2] : ''; 14 | 15 | readDatabase(dataPath) 16 | .then((studentGroups) => { 17 | const responseParts = ['This is the list of our students']; 18 | // A comparison function for ordering a list of strings in ascending 19 | // order by alphabetic order and case insensitive 20 | const cmpFxn = (a, b) => { 21 | if (a[0].toLowerCase() < b[0].toLowerCase()) { 22 | return -1; 23 | } 24 | if (a[0].toLowerCase() > b[0].toLowerCase()) { 25 | return 1; 26 | } 27 | return 0; 28 | }; 29 | 30 | for (const [field, group] of Object.entries(studentGroups).sort(cmpFxn)) { 31 | responseParts.push([ 32 | `Number of students in ${field}: ${group.length}.`, 33 | 'List:', 34 | group.map((student) => student.firstname).join(', '), 35 | ].join(' ')); 36 | } 37 | response.status(200).send(responseParts.join('\n')); 38 | }) 39 | .catch((err) => { 40 | response 41 | .status(500) 42 | .send(err instanceof Error ? err.message : err.toString()); 43 | }); 44 | } 45 | 46 | static getAllStudentsByMajor(request, response) { 47 | const dataPath = process.argv.length > 2 ? process.argv[2] : ''; 48 | const { major } = request.params; 49 | 50 | if (!VALID_MAJORS.includes(major)) { 51 | response.status(500).send('Major parameter must be CS or SWE'); 52 | return; 53 | } 54 | readDatabase(dataPath) 55 | .then((studentGroups) => { 56 | let responseText = ''; 57 | 58 | if (Object.keys(studentGroups).includes(major)) { 59 | const group = studentGroups[major]; 60 | responseText = `List: ${group.map((student) => student.firstname).join(', ')}`; 61 | } 62 | response.status(200).send(responseText); 63 | }) 64 | .catch((err) => { 65 | response 66 | .status(500) 67 | .send(err instanceof Error ? err.message : err.toString()); 68 | }); 69 | } 70 | } 71 | 72 | export default StudentsController; 73 | module.exports = StudentsController; 74 | -------------------------------------------------------------------------------- /0x05-Node_JS_basic/7-http_express.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const fs = require('fs'); 3 | 4 | const app = express(); 5 | const PORT = 1245; 6 | const DB_FILE = process.argv.length > 2 ? process.argv[2] : ''; 7 | 8 | /** 9 | * Counts the students in a CSV data file. 10 | * @param {String} dataPath The path to the CSV data file. 11 | */ 12 | const countStudents = (dataPath) => new Promise((resolve, reject) => { 13 | if (!dataPath) { 14 | reject(new Error('Cannot load the database')); 15 | } 16 | if (dataPath) { 17 | fs.readFile(dataPath, (err, data) => { 18 | if (err) { 19 | reject(new Error('Cannot load the database')); 20 | } 21 | if (data) { 22 | const reportParts = []; 23 | const fileLines = data.toString('utf-8').trim().split('\n'); 24 | const studentGroups = {}; 25 | const dbFieldNames = fileLines[0].split(','); 26 | const studentPropNames = dbFieldNames.slice( 27 | 0, 28 | dbFieldNames.length - 1, 29 | ); 30 | 31 | for (const line of fileLines.slice(1)) { 32 | const studentRecord = line.split(','); 33 | const studentPropValues = studentRecord.slice( 34 | 0, 35 | studentRecord.length - 1, 36 | ); 37 | const field = studentRecord[studentRecord.length - 1]; 38 | if (!Object.keys(studentGroups).includes(field)) { 39 | studentGroups[field] = []; 40 | } 41 | const studentEntries = studentPropNames.map((propName, idx) => [ 42 | propName, 43 | studentPropValues[idx], 44 | ]); 45 | studentGroups[field].push(Object.fromEntries(studentEntries)); 46 | } 47 | 48 | const totalStudents = Object.values(studentGroups).reduce( 49 | (pre, cur) => (pre || []).length + cur.length, 50 | ); 51 | reportParts.push(`Number of students: ${totalStudents}`); 52 | for (const [field, group] of Object.entries(studentGroups)) { 53 | reportParts.push([ 54 | `Number of students in ${field}: ${group.length}.`, 55 | 'List:', 56 | group.map((student) => student.firstname).join(', '), 57 | ].join(' ')); 58 | } 59 | resolve(reportParts.join('\n')); 60 | } 61 | }); 62 | } 63 | }); 64 | 65 | app.get('/', (_, res) => { 66 | res.send('Hello Holberton School!'); 67 | }); 68 | 69 | app.get('/students', (_, res) => { 70 | const responseParts = ['This is the list of our students']; 71 | 72 | countStudents(DB_FILE) 73 | .then((report) => { 74 | responseParts.push(report); 75 | const responseText = responseParts.join('\n'); 76 | res.setHeader('Content-Type', 'text/plain'); 77 | res.setHeader('Content-Length', responseText.length); 78 | res.statusCode = 200; 79 | res.write(Buffer.from(responseText)); 80 | }) 81 | .catch((err) => { 82 | responseParts.push(err instanceof Error ? err.message : err.toString()); 83 | const responseText = responseParts.join('\n'); 84 | res.setHeader('Content-Type', 'text/plain'); 85 | res.setHeader('Content-Length', responseText.length); 86 | res.statusCode = 200; 87 | res.write(Buffer.from(responseText)); 88 | }); 89 | }); 90 | 91 | app.listen(PORT, () => { 92 | console.log(`Server listening on PORT ${PORT}`); 93 | }); 94 | 95 | module.exports = app; 96 | -------------------------------------------------------------------------------- /0x05-Node_JS_basic/5-http.js: -------------------------------------------------------------------------------- 1 | const http = require('http'); 2 | const fs = require('fs'); 3 | 4 | const PORT = 1245; 5 | const HOST = 'localhost'; 6 | const app = http.createServer(); 7 | const DB_FILE = process.argv.length > 2 ? process.argv[2] : ''; 8 | 9 | /** 10 | * Counts the students in a CSV data file. 11 | * @param {String} dataPath The path to the CSV data file. 12 | */ 13 | const countStudents = (dataPath) => new Promise((resolve, reject) => { 14 | if (!dataPath) { 15 | reject(new Error('Cannot load the database')); 16 | } 17 | if (dataPath) { 18 | fs.readFile(dataPath, (err, data) => { 19 | if (err) { 20 | reject(new Error('Cannot load the database')); 21 | } 22 | if (data) { 23 | const reportParts = []; 24 | const fileLines = data.toString('utf-8').trim().split('\n'); 25 | const studentGroups = {}; 26 | const dbFieldNames = fileLines[0].split(','); 27 | const studentPropNames = dbFieldNames.slice( 28 | 0, 29 | dbFieldNames.length - 1, 30 | ); 31 | 32 | for (const line of fileLines.slice(1)) { 33 | const studentRecord = line.split(','); 34 | const studentPropValues = studentRecord.slice( 35 | 0, 36 | studentRecord.length - 1, 37 | ); 38 | const field = studentRecord[studentRecord.length - 1]; 39 | if (!Object.keys(studentGroups).includes(field)) { 40 | studentGroups[field] = []; 41 | } 42 | const studentEntries = studentPropNames.map((propName, idx) => [ 43 | propName, 44 | studentPropValues[idx], 45 | ]); 46 | studentGroups[field].push(Object.fromEntries(studentEntries)); 47 | } 48 | 49 | const totalStudents = Object.values(studentGroups).reduce( 50 | (pre, cur) => (pre || []).length + cur.length, 51 | ); 52 | reportParts.push(`Number of students: ${totalStudents}`); 53 | for (const [field, group] of Object.entries(studentGroups)) { 54 | reportParts.push([ 55 | `Number of students in ${field}: ${group.length}.`, 56 | 'List:', 57 | group.map((student) => student.firstname).join(', '), 58 | ].join(' ')); 59 | } 60 | resolve(reportParts.join('\n')); 61 | } 62 | }); 63 | } 64 | }); 65 | 66 | const SERVER_ROUTE_HANDLERS = [ 67 | { 68 | route: '/', 69 | handler(_, res) { 70 | const responseText = 'Hello Holberton School!'; 71 | 72 | res.setHeader('Content-Type', 'text/plain'); 73 | res.setHeader('Content-Length', responseText.length); 74 | res.statusCode = 200; 75 | res.write(Buffer.from(responseText)); 76 | }, 77 | }, 78 | { 79 | route: '/students', 80 | handler(_, res) { 81 | const responseParts = ['This is the list of our students']; 82 | 83 | countStudents(DB_FILE) 84 | .then((report) => { 85 | responseParts.push(report); 86 | const responseText = responseParts.join('\n'); 87 | res.setHeader('Content-Type', 'text/plain'); 88 | res.setHeader('Content-Length', responseText.length); 89 | res.statusCode = 200; 90 | res.write(Buffer.from(responseText)); 91 | }) 92 | .catch((err) => { 93 | responseParts.push(err instanceof Error ? err.message : err.toString()); 94 | const responseText = responseParts.join('\n'); 95 | res.setHeader('Content-Type', 'text/plain'); 96 | res.setHeader('Content-Length', responseText.length); 97 | res.statusCode = 200; 98 | res.write(Buffer.from(responseText)); 99 | }); 100 | }, 101 | }, 102 | ]; 103 | 104 | app.on('request', (req, res) => { 105 | for (const routeHandler of SERVER_ROUTE_HANDLERS) { 106 | if (routeHandler.route === req.url) { 107 | routeHandler.handler(req, res); 108 | break; 109 | } 110 | } 111 | }); 112 | 113 | app.listen(PORT, HOST, () => { 114 | process.stdout.write(`Server listening at -> http://${HOST}:${PORT}\n`); 115 | }); 116 | 117 | module.exports = app; 118 | -------------------------------------------------------------------------------- /0x06-unittests_in_js/2-calcul_chai.test.js: -------------------------------------------------------------------------------- 1 | const { expect } = require('chai'); 2 | const calculateNumber = require('./2-calcul_chai'); 3 | 4 | describe('calculateNumber', () => { 5 | describe('type == "SUM"', () => { 6 | it('equal positive numbers', () => { 7 | expect(calculateNumber('SUM', 2.0, 2.0)).to.equal(4); 8 | }); 9 | 10 | it('equal positive numbers (alternate)', () => { 11 | expect(calculateNumber('SUM', 2.3, 1.8)).to.equal(4); 12 | }); 13 | 14 | it('equal negative numbers', () => { 15 | expect(calculateNumber('SUM', -2.0, -2.0)).to.equal(-4); 16 | }); 17 | 18 | it('equal negative numbers (alternate)', () => { 19 | expect(calculateNumber('SUM', -2.3, -1.8)).to.equal(-4); 20 | }); 21 | 22 | it('negative and positive numbers', () => { 23 | expect(calculateNumber('SUM', -2.0, 2.0)).to.equal(0); 24 | }); 25 | 26 | it('positive and negative numbers', () => { 27 | expect(calculateNumber('SUM', 2.0, -2.0)).to.equal(0); 28 | }); 29 | 30 | it('0 and 0', () => { 31 | expect(calculateNumber('SUM', 0.0, 0.0)).to.equal(0); 32 | }); 33 | }); 34 | 35 | describe('type == "SUBTRACT"', () => { 36 | it('equal positive numbers', () => { 37 | expect(calculateNumber('SUBTRACT', 2.0, 2.0)).to.equal(0); 38 | }); 39 | 40 | it('equal positive numbers (alternate)', () => { 41 | expect(calculateNumber('SUBTRACT', 2.3, 1.8)).to.equal(0); 42 | }); 43 | 44 | it('equal negative numbers', () => { 45 | expect(calculateNumber('SUBTRACT', -2.0, -2.0)).to.equal(0); 46 | }); 47 | 48 | it('equal negative numbers (alternate)', () => { 49 | expect(calculateNumber('SUBTRACT', -2.3, -1.8)).to.equal(0); 50 | }); 51 | 52 | it('negative and positive numbers', () => { 53 | expect(calculateNumber('SUBTRACT', -2.0, 2.0)).to.equal(-4.0); 54 | }); 55 | 56 | it('positive and negative numbers', () => { 57 | expect(calculateNumber('SUBTRACT', 2.0, -2.0)).to.equal(4.0); 58 | }); 59 | 60 | it('0 and 0', () => { 61 | expect(calculateNumber('SUBTRACT', 0.0, 0.0)).to.equal(0); 62 | }); 63 | }); 64 | 65 | describe('type == "DIVIDE"', () => { 66 | it('positive numbers', () => { 67 | expect(calculateNumber('DIVIDE', 8.0, 2.0)).to.equal(4.0); 68 | }); 69 | 70 | it('numbers with different signs', () => { 71 | expect(calculateNumber('DIVIDE', -7.0, 2.0)).to.equal(-3.5); 72 | }); 73 | 74 | it('numbers with different signs (alternate)', () => { 75 | expect(calculateNumber('DIVIDE', 7.0, -2.0)).to.equal(-3.5); 76 | }); 77 | 78 | it('negative numbers', () => { 79 | expect(calculateNumber('DIVIDE', -7.0, -2.0)).to.equal(3.5); 80 | }); 81 | 82 | it('equal positive numbers', () => { 83 | expect(calculateNumber('DIVIDE', 2.0, 2.0)).to.equal(1); 84 | }); 85 | 86 | it('equal negative numbers', () => { 87 | expect(calculateNumber('DIVIDE', -2.0, -2.0)).to.equal(1); 88 | }); 89 | 90 | it('equal rounded up numbers', () => { 91 | expect(calculateNumber('DIVIDE', 2.6, 3.0)).to.equal(1); 92 | }); 93 | 94 | it('equal rounded down numbers', () => { 95 | expect(calculateNumber('DIVIDE', 2.4, 2.0)).to.equal(1); 96 | }); 97 | 98 | it('0 and positive number', () => { 99 | expect(calculateNumber('DIVIDE', 0.0, 5.0)).to.equal(0); 100 | }); 101 | 102 | it('0 and negative number', () => { 103 | expect(calculateNumber('DIVIDE', 0.0, -5.0)).to.equal(-0); 104 | }); 105 | 106 | it('positive number and 0', () => { 107 | expect(calculateNumber('DIVIDE', 5.0, 0)).to.equal('Error'); 108 | }); 109 | 110 | it('positive number and number rounded down to 0', () => { 111 | expect(calculateNumber('DIVIDE', 5.0, 0.2)).to.equal('Error'); 112 | }); 113 | 114 | it('positive number and number rounded up to 0', () => { 115 | expect(calculateNumber('DIVIDE', 5.0, -0.2)).to.equal('Error'); 116 | }); 117 | 118 | it('negative number and 0', () => { 119 | expect(calculateNumber('DIVIDE', -5.0, 0)).to.equal('Error'); 120 | }); 121 | 122 | it('negative number and number rounded down to zero', () => { 123 | expect(calculateNumber('DIVIDE', -5.0, 0.2)).to.equal('Error'); 124 | }); 125 | 126 | it('negative number and number rounded up to zero', () => { 127 | expect(calculateNumber('DIVIDE', -5.0, -0.2)).to.equal('Error'); 128 | }); 129 | 130 | it('0 and 0', () => { 131 | expect(calculateNumber('DIVIDE', 0.0, 0.0)).to.equal('Error'); 132 | }); 133 | }); 134 | }); 135 | -------------------------------------------------------------------------------- /0x06-unittests_in_js/1-calcul.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | const calculateNumber = require('./1-calcul'); 3 | 4 | describe('calculateNumber', () => { 5 | describe('type == "SUM"', () => { 6 | it('equal positive numbers', () => { 7 | assert.strictEqual(calculateNumber('SUM', 2.0, 2.0), 4); 8 | }); 9 | 10 | it('equal positive numbers (alternate)', () => { 11 | assert.strictEqual(calculateNumber('SUM', 2.3, 1.8), 4); 12 | }); 13 | 14 | it('equal negative numbers', () => { 15 | assert.strictEqual(calculateNumber('SUM', -2.0, -2.0), -4); 16 | }); 17 | 18 | it('equal negative numbers (alternate)', () => { 19 | assert.strictEqual(calculateNumber('SUM', -2.3, -1.8), -4); 20 | }); 21 | 22 | it('negative and positive numbers', () => { 23 | assert.strictEqual(calculateNumber('SUM', -2.0, 2.0), 0); 24 | }); 25 | 26 | it('positive and negative numbers', () => { 27 | assert.strictEqual(calculateNumber('SUM', 2.0, -2.0), 0); 28 | }); 29 | 30 | it('0 and 0', () => { 31 | assert.strictEqual(calculateNumber('SUM', 0.0, 0.0), 0); 32 | }); 33 | }); 34 | 35 | describe('type == "SUBTRACT"', () => { 36 | it('equal positive numbers', () => { 37 | assert.strictEqual(calculateNumber('SUBTRACT', 2.0, 2.0), 0); 38 | }); 39 | 40 | it('equal positive numbers (alternate)', () => { 41 | assert.strictEqual(calculateNumber('SUBTRACT', 2.3, 1.8), 0); 42 | }); 43 | 44 | it('equal negative numbers', () => { 45 | assert.strictEqual(calculateNumber('SUBTRACT', -2.0, -2.0), 0); 46 | }); 47 | 48 | it('equal negative numbers (alternate)', () => { 49 | assert.strictEqual(calculateNumber('SUBTRACT', -2.3, -1.8), 0); 50 | }); 51 | 52 | it('negative and positive numbers', () => { 53 | assert.strictEqual(calculateNumber('SUBTRACT', -2.0, 2.0), -4.0); 54 | }); 55 | 56 | it('positive and negative numbers', () => { 57 | assert.strictEqual(calculateNumber('SUBTRACT', 2.0, -2.0), 4.0); 58 | }); 59 | 60 | it('0 and 0', () => { 61 | assert.strictEqual(calculateNumber('SUBTRACT', 0.0, 0.0), 0); 62 | }); 63 | }); 64 | 65 | describe('type == "DIVIDE"', () => { 66 | it('positive numbers', () => { 67 | assert.strictEqual(calculateNumber('DIVIDE', 8.0, 2.0), 4.0); 68 | }); 69 | 70 | it('numbers with different signs', () => { 71 | assert.strictEqual(calculateNumber('DIVIDE', -7.0, 2.0), -3.5); 72 | }); 73 | 74 | it('numbers with different signs (alternate)', () => { 75 | assert.strictEqual(calculateNumber('DIVIDE', 7.0, -2.0), -3.5); 76 | }); 77 | 78 | it('negative numbers', () => { 79 | assert.strictEqual(calculateNumber('DIVIDE', -7.0, -2.0), 3.5); 80 | }); 81 | 82 | it('equal positive numbers', () => { 83 | assert.strictEqual(calculateNumber('DIVIDE', 2.0, 2.0), 1); 84 | }); 85 | 86 | it('equal negative numbers', () => { 87 | assert.strictEqual(calculateNumber('DIVIDE', -2.0, -2.0), 1); 88 | }); 89 | 90 | it('equal rounded up numbers', () => { 91 | assert.strictEqual(calculateNumber('DIVIDE', 2.6, 3.0), 1); 92 | }); 93 | 94 | it('equal rounded down numbers', () => { 95 | assert.strictEqual(calculateNumber('DIVIDE', 2.4, 2.0), 1); 96 | }); 97 | 98 | it('0 and positive number', () => { 99 | assert.strictEqual(calculateNumber('DIVIDE', 0.0, 5.0), 0); 100 | }); 101 | 102 | it('0 and negative number', () => { 103 | assert.strictEqual(calculateNumber('DIVIDE', 0.0, -5.0), -0); 104 | }); 105 | 106 | it('positive number and 0', () => { 107 | assert.strictEqual(calculateNumber('DIVIDE', 5.0, 0), 'Error'); 108 | }); 109 | 110 | it('positive number and number rounded down to 0', () => { 111 | assert.strictEqual(calculateNumber('DIVIDE', 5.0, 0.2), 'Error'); 112 | }); 113 | 114 | it('positive number and number rounded up to 0', () => { 115 | assert.strictEqual(calculateNumber('DIVIDE', 5.0, -0.2), 'Error'); 116 | }); 117 | 118 | it('negative number and 0', () => { 119 | assert.strictEqual(calculateNumber('DIVIDE', -5.0, 0), 'Error'); 120 | }); 121 | 122 | it('negative number and number rounded down to zero', () => { 123 | assert.strictEqual(calculateNumber('DIVIDE', -5.0, 0.2), 'Error'); 124 | }); 125 | 126 | it('negative number and number rounded up to zero', () => { 127 | assert.strictEqual(calculateNumber('DIVIDE', -5.0, -0.2), 'Error'); 128 | }); 129 | 130 | it('0 and 0', () => { 131 | assert.strictEqual(calculateNumber('DIVIDE', 0.0, 0.0), 'Error'); 132 | }); 133 | }); 134 | }); 135 | --------------------------------------------------------------------------------