Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
155 changes: 155 additions & 0 deletions projects/homework_3/index.js
Original file line number Diff line number Diff line change
@@ -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 };
183 changes: 183 additions & 0 deletions projects/homework_3/index.spec.js
Original file line number Diff line number Diff line change
@@ -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));
});
});
});