Skip to content

Commit

Permalink
feat: Add It.isArray
Browse files Browse the repository at this point in the history
  • Loading branch information
NiGhTTraX committed Jun 27, 2020
1 parent 3b6d9e8 commit 2359b43
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 0 deletions.
35 changes: 35 additions & 0 deletions src/matcher.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { printExpected } from 'jest-matcher-utils';
import isEqual from 'lodash/isEqual';
import isMatch from 'lodash/isMatch';

type DeepPartial<T> = T extends object
Expand Down Expand Up @@ -153,6 +154,39 @@ const isString = ({
} as any;
};

/**
* Match an array.
*
* @param containing If given, the matched array has to contain ALL of these
* elements in ANY order.
*
* @example
* const fn = mock<(arr: number[]) => number>();
* when(fn(It.isArray())).thenReturn(1);
* when(fn(It.isArray([2, 3))).thenReturn(2);
*
* instance(fn)({ length: 1, 0: 42 }) // throws
* instance(fn)([]]) === 1
* instance(fn)([3, 2, 1) === 2
*/
const isArray = <T extends any[]>(containing?: T): Matcher<T> => {
return {
__isMatcher: true,
matches: (arg: any) => {
if (!Array.isArray(arg)) {
return false;
}

if (containing) {
return containing.every((x) => arg.find((y) => isEqual(x, y)));
}

return true;
},
toJSON: () =>
containing ? `array(${printExpected(containing)})` : 'array',
} as any;
};
/**
* Contains argument matchers that can be used to ignore arguments in an
* expectation or to match complex arguments.
Expand All @@ -163,4 +197,5 @@ export const It = {
isObject,
isNumber,
isString,
isArray,
};
48 changes: 48 additions & 0 deletions tests/matcher.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,54 @@ describe('It', () => {
});
});

describe('isArray', () => {
it('should match an empty array', () => {
expect(It.isArray().matches([])).toBeTruthy();
});

it('should not match array likes', () => {
expect(It.isArray().matches({ length: 0 })).toBeFalsy();
expect(It.isArray().matches(new Set([1, 2, 3]))).toBeFalsy();
});

it('should match a non-empty array', () => {
expect(It.isArray().matches([1, '2', true, {}])).toBeTruthy();
});

it('should match an array containing an empty array', () => {
expect(It.isArray([]).matches([1, '2', true, {}])).toBeTruthy();
expect(It.isArray([]).matches([])).toBeTruthy();
});

it('should match arrays that include the given sub-array', () => {
expect(It.isArray([2, 3]).matches([1, 2, 3, 4])).toBeTruthy();
expect(It.isArray([2, 3]).matches([3, 4])).toBeFalsy();
expect(It.isArray([1, 2]).matches([1, 2, 3, 4])).toBeTruthy();
expect(It.isArray([1, 2]).matches([2])).toBeFalsy();
expect(It.isArray([3, 4]).matches([1, 2, 3, 4])).toBeTruthy();
expect(It.isArray([1, 2, 3, 4]).matches([1, 2, 3, 4])).toBeTruthy();
});

it('should match arrays that includes all elements in the given array, in any order', () => {
expect(It.isArray([1, 2, 3]).matches([3, 2, 1])).toBeTruthy();
expect(It.isArray([3, 2, 1]).matches([1, 1, 2, 2, 3, 3])).toBeTruthy();
});

it('should match arrays of objects', () => {
expect(
It.isArray([{ foo: 'bar' }]).matches([{ foo: 'bar' }, { foo: 'baz' }])
).toBeTruthy();
expect(
It.isArray([{ foo: 'boo' }]).matches([{ foo: 'bar' }, { foo: 'baz' }])
).toBeFalsy();
});

it('should pretty print', () => {
expectAnsilessEqual(It.isArray().toJSON(), 'array');
expectAnsilessEqual(It.isArray([1, 2, 3]).toJSON(), 'array([1, 2, 3])');
});
});

describe('matches', () => {
it('should support custom predicates', () => {
expect(It.matches(() => true).matches(':irrelevant:')).toBeTruthy();
Expand Down

0 comments on commit 2359b43

Please sign in to comment.