Skip to content

Instantly share code, notes, and snippets.

@marcusradell
Created March 11, 2019 20:44
Show Gist options
  • Save marcusradell/ca3ee750d52091f54e62e94fde1fd4e6 to your computer and use it in GitHub Desktop.
Save marcusradell/ca3ee750d52091f54e62e94fde1fd4e6 to your computer and use it in GitHub Desktop.
io-ts code kata
import { PathReporter } from "io-ts/lib/PathReporter";
import * as t from "io-ts";
const User = t.type({
nickname: t.string,
age: t.number
});
type User = t.TypeOf<typeof User>;
test("User is valid", () => {
const input = {
nickname: "Nick",
age: 9001
};
const result = User.decode(input).isRight();
expect(result).toEqual(true);
});
test("Invalid user is reported with validation errors", () => {
const input = {};
const result = PathReporter.report(User.decode(input));
expect(result).toEqual([
"Invalid value undefined supplied to : { nickname: string, age: number }/nickname: string",
"Invalid value undefined supplied to : { nickname: string, age: number }/age: number"
]);
});
interface IUsersModel {
add: (u: User) => Promise<void>;
}
interface IDb {
none: (query: string, data: any) => Promise<void>;
}
class UsersModel implements IUsersModel {
private db: IDb;
constructor(db: IDb) {
this.db = db;
}
public add(u: User) {
return this.db.none(`insert into users values ($<nickname>, $<age>)`, u);
}
}
function setup(result: any[]) {
const db: IDb = {
none: (query: string, data: any) => {
result.push([query, data]);
return Promise.resolve();
}
};
const usersModel = new UsersModel(db);
function addUserHandler(input: unknown): Promise<void> {
const validationResult = User.decode(input);
if (validationResult.isLeft()) {
return Promise.reject(PathReporter.report(validationResult));
}
return usersModel.add(validationResult.value);
}
return { addUserHandler };
}
test("Validate unknown data and send to the business layer", async () => {
let result: any[] = [];
const { addUserHandler } = setup(result);
const input: unknown = {
nickname: "Nick",
age: 1
};
await addUserHandler(input);
expect(result).toEqual([
[
"insert into users values ($<nickname>, $<age>)",
{ age: 1, nickname: "Nick" }
]
]);
});
test("Validate unknown data and fail validation", async () => {
expect.assertions(1);
const { addUserHandler } = setup([]);
const input: unknown = {};
await addUserHandler(input).catch(result => {
expect(result).toEqual([
"Invalid value undefined supplied to : { nickname: string, age: number }/nickname: string",
"Invalid value undefined supplied to : { nickname: string, age: number }/age: number"
]);
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment