/
array.ts
151 lines (136 loc) · 4.22 KB
/
array.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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
import isEqual = require('lodash.isequal'); // tslint:disable-line:no-require-imports
import ow from '../..';
import {Predicate, Context} from './predicate';
export class ArrayPredicate extends Predicate<any[]> {
constructor(context?: Context) {
super('array', context);
}
/**
* Test an array to have a specific length.
*
* @param length The length of the array.
*/
length(length: number) {
return this.addValidator({
message: value => `Expected array to have length \`${length}\`, got \`${value.length}\``,
validator: value => value.length === length
});
}
/**
* Test an array to have a minimum length.
*
* @param length The minimum length of the array.
*/
minLength(length: number) {
return this.addValidator({
message: value => `Expected array to have a minimum length of \`${length}\`, got \`${value.length}\``,
validator: value => value.length >= length
});
}
/**
* Test an array to have a maximum length.
*
* @param length The maximum length of the array.
*/
maxLength(length: number) {
return this.addValidator({
message: value => `Expected array to have a maximum length of \`${length}\`, got \`${value.length}\``,
validator: value => value.length <= length
});
}
/**
* Test an array to start with a specific value. The value is tested by identity, not structure.
*
* @param searchElement The value that should be the start of the array.
*/
startsWith(searchElement: any) {
return this.addValidator({
message: value => `Expected array to start with \`${searchElement}\`, got \`${value[0]}\``,
validator: value => value[0] === searchElement
});
}
/**
* Test an array to end with a specific value. The value is tested by identity, not structure.
*
* @param searchElement The value that should be the end of the array.
*/
endsWith(searchElement: any) {
return this.addValidator({
message: value => `Expected array to end with \`${searchElement}\`, got \`${value[value.length - 1]}\``,
validator: value => value[value.length - 1] === searchElement
});
}
/**
* Test an array to include all the provided elements. The values are tested by identity, not structure.
*
* @param searchElements The values that should be included in the array.
*/
includes(...searchElements: any[]) {
return this.addValidator({
message: value => `Expected array to include all elements of \`${JSON.stringify(searchElements)}\`, got \`${JSON.stringify(value)}\``,
validator: value => searchElements.every(el => value.indexOf(el) !== -1)
});
}
/**
* Test an array to include any of the provided elements. The values are tested by identity, not structure.
*
* @param searchElements The values that should be included in the array.
*/
includesAny(...searchElements: any[]) {
return this.addValidator({
message: value => `Expected array to include any element of \`${JSON.stringify(searchElements)}\`, got \`${JSON.stringify(value)}\``,
validator: value => searchElements.some(el => value.indexOf(el) !== -1)
});
}
/**
* Test an array to be empty.
*/
get empty() {
return this.addValidator({
message: value => `Expected array to be empty, got \`${JSON.stringify(value)}\``,
validator: value => value.length === 0
});
}
/**
* Test an array to be not empty.
*/
get nonEmpty() {
return this.addValidator({
message: () => 'Expected array to not be empty',
validator: value => value.length > 0
});
}
/**
* Test an array to be deeply equal to the provided array.
*
* @param expected Expected value to match.
*/
deepEqual(expected: any[]) {
return this.addValidator({
message: value => `Expected array to be deeply equal to \`${JSON.stringify(expected)}\`, got \`${JSON.stringify(value)}\``,
validator: value => isEqual(value, expected)
});
}
/**
* Test all elements in the array to match to provided predicate.
*
* @param predicate The predicate that should be applied against every individual item.
*/
ofType<T>(predicate: Predicate<T>) {
let error: string;
return this.addValidator({
message: () => error,
validator: value => {
try {
for (const item of value) {
ow(item, predicate);
}
return true;
} catch (err) {
error = err.message;
return false;
}
}
});
}
}