diff --git a/ts/hasAll.spec.ts b/ts/hasAll.spec.ts new file mode 100644 index 0000000..7d1c1f9 --- /dev/null +++ b/ts/hasAll.spec.ts @@ -0,0 +1,62 @@ +import t from 'assert' +import a from 'assertron' +import { createSatisfier, hasAll } from './index.js' + +test('non array returns false', () => { + a.false(createSatisfier(hasAll(1)).test(undefined)) + a.false(createSatisfier(hasAll(1)).test(null)) + a.false(createSatisfier(hasAll(1)).test(1)) + a.false(createSatisfier(hasAll(1)).test(true)) + a.false(createSatisfier(hasAll(1)).test('a')) + a.false(createSatisfier(hasAll({ a: 1 })).test(true)) + a.false(createSatisfier(hasAll({ a: 1 })).test(1)) + a.false(createSatisfier(hasAll({ a: 1 })).test('{ a: 1 }')) + a.false(createSatisfier(hasAll({ a: 1 })).test({ a: 1 })) +}) + +test('array with no match returns false', () => { + a.false(createSatisfier(hasAll(1)).test([2, 2, 3])) + a.false(createSatisfier(hasAll({ a: 1 })).test([{ b: 1 }])) +}) + +test('exact match array returns true', () => { + t(createSatisfier(hasAll(1)).test([1])) + t(createSatisfier(hasAll(false, false)).test([false, false])) + t(createSatisfier(hasAll('a', 'b')).test(['a', 'b'])) + t(createSatisfier(hasAll({ a: 1 })).test([{ a: 1 }])) + t(createSatisfier(hasAll({ a: 1 })).test([{ b: 1 }, { a: 1 }])) +}) + +test('array with more than one match returns true', () => { + t(createSatisfier(hasAll({ a: 1 })).test([{ a: 1 }, { a: 1 }])) + t(createSatisfier(hasAll({ a: 1 })).test([{ b: 1 }, { a: 1 }, { a: 1 }, 'x'])) +}) + +it('is true if all entries are in the target', () => { + t(createSatisfier(hasAll(1)).test([1, 2, 3])) + t(createSatisfier(hasAll(2)).test([1, 2, 3])) + t(createSatisfier(hasAll(3)).test([1, 2, 3])) + t(createSatisfier(hasAll(1, 2)).test([1, 2, 3])) + t(createSatisfier(hasAll(1, 3)).test([1, 2, 3])) + t(createSatisfier(hasAll(2, 3)).test([1, 2, 3])) + t(createSatisfier(hasAll(2, 1)).test([1, 2, 3])) + t(createSatisfier(hasAll(3, 1)).test([1, 2, 3])) + t(createSatisfier(hasAll(3, 1)).test([1, 2, 3])) + t(createSatisfier(hasAll(1, 2, 3)).test([1, 2, 3])) + t(createSatisfier(hasAll(1, 3, 2)).test([1, 2, 3])) + t(createSatisfier(hasAll(2, 1, 3)).test([1, 2, 3])) + t(createSatisfier(hasAll(2, 3, 1)).test([1, 2, 3])) + t(createSatisfier(hasAll(3, 1, 2)).test([1, 2, 3])) + t(createSatisfier(hasAll(3, 2, 1)).test([1, 2, 3])) +}) + +it('is true even if there are duplicates in expectation', () => { + t(createSatisfier(hasAll(1, 1)).test([1, 2, 3])) + t(createSatisfier(hasAll(1, 1, 2)).test([1, 2, 3])) + t(createSatisfier(hasAll(1, 2, 1)).test([1, 2, 3])) + t(createSatisfier(hasAll(2, 1, 1)).test([1, 2, 3])) +}) + +test('tersify()', () => { + t.strictEqual(hasAll({ a: 1 }, { b: 2 }).tersify(), 'hasAll({ a: 1 }, { b: 2 })') +}) diff --git a/ts/hasAll.ts b/ts/hasAll.ts new file mode 100644 index 0000000..9a2b8df --- /dev/null +++ b/ts/hasAll.ts @@ -0,0 +1,12 @@ +import { tersible, tersify } from 'tersify' +import { some } from './some.js' + +/** + * Check if an array has all of the expected entries, regardless of order. + */ +export function hasAll(...expectations: any[]) { + return tersible((arr: any) => { + if (!Array.isArray(arr)) return false + return expectations.every(e => some(e)(arr)) + }, () => `hasAll(${expectations.map(e => tersify(e)).join(', ')})`) +} diff --git a/ts/index.ts b/ts/index.ts index 85e626a..3c9ba30 100644 --- a/ts/index.ts +++ b/ts/index.ts @@ -3,6 +3,7 @@ export * from './createSatisfier.js' export * from './every.js' export * from './formatDiffs.js' export * from './has.js' +export * from './hasAll.js' export * from './interfaces.js' export * from './isInInterval.js' export * from './isInRange.js'