mirror of https://github.com/lukechilds/ow.git
Sam Verschueren
7 years ago
committed by
Sindre Sorhus
5 changed files with 229 additions and 1 deletions
@ -0,0 +1,151 @@ |
|||
import * as isEqual from 'lodash.isequal'; |
|||
import {ow} from '../../ow'; |
|||
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; |
|||
|
|||
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; |
|||
} |
|||
} |
|||
}); |
|||
} |
|||
} |
@ -0,0 +1,69 @@ |
|||
import test from 'ava'; |
|||
import * as m from '..'; |
|||
|
|||
test('array', t => { |
|||
t.notThrows(() => m([], m.array)); |
|||
t.throws(() => m('12', m.array), 'Expected argument to be of type `array` but received type `string`'); |
|||
}); |
|||
|
|||
test('array.length', t => { |
|||
t.notThrows(() => m(['foo'], m.array.length(1))); |
|||
t.notThrows(() => m(['foo', 'bar'], m.array.length(2))); |
|||
t.throws(() => m(['foo'], m.array.length(2)), 'Expected array to have length `2`, got `1`'); |
|||
}); |
|||
|
|||
test('array.minLength', t => { |
|||
t.notThrows(() => m(['foo'], m.array.minLength(1))); |
|||
t.notThrows(() => m(['foo', 'bar'], m.array.minLength(1))); |
|||
t.throws(() => m(['foo'], m.array.minLength(2)), 'Expected array to have a minimum length of `2`, got `1`'); |
|||
}); |
|||
|
|||
test('array.maxLength', t => { |
|||
t.notThrows(() => m(['foo'], m.array.maxLength(1))); |
|||
t.notThrows(() => m(['foo', 'bar'], m.array.maxLength(4))); |
|||
t.throws(() => m(['foo', 'bar'], m.array.maxLength(1)), 'Expected array to have a maximum length of `1`, got `2`'); |
|||
}); |
|||
|
|||
test('array.startsWith', t => { |
|||
t.notThrows(() => m(['foo', 'bar'], m.array.startsWith('foo'))); |
|||
t.throws(() => m(['foo', 'bar'], m.array.startsWith('bar')), 'Expected array to start with `bar`, got `foo`'); |
|||
}); |
|||
|
|||
test('array.endsWith', t => { |
|||
t.notThrows(() => m(['foo', 'bar'], m.array.endsWith('bar'))); |
|||
t.throws(() => m(['foo', 'bar'], m.array.endsWith('foo')), 'Expected array to end with `foo`, got `bar`'); |
|||
}); |
|||
|
|||
test('array.includes', t => { |
|||
t.notThrows(() => m(['foo', 'bar'], m.array.includes('foo'))); |
|||
t.notThrows(() => m(['foo', 'bar', 'unicorn'], m.array.includes('foo', 'bar'))); |
|||
t.throws(() => m(['foo', 'bar'], m.array.includes('foo', 'unicorn')), 'Expected array to include all elements of `["foo","unicorn"]`, got `["foo","bar"]`'); |
|||
}); |
|||
|
|||
test('array.includesAny', t => { |
|||
t.notThrows(() => m(['foo', 'bar'], m.array.includesAny('foo'))); |
|||
t.notThrows(() => m(['foo', 'bar', 'unicorn'], m.array.includesAny('unicorn', 'rainbow'))); |
|||
t.throws(() => m(['foo', 'bar'], m.array.includesAny('unicorn')), 'Expected array to include any element of `["unicorn"]`, got `["foo","bar"]`'); |
|||
}); |
|||
|
|||
test('array.empty', t => { |
|||
t.notThrows(() => m([], m.array.empty)); |
|||
t.throws(() => m(['foo'], m.array.empty), 'Expected array to be empty, got `["foo"]`'); |
|||
}); |
|||
|
|||
test('array.nonEmpty', t => { |
|||
t.notThrows(() => m(['foo'], m.array.nonEmpty)); |
|||
t.throws(() => m([], m.array.nonEmpty), 'Expected array to not be empty'); |
|||
}); |
|||
|
|||
test('array.deepEqual', t => { |
|||
t.notThrows(() => m(['foo'], m.array.deepEqual(['foo']))); |
|||
t.notThrows(() => m(['foo', {id: 1}], m.array.deepEqual(['foo', {id: 1}]))); |
|||
t.throws(() => m(['foo', {id: 1}], m.array.deepEqual(['foo', {id: 2}])), 'Expected array to be deeply equal to `["foo",{"id":2}]`, got `["foo",{"id":1}]`'); |
|||
}); |
|||
|
|||
test('array.ofType', t => { |
|||
t.notThrows(() => m(['foo', 'bar'], m.array.ofType(m.string))); |
|||
t.notThrows(() => m(['foo', 'bar'], m.array.ofType(m.string.minLength(3)))); |
|||
t.throws(() => m(['foo', 'b'], m.array.ofType(m.string.minLength(3))), 'Expected string to have a minimum length of `3`, got `b`'); |
|||
}); |
Loading…
Reference in new issue