From 98396e87c0a8955c499b995231590f8c44e38cad Mon Sep 17 00:00:00 2001 From: Sam Verschueren Date: Fri, 29 Dec 2017 15:18:33 +0100 Subject: [PATCH] Add WeakSet predicate (#44) --- source/index.ts | 8 ++++++ source/lib/predicates/weak-set.ts | 47 +++++++++++++++++++++++++++++++ source/test/weak-set.ts | 29 +++++++++++++++++++ 3 files changed, 84 insertions(+) create mode 100644 source/lib/predicates/weak-set.ts create mode 100644 source/test/weak-set.ts diff --git a/source/index.ts b/source/index.ts index 8cf77b3..5e52b42 100644 --- a/source/index.ts +++ b/source/index.ts @@ -8,6 +8,7 @@ import {DatePredicate} from './lib/predicates/date'; import {ErrorPredicate} from './lib/predicates/error'; import {MapPredicate} from './lib/predicates/map'; import {SetPredicate} from './lib/predicates/set'; +import {WeakSetPredicate} from './lib/predicates/weak-set'; /** * @hidden @@ -74,6 +75,10 @@ export interface Ow { * Test the value to be a Set. */ readonly set: SetPredicate; + /** + * Test the value to be a WeakSet. + */ + readonly weakSet: WeakSetPredicate; /** * Test the value to be a Function. */ @@ -196,6 +201,9 @@ Object.defineProperties(main, { set: { get: () => new SetPredicate() }, + weakSet: { + get: () => new WeakSetPredicate() + }, function: { get: () => new Predicate('function') }, diff --git a/source/lib/predicates/weak-set.ts b/source/lib/predicates/weak-set.ts new file mode 100644 index 0000000..0f9cbaa --- /dev/null +++ b/source/lib/predicates/weak-set.ts @@ -0,0 +1,47 @@ +import {Predicate, Context} from './predicate'; + +export class WeakSetPredicate extends Predicate> { + constructor(context?: Context) { + super('weakSet', context); + } + + /** + * Test a WeakSet 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 WeakSet. + */ + has(...items: any[]) { + const missingItems: any[] = []; + + return this.addValidator({ + message: () => `Expected WeakSet to have items \`${JSON.stringify(missingItems)}\``, + validator: set => { + for (const key of items) { + if (set.has(key)) { + continue; + } + + missingItems.push(key); + + if (missingItems.length === 5) { + return false; + } + } + + return missingItems.length === 0; + } + }); + } + + /** + * Test a WeakSet 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 WeakSet. + */ + hasAny(...items: any[]) { + return this.addValidator({ + message: () => `Expected WeakSet to have any item of \`${JSON.stringify(items)}\``, + validator: set => items.some(item => set.has(item)) + }); + } +} diff --git a/source/test/weak-set.ts b/source/test/weak-set.ts new file mode 100644 index 0000000..28e4cf8 --- /dev/null +++ b/source/test/weak-set.ts @@ -0,0 +1,29 @@ +import test from 'ava'; +import m from '..'; + +const unicorn: any = {unicorn: '🦄'}; +const rainbow: any = {rainbow: '🌈'}; +const rocket: any = {rocket: '🚀'}; + +test('weakSet', t => { + t.notThrows(() => m(new WeakSet(), m.weakSet)); + t.notThrows(() => m(new WeakSet([{unicorn: '🦄'}]), m.weakSet)); + t.notThrows(() => m(new WeakSet([unicorn]), m.weakSet)); + t.throws(() => m(12 as any, m.weakSet), 'Expected argument to be of type `weakSet` but received type `number`'); +}); + +test('weakSet.has', t => { + const keys = [{x: 1}, {x: 2}, {x: 3}, {x: 4}, {x: 5}, {x: 6}, {x: 7}, {x: 8}, {x: 9}, {x: 10}]; + + t.notThrows(() => m(new WeakSet([unicorn]), m.weakSet.has(unicorn))); + t.notThrows(() => m(new WeakSet([unicorn, rainbow]), m.weakSet.has(unicorn, rainbow))); + t.throws(() => m(new WeakSet([unicorn, rainbow]), m.weakSet.has(rocket)), 'Expected WeakSet to have items `[{"rocket":"🚀"}]`'); + t.throws(() => m(new WeakSet([unicorn, rocket]), m.weakSet.has(rainbow, rocket)), 'Expected WeakSet to have items `[{"rainbow":"🌈"}]`'); + t.throws(() => m(new WeakSet([keys[1], keys[3]]), m.weakSet.has(...keys)), 'Expected WeakSet to have items `[{"x":1},{"x":3},{"x":5},{"x":6},{"x":7}]`'); +}); + +test('weakSet.hasAny', t => { + t.notThrows(() => m(new WeakSet([unicorn]), m.weakSet.hasAny(unicorn, rainbow))); + t.notThrows(() => m(new WeakSet([unicorn, rainbow]), m.weakSet.hasAny(unicorn))); + t.throws(() => m(new WeakSet([unicorn, rainbow]), m.weakSet.hasAny(rocket)), 'Expected WeakSet to have any item of `[{"rocket":"🚀"}]`'); +});