move validation to types

This commit is contained in:
Ruidy 2021-02-19 14:09:07 +01:00
parent 54ae738762
commit afe5a6c7e8
6 changed files with 45 additions and 36 deletions

View file

@ -4,6 +4,6 @@ Web app which returns the iconic Hello, World in various locales
## Features ## Features
- [ ] Print hello world in a random locale - [x] Print hello world in a random locale
- [ ] Select the locale by id - [x] Select the locale by id
- [ ] Serve via internet - [ ] Serve via internet

View file

@ -1,12 +1,8 @@
import { import { assertStrictEquals } from "https://deno.land/std@0.87.0/testing/asserts.ts";
assertStrictEquals,
assertThrows,
} from "https://deno.land/std@0.87.0/testing/asserts.ts";
import { sayHello, sayRandomHello } from "./index.ts"; import { sayHello, sayRandomHello } from "./index.ts";
import { ValidationError } from "./validation.ts"; import { ID } from "./types.ts";
import { localesSize } from "./repository/locales.ts";
Deno.test("Hello test", () => { Deno.test("Random Hello", () => {
const result = sayRandomHello(); const result = sayRandomHello();
const actual = typeof result; const actual = typeof result;
const expected = "string"; const expected = "string";
@ -14,11 +10,11 @@ Deno.test("Hello test", () => {
}); });
Deno.test("Specific Hello", () => { Deno.test("Specific Hello", () => {
type TestCase = { in: number; want: string }; type TestCase = { in: ID; want: string };
const testCases: TestCase[] = [ const testCases: TestCase[] = [
{ in: 25, want: "Salut le Monde!" }, { in: new ID(25), want: "Salut le Monde!" },
{ in: 21, want: "Hello World!" }, { in: new ID(21), want: "Hello World!" },
]; ];
for (const test of testCases) { for (const test of testCases) {
@ -28,17 +24,3 @@ Deno.test("Specific Hello", () => {
assertStrictEquals(actual, expected); assertStrictEquals(actual, expected);
} }
}); });
Deno.test("Hello fails for non strictly positive values", () => {
const id = -1;
assertThrows(() => sayHello(id), ValidationError, "Invalid index: -1");
});
Deno.test("Hello fails for too large values", () => {
const id = localesSize;
assertThrows(
() => sayHello(id),
ValidationError,
`Invalid index: ${localesSize}`,
);
});

View file

@ -1,21 +1,19 @@
import { idIsValid, ValidationError } from "./validation.ts";
import { getLocaleById, localesSize } from "./repository/locales.ts"; import { getLocaleById, localesSize } from "./repository/locales.ts";
import { ID } from "./types.ts";
/** /**
* Display the iconic Hello, World in a random locale * Display the iconic Hello, World in a random locale
*/ */
export const sayRandomHello = () => { export const sayRandomHello = () => {
const id = Math.ceil(Math.random() * localesSize); const id = Math.ceil(Math.random() * localesSize);
return sayHello(id); const val = new ID(id);
return sayHello(val);
}; };
/** /**
* Display the iconic Hello, World in a locale identified by id * Display the iconic Hello, World in a locale identified by id
* @param id Unique identifier * @param id Unique identifier
*/ */
export const sayHello = (id: number): string => { export const sayHello = (id: ID): string => {
if (!idIsValid(id)) { return getLocaleById(id.id);
throw new ValidationError(`Invalid index: ${id}`);
}
return getLocaleById(id);
}; };

16
src/types.test.ts Normal file
View file

@ -0,0 +1,16 @@
import { ID } from "./types.ts";
import { ValidationError } from "./validation.ts";
import { assertThrows } from "https://deno.land/std@0.87.0/testing/asserts.ts";
import { localesSize } from "./repository/locales.ts";
Deno.test("ID validation fails for non strictly positive values", () => {
assertThrows(() => new ID(-1), ValidationError, "Invalid index: -1");
});
Deno.test("Hello fails for too large values", () => {
assertThrows(
() => new ID(localesSize),
ValidationError,
`Invalid index: ${localesSize}`,
);
});

16
src/types.ts Normal file
View file

@ -0,0 +1,16 @@
import { ValidationError } from "./validation.ts";
import { localesSize } from "./repository/locales.ts";
export class ID {
constructor(public id: number) {
this.#isValid(id);
}
#idIsValid = (id: number) => id > 0 && id < localesSize;
#isValid = (id: number) => {
if (!this.#idIsValid(id)) {
throw new ValidationError(`Invalid index: ${id}`);
}
};
}

View file

@ -4,8 +4,5 @@
* *
@example * `throw new ValidationError("Bad id")` @example * `throw new ValidationError("Bad id")`
*/ */
import { localesSize } from "./repository/locales.ts";
export class ValidationError extends Error {} export class ValidationError extends Error {}
export const idIsValid = (id: number) => id > 0 && id < localesSize;