From 6b1f5c3df4e12ec4649e18bcaba67d1fce57e06c Mon Sep 17 00:00:00 2001 From: Vlad Possin Date: Tue, 24 Nov 2020 16:52:40 +0600 Subject: [PATCH] created homework_3 --- projects/homework_3/index.js | 155 +++++++++++++++++++++++++ projects/homework_3/index.spec.js | 183 ++++++++++++++++++++++++++++++ 2 files changed, 338 insertions(+) create mode 100644 projects/homework_3/index.js create mode 100644 projects/homework_3/index.spec.js diff --git a/projects/homework_3/index.js b/projects/homework_3/index.js new file mode 100644 index 0000000..1c4f27a --- /dev/null +++ b/projects/homework_3/index.js @@ -0,0 +1,155 @@ +/* ДЗ 3 - работа с исключениями и отладчиком */ + +/* + Задание 1: + + 1.1: Функция принимает массив и фильтрующую функцию и должна вернуть true или false + Функция должна вернуть true только если fn вернула true для всех элементов массива + + 1.2: Необходимо выбрасывать исключение в случаях: + - array не массив или пустой массив (с текстом "empty array") + - fn не является функцией (с текстом "fn is not a function") + + Запрещено использовать встроенные методы для работы с массивами + + Пример: + isAllTrue([1, 2, 3, 4, 5], n => n < 10) // вернет true + isAllTrue([100, 2, 3, 4, 5], n => n < 10) // вернет false + */ +function isAllTrue(array, fn) { + if (typeof fn !== 'function') { + throw new Error('fn is not a function'); + } + + if (!Array.isArray(array) || !array.length) { + throw new Error('empty array'); + } + + for (const el of array) { + if (!fn(el)) { + return false; + } + } + + return true; +} + +/* + Задание 2: + + 2.1: Функция принимает массив и фильтрующую функцию и должна вернуть true или false + Функция должна вернуть true если fn вернула true хотя бы для одного из элементов массива + + 2.2: Необходимо выбрасывать исключение в случаях: + - array не массив или пустой массив (с текстом "empty array") + - fn не является функцией (с текстом "fn is not a function") + + Запрещено использовать встроенные методы для работы с массивами + + Пример: + isSomeTrue([1, 2, 30, 4, 5], n => n > 20) // вернет true + isSomeTrue([1, 2, 3, 4, 5], n => n > 20) // вернет false + */ +function isSomeTrue(array, fn) { + if (typeof fn !== 'function') { + throw new Error('fn is not a function'); + } + + if (!Array.isArray(array) || !array.length) { + throw new Error('empty array'); + } + + for (const el of array) { + if (fn(el)) { + return true; + } + } + return false; +} + +/* + Задание 3: + + 3.1: Функция принимает заранее неизвестное количество аргументов, первым из которых является функция fn + Функция должна поочередно запустить fn для каждого переданного аргумента (кроме самой fn) + + 3.2: Функция должна вернуть массив аргументов, для которых fn выбросила исключение + + 3.3: Необходимо выбрасывать исключение в случаях: + - fn не является функцией (с текстом "fn is not a function") + */ +function returnBadArguments(fn, ...args) { + if (typeof fn !== 'function') { + throw new Error('fn is not a function'); + } + const bad = []; + + for (const arg of args) { + try { + fn(arg); + } catch { + bad.push(arg); + } + } + return bad; +} + +/* + Задание 4: + + 4.1: Функция имеет параметр number (по умолчанию - 0) + + 4.2: Функция должна вернуть объект, у которого должно быть несколько методов: + - sum - складывает number с переданными аргументами + - dif - вычитает из number переданные аргументы + - div - делит number на первый аргумент. Результат делится на следующий аргумент (если передан) и так далее + - mul - умножает number на первый аргумент. Результат умножается на следующий аргумент (если передан) и так далее + + Количество передаваемых в методы аргументов заранее неизвестно + + 4.3: Необходимо выбрасывать исключение в случаях: + - number не является числом (с текстом "number is not a number") + - какой-либо из аргументов div является нулем (с текстом "division by 0") + */ +function calculator(number = 0) { + if (!Number.isFinite(number)) { + throw new Error('number is not a number'); + } + return { + sum(...args) { + let result = number; + for (const arg of args) { + result += arg; + } + return result; + }, + dif(...args) { + let result = number; + for (const arg of args) { + result -= arg; + } + return result; + }, + div(...args) { + let result = number; + for (const arg of args) { + if (arg === 0) { + throw new Error('division by 0'); + } + result /= arg; + } + return result; + }, + mul(...args) { + let result = number; + for (const arg of args) { + result *= arg; + } + return result; + }, + }; +} + +/* При решении задач, постарайтесь использовать отладчик */ + +export { isAllTrue, isSomeTrue, returnBadArguments, calculator }; diff --git a/projects/homework_3/index.spec.js b/projects/homework_3/index.spec.js new file mode 100644 index 0000000..85335f2 --- /dev/null +++ b/projects/homework_3/index.spec.js @@ -0,0 +1,183 @@ +import { + randomNumberArray, + randomStringArray, + randomValue as random, +} from '../../scripts/helper'; +import { calculator, isAllTrue, isSomeTrue, returnBadArguments } from './index'; + +describe('ДЗ 2 - работа с исключениями и отладчиком', () => { + describe('isAllTrue', () => { + it('должна вызывать fn для всех элементов массива', () => { + const array = random('array', 1); + const pass = []; + + isAllTrue(array, (e) => pass.push(e)); + + expect(pass).toEqual(array); + }); + + it('должна вернуть true, если fn вернула true для всех элементов массива', () => { + const array = randomNumberArray(); + const result = isAllTrue(array, Number.isFinite); + + expect(result); + }); + + it('должна вернуть false, если fn вернула false хотя бы для одного элемента массива', () => { + const array = randomNumberArray(); + + array.push(random('string')); + const result = isAllTrue(array, Number.isFinite); + + expect(!result); + }); + + it('должна выбросить исключение, если передан пустой массив', () => { + expect(() => isAllTrue([], () => {})).toThrow('empty array'); + }); + + it('должна выбросить исключение, если передан не массив', () => { + expect(() => isAllTrue(':(', () => {})).toThrow('empty array'); + expect(() => isAllTrue({}, () => {})).toThrow('empty array'); + }); + + it('должна выбросить исключение, если fn не функция', () => { + const array = randomNumberArray(); + + expect(() => isAllTrue(array, ':(')).toThrow('fn is not a function'); + }); + }); + + describe('isSomeTrue', () => { + it('должна вернуть true, если fn вернула true хотя бы для одного элемента массива', () => { + const array = randomStringArray().concat(random('number')); + const result = isSomeTrue(array, Number.isFinite); + + expect(result); + }); + + it('должна вернуть false, если fn не вернула true хотя бы для одного элемента массива', () => { + const array = randomStringArray(); + const result = isSomeTrue(array, Number.isFinite); + + expect(!result); + }); + + it('должна выбросить исключение, если передан пустой массив', () => { + expect(() => isSomeTrue([], () => {})).toThrow('empty array'); + }); + + it('должна выбросить исключение, если передан не массив', () => { + expect(() => isSomeTrue(':(', () => {})).toThrow('empty array'); + expect(() => isSomeTrue({}, () => {})).toThrow('empty array'); + }); + + it('должна выбросить исключение, если fn не функция', () => { + const array = randomNumberArray(); + + expect(() => isSomeTrue(array, ':(')).toThrow('fn is not a function'); + }); + }); + + describe('returnBadArguments', () => { + it('должна вызывать fn для всех элементов массива', () => { + const array = random('array', 1); + const pass = []; + + returnBadArguments((e) => pass.push(e), ...array); + + expect(pass).toEqual(array); + }); + + it('должна вернуть массив с аргументами, для которых fn выбрасила исключение', () => { + const evenNumbers = randomNumberArray('even'); + const oddNumbers = randomNumberArray('odd'); + const fn = (a) => { + if (a % 2 !== 0) { + throw new Error('not even'); + } + }; + const result = returnBadArguments(fn, ...evenNumbers, ...oddNumbers); + + expect(result).toEqual(oddNumbers); + }); + + it('должна вернуть массив пустой массив, если не передано дополнительных аргументов', () => { + const fn = () => ':)'; + const result = returnBadArguments(fn); + + expect(result.length).toBe(0); + }); + + it('должна выбросить исключение, если fn не функция', () => { + expect(() => returnBadArguments(':(')).toThrow('fn is not a function'); + }); + }); + + describe('calculator', () => { + it('должна возвращать объект с методами', () => { + const calc = calculator(); + + expect(Object.keys(calc)).toEqual(['sum', 'dif', 'div', 'mul']); + }); + + it('метод sum должен складывать аргументы', () => { + const initialValue = random('number'); + const calc = calculator(initialValue); + const args = randomNumberArray(); + + expect(calc.sum(...args)).toBe( + args.reduce((prev, current) => prev + current, initialValue) + ); + }); + + it('метод dif должен вычитать аргументы', () => { + const initialValue = random('number'); + const calc = calculator(initialValue); + const args = randomNumberArray(); + + expect(calc.dif(...args)).toBe( + args.reduce((prev, current) => prev - current, initialValue) + ); + }); + + it('метод div должен делить аргументы', () => { + const initialValue = random('number'); + const calc = calculator(initialValue); + const args = randomNumberArray(); + + expect(calc.div(...args)).toBe( + args.reduce((prev, current) => prev / current, initialValue) + ); + }); + + it('метод div должен выбрасывать исключение, если хотя бы один из аргументов равен 0', () => { + const initialValue = random('number'); + const calc = calculator(initialValue); + const args = [...randomNumberArray(), 0]; + + expect(() => calc.div(...args)).toThrow('division by 0'); + }); + + it('метод mul должен умножать аргументы', () => { + const initialValue = random('number'); + const calc = calculator(initialValue); + const args = randomNumberArray(); + + expect(calc.mul(...args)).toBe( + args.reduce((prev, current) => prev * current, initialValue) + ); + }); + + it('функция должна выбрасывать исключение, если number не является числом', () => { + expect(() => calculator(':(')).toThrow('number is not a number'); + }); + + it('значение по умолчанию для аргумента number должно быть равно 0', () => { + const calc = calculator(); + const args = randomNumberArray(); + + expect(calc.sum(...args)).toBe(args.reduce((prev, current) => prev + current)); + }); + }); +});