/
Either.examples.spec.ts
86 lines (71 loc) 路 2.91 KB
/
Either.examples.spec.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import { expect, assert } from 'chai';
import { spy } from 'sinon';
import { Either, left, right } from '../src/Either';
describe('Either examples', () => {
describe('Example #1: input parser', () => {
function tryParseInt(input: string): Either<string, number> {
let n: number = parseInt(input, 10);
return Either.cond(!isNaN(n), n, 'not a number');
}
it('should return `Right` if input has been parsed successfully', () => {
let res = tryParseInt('42');
expect(res).to.deep.eq(right(42));
});
it('should return `Left` with error message if input has been parsed with errors', () => {
let res = tryParseInt('not a number');
expect(res).to.deep.eq(left('not a number'));
});
});
describe('Example #2: input validation', () => {
const AGE_MIN = 14;
const AGE_MAX = 30;
function validateAge(input: string): Either<string, number> {
try {
let age: number = parseInt(input, 10);
if(isNaN(age)){
throw new Error('Invalid input, the age should be a number.');
}
if(age < AGE_MIN || age > AGE_MAX){
throw new RangeError(`The age should be in range between ${AGE_MIN} and ${AGE_MAX}.`);
}
return right(age);
} catch (e) {
return left(e.message);
}
}
it('should return `Right` with a valid age', () => {
expect(validateAge('20')).to.deep.eq(right(20));
});
it('should return `Left` if age is not a number', () => {
expect(validateAge('WAT')).to.deep.eq(left('Invalid input, the age should be a number.'));
});
it('should return `Left` if age is out of range', () => {
expect(validateAge('10')).to.deep.eq(left(`The age should be in range between ${AGE_MIN} and ${AGE_MAX}.`));
});
});
describe('Example #3: working with `Left`', () => {
let printNumber;
let printError;
function print(numberOrError: Either<Error, number>) {
numberOrError
.map(num => num)
.foreach(printNumber)
.mapLeft(err => err.message)
.foreachLeft(printError);
}
beforeEach(() => {
printNumber = spy();
printError = spy();
});
it('should print an error message', () => {
let numberOrError: Either<Error, number> = left(new RangeError('It\'s not a number.'));
print(numberOrError);
assert(printError.calledWith('It\'s not a number.'));
});
it('should print a number', () => {
let numberOrError: Either<Error, number> = right(42);
print(numberOrError);
assert(printNumber.calledWith(42));
});
});
});