UNPKG

6.4 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.ArrayPredicate = void 0;
4const isEqual = require("lodash.isequal");
5const predicate_1 = require("./predicate");
6const __1 = require("..");
7const match_shape_1 = require("../utils/match-shape");
8class ArrayPredicate extends predicate_1.Predicate {
9 /**
10 @hidden
11 */
12 constructor(options) {
13 super('array', options);
14 }
15 /**
16 Test an array to have a specific length.
17
18 @param length - The length of the array.
19 */
20 length(length) {
21 return this.addValidator({
22 message: (value, label) => `Expected ${label} to have length \`${length}\`, got \`${value.length}\``,
23 validator: value => value.length === length
24 });
25 }
26 /**
27 Test an array to have a minimum length.
28
29 @param length - The minimum length of the array.
30 */
31 minLength(length) {
32 return this.addValidator({
33 message: (value, label) => `Expected ${label} to have a minimum length of \`${length}\`, got \`${value.length}\``,
34 validator: value => value.length >= length,
35 negatedMessage: (value, label) => `Expected ${label} to have a maximum length of \`${length - 1}\`, got \`${value.length}\``
36 });
37 }
38 /**
39 Test an array to have a maximum length.
40
41 @param length - The maximum length of the array.
42 */
43 maxLength(length) {
44 return this.addValidator({
45 message: (value, label) => `Expected ${label} to have a maximum length of \`${length}\`, got \`${value.length}\``,
46 validator: value => value.length <= length,
47 negatedMessage: (value, label) => `Expected ${label} to have a minimum length of \`${length + 1}\`, got \`${value.length}\``
48 });
49 }
50 /**
51 Test an array to start with a specific value. The value is tested by identity, not structure.
52
53 @param searchElement - The value that should be the start of the array.
54 */
55 startsWith(searchElement) {
56 return this.addValidator({
57 message: (value, label) => `Expected ${label} to start with \`${searchElement}\`, got \`${value[0]}\``,
58 validator: value => value[0] === searchElement
59 });
60 }
61 /**
62 Test an array to end with a specific value. The value is tested by identity, not structure.
63
64 @param searchElement - The value that should be the end of the array.
65 */
66 endsWith(searchElement) {
67 return this.addValidator({
68 message: (value, label) => `Expected ${label} to end with \`${searchElement}\`, got \`${value[value.length - 1]}\``,
69 validator: value => value[value.length - 1] === searchElement
70 });
71 }
72 /**
73 Test an array to include all the provided elements. The values are tested by identity, not structure.
74
75 @param searchElements - The values that should be included in the array.
76 */
77 includes(...searchElements) {
78 return this.addValidator({
79 message: (value, label) => `Expected ${label} to include all elements of \`${JSON.stringify(searchElements)}\`, got \`${JSON.stringify(value)}\``,
80 validator: value => searchElements.every(element => value.includes(element))
81 });
82 }
83 /**
84 Test an array to include any of the provided elements. The values are tested by identity, not structure.
85
86 @param searchElements - The values that should be included in the array.
87 */
88 includesAny(...searchElements) {
89 return this.addValidator({
90 message: (value, label) => `Expected ${label} to include any element of \`${JSON.stringify(searchElements)}\`, got \`${JSON.stringify(value)}\``,
91 validator: value => searchElements.some(element => value.includes(element))
92 });
93 }
94 /**
95 Test an array to be empty.
96 */
97 get empty() {
98 return this.addValidator({
99 message: (value, label) => `Expected ${label} to be empty, got \`${JSON.stringify(value)}\``,
100 validator: value => value.length === 0
101 });
102 }
103 /**
104 Test an array to be not empty.
105 */
106 get nonEmpty() {
107 return this.addValidator({
108 message: (_, label) => `Expected ${label} to not be empty`,
109 validator: value => value.length > 0
110 });
111 }
112 /**
113 Test an array to be deeply equal to the provided array.
114
115 @param expected - Expected value to match.
116 */
117 deepEqual(expected) {
118 return this.addValidator({
119 message: (value, label) => `Expected ${label} to be deeply equal to \`${JSON.stringify(expected)}\`, got \`${JSON.stringify(value)}\``,
120 validator: value => isEqual(value, expected)
121 });
122 }
123 /**
124 Test all elements in the array to match to provided predicate.
125
126 @param predicate - The predicate that should be applied against every individual item.
127
128 @example
129 ```
130 ow(['a', 1], ow.array.ofType(ow.any(ow.string, ow.number)));
131 ```
132 */
133 ofType(predicate) {
134 let error;
135 // TODO [typescript@>=5] If higher-kinded types are supported natively by typescript, refactor `addValidator` to use them to avoid the usage of `any`. Otherwise, bump or remove this TODO.
136 return this.addValidator({
137 message: (_, label) => `(${label}) ${error}`,
138 validator: value => {
139 try {
140 for (const item of value) {
141 __1.default(item, predicate);
142 }
143 return true;
144 }
145 catch (error_) {
146 error = error_.message;
147 return false;
148 }
149 }
150 });
151 }
152 /**
153 Test if the elements in the array exactly matches the elements placed at the same indices in the predicates array.
154
155 @param predicates - Predicates to test the array against. Describes what the tested array should look like.
156
157 @example
158 ```
159 ow(['1', 2], ow.array.exactShape([ow.string, ow.number]));
160 ```
161 */
162 exactShape(predicates) {
163 const shape = predicates;
164 return this.addValidator({
165 message: (_, label, message) => `${message.replace('Expected', 'Expected element')} in ${label}`,
166 validator: object => match_shape_1.exact(object, shape, undefined, true)
167 });
168 }
169}
170exports.ArrayPredicate = ArrayPredicate;