Skip to content

Commit

Permalink
feat(expect): add 13 new matchers
Browse files Browse the repository at this point in the history
Closes #8, #9, #10, #11, #12, #13, #14, #15, #16
  • Loading branch information
JamieMason committed Aug 31, 2021
1 parent 033c3ac commit d880ff3
Show file tree
Hide file tree
Showing 113 changed files with 2,640 additions and 97 deletions.
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
**/CHANGELOG.md
**/README.md
77 changes: 37 additions & 40 deletions packages/expect-more-jasmine/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ npm install expect-more-jasmine --save-dev
describe('expect-more-jasmine', () => {
it('makes your tests and output easier to read', () => {
expect(new Date('2020-01-01')).toBeAfter(new Date('2019-12-31'));
expect([12, 0, 14, 'Ivo']).toBeArrayIncludingAllOf(['Ivo', 14]);
expect([12, 0, 14, 'Ginola']).toBeArrayIncludingAnyOf(['Ginola', 3]);
expect([5, 10, 1]).toBeArrayIncludingOnly([1, 5, 10]);
expect([true, false, new Boolean(true)]).toBeArrayOfBooleans();
expect([12, 0, 14]).toBeArrayOfNumbers();
expect([{}, new Object()]).toBeArrayOfObjects();
Expand All @@ -57,6 +60,13 @@ describe('expect-more-jasmine', () => {
expect(new Date('2019-12-31')).toBeBefore(new Date('2020-01-01'));
expect(false).toBeBoolean();
expect('100').toBeCalculable();
expect(new Date('2019-12-11')).toBeDateBetween(new Date('2019-12-10'), new Date('2019-12-12'));
expect(new Date('2021-08-29')).toBeDateInMonth(7);
expect(new Date('2021-08-29')).toBeDateInYear(2021);
expect(new Date('2021-08-29')).toBeDateOnDayOfMonth(29);
expect(new Date('2021-08-29')).toBeDateOnDayOfWeek(0);
expect(new Date('2019-12-31')).toBeDateOnOrAfter(new Date('2019-12-15'));
expect(new Date('2019-12-15')).toBeDateOnOrBefore(new Date('2019-12-31'));
expect(new Date('2019-12-31')).toBeDate();
expect(12.55).toBeDecimalNumber();
expect(12).toBeDivisibleBy(2);
Expand All @@ -71,12 +81,15 @@ describe('expect-more-jasmine', () => {
expect('1999-12-31T23:59:59').toBeIso8601();
expect('{"i":"am valid JSON"}').toBeJsonString();
expect(['i', 'have', 3]).toBeLongerThan([2, 'items']);
expect(-18).toBeNegativeNumber();
expect(undefined).toBeNil();
expect(['i', 'am not empty']).toBeNonEmptyArray();
expect({ i: 'am not empty' }).toBeNonEmptyObject();
expect('i am not empty').toBeNonEmptyString();
expect(8).toBeNumber();
expect({}).toBeObject();
expect(5).toBeOddNumber();
expect(5).toBePositiveNumber();
expect(new RegExp('i am a regular expression')).toBeRegExp();
expect(['i also have', '2 items']).toBeSameLengthAs(['i have', '2 items']);
expect(['i have one item']).toBeShorterThan(['i', 'have', 4, 'items']);
Expand All @@ -88,18 +101,14 @@ describe('expect-more-jasmine', () => {
expect(8).toBeWholeNumber();
expect(7).toBeWithinRange(0, 10);
expect('JavaScript').toEndWith('Script');
expect({ child: { grandchild: [true, false, new Boolean(true)] } }).toHaveArrayOfBooleans(
'child.grandchild',
);
expect({ child: { grandchild: [12, 0, 14, 'Ivo'] } }).toHaveArrayIncludingAllOf('child.grandchild', ['Ivo', 14]);
expect({ child: { grandchild: [12, 0, 14, 'Ginola'] } }).toHaveArrayIncludingAnyOf('child.grandchild', ['Ginola', 3]);
expect({ child: { grandchild: [5, 10, 1] } }).toHaveArrayIncludingOnly('child.grandchild', [1, 5, 10]);
expect({ child: { grandchild: [true, false, new Boolean(true)] } }).toHaveArrayOfBooleans('child.grandchild');
expect({ child: { grandchild: [12, 0, 14] } }).toHaveArrayOfNumbers('child.grandchild');
expect({ child: { grandchild: [{}, new Object()] } }).toHaveArrayOfObjects('child.grandchild');
expect({ child: { grandchild: ['i', 'contain', 4, 'items'] } }).toHaveArrayOfSize(
'child.grandchild',
4,
);
expect({ child: { grandchild: ['we', 'are', 'all', 'strings'] } }).toHaveArrayOfStrings(
'child.grandchild',
);
expect({ child: { grandchild: ['i', 'contain', 4, 'items'] } }).toHaveArrayOfSize('child.grandchild', 4);
expect({ child: { grandchild: ['we', 'are', 'all', 'strings'] } }).toHaveArrayOfStrings('child.grandchild');
expect({ child: { grandchild: [2, true, 'string'] } }).toHaveArray('child.grandchild');
expect({
child: {
Expand All @@ -110,14 +119,15 @@ describe('expect-more-jasmine', () => {
}).toHaveAsyncFunction('child.grandchild');
expect({ child: { grandchild: false } }).toHaveBoolean('child.grandchild');
expect({ child: { grandchild: '100' } }).toHaveCalculable('child.grandchild');
expect({ child: { grandchild: new Date('2020-01-01') } }).toHaveDateAfter(
'child.grandchild',
new Date('2019-12-31'),
);
expect({ child: { grandchild: new Date('2019-12-31') } }).toHaveDateBefore(
'child.grandchild',
new Date('2020-01-01'),
);
expect({ child: { grandchild: new Date('2020-01-01') } }).toHaveDateAfter('child.grandchild', new Date('2019-12-31'));
expect({ child: { grandchild: new Date('2019-12-31') } }).toHaveDateBefore('child.grandchild', new Date('2020-01-01'));
expect({ child: { grandchild: new Date('2019-12-11') } }).toHaveDateBetween('child.grandchild', new Date('2019-12-10'), new Date('2019-12-12'));
expect({ child: { grandchild: new Date('2021-08-29') } }).toHaveDateInMonth('child.grandchild', 7);
expect({ child: { grandchild: new Date('2021-08-29') } }).toHaveDateInYear('child.grandchild', 2021);
expect({ child: { grandchild: new Date('2021-08-29') } }).toHaveDateOnDayOfMonth('child.grandchild', 29);
expect({ child: { grandchild: new Date('2021-08-29') } }).toHaveDateOnDayOfWeek('child.grandchild', 0);
expect({ child: { grandchild: new Date('2019-12-31') } }).toHaveDateOnOrAfter('child.grandchild', new Date('2019-12-15'));
expect({ child: { grandchild: new Date('2019-12-15') } }).toHaveDateOnOrBefore('child.grandchild', new Date('2019-12-31'));
expect({ child: { grandchild: new Date('2019-12-31') } }).toHaveDate('child.grandchild');
expect({ child: { grandchild: 12.55 } }).toHaveDecimalNumber('child.grandchild');
expect({ child: { grandchild: 12 } }).toHaveDivisibleBy('child.grandchild', 2);
Expand All @@ -138,36 +148,23 @@ describe('expect-more-jasmine', () => {
expect({ child: { grandchild: '1999-12-31T23:59:59' } }).toHaveIso8601('child.grandchild');
expect({ child: { grandchild: '{"i":"am valid JSON"}' } }).toHaveJsonString('child.grandchild');
expect({ child: { grandchild: 8 } }).toHaveLessThanOrEqualTo('child.grandchild', 12);
expect({ child: { grandchild: ['i', 'have', 3] } }).toHaveLongerThan('child.grandchild', [
2,
'items',
]);
expect({ child: { grandchild: ['i', 'have', 3] } }).toHaveLongerThan('child.grandchild', [2, 'items']);
expect({ child: { grandchild: () => 'i am a function' } }).toHaveMethod('child.grandchild');
expect({ child: { grandchild: ['i', 'am not empty'] } }).toHaveNonEmptyArray(
'child.grandchild',
);
expect({ child: { grandchild: { i: 'am not empty' } } }).toHaveNonEmptyObject(
'child.grandchild',
);
expect({ child: { grandchild: -18 } }).toHaveNegativeNumber('child.grandchild');
expect({ child: { grandchild: undefined } }).toHaveNil('child.grandchild');
expect({ child: { grandchild: ['i', 'am not empty'] } }).toHaveNonEmptyArray('child.grandchild');
expect({ child: { grandchild: { i: 'am not empty' } } }).toHaveNonEmptyObject('child.grandchild');
expect({ child: { grandchild: 'i am not empty' } }).toHaveNonEmptyString('child.grandchild');
expect({ child: { grandchild: null } }).toHaveNull('child.grandchild');
expect({ child: { grandchild: 4.8 } }).toHaveNumberNear('child.grandchild', 5, 0.5);
expect({ child: { grandchild: 7 } }).toHaveNumberWithinRange('child.grandchild', 0, 10);
expect({ child: { grandchild: 8 } }).toHaveNumber('child.grandchild');
expect({ child: { grandchild: {} } }).toHaveObject('child.grandchild');
expect({ child: { grandchild: 5 } }).toHaveOddNumber('child.grandchild');
expect({ child: { grandchild: new RegExp('i am a regular expression') } }).toHaveRegExp(
'child.grandchild',
);
expect({
child: { grandchild: ['i also have', '2 items'] },
}).toHaveSameLengthAs('child.grandchild', ['i have', '2 items']);
expect({ child: { grandchild: ['i have one item'] } }).toHaveShorterThan('child.grandchild', [
'i',
'have',
4,
'items',
]);
expect({ child: { grandchild: 5 } }).toHavePositiveNumber('child.grandchild');
expect({ child: { grandchild: new RegExp('i am a regular expression') } }).toHaveRegExp('child.grandchild');
expect({ child: { grandchild: ['i also have', '2 items'] } }).toHaveSameLengthAs('child.grandchild', ['i have', '2 items']);
expect({ child: { grandchild: ['i have one item'] } }).toHaveShorterThan('child.grandchild', ['i', 'have', 4, 'items']);
expect({ child: { grandchild: 'JavaScript' } }).toHaveStartingWith('child.grandchild', 'Java');
expect({ child: { grandchild: 'i am a string' } }).toHaveString('child.grandchild');
expect({ child: { grandchild: true } }).toHaveTrue('child.grandchild');
Expand Down
26 changes: 26 additions & 0 deletions packages/expect-more-jasmine/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
export { toBeAfterMatcher } from './to-be-after';
export { toBeArrayIncludingAllOfMatcher } from './to-be-array-including-all-of';
export { toBeArrayIncludingAnyOfMatcher } from './to-be-array-including-any-of';
export { toBeArrayIncludingOnlyMatcher } from './to-be-array-including-only';
export { toBeArrayMatcher } from './to-be-array';
export { toBeArrayOfBooleansMatcher } from './to-be-array-of-booleans';
export { toBeArrayOfNumbersMatcher } from './to-be-array-of-numbers';
Expand All @@ -9,7 +12,14 @@ export { toBeAsyncFunctionMatcher } from './to-be-async-function';
export { toBeBeforeMatcher } from './to-be-before';
export { toBeBooleanMatcher } from './to-be-boolean';
export { toBeCalculableMatcher } from './to-be-calculable';
export { toBeDateBetweenMatcher } from './to-be-date-between';
export { toBeDateInMonthMatcher } from './to-be-date-in-month';
export { toBeDateInYearMatcher } from './to-be-date-in-year';
export { toBeDateMatcher } from './to-be-date';
export { toBeDateOnDayOfMonthMatcher } from './to-be-date-on-day-of-month';
export { toBeDateOnDayOfWeekMatcher } from './to-be-date-on-day-of-week';
export { toBeDateOnOrAfterMatcher } from './to-be-date-on-or-after';
export { toBeDateOnOrBeforeMatcher } from './to-be-date-on-or-before';
export { toBeDecimalNumberMatcher } from './to-be-decimal-number';
export { toBeDivisibleByMatcher } from './to-be-divisible-by';
export { toBeEmptyArrayMatcher } from './to-be-empty-array';
Expand All @@ -21,12 +31,15 @@ export { toBeGeneratorFunctionMatcher } from './to-be-generator-function';
export { toBeIso8601Matcher } from './to-be-iso8601';
export { toBeJsonStringMatcher } from './to-be-json-string';
export { toBeLongerThanMatcher } from './to-be-longer-than';
export { toBeNegativeNumberMatcher } from './to-be-negative-number';
export { toBeNilMatcher } from './to-be-nil';
export { toBeNonEmptyArrayMatcher } from './to-be-non-empty-array';
export { toBeNonEmptyObjectMatcher } from './to-be-non-empty-object';
export { toBeNonEmptyStringMatcher } from './to-be-non-empty-string';
export { toBeNumberMatcher } from './to-be-number';
export { toBeObjectMatcher } from './to-be-object';
export { toBeOddNumberMatcher } from './to-be-odd-number';
export { toBePositiveNumberMatcher } from './to-be-positive-number';
export { toBeRegExpMatcher } from './to-be-reg-exp';
export { toBeSameLengthAsMatcher } from './to-be-same-length-as';
export { toBeShorterThanMatcher } from './to-be-shorter-than';
Expand All @@ -38,6 +51,9 @@ export { toBeWhitespaceMatcher } from './to-be-whitespace';
export { toBeWholeNumberMatcher } from './to-be-whole-number';
export { toBeWithinRangeMatcher } from './to-be-within-range';
export { toEndWithMatcher } from './to-end-with';
export { toHaveArrayIncludingAllOfMatcher } from './to-have-array-including-all-of';
export { toHaveArrayIncludingAnyOfMatcher } from './to-have-array-including-any-of';
export { toHaveArrayIncludingOnlyMatcher } from './to-have-array-including-only';
export { toHaveArrayMatcher } from './to-have-array';
export { toHaveArrayOfBooleansMatcher } from './to-have-array-of-booleans';
export { toHaveArrayOfNumbersMatcher } from './to-have-array-of-numbers';
Expand All @@ -49,7 +65,14 @@ export { toHaveBooleanMatcher } from './to-have-boolean';
export { toHaveCalculableMatcher } from './to-have-calculable';
export { toHaveDateAfterMatcher } from './to-have-date-after';
export { toHaveDateBeforeMatcher } from './to-have-date-before';
export { toHaveDateBetweenMatcher } from './to-have-date-between';
export { toHaveDateInMonthMatcher } from './to-have-date-in-month';
export { toHaveDateInYearMatcher } from './to-have-date-in-year';
export { toHaveDateMatcher } from './to-have-date';
export { toHaveDateOnDayOfMonthMatcher } from './to-have-date-on-day-of-month';
export { toHaveDateOnDayOfWeekMatcher } from './to-have-date-on-day-of-week';
export { toHaveDateOnOrAfterMatcher } from './to-have-date-on-or-after';
export { toHaveDateOnOrBeforeMatcher } from './to-have-date-on-or-before';
export { toHaveDecimalNumberMatcher } from './to-have-decimal-number';
export { toHaveDivisibleByMatcher } from './to-have-divisible-by';
export { toHaveEmptyArrayMatcher } from './to-have-empty-array';
Expand All @@ -65,6 +88,8 @@ export { toHaveJsonStringMatcher } from './to-have-json-string';
export { toHaveLessThanOrEqualToMatcher } from './to-have-less-than-or-equal-to';
export { toHaveLongerThanMatcher } from './to-have-longer-than';
export { toHaveMethodMatcher } from './to-have-method';
export { toHaveNegativeNumberMatcher } from './to-have-negative-number';
export { toHaveNilMatcher } from './to-have-nil';
export { toHaveNonEmptyArrayMatcher } from './to-have-non-empty-array';
export { toHaveNonEmptyObjectMatcher } from './to-have-non-empty-object';
export { toHaveNonEmptyStringMatcher } from './to-have-non-empty-string';
Expand All @@ -74,6 +99,7 @@ export { toHaveNumberNearMatcher } from './to-have-number-near';
export { toHaveNumberWithinRangeMatcher } from './to-have-number-within-range';
export { toHaveObjectMatcher } from './to-have-object';
export { toHaveOddNumberMatcher } from './to-have-odd-number';
export { toHavePositiveNumberMatcher } from './to-have-positive-number';
export { toHaveRegExpMatcher } from './to-have-reg-exp';
export { toHaveSameLengthAsMatcher } from './to-have-same-length-as';
export { toHaveShorterThanMatcher } from './to-have-shorter-than';
Expand Down
38 changes: 38 additions & 0 deletions packages/expect-more-jasmine/src/to-be-array-including-all-of.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { isArrayIncludingAllOf } from 'expect-more';
import { printExpected, printReceived } from 'jest-matcher-utils';

declare global {
namespace jasmine {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
interface Matchers<T> {
/**
* Asserts that `value` is an `Array` including all of the values provided in `requiredValues`. It could also include additional values or be in a different order, but if every value in `requiredValues` features in `value` then this will return `true`.
* @example
* expect([12, 0, 14, 'Ivo']).toBeArrayIncludingAllOf(['Ivo', 14]);
*/
toBeArrayIncludingAllOf(requiredValues: unknown[]): boolean;
}
}
}

export const toBeArrayIncludingAllOfMatcher: jasmine.CustomMatcherFactory = () => {
return {
compare(value: unknown, requiredValues: unknown[]) {
const pass = isArrayIncludingAllOf(requiredValues, value);
const message = pass
? `expected ${printReceived(value)} not to include every value provided in ${printExpected(
requiredValues,
)}`
: `expected ${printReceived(value)} to include every value provided in ${printExpected(
requiredValues,
)}`;
return { message, pass };
},
};
};

beforeAll(() => {
jasmine.addMatchers({
toBeArrayIncludingAllOf: toBeArrayIncludingAllOfMatcher,
});
});
38 changes: 38 additions & 0 deletions packages/expect-more-jasmine/src/to-be-array-including-any-of.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { isArrayIncludingAnyOf } from 'expect-more';
import { printExpected, printReceived } from 'jest-matcher-utils';

declare global {
namespace jasmine {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
interface Matchers<T> {
/**
* Asserts that `value` is an `Array` including at least one of the members of `values`.
* @example
* expect([12, 0, 14, 'Ginola']).toBeArrayIncludingAnyOf(['Ginola', 3]);
*/
toBeArrayIncludingAnyOf(values: unknown[]): boolean;
}
}
}

export const toBeArrayIncludingAnyOfMatcher: jasmine.CustomMatcherFactory = () => {
return {
compare(value: unknown, values: unknown[]) {
const pass = isArrayIncludingAnyOf(values, value);
const message = pass
? `expected ${printReceived(
value,
)} not to include at least one of the values in ${printExpected(values)}`
: `expected ${printReceived(
value,
)} to include at least one of the values in ${printExpected(values)}`;
return { message, pass };
},
};
};

beforeAll(() => {
jasmine.addMatchers({
toBeArrayIncludingAnyOf: toBeArrayIncludingAnyOfMatcher,
});
});
38 changes: 38 additions & 0 deletions packages/expect-more-jasmine/src/to-be-array-including-only.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { isArrayIncludingOnly } from 'expect-more';
import { printExpected, printReceived } from 'jest-matcher-utils';

declare global {
namespace jasmine {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
interface Matchers<T> {
/**
* Asserts that a value is an `Array` including only the values provided in the given `allowedValues` array and no others. The order and number of times each value appears in either array does not matter. Returns true unless `value` contains a value which does not feature in `allowedValues`.
* @example
* expect([5, 10, 1]).toBeArrayIncludingOnly([1, 5, 10]);
*/
toBeArrayIncludingOnly(allowedValues: unknown[]): boolean;
}
}
}

export const toBeArrayIncludingOnlyMatcher: jasmine.CustomMatcherFactory = () => {
return {
compare(value: unknown, allowedValues: unknown[]) {
const pass = isArrayIncludingOnly(allowedValues, value);
const message = pass
? `expected ${printReceived(value)} not to only include values featured in ${printExpected(
allowedValues,
)} and no others`
: `expected ${printReceived(value)} to only include values featured in ${printExpected(
allowedValues,
)} and no others`;
return { message, pass };
},
};
};

beforeAll(() => {
jasmine.addMatchers({
toBeArrayIncludingOnly: toBeArrayIncludingOnlyMatcher,
});
});
42 changes: 42 additions & 0 deletions packages/expect-more-jasmine/src/to-be-date-between.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { isDateBetween } from 'expect-more';
import { printExpected, printReceived } from 'jest-matcher-utils';

declare global {
namespace jasmine {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
interface Matchers<T> {
/**
* Asserts that a value is an instance of `Date` occurring on or after `floor` and on or before `ceiling`.
* @example
* expect(new Date('2019-12-11')).toBeDateBetween(new Date('2019-12-10'), new Date('2019-12-12'));
*/
toBeDateBetween(floor: unknown, ceiling: unknown): boolean;
}
}
}

export const toBeDateBetweenMatcher: jasmine.CustomMatcherFactory = () => {
return {
compare(value: unknown, floor: unknown, ceiling: unknown) {
const pass = isDateBetween(floor, ceiling, value);
const message = pass
? `expected ${printReceived(
value,
)} not to be an instance of Date occurring on or after ${printExpected(
floor,
)} and on or before ${printExpected(ceiling)}`
: `expected ${printReceived(
value,
)} to be an instance of Date occurring on or after ${printExpected(
floor,
)} and on or before ${printExpected(ceiling)}`;
return { message, pass };
},
};
};

beforeAll(() => {
jasmine.addMatchers({
toBeDateBetween: toBeDateBetweenMatcher,
});
});

0 comments on commit d880ff3

Please sign in to comment.