Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Constants #338

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .eslintcache

This file was deleted.

1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ npm-debug.log
coverage/
/test/fixtures/built-sw.js
.nyc_output
.eslintcache
11 changes: 6 additions & 5 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Replaces `fetch` with a stub which records its calls, grouped by route, and opti
* `RegExp`: A regular expression to test the url against
* `Function(url, opts)`: A function (returning a Boolean) that is passed the url and opts `fetch()` is called with (or, if `fetch()` was called with one, the `Request` instance)

_Note that if using `end:` or an exact url matcher, `fetch-mock` ([for good reason](https://url.spec.whatwg.org/#url-equivalence)) is unable to distinguish whether URLs without a path end in a trailing slash or not i.e. `http://thing` is treated the same as `http://thing/`_
* `response`: Configures the http response returned by the mock. Can take any of the following values (or be a `Promise` for any of them, enabling full control when testing race conditions etc.)
* `Response`: A `Response` instance - will be used unaltered
* `number`: Creates a response with this status
Expand All @@ -33,7 +34,7 @@ Replaces `fetch` with a stub which records its calls, grouped by route, and opti
* `body`: Set the response body (`string` or `object`)
* `status`: Set the response status (default `200`)
* `headers`: Set the response headers. (`object`)
* `throws`: If this property is present then a the value of `throws` is thrown
* `throws`: If this property is present then fetch returns a `Promise` rejected with the value of `throws`
* `sendAsJson`: This property determines whether or not the request body should be converted to `JSON` before being sent (defaults to `true`).
* `includeContentLength`: Set this property to true to automatically add the `content-length` header (defaults to `true`).
* `redirectUrl`: *experimental* the url the response should be from (to imitate followed redirects - will set `redirected: true` on the response)
Expand Down Expand Up @@ -97,8 +98,8 @@ Most of the methods below accept two parameters, `(filter, method)`
- the name of a route
- The value of `matcher` or `matcher.toString()` for any unnamed route. You _can_ pass in the original regex or function as a matcher, but they will be converted to strings and used to look up values in fetch-mock's internal maps of calls, _not_ used as regexes or functions executed on teh url
- If `filter` is a string, and it does not match any routes, it is asumed the string is a url, and calls to `fetch` made with that url are returned
- `true` for matched calls only
- `false` for unmatched calls only
- `true` for matched calls only. For readability, it's recommended to use `fetchMock.MATCHED`, which is a constant equal to `true`
- `false` for unmatched calls only. For readability, it's recommended to use `fetchMock.UNMATCHED`, which is a constant equal to `false`
- `undefined` for all calls to fetch
- `method` A http method to filter by

Expand All @@ -118,10 +119,10 @@ Returns the arguments for the last matched call to fetch
Returns the url for the last matched call to fetch. When `fetch` was last called using a `Request` instance, the url will be extracted from this

#### `lastOptions(filter, method)`
Returns the options for the last matched call to fetch. When `fetch` was last called using a `Request` instance, the entire `Request` instance will be returned
Returns the options for the last matched call to fetch. When `fetch` was last called using a `Request` instance, a set of `options` inferred from the `Request` will be returned

#### `flush()`
Returns a `Promise` that resolves once all fetches handled by fetch-mock have resolved. Useful for testing code that uses `fetch` but doesn't return a promise.
Returns a `Promise` that resolves once all fetches handled by fetch-mock have resolved. Pass in `true` to wait for all response methods (`res.json()`, `res.text()`, etc.) to resolve too. Useful for testing code that uses `fetch` but doesn't return a promise.

## Config

Expand Down
22 changes: 17 additions & 5 deletions docs/installation.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,33 @@
- [Introduction](/fetch-mock)
- [Quickstart](/fetch-mock/quickstart)
- Installation and usage
- Installation and usage
- [API documentation](/fetch-mock/api)
- [Troubleshooting](/fetch-mock/troubleshooting)
- [Examples](/fetch-mock/examples)

# Installation
Install fetch-mock using `npm install --save-dev fetch-mock`

In most environments use `const fetchMock = require('fetch-mock')` to use it in your code. Some exceptions include:
In most environments use one of the following to use it in your code.

```js
const fetchMock = require('fetch-mock');

// The following is recommended in order to expose constants that
// will make tests that check for matched or unmatched calls more
// readable
const { fetchMock, MATCHED, UNMATCHED } = require('fetch-mock');
```


Some exceptions include:

* If your client-side code or tests do not use a loader that respects the browser field of `package.json` use `require('fetch-mock/es5/client')`.
* If you need to use fetch-mock without commonjs, you can include the precompiled `node_modules/fetch-mock/es5/client-bundle.js` in a script tag. This loads fetch-mock into the `fetchMock` global variable.
* For server side tests running in nodejs 6 or lower use `require('fetch-mock/es5/server')`. You will also need to `npm i -D babel-polyfill`

## Global fetch
By default fetch-mock assumes `fetch` is a global so once you've required fetch-mock refer to the quickstart and api docs.
By default fetch-mock assumes `fetch` is a global so once you've required fetch-mock refer to the quickstart and api docs.

### Polyfilling fetch
Many older browsers will require polyfilling the `fetch` global
Expand All @@ -36,7 +48,7 @@ expect(myMock.called('/home')).to.be.true;
```

## References to Request, Response, Headers, fetch and Promise
If you're using a non-global fetch implementation, or wish to use a custom Promise implementation, you may need to tell fetch-mock to use these when matching requests and returning responses. Do this by setting these properties on `fetchMock.config`, e.g
If you're using a non-global fetch implementation, or wish to use a custom Promise implementation, you may need to tell fetch-mock to use these when matching requests and returning responses. Do this by setting these properties on `fetchMock.config`, e.g

```
const ponyfill = require('fetch-ponyfill')();
Expand All @@ -46,7 +58,7 @@ fetchMock.config = Object.assign(fetchMock.config, {
Request: ponyfill.Request,
Response: ponyfill.Response,
fetch: ponyfill
},
},
```
This should be done before running any tests.

Expand Down
41 changes: 41 additions & 0 deletions docs/v6-v7-upgrade.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Upgrading from V6 to V7

Most changes are relatively minor and shouldn't affect most users.

# Changes

## `throws` option now rejects a Promise
A regression was introduced in v6 whereby the `throws: true` option woudl throw an uncaught error. The `fetch` api catches all its internal errors and returns a rejected `Promise` in every case, so this change has been reverted to be more useful for mocking typical `fetch` errors.

## Responses are wrapped in an ES Proxy
This is to enable a more powerful `flush()` method, able to wait for asynchronous resolution of response methods such as `.json()` and `.text()`. `flush(true)` will resolve only when Promises returnes by any response methods called before `flush()` have resolved

## Supports resolving dots in urls
As resolving `../` and `./` as relative paths is [speced url behaviour](https://url.spec.whatwg.org/#double-dot-path-segment), fetch-mock has been updated to also do this resolution when matching urls. URLs are normalised _before_ any matchers try to match against them as, to the `fetch` api, `http://thing/decoy/../quarry` is indistinguishable from `http://thing/quarry`, so it would make no sense to allow different mocking based on which variant is used.

## Agnostic as to whether hosts have a trailing slash or not
A side-effect of the above normalisation - using [whatwg-url](https://www.npmjs.com/package/whatwg-url) - is that fetch-mock is no longer able to distinguish between pathless URLs which do/do not end in a trailing slash i.e. `http://thing` behaves exactly the same as `http://thing/` when used in any of the library's APIs, and any mocks that match one will match the other. As mentioned above, URL normalization happens _before_ any matching is attempted.

## Request instances are normalized early to [url, options] pairs
The `fetch` api can be called with either a `Request` object or a `url` with an `options` object. To make the library easier to maintain and its APIs - in particular the call inspecting APIs such as `called()` - agnostic as to how `fetch` was called, Request objects are normalised early into `url`, `options` pairs. So the fetch args returned by `calls()` will always be of the form `[url, options]` even if `fetch` was called with a `Request` object. The original `Request` object is still provided as a third item in the args array in case it is needed.

## Exporting as property
`fetch-mock` now has a property `fetchMock`, which means the libarry can be imported using any of the below

```js
const fetchMock = require('fetch-mock');
const fetchMock = require('fetch-mock').fetchMock;
const { fetchMock } = require('fetch-mock');
```

The reason for this shoudl become clear in the next point

## Adds MATCHED and UNMATCHED constants
The inspection APIs e.g. `calls()` can be passed `true` or `false` to return matched/unmatched calls respectively. To aid with more comprehensible code, fetchMock now exports `MATCHED` and `UNMATCHED` constants, equal to `true` and `false`. Using `true` or `false` still works, but I'd recommend using the constants. Compare the readbility of the following:

```js
const { fetchMock, MATCHED, UNMATCHED } = require('fetch-mock');

fetchMock.called(true);
fetchMock.called(MATCHED);
```
2 changes: 1 addition & 1 deletion karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ module.exports = karma =>
},
webpack: {
mode: 'development',
devtool: 'source-map',
devtool: 'inline-source-map',
module: {
rules: [
{
Expand Down
Loading