mirror of https://github.com/lukechilds/ow.git
committed by
Sindre Sorhus
3 changed files with 218 additions and 0 deletions
@ -0,0 +1,143 @@ |
|||
import * as isEqual from 'lodash.isequal'; |
|||
import ow from '../..'; |
|||
import {Predicate, Context} from './predicate'; |
|||
|
|||
export class SetPredicate extends Predicate<Set<any>> { |
|||
constructor(context?: Context) { |
|||
super('set', context); |
|||
} |
|||
|
|||
/** |
|||
* Test a Set to have a specific size. |
|||
* |
|||
* @param size The size of the Set. |
|||
*/ |
|||
size(size: number) { |
|||
return this.addValidator({ |
|||
message: set => `Expected Set to have size \`${size}\`, got \`${set.size}\``, |
|||
validator: set => set.size === size |
|||
}); |
|||
} |
|||
|
|||
/** |
|||
* Test an Size to have a minimum size. |
|||
* |
|||
* @param size The minimum size of the Set. |
|||
*/ |
|||
minSize(size: number) { |
|||
return this.addValidator({ |
|||
message: set => `Expected Set to have a minimum size of \`${size}\`, got \`${set.size}\``, |
|||
validator: set => set.size >= size |
|||
}); |
|||
} |
|||
|
|||
/** |
|||
* Test an Set to have a maximum size. |
|||
* |
|||
* @param size The maximum size of the Set. |
|||
*/ |
|||
maxSize(size: number) { |
|||
return this.addValidator({ |
|||
message: set => `Expected Set to have a maximum size of \`${size}\`, got \`${set.size}\``, |
|||
validator: set => set.size <= size |
|||
}); |
|||
} |
|||
|
|||
/** |
|||
* Test a Set to include all the provided items. The items are tested by identity, not structure. |
|||
* |
|||
* @param items The items that should be a item in the Set. |
|||
*/ |
|||
has(...items: any[]) { |
|||
const missingItems: any[] = []; |
|||
|
|||
return this.addValidator({ |
|||
message: () => `Expected Set to have items \`${JSON.stringify(missingItems)}\``, |
|||
validator: set => { |
|||
for (const item of items) { |
|||
if (set.has(item)) { |
|||
continue; |
|||
} |
|||
|
|||
missingItems.push(item); |
|||
|
|||
if (missingItems.length === 5) { |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
return missingItems.length === 0; |
|||
} |
|||
}); |
|||
} |
|||
|
|||
/** |
|||
* Test a Set to include any of the provided items. The items are tested by identity, not structure. |
|||
* |
|||
* @param items The items that could be a item in the Set. |
|||
*/ |
|||
hasAny(...items: any[]) { |
|||
return this.addValidator({ |
|||
message: () => `Expected Set to have any item of \`${JSON.stringify(items)}\``, |
|||
validator: set => items.some(item => set.has(item)) |
|||
}); |
|||
} |
|||
|
|||
/** |
|||
* Test all the items in the Set to match the provided predicate. |
|||
* |
|||
* @param predicate The predicate that should be applied against every item in the Set. |
|||
*/ |
|||
ofType<T>(predicate: Predicate<T>) { |
|||
let error: string; |
|||
|
|||
return this.addValidator({ |
|||
message: () => error, |
|||
validator: set => { |
|||
try { |
|||
for (const item of set.keys()) { |
|||
ow(item, predicate); |
|||
} |
|||
|
|||
return true; |
|||
} catch (err) { |
|||
error = err.message; |
|||
|
|||
return false; |
|||
} |
|||
} |
|||
}); |
|||
} |
|||
|
|||
/** |
|||
* Test a Set to be empty. |
|||
*/ |
|||
get empty() { |
|||
return this.addValidator({ |
|||
message: set => `Expected Set to be empty, got \`${JSON.stringify(Array.from(set))}\``, |
|||
validator: set => set.size === 0 |
|||
}); |
|||
} |
|||
|
|||
/** |
|||
* Test a Set to be not empty. |
|||
*/ |
|||
get nonEmpty() { |
|||
return this.addValidator({ |
|||
message: () => 'Expected Set to not be empty', |
|||
validator: set => set.size > 0 |
|||
}); |
|||
} |
|||
|
|||
/** |
|||
* Test a Set to be deeply equal to the provided Set. |
|||
* |
|||
* @param expected Expected Set to match. |
|||
*/ |
|||
deepEqual(expected: Set<any>) { |
|||
return this.addValidator({ |
|||
message: set => `Expected Set to be deeply equal to \`${JSON.stringify(Array.from(expected))}\`, got \`${JSON.stringify(Array.from(set))}\``, |
|||
validator: set => isEqual(set, expected) |
|||
}); |
|||
} |
|||
} |
@ -0,0 +1,67 @@ |
|||
import test from 'ava'; |
|||
import m from '..'; |
|||
|
|||
test('set', t => { |
|||
t.notThrows(() => m(new Set(), m.set)); |
|||
t.notThrows(() => m(new Set(['🦄']), m.set)); |
|||
t.throws(() => m(12 as any, m.set), 'Expected argument to be of type `set` but received type `number`'); |
|||
}); |
|||
|
|||
test('set.size', t => { |
|||
t.notThrows(() => m(new Set(), m.set.size(0))); |
|||
t.notThrows(() => m(new Set(['🦄']), m.set.size(1))); |
|||
t.throws(() => m(new Set(['🦄']), m.set.size(0)), 'Expected Set to have size `0`, got `1`'); |
|||
}); |
|||
|
|||
test('set.minSize', t => { |
|||
t.notThrows(() => m(new Set(['🦄']), m.set.minSize(1))); |
|||
t.notThrows(() => m(new Set(['🦄', '🌈']), m.set.minSize(1))); |
|||
t.throws(() => m(new Set(['🦄']), m.set.minSize(2)), 'Expected Set to have a minimum size of `2`, got `1`'); |
|||
}); |
|||
|
|||
test('set.maxSize', t => { |
|||
t.notThrows(() => m(new Set(['🦄']), m.set.maxSize(1))); |
|||
t.notThrows(() => m(new Set(['🦄', '🌈']), m.set.maxSize(4))); |
|||
t.throws(() => m(new Set(['🦄', '🌈']), m.set.maxSize(1)), 'Expected Set to have a maximum size of `1`, got `2`'); |
|||
}); |
|||
|
|||
test('set.hasKeys', t => { |
|||
t.notThrows(() => m(new Set(['unicorn']), m.set.has('unicorn'))); |
|||
t.notThrows(() => m(new Set(['unicorn', 'rainbow']), m.set.has('unicorn', 'rainbow'))); |
|||
t.notThrows(() => m(new Set([1, 2]), m.set.has(1, 2))); |
|||
t.throws(() => m(new Set(['unicorn', 'rainbow']), m.set.has('foo')), 'Expected Set to have items `["foo"]`'); |
|||
t.throws(() => m(new Set(['unicorn', 'foo']), m.set.has('foo', 'bar')), 'Expected Set to have items `["bar"]`'); |
|||
t.throws(() => m(new Set([2, 4]), m.set.has(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)), 'Expected Set to have items `[1,3,5,6,7]`'); |
|||
}); |
|||
|
|||
test('set.hasAny', t => { |
|||
t.notThrows(() => m(new Set(['unicorn']), m.set.hasAny('unicorn', 'rainbow'))); |
|||
t.notThrows(() => m(new Set(['unicorn', 'rainbow']), m.set.hasAny('unicorn'))); |
|||
t.notThrows(() => m(new Set([1, 2]), m.set.hasAny(1, 2, 3, 4))); |
|||
t.throws(() => m(new Set(['unicorn', 'rainbow']), m.set.hasAny('foo')), 'Expected Set to have any item of `["foo"]`'); |
|||
}); |
|||
|
|||
test('set.ofType', t => { |
|||
t.notThrows(() => m(new Set(['unicorn']), m.set.ofType(m.string))); |
|||
t.notThrows(() => m(new Set(['unicorn', 'rainbow']), m.set.ofType(m.string.minLength(3)))); |
|||
t.notThrows(() => m(new Set([1]), m.set.ofType(m.number))); |
|||
t.throws(() => m(new Set(['unicorn']), m.set.ofType(m.number)), 'Expected argument to be of type `number` but received type `string`'); |
|||
}); |
|||
|
|||
test('set.empty', t => { |
|||
t.notThrows(() => m(new Set(), m.set.empty)); |
|||
t.notThrows(() => m(new Set([]), m.set.empty)); |
|||
t.throws(() => m(new Set(['unicorn']), m.set.empty), 'Expected Set to be empty, got `["unicorn"]`'); |
|||
}); |
|||
|
|||
test('set.notEmpty', t => { |
|||
t.notThrows(() => m(new Set(['unicorn']), m.set.nonEmpty)); |
|||
t.throws(() => m(new Set(), m.set.nonEmpty), 'Expected Set to not be empty'); |
|||
}); |
|||
|
|||
test('set.deepEqual', t => { |
|||
t.notThrows(() => m(new Set(['unicorn']), m.set.deepEqual(new Set(['unicorn'])))); |
|||
t.notThrows(() => m(new Set([{foo: 'bar'}]), m.set.deepEqual(new Set([{foo: 'bar'}])))); |
|||
t.throws(() => m(new Set(['unicorn']), m.set.deepEqual(new Set(['rainbow']))), 'Expected Set to be deeply equal to `["rainbow"]`, got `["unicorn"]`'); |
|||
t.throws(() => m(new Set([{foo: 'bar'}]), m.set.deepEqual(new Set([{foo: 'baz'}]))), 'Expected Set to be deeply equal to `[{"foo":"baz"}]`, got `[{"foo":"bar"}]`'); |
|||
}); |
Loading…
Reference in new issue