debut TP2
This commit is contained in:
parent
a17920df41
commit
e092272bd4
@ -23,8 +23,8 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"nodemon": "^3.1.0",
|
"nodemon": "^3.1.0",
|
||||||
"reflect-metadata": "^0.2.1",
|
"reflect-metadata": "^0.2.2",
|
||||||
"ts-node": "^10.9.2",
|
"ts-node": "^10.9.2",
|
||||||
"tsyringe": "^4.8.0"
|
"tsyringe": "^4.8.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
57
src/exercises/TP2/fibo/index.test.ts
Normal file
57
src/exercises/TP2/fibo/index.test.ts
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import { fibo } from "./index";
|
||||||
|
|
||||||
|
describe("fibo", () => {
|
||||||
|
it("should return 0 when given 0", () => {
|
||||||
|
// arrange
|
||||||
|
const input = 0;
|
||||||
|
const expected = 0;
|
||||||
|
|
||||||
|
// act
|
||||||
|
const result = fibo(input);
|
||||||
|
|
||||||
|
// assert
|
||||||
|
expect(result).toBe(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return 1 when given 1", () => {
|
||||||
|
// arrange
|
||||||
|
const input = 1;
|
||||||
|
const expected = 1;
|
||||||
|
|
||||||
|
// act
|
||||||
|
const result = fibo(input);
|
||||||
|
|
||||||
|
// assert
|
||||||
|
expect(result).toBe(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it.each([
|
||||||
|
{
|
||||||
|
input: 2,
|
||||||
|
expected: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: 3,
|
||||||
|
expected: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: 4,
|
||||||
|
expected: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: 5,
|
||||||
|
expected: 5,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: 6,
|
||||||
|
expected: 8,
|
||||||
|
},
|
||||||
|
])("should return fibo(n) when given n", ({ input, expected }) => {
|
||||||
|
// arrange
|
||||||
|
// act
|
||||||
|
const result = fibo(input);
|
||||||
|
|
||||||
|
// assert
|
||||||
|
expect(result).toBe(expected);
|
||||||
|
});
|
||||||
|
});
|
5
src/exercises/TP2/fibo/index.ts
Normal file
5
src/exercises/TP2/fibo/index.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export function fibo(n: number): number {
|
||||||
|
if (n <= 1) return n;
|
||||||
|
|
||||||
|
return fibo(n - 2) + fibo(n - 1);
|
||||||
|
}
|
64
src/exercises/TP2/fizzbuzz/index.test.ts
Normal file
64
src/exercises/TP2/fizzbuzz/index.test.ts
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
import { fizzBuzz } from "./index";
|
||||||
|
|
||||||
|
describe("fizzBuzz", () => {
|
||||||
|
it.each([
|
||||||
|
{
|
||||||
|
input: 1,
|
||||||
|
expected: "1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: 2,
|
||||||
|
expected: "2",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: 4,
|
||||||
|
expected: "4",
|
||||||
|
},
|
||||||
|
])(
|
||||||
|
"should return the number as string when given a non multiple of 3, 5 or 15",
|
||||||
|
({ input, expected }) => {
|
||||||
|
// arrange
|
||||||
|
// act
|
||||||
|
const result = fizzBuzz(input);
|
||||||
|
|
||||||
|
// assert
|
||||||
|
expect(result).toBe(expected);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
it.each([3, 6, 9])(
|
||||||
|
"should return 'Fizz' when given a multiple of 3",
|
||||||
|
(input) => {
|
||||||
|
// arrange
|
||||||
|
// act
|
||||||
|
const result = fizzBuzz(input);
|
||||||
|
|
||||||
|
// assert
|
||||||
|
expect(result).toBe("Fizz");
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
it.each([5, 10, 20])(
|
||||||
|
'should return "Buzz" when given a multiple of 5',
|
||||||
|
(input) => {
|
||||||
|
// arrange
|
||||||
|
// act
|
||||||
|
const result = fizzBuzz(input);
|
||||||
|
|
||||||
|
// assert
|
||||||
|
expect(result).toBe("Buzz");
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
it.each([15, 30, 45])(
|
||||||
|
'should return "FizzBuzz" when given a multiple of 15',
|
||||||
|
(input) => {
|
||||||
|
// arrange
|
||||||
|
// act
|
||||||
|
const result = fizzBuzz(input);
|
||||||
|
|
||||||
|
// assert
|
||||||
|
expect(result).toBe("FizzBuzz");
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
7
src/exercises/TP2/fizzbuzz/index.ts
Normal file
7
src/exercises/TP2/fizzbuzz/index.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
export function fizzBuzz(input: number): string {
|
||||||
|
if (input % 15 === 0) return "FizzBuzz";
|
||||||
|
if (input % 5 === 0) return "Buzz";
|
||||||
|
if (input % 3 === 0) return "Fizz";
|
||||||
|
|
||||||
|
return input.toString();
|
||||||
|
}
|
@ -1,32 +0,0 @@
|
|||||||
import { divide } from "./index";
|
|
||||||
|
|
||||||
describe("Test divide", () => {
|
|
||||||
it.each([
|
|
||||||
{ foo: "", bar: "", expected: "" },
|
|
||||||
])(
|
|
||||||
"should $foo $bar",
|
|
||||||
({ foo, bar, expected }) => {
|
|
||||||
// act
|
|
||||||
// const result = function (foo, bar);
|
|
||||||
const result = 0;
|
|
||||||
// assert
|
|
||||||
expect(result).toEqual(expected);
|
|
||||||
console.log(`Test with foo = ${foo}, bar = ${bar}, expected = ${expected}, result = ${result}`);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
* If exception test
|
|
||||||
*
|
|
||||||
* */
|
|
||||||
it("should throw an exception when dividing by zero", () => {
|
|
||||||
// arrange
|
|
||||||
const foo = "";
|
|
||||||
const bar = "";
|
|
||||||
// act & assert
|
|
||||||
///TODO
|
|
||||||
// expect(() => function (foo, bar).toThrow("E");
|
|
||||||
console.log(foo + bar);
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,3 +0,0 @@
|
|||||||
export function name(foo : number) : number {
|
|
||||||
return foo + 1;
|
|
||||||
}
|
|
70
src/exercises/addStringOfNumbers/index.test.ts
Normal file
70
src/exercises/addStringOfNumbers/index.test.ts
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
import { addStringOfNumbers } from "./index";
|
||||||
|
|
||||||
|
describe("addStringOfNumbers", () => {
|
||||||
|
it("should return 0 when given an empty string", () => {
|
||||||
|
// arrange
|
||||||
|
const input = "";
|
||||||
|
const expected = 0;
|
||||||
|
|
||||||
|
// act
|
||||||
|
const result = addStringOfNumbers(input);
|
||||||
|
|
||||||
|
// assert
|
||||||
|
expect(result).toBe(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it.each([
|
||||||
|
{ input: "12", expected: 12 },
|
||||||
|
{ input: "1.5", expected: 1.5 },
|
||||||
|
{ input: "-2", expected: -2 },
|
||||||
|
{ input: "-2.333", expected: -2.333 },
|
||||||
|
])(
|
||||||
|
"should return n when given the string representation of n",
|
||||||
|
({ input, expected }) => {
|
||||||
|
// arrange
|
||||||
|
// act
|
||||||
|
const result = addStringOfNumbers(input);
|
||||||
|
|
||||||
|
// assert
|
||||||
|
expect(result).toBe(expected);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
it.each(["--4", "1-23", "3..5"])(
|
||||||
|
"should throw an error when given a string that is not a number",
|
||||||
|
(input) => {
|
||||||
|
// arrange
|
||||||
|
// act
|
||||||
|
const act = () => addStringOfNumbers(input);
|
||||||
|
|
||||||
|
// assert
|
||||||
|
expect(act).toThrow("Not valid number");
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
it.each([
|
||||||
|
{ input: "2,3", expected: 5 },
|
||||||
|
{ input: "-2.5,4", expected: 1.5 },
|
||||||
|
])(
|
||||||
|
"should add two comma separated numbers in a string",
|
||||||
|
({ input, expected }) => {
|
||||||
|
// arrange
|
||||||
|
// act
|
||||||
|
const result = addStringOfNumbers(input);
|
||||||
|
|
||||||
|
// assert
|
||||||
|
expect(result).toBe(expected);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
it("should throw an error when given a string with wrong separator", () => {
|
||||||
|
// arrange
|
||||||
|
const input = "-2.5;3";
|
||||||
|
|
||||||
|
// act
|
||||||
|
const act = () => addStringOfNumbers(input);
|
||||||
|
|
||||||
|
// assert
|
||||||
|
expect(act).toThrow("Invalid characters");
|
||||||
|
});
|
||||||
|
});
|
21
src/exercises/addStringOfNumbers/index.ts
Normal file
21
src/exercises/addStringOfNumbers/index.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
export function addStringOfNumbers(input: string) {
|
||||||
|
if (input === "") return 0;
|
||||||
|
|
||||||
|
// Regex to catch any character that is not a digit, comma, dot or minus sign
|
||||||
|
const isContainingBadCharacters = /[^-,.\d]/.test(input);
|
||||||
|
if (isContainingBadCharacters) throw new Error("Invalid characters");
|
||||||
|
|
||||||
|
if (!input.includes(",")) {
|
||||||
|
const num = Number(input);
|
||||||
|
if (isNaN(num)) throw new Error("Not valid number");
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
|
const arr = input.split(",");
|
||||||
|
return arr.reduce((acc, str) => {
|
||||||
|
const num = Number(str);
|
||||||
|
if (isNaN(num)) throw new Error("Not valid numbers");
|
||||||
|
|
||||||
|
return acc + num;
|
||||||
|
}, 0);
|
||||||
|
}
|
19
src/exercises/convertToLowercase/index.test.ts
Normal file
19
src/exercises/convertToLowercase/index.test.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { convertToLowercase } from "./index";
|
||||||
|
|
||||||
|
describe("convertToLowercase", () => {
|
||||||
|
it.each([
|
||||||
|
{ input: "ToTO", expected: "toto" },
|
||||||
|
{ input: "ToTo", expected: "toto" },
|
||||||
|
{ input: "TOTo", expected: "toto" },
|
||||||
|
])(
|
||||||
|
"should return the input in lowercase when all letters are uppercases",
|
||||||
|
({ input, expected }) => {
|
||||||
|
// Arrange
|
||||||
|
// Act
|
||||||
|
const result = convertToLowercase(input);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(result).toStrictEqual(expected);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
3
src/exercises/convertToLowercase/index.ts
Normal file
3
src/exercises/convertToLowercase/index.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export function convertToLowercase(input: string): string {
|
||||||
|
return input.toLowerCase();
|
||||||
|
}
|
37
src/exercises/isBeforeNow/index.test.ts
Normal file
37
src/exercises/isBeforeNow/index.test.ts
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import { isBeforeNow } from "./index";
|
||||||
|
|
||||||
|
const dateBefore = new Date("2022-01-01T00:00:00.000Z");
|
||||||
|
const dateNow = new Date("2023-01-01T00:00:00.000Z");
|
||||||
|
const dateAfter = new Date("2024-01-01T00:00:00.000Z");
|
||||||
|
|
||||||
|
describe("isBeforeNow", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.useFakeTimers({
|
||||||
|
now: dateNow,
|
||||||
|
});
|
||||||
|
|
||||||
|
// or
|
||||||
|
|
||||||
|
// jest.spyOn(Date, "now").mockReturnValue(dateNow.getTime());
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
jest.useRealTimers();
|
||||||
|
|
||||||
|
// or
|
||||||
|
|
||||||
|
// jest.restoreAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns true if the date is before now", () => {
|
||||||
|
expect(isBeforeNow(dateBefore)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns false if the date is now", () => {
|
||||||
|
expect(isBeforeNow(dateNow)).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns false if the date is after now", () => {
|
||||||
|
expect(isBeforeNow(dateAfter)).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
3
src/exercises/isBeforeNow/index.ts
Normal file
3
src/exercises/isBeforeNow/index.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export function isBeforeNow(date: Date): boolean {
|
||||||
|
return date.getTime() < Date.now();
|
||||||
|
}
|
18
src/exercises/mockMathPow/index.test.ts
Normal file
18
src/exercises/mockMathPow/index.test.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { square } from "./index";
|
||||||
|
|
||||||
|
describe("square", () => {
|
||||||
|
it("returns the number pow 2", () => {
|
||||||
|
// Arrange
|
||||||
|
const num = 3;
|
||||||
|
Math.pow = jest.fn(); //.mockReturnValue(2);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
square(num);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(Math.pow).toHaveBeenCalledTimes(1);
|
||||||
|
expect(Math.pow).toHaveBeenCalledWith(3, 2);
|
||||||
|
|
||||||
|
// expect(square(num)).toBe(2);
|
||||||
|
});
|
||||||
|
});
|
3
src/exercises/mockMathPow/index.ts
Normal file
3
src/exercises/mockMathPow/index.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export function square(value: number): number {
|
||||||
|
return Math.pow(value, 2);
|
||||||
|
}
|
18
src/exercises/mockStringUppercase/index.test.ts
Normal file
18
src/exercises/mockStringUppercase/index.test.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { toUpperCase } from "./index";
|
||||||
|
|
||||||
|
describe("toUpperCase", () => {
|
||||||
|
it("returns the string in uppercase", () => {
|
||||||
|
// Arrange
|
||||||
|
const input = "hello";
|
||||||
|
String.prototype.toUpperCase = jest.fn(); //.mockReturnValue("BLABLA");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
toUpperCase(input);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(input.toUpperCase).toHaveBeenCalledTimes(1);
|
||||||
|
expect(input.toUpperCase).toHaveBeenCalledWith();
|
||||||
|
|
||||||
|
// expect(toUpperCase(input)).toBe("BLABLA");
|
||||||
|
});
|
||||||
|
});
|
3
src/exercises/mockStringUppercase/index.ts
Normal file
3
src/exercises/mockStringUppercase/index.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export function toUpperCase(value: string): string {
|
||||||
|
return value.toUpperCase();
|
||||||
|
}
|
47
src/exercises/multiplyArrays/index.test.ts
Normal file
47
src/exercises/multiplyArrays/index.test.ts
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
import { multiplyArrays } from "./index";
|
||||||
|
|
||||||
|
describe("multiplyArrays", () => {
|
||||||
|
it.each([
|
||||||
|
{
|
||||||
|
arr1: [1, 2, 3],
|
||||||
|
arr2: [4, 5, 6],
|
||||||
|
expected: [4, 10, 18],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arr1: [3, 2, 3],
|
||||||
|
arr2: [4, 5, 3],
|
||||||
|
expected: [12, 10, 9],
|
||||||
|
},
|
||||||
|
])("should multiply all numbers of 2 arrays", ({ arr1, arr2, expected }) => {
|
||||||
|
// Arrange
|
||||||
|
// Act
|
||||||
|
const result = multiplyArrays(arr1, arr2);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(result).toStrictEqual(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should throw when one array is empty", () => {
|
||||||
|
// Arrange
|
||||||
|
const arr1 = [1, 2, 3];
|
||||||
|
const arr2: number[] = [];
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const act = () => multiplyArrays(arr1, arr2);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(act).toThrow("Arrays must have at least one element");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should throw when arrays length is different", () => {
|
||||||
|
// Arrange
|
||||||
|
const arr1 = [1, 2, 3];
|
||||||
|
const arr2 = [4, 5];
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const act = () => multiplyArrays(arr1, arr2);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(act).toThrow("Arrays must have the same length");
|
||||||
|
});
|
||||||
|
});
|
16
src/exercises/multiplyArrays/index.ts
Normal file
16
src/exercises/multiplyArrays/index.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
export function multiplyArrays(a: number[], b: number[]): number[] {
|
||||||
|
if (a.length === 0 || b.length === 0) {
|
||||||
|
throw new Error("Arrays must have at least one element");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a.length !== b.length) {
|
||||||
|
throw new Error("Arrays must have the same length");
|
||||||
|
}
|
||||||
|
|
||||||
|
const output: number[] = new Array(a.length);
|
||||||
|
for (let i = 0; i < output.length; i++) {
|
||||||
|
output[i] = a[i] * b[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
44
src/exercises/multiplyArrays2/index.test.ts
Normal file
44
src/exercises/multiplyArrays2/index.test.ts
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import { multiplyArrays } from "./index";
|
||||||
|
|
||||||
|
describe("multiplyArrays", () => {
|
||||||
|
it.each([
|
||||||
|
{ arr1: [1, 2, 3], arr2: [4, 5, 6], expected: [4, 10, 18] },
|
||||||
|
{ arr1: [-1, -2, -3], arr2: [4, -5, 6], expected: [-4, 10, -18] },
|
||||||
|
{
|
||||||
|
arr1: [-1.1, -2.1, -3.1],
|
||||||
|
arr2: [4, -5, 6],
|
||||||
|
expected: [-4.4, 10.5, -18.6],
|
||||||
|
},
|
||||||
|
])("should multiply two arrays", ({ arr1, arr2, expected }) => {
|
||||||
|
// arrange
|
||||||
|
// act
|
||||||
|
const result = multiplyArrays(arr1, arr2);
|
||||||
|
|
||||||
|
// assert
|
||||||
|
expect(result).toStrictEqual(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should throw an error if arrays are not the same length", () => {
|
||||||
|
// arrange
|
||||||
|
const arr1 = [1, 2, 3];
|
||||||
|
const arr2 = [4, 5];
|
||||||
|
|
||||||
|
// act
|
||||||
|
const act = () => multiplyArrays(arr1, arr2);
|
||||||
|
|
||||||
|
// assert
|
||||||
|
expect(act).toThrow("Arrays must be the same length");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should throw an error if arrays are empty", () => {
|
||||||
|
// arrange
|
||||||
|
const arr1: number[] = [];
|
||||||
|
const arr2: number[] = [];
|
||||||
|
|
||||||
|
// act
|
||||||
|
const act = () => multiplyArrays(arr1, arr2);
|
||||||
|
|
||||||
|
// assert
|
||||||
|
expect(act).toThrow("Arrays must not be empty");
|
||||||
|
});
|
||||||
|
});
|
10
src/exercises/multiplyArrays2/index.ts
Normal file
10
src/exercises/multiplyArrays2/index.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
export function multiplyArrays(arr1: number[], arr2: number[]): number[] {
|
||||||
|
const isSameLength = arr1.length === arr2.length;
|
||||||
|
|
||||||
|
if (!isSameLength) throw new Error("Arrays must be the same length");
|
||||||
|
|
||||||
|
const isOneEmpty = arr1.length === 0 || arr2.length === 0;
|
||||||
|
if (isOneEmpty) throw new Error("Arrays must not be empty");
|
||||||
|
|
||||||
|
return arr1.map((num, index) => num * arr2[index]);
|
||||||
|
}
|
14
src/exercises/removeDuplicates/index.test.ts
Normal file
14
src/exercises/removeDuplicates/index.test.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { removeDuplicates } from "./index";
|
||||||
|
|
||||||
|
describe("removeDuplicates", () => {
|
||||||
|
it("should multiply all numbers of 2 arrays", () => {
|
||||||
|
// Arrange
|
||||||
|
const arr = [1, 2, 2, 2, 3, 3, 4];
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const result = removeDuplicates(arr);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(result).toStrictEqual([1, 2, 3, 4]);
|
||||||
|
});
|
||||||
|
});
|
3
src/exercises/removeDuplicates/index.ts
Normal file
3
src/exercises/removeDuplicates/index.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export function removeDuplicates(a: number[]): number[] {
|
||||||
|
return Array.from(new Set(a));
|
||||||
|
}
|
14
src/exercises/removeDuplicates2/index.test.ts
Normal file
14
src/exercises/removeDuplicates2/index.test.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { removeDuplicates } from "./index";
|
||||||
|
|
||||||
|
describe("removeDuplicates", () => {
|
||||||
|
it("should remove duplicates from an array", () => {
|
||||||
|
// arrange
|
||||||
|
const arr = [1, 2, 2, 3, 4, 4, 5];
|
||||||
|
|
||||||
|
// act
|
||||||
|
const result = removeDuplicates(arr);
|
||||||
|
|
||||||
|
// assert
|
||||||
|
expect(result).toStrictEqual([1, 2, 3, 4, 5]);
|
||||||
|
});
|
||||||
|
});
|
3
src/exercises/removeDuplicates2/index.ts
Normal file
3
src/exercises/removeDuplicates2/index.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export function removeDuplicates(arr: number[]): number[] {
|
||||||
|
return Array.from(new Set(arr));
|
||||||
|
}
|
14
src/exercises/testAnException/index.test.ts
Normal file
14
src/exercises/testAnException/index.test.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { throwAnException } from "./index";
|
||||||
|
|
||||||
|
describe("testAnException", () => {
|
||||||
|
it("should throw an exception", () => {
|
||||||
|
// Arrange
|
||||||
|
// Act
|
||||||
|
const act = () => {
|
||||||
|
throwAnException();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(act).toThrow("I am an exception");
|
||||||
|
});
|
||||||
|
});
|
3
src/exercises/testAnException/index.ts
Normal file
3
src/exercises/testAnException/index.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export function throwAnException(): void {
|
||||||
|
throw new Error("I am an exception");
|
||||||
|
}
|
37
src/exercises/validation/age/index.test.ts
Normal file
37
src/exercises/validation/age/index.test.ts
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import "reflect-metadata";
|
||||||
|
import { container } from "tsyringe";
|
||||||
|
import { AgeValidation } from "./index";
|
||||||
|
|
||||||
|
describe("AgeValidation", () => {
|
||||||
|
const ageValidation = container.resolve(AgeValidation);
|
||||||
|
|
||||||
|
describe("validateAge", () => {
|
||||||
|
it.each([
|
||||||
|
{ input: "1", expected: 1 },
|
||||||
|
{ input: "18", expected: 18 },
|
||||||
|
{ input: "100", expected: 100 },
|
||||||
|
])(
|
||||||
|
"should return a number when given a string if represents a valid age",
|
||||||
|
({ input, expected }) => {
|
||||||
|
// arrange
|
||||||
|
// act
|
||||||
|
const result = ageValidation.validateAge(input);
|
||||||
|
|
||||||
|
// assert
|
||||||
|
expect(result).toBe(expected);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
it.each([{ input: "-2", expected: "Input must be a valid age" }])(
|
||||||
|
"should throw an error if input does not represent a valid age",
|
||||||
|
({ input, expected }) => {
|
||||||
|
// arrange
|
||||||
|
// act
|
||||||
|
const act = () => ageValidation.validateAge(input);
|
||||||
|
|
||||||
|
// assert
|
||||||
|
expect(act).toThrow(expected);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
18
src/exercises/validation/age/index.ts
Normal file
18
src/exercises/validation/age/index.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { singleton } from "tsyringe";
|
||||||
|
import { NumberValidation } from "../number";
|
||||||
|
|
||||||
|
@singleton()
|
||||||
|
export class AgeValidation {
|
||||||
|
public constructor(private numberValidation: NumberValidation) {}
|
||||||
|
|
||||||
|
public validateAge(input: string) {
|
||||||
|
try {
|
||||||
|
let number: number = this.numberValidation.validateInteger(input);
|
||||||
|
number = this.numberValidation.validatePositive(input);
|
||||||
|
|
||||||
|
return number;
|
||||||
|
} catch (error) {
|
||||||
|
throw new Error("Input must be a valid age");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
109
src/exercises/validation/number/index.test.ts
Normal file
109
src/exercises/validation/number/index.test.ts
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
import "reflect-metadata"
|
||||||
|
import { container } from "tsyringe";
|
||||||
|
import { NumberValidation } from "./index";
|
||||||
|
|
||||||
|
describe("NumberValidation", () => {
|
||||||
|
const numberValidation = container.resolve(NumberValidation);
|
||||||
|
|
||||||
|
describe("validateNumber", () => {
|
||||||
|
it.each([
|
||||||
|
{ input: "0", expected: 0 },
|
||||||
|
{ input: "1", expected: 1 },
|
||||||
|
{ input: "-1", expected: -1 },
|
||||||
|
{ input: "1.67", expected: 1.67 },
|
||||||
|
{ input: "-1.67", expected: -1.67 },
|
||||||
|
{ input: "-1e7", expected: -1e7 },
|
||||||
|
])(
|
||||||
|
"should return a number when given a string if valid",
|
||||||
|
({ input, expected }) => {
|
||||||
|
// arrange
|
||||||
|
// act
|
||||||
|
const result = numberValidation.validateNumber(input);
|
||||||
|
|
||||||
|
// assert
|
||||||
|
expect(result).toBe(expected);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
it("should throw an error if input is not a number", () => {
|
||||||
|
// arrange
|
||||||
|
const input = "a";
|
||||||
|
|
||||||
|
// act
|
||||||
|
const act = () => numberValidation.validateNumber(input);
|
||||||
|
|
||||||
|
// assert
|
||||||
|
expect(act).toThrow("Input must be a number");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("validateInteger", () => {
|
||||||
|
it.each([
|
||||||
|
{ input: "0", expected: 0 },
|
||||||
|
{ input: "1", expected: 1 },
|
||||||
|
{ input: "-1", expected: -1 },
|
||||||
|
{ input: "1e3", expected: 1e3 },
|
||||||
|
])(
|
||||||
|
"should return an integer when given a string if valid",
|
||||||
|
({ input, expected }) => {
|
||||||
|
// arrange
|
||||||
|
// act
|
||||||
|
const result = numberValidation.validateInteger(input);
|
||||||
|
|
||||||
|
// assert
|
||||||
|
expect(result).toBe(expected);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
it.each([
|
||||||
|
{ input: "1.67", expected: "Input must be an integer" },
|
||||||
|
{ input: "-1.67", expected: "Input must be an integer" },
|
||||||
|
{ input: "1e-3", expected: "Input must be an integer" },
|
||||||
|
])(
|
||||||
|
"should throw an error if input is not an integer",
|
||||||
|
({ input, expected }) => {
|
||||||
|
// arrange
|
||||||
|
// act
|
||||||
|
const act = () => numberValidation.validateInteger(input);
|
||||||
|
|
||||||
|
// assert
|
||||||
|
expect(act).toThrow(expected);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("validatePositive", () => {
|
||||||
|
it.each([
|
||||||
|
{ input: "0", expected: 0 },
|
||||||
|
{ input: "1", expected: 1 },
|
||||||
|
{ input: "1.67", expected: 1.67 },
|
||||||
|
{ input: "1e3", expected: 1e3 },
|
||||||
|
])(
|
||||||
|
"should return a positive number when given a string if valid",
|
||||||
|
({ input, expected }) => {
|
||||||
|
// arrange
|
||||||
|
// act
|
||||||
|
const result = numberValidation.validatePositive(input);
|
||||||
|
|
||||||
|
// assert
|
||||||
|
expect(result).toBe(expected);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
it.each([
|
||||||
|
{ input: "-1", expected: "Input must be positive" },
|
||||||
|
{ input: "-1.67", expected: "Input must be positive" },
|
||||||
|
{ input: "-1e3", expected: "Input must be positive" },
|
||||||
|
])(
|
||||||
|
"should throw an error if input is not positive",
|
||||||
|
({ input, expected }) => {
|
||||||
|
// arrange
|
||||||
|
// act
|
||||||
|
const act = () => numberValidation.validatePositive(input);
|
||||||
|
|
||||||
|
// assert
|
||||||
|
expect(act).toThrow(expected);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
34
src/exercises/validation/number/index.ts
Normal file
34
src/exercises/validation/number/index.ts
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import { singleton } from "tsyringe";
|
||||||
|
|
||||||
|
@singleton()
|
||||||
|
export class NumberValidation {
|
||||||
|
public validateNumber(input: string): number {
|
||||||
|
const number = Number(input);
|
||||||
|
|
||||||
|
if (isNaN(number)) {
|
||||||
|
throw new Error("Input must be a number");
|
||||||
|
}
|
||||||
|
|
||||||
|
return number;
|
||||||
|
}
|
||||||
|
|
||||||
|
public validateInteger(input: string): number {
|
||||||
|
const number = this.validateNumber(input);
|
||||||
|
|
||||||
|
if (!Number.isInteger(number)) {
|
||||||
|
throw new Error("Input must be an integer");
|
||||||
|
}
|
||||||
|
|
||||||
|
return number;
|
||||||
|
}
|
||||||
|
|
||||||
|
public validatePositive(input: string): number {
|
||||||
|
const number = this.validateNumber(input);
|
||||||
|
|
||||||
|
if (number < 0) {
|
||||||
|
throw new Error("Input must be positive");
|
||||||
|
}
|
||||||
|
|
||||||
|
return number;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user