JamieMason/expect-more

View on GitHub
packages/expect-more-jasmine/README.md

Summary

Maintainability
Test Coverage
# expect-more-jasmine

> Write Beautiful Specs with Custom Matchers for Jasmine

[![NPM version](http://img.shields.io/npm/v/expect-more-jasmine.svg?style=flat-square)](https://www.npmjs.com/package/expect-more-jasmine)
[![NPM downloads](http://img.shields.io/npm/dm/expect-more-jasmine.svg?style=flat-square)](https://www.npmjs.com/package/expect-more-jasmine)
[![Build Status](http://img.shields.io/travis/JamieMason/expect-more/master.svg?style=flat-square)](https://travis-ci.org/JamieMason/expect-more)
[![Maintainability](https://api.codeclimate.com/v1/badges/9f4abbef97ae0d23d97e/maintainability)](https://codeclimate.com/github/JamieMason/expect-more/maintainability)
[![Follow JamieMason on GitHub](https://img.shields.io/github/followers/JamieMason.svg?style=social&label=Follow)](https://github.com/JamieMason)
[![Follow fold_left on Twitter](https://img.shields.io/twitter/follow/fold_left.svg?style=social&label=Follow)](https://twitter.com/fold_left)

## Table of Contents

- [Overview](#overview)
- [🌩 Installation](#-installation)
- [🕹 Configuration](#-configuration)
- [🔬 Matchers](#-matchers)
- [🙋🏽‍♂️ Getting Help](#%EF%B8%8F-getting-help)
- [👀 Other Projects](#-other-projects)
- [🤓 Author](#-author)

## Overview

expect-more-jasmine is a huge library of test matchers for a range of common use-cases, to make
tests easier to read and produce relevant and useful messages when they fail.

Avoid vague messages such as _"expected false to be true"_ in favour of useful cues like _"expected
3 to be even number"_, and avoid implementation noise such as
`expect(paws.length % 2 === 0).toEqual(true)` in favour of simply stating that you
`expect(paws.length).toBeEvenNumber()`.

## 🌩 Installation

```
npm install expect-more-jasmine --save-dev
```

## 🕹 Configuration

`import 'expect-more-jasmine'` or `require('expect-more-jasmine')` at the top your test file.

## 🔬 Matchers

```js
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();
    expect(['i', 'contain', 4, 'items']).toBeArrayOfSize(4);
    expect(['we', 'are', 'all', 'strings']).toBeArrayOfStrings();
    expect([2, true, 'string']).toBeArray();
    expect(async () => {
      await fetch('...');
    }).toBeAsyncFunction();
    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);
    expect([]).toBeEmptyArray();
    expect({}).toBeEmptyObject();
    expect('').toBeEmptyString();
    expect(2).toBeEvenNumber();
    expect(() => 'i am a function').toBeFunction();
    expect(function* gen() {
      yield 'i am a generator';
    }).toBeGeneratorFunction();
    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']);
    expect('i am a string').toBeString();
    expect(new Date('2020-01-01')).toBeValidDate();
    expect('i am visible').toBeVisibleString();
    expect({}).toBeWalkable();
    expect(' ').toBeWhitespace();
    expect(8).toBeWholeNumber();
    expect(7).toBeWithinRange(0, 10);
    expect('JavaScript').toEndWith('Script');
    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: [2, true, 'string'] } }).toHaveArray('child.grandchild');
    expect({
      child: {
        grandchild: async () => {
          await fetch('...');
        },
      },
    }).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('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);
    expect({ child: { grandchild: [] } }).toHaveEmptyArray('child.grandchild');
    expect({ child: { grandchild: {} } }).toHaveEmptyObject('child.grandchild');
    expect({ child: { grandchild: '' } }).toHaveEmptyString('child.grandchild');
    expect({ child: { grandchild: 'JavaScript' } }).toHaveEndingWith('child.grandchild', 'Script');
    expect({ child: { grandchild: 2 } }).toHaveEvenNumber('child.grandchild');
    expect({ child: { grandchild: false } }).toHaveFalse('child.grandchild');
    expect({
      child: {
        grandchild: function* gen() {
          yield 'i am a generator';
        },
      },
    }).toHaveGeneratorFunction('child.grandchild');
    expect({ child: { grandchild: 10 } }).toHaveGreaterThanOrEqualTo('child.grandchild', 5);
    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 am a function' } }).toHaveMethod('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: 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');
    expect({ child: { grandchild: undefined } }).toHaveUndefined('child.grandchild');
    expect({ child: { grandchild: new Date('2020-01-01') } }).toHaveValidDate('child.grandchild');
    expect({ child: { grandchild: 'i am visible' } }).toHaveVisibleString('child.grandchild');
    expect({ child: { grandchild: {} } }).toHaveWalkable('child.grandchild');
    expect({ child: { grandchild: ' ' } }).toHaveWhitespace('child.grandchild');
    expect({ child: { grandchild: 8 } }).toHaveWholeNumber('child.grandchild');
    expect('JavaScript').toStartWith('Java');
  });
});
```

## 🙋🏽‍♂️ Getting Help

Get help with issues by creating a [Bug Report] or discuss ideas by opening a [Feature Request].

[bug report]: https://github.com/JamieMason/expect-more/issues/new?template=bug_report.md
[feature request]: https://github.com/JamieMason/expect-more/issues/new?template=feature_request.md

## 👀 Other Projects

If you find my Open Source projects useful, please share them ❤️

- [**eslint-formatter-git-log**](https://github.com/JamieMason/eslint-formatter-git-log)<br>ESLint
  Formatter featuring Git Author, Date, and Hash
- [**eslint-plugin-move-files**](https://github.com/JamieMason/eslint-plugin-move-files)<br>Move and
  rename files while keeping imports up to date
- [**eslint-plugin-prefer-arrow-functions**](https://github.com/JamieMason/eslint-plugin-prefer-arrow-functions)<br>Convert
  functions to arrow functions
- [**ImageOptim-CLI**](https://github.com/JamieMason/ImageOptim-CLI)<br>Automates ImageOptim,
  ImageAlpha, and JPEGmini for Mac to make batch optimisation of images part of your automated build
  process.
- [**karma-benchmark**](https://github.com/JamieMason/karma-benchmark)<br>Run Benchmark.js over
  multiple Browsers, with CI compatible output
- [**self-help**](https://github.com/JamieMason/self-help#readme)<br>Interactive Q&A Guides for Web
  and the Command Line
- [**syncpack**](https://github.com/JamieMason/syncpack#readme)<br>Manage multiple package.json
  files, such as in Lerna Monorepos and Yarn Workspaces

## 🤓 Author

<img src="https://www.gravatar.com/avatar/acdf106ce071806278438d8c354adec8?s=100" align="left">

I'm [Jamie Mason] from [Leeds] in England, I began Web Design and Development in 1999 and have been
Contracting and offering Consultancy as Fold Left Ltd since 2012. Who I've worked with includes [Sky
Sports], [Sky Bet], [Sky Poker], The [Premier League], [William Hill], [Shell], [Betfair], and
Football Clubs including [Leeds United], [Spurs], [West Ham], [Arsenal], and more.

<div align="center">

[![Follow JamieMason on GitHub][github badge]][github]
[![Follow fold_left on Twitter][twitter badge]][twitter]

</div>

<!-- images -->

[github badge]: https://img.shields.io/github/followers/JamieMason.svg?style=social&label=Follow
[twitter badge]: https://img.shields.io/twitter/follow/fold_left.svg?style=social&label=Follow

<!-- links -->

[arsenal]: https://www.arsenal.com
[betfair]: https://www.betfair.com
[github]: https://github.com/JamieMason
[jamie mason]: https://www.linkedin.com/in/jamiemasonleeds
[leeds united]: https://www.leedsunited.com/
[leeds]: https://www.instagram.com/visitleeds
[premier league]: https://www.premierleague.com
[shell]: https://www.shell.com
[sky bet]: https://www.skybet.com
[sky poker]: https://www.skypoker.com
[sky sports]: https://www.skysports.com
[spurs]: https://www.tottenhamhotspur.com
[twitter]: https://twitter.com/fold_left
[west ham]: https://www.whufc.com
[william hill]: https://www.williamhill.com
[jest-config]: https://jestjs.io/docs/en/configuration
[jest]: https://jestjs.io
[setup-files-after-env]: https://jestjs.io/docs/en/configuration#setupfilesafterenv-array