From 1b1bfc41a34d10eb1216346006fcff9793ce63e0 Mon Sep 17 00:00:00 2001 From: Vedant K Date: Fri, 10 Dec 2021 21:32:32 +0530 Subject: [PATCH] [DOCS]: Improve installation and setup guide (#91) * docs: improve installation and setup guide - add command to install via `pnpm`. - change commands to install package as a dev dependency. - use `setupFilesAfterEnv` instead of `setupTestFrameworkScriptFile`, which was deprecated in Jest v24.0.0. * meta: add `@gamemaker1` to contributors list * style: use spaces in `readme.md` like the rest of project --- Readme.md | 112 +++++++++++++++++++++++++++++++-------------------- package.json | 5 +++ 2 files changed, 73 insertions(+), 44 deletions(-) diff --git a/Readme.md b/Readme.md index 8deefd9..7fbdf15 100644 --- a/Readme.md +++ b/Readme.md @@ -4,24 +4,34 @@ [![codecov](https://codecov.io/gh/Dean177/jest-to-match-shape-of/branch/master/graph/badge.svg)](https://codecov.io/gh/Dean177/jest-to-match-shape-of) [![Npm](https://badge.fury.io/js/jest-to-match-shape-of.svg)](https://www.npmjs.com/package/jest-to-match-shape-of) - -A [Jest matcher](https://facebook.github.io/jest/docs/en/using-matchers.html) to verify the structure of an object, particularly useful for api integration tests +A [Jest matcher](https://facebook.github.io/jest/docs/en/using-matchers.html) to verify the structure of an object, particularly useful for API integration tests. ![example-gif](./example/huge-demo-gif.gif) ## Installation +First install the package via `npm`, `pnpm` or `yarn`: + ```bash -yarn add jest-to-match-shape-of +npm install --save-dev jest-to-match-shape-of ``` ```bash -npm install jest-to-match-shape-of --save +pnpm add --dev jest-to-match-shape-of ``` -In your setupTests.js +```bash +yarn add --dev jest-to-match-shape-of +``` + +Then create a file to setup your tests. This guide uses `test/setup.js` (for Javascript projects) or `test/setup.ts` (for Typescript projects), but it should still work if you place it somewhere else. + +Add the following to `test/setup.js` file (if you are using CommonJS): + ```javascript -// src/setupTests.js +// /test/setup.js +// Setup your test environment + const { toMatchOneOf, toMatchShapeOf } = require('jest-to-match-shape-of') expect.extend({ @@ -29,10 +39,13 @@ expect.extend({ toMatchShapeOf, }) ``` -or if you are using Typescript + +If you are using ESM or Typescript, use the following instead: ```typescript -// src/setupTests.ts +// /test/setup.ts +// Setup your test environment + import { toMatchOneOf, toMatchShapeOf } from 'jest-to-match-shape-of' expect.extend({ @@ -41,19 +54,22 @@ expect.extend({ }) ``` -Then in the "jest" section of your package.json add the following: -`"setupTestFrameworkScriptFile": "/src/setupTests.js"` +Then add the following to your [Jest configuration](https://jestjs.io/docs/configuration): -or for typescript: -`"setupTestFrameworkScriptFile": "/src/setupTests.ts"` - -### Installation with create-react-app -For project created using CRA (create-react-app) you need to add setup code to the `setupTests.js` file, there is no need to modify `package.json`. +```jsonc +// CommonJS/ESM +"setupFilesAfterEnv": ["./test/setup.js"] +// Typescript +"setupFilesAfterEnv": ["./test/setup.ts"] ``` -// src/setupTests.js -const { toMatchOneOf, toMatchShapeOf } = require('jest-to-match-shape-of') -// or with ES6 module import { toMatchOneOf, toMatchShapeOf } from 'jest-to-match-shape-of'; + +For usage in a project created using CRA ([`create-react-app`](https://create-react-app.dev/)) you simply need to add the above setup code to the test setup file (usually `src/setupTests.js` or `src/setupTests.ts`), there is no need to modify your Jest configuration. + +```javascript +import '@testing-library/jest-dom' + +import { toMatchOneOf, toMatchShapeOf } from 'jest-to-match-shape-of' expect.extend({ toMatchOneOf, @@ -63,8 +79,12 @@ expect.extend({ ## Usage -```javascript -expect(someThing).toMatchOneOf([someOtherThingA, someOtherThingB, someOtherThingC]) +```typescript +expect(someThing).toMatchOneOf([ + someOtherThingA, + someOtherThingB, + someOtherThingC, +]) expect(someThing).toMatchShapeOf(someOtherThing) ``` @@ -72,8 +92,8 @@ Works particularly well when being used with [Typescript](https://www.typescript ```typescript type Resource = { - maybeNumber: number | null, - someString: string, + maybeNumber: number | null + someString: string } const testResource: Resource = { @@ -88,48 +108,52 @@ const testResourceAlt: Resource = { describe('an api', () => { it('returns what I was expecting', () => { - return fetch('/resources/1').then(response => response.json()).then((data) => { - expect(data).toMatchShapeOf(testResource) - }) + return fetch('/resources/1') + .then((response) => response.json()) + .then((data) => { + expect(data).toMatchShapeOf(testResource) + }) }) - + it('could return a couple of different things', () => { - return fetch('/resources/1').then(response => response.json()).then((data) => { - expect(data).toMatchOneOf([testResource, testResourceAlt]) - }) + return fetch('/resources/1') + .then((response) => response.json()) + .then((data) => { + expect(data).toMatchOneOf([testResource, testResourceAlt]) + }) }) }) - ``` -### How to match a shape with optional fields? +### Matching Optional Fields -Sometimes, the expected shape may vary during integration tests. (e.g: A field may be missing) +Sometimes, the expected shape may vary during integration tests (for example, a field may be missing). If you want to make a shape allow optional fields, the simplest way is to remove those fields from the expected shape, as follow: -```ts -toMatchOneOf([{ ant: 17 }]) // bat is optional here +```typescript +toMatchShapeOf({ ant: 17 }) // `bat` is optional here ``` -A more robust alternative is to define all possible shapes, this way you still test the types of the properties: +A more robust alternative is to define all possible shapes, this way you still test the types of the properties: -```ts -toMatchOneOf([{ ant: 17, bat: 176 }, { ant: 17 }]) // bat is still optional, but must be numeric +```typescript +toMatchOneOf([{ ant: 17, bat: 176 }, { ant: 17 }]) // `bat` is still optional, but must be numeric ``` ## Motivation -I wanted to write integration test for my frontend code but found it was tedious, brittle and -hard to debug when I encountered a legitimate failure. +I wanted to write integration test for my frontend code but found it was tedious, brittle and +hard to debug when I encountered a legitimate failure. I realised that + - Almost all of the errors were due to bad data from the API, most often missing data -- I did not care about *exactly* what data came back, but more about the *shape* of the data. +- I did not care about _exactly_ what data came back, but more about the _shape_ of the data. - Since I was using React and Typescript I could be confident my app would work as intended if the types were correct -- Thanks to [Enzyme](https://github.com/airbnb/enzyme) I already had a great way to test my component interactions - - `toMatchShapeOf` hopefully achieves a lot of the value of full blown integration test written with something like +- Thanks to [Enzyme](https://github.com/airbnb/enzyme), I already had a great way to test my component interactions + +`toMatchShapeOf` hopefully achieves a lot of the value of full blown integration test written with something like [Nightwatch](http://nightwatchjs.org/) whilst being simpler to write, understand and debug. -Additionally I found that the test data I created for use with this matcher were useful for other unit tests in my application. +I also found out that the test data I created for use with this matcher was useful for other unit tests in my application. diff --git a/package.json b/package.json index c0b25e7..2fc8e5c 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,11 @@ "name": "Christian Cuna", "email": "christian.cuna89@gmail.com", "url": "https://github.com/christian-cuna" + }, + { + "name": "Vedant K", + "email": "gamemaker0042@gmail.com", + "url": "https://github.com/gamemaker1" } ], "dependencies": {