From b68932bc8118818764495cb1b9886ea0a71823e5 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Sun, 26 Aug 2018 18:23:26 +0100 Subject: [PATCH 001/127] doc-redux-beginnings --- docs/_config.yml | 2 +- docs/api-basic.md | 160 ++++++++++++++++++++++++++++++++++++++++++ docs/basic-usage.md | 161 +++++++++++++++++++++++++++++++++++++++++++ docs/installation.md | 40 ++++++++--- 4 files changed, 352 insertions(+), 11 deletions(-) create mode 100644 docs/api-basic.md create mode 100644 docs/basic-usage.md diff --git a/docs/_config.yml b/docs/_config.yml index b7e0752a..43fd5783 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,4 +1,4 @@ markdown: kramdown -theme: jekyll-theme-slate +theme: CloudCannon/aviator-jekyll-template title: fetch-mock description: Mock http requests made using fetch diff --git a/docs/api-basic.md b/docs/api-basic.md new file mode 100644 index 00000000..85073fa6 --- /dev/null +++ b/docs/api-basic.md @@ -0,0 +1,160 @@ +- [Introduction](/fetch-mock) +- [Quickstart](/fetch-mock/quickstart) +- [Installation and usage](/fetch-mock/installation) +- API documentation +- [Troubleshooting](/fetch-mock/troubleshooting) +- [Examples](/fetch-mock/examples) + +# Basic API Documentation + +These docs are intended to cover 80% of use cases. + +## Mocking calls to `fetch` + +#### `mock(matcher, response, options)` or `mock(options)` + +Replaces `fetch` with a stub which records its calls, grouped by route, and optionally returns a mocked `Response` object or passes the call through to `fetch()`. Calls to `.mock()` can be chained. _Note that once mocked, `fetch` will error on any unmatched calls. Use `.spy()` or `.catch()` to handle unmocked calls more gracefully_ + +- `matcher`: Condition for selecting which requests to mock. (For matching based on headers, query strings or other `fetch` options see the `options` parameter documented below). Accepts any of the following: + - `string`: Either + - an exact url to match e.g. 'http://www.site.com/page.html' + - `*` to match any url + - `begin:http://www.site.com/` to match urls beginning with a string + - `end:.jpg` to match urls ending with a string + - `path:/posts/2018/7/3` to match urls with a given path + - `glob:http://*.*` to match glob patterns + - `express:/user/:user` to match [express style paths](https://www.npmjs.com/package/path-to-regexp) + - `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 + - `string`: Creates a 200 response with the string as the response body + - `configObject` If an object _does not contain_ any properties aside from those listed below it is treated as config to build a `Response` + - `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 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) + - `object`: All objects that do not meet the criteria above are converted to `JSON` and returned as the body of a 200 response. + - `Function(url, opts)`: A function that is passed the url and opts `fetch()` is called with and that returns any of the responses listed above (or a `Promise` for any of them) +- `options`: A configuration object with all/additional properties to define a route to mock + - `name`: A unique string naming the route. Used to subsequently retrieve references to the calls, grouped by name. Defaults to `matcher.toString()` + - `method`: http method to match + - `headers`: key/value map of headers to match + - `query`: key/value map of query strings to match, in any order + - `params`: when the `express:` keyword is used in a string matcher, a key/value map `params` can be passed here, to match the parameters extracted by express path matching + - `matcher`: as specified above + - `response`: as specified above + - `repeat`: An integer, `n`, limiting the number of times the matcher can be used. If the route has already been called `n` times the route will be ignored and the call to `fetch()` will fall through to be handled by any other routes defined (which may eventually result in an error if nothing matches it) + - `overwriteRoutes`: If the route you're adding clashes with an existing route, setting `true` here will overwrite the clashing route, `false` will add another route to the stack which will be used as a fallback (useful when using the `repeat` option). Adding a clashing route without specifying this option will throw an error. It can also be set as a global option (see the **Config** section below) + +#### `sandbox()` + +This returns a drop-in mock for fetch which can be passed to other mocking libraries. It implements the full fetch-mock api and maintains its own state independent of other instances, so tests can be run in parallel. e.g. + +#### `once()` + +Shorthand for `mock()` which limits to being called one time only. (see `repeat` option above) + +#### `get()`, `post()`, `put()`, `delete()`, `head()`, `patch()` + +Shorthands for `mock()` restricted to a particular method _Tip: if you use some other method a lot you can easily define your own shorthands e.g.:_ + +``` +fetchMock.purge = function (matcher, response, options) { + return this.mock(matcher, response, Object.assign({}, options, {method: 'PURGE'})); +} +``` + +#### `getOnce()`, `postOnce()`, `putOnce()`, `deleteOnce()`, `headOnce()`, `patchOnce()` + +Shorthands for `mock()` restricted to a particular method and that will only respond once + +#### `catch(response)` + +This is used to define how to respond to calls to fetch that don't match any of the defined mocks. It accepts the same types of response as a normal call to `.mock()`. It can also take an arbitrary function to completely customise behaviour of unmatched calls. It is chainable and can be called before or after other calls to `.mock()`. If `.catch()` is called without any parameters then every unmatched call will receive a `200` response + +#### `spy()` + +Similar to `catch()`, this records the call history of unmatched calls, but instead of responding with a stubbed response, the request is passed through to native `fetch()` and is allowed to communicate over the network. + +To use `.spy()` on a sandboxed `fetchMock`, `fetchMock.config.fetch` must be set to a reference to the `fetch` implementation you use in your code. + +``` + fetchMock.sandbox().mock('http://domain.com', 200) +``` + +Existing sandboxed `fetchMock`s can also have `.sandbox()` called on them, thus building mocks that inherit some settings from a parent mock + +#### `restore()/reset()` + +Chainable method that restores `fetch()` to its unstubbed state and clears all data recorded for its calls. + +#### `resetHistory()` + +Chainable method that clears all data recorded for `fetch()`'s calls. _It will not restore fetch to its default implementation_ + +_Note that `restore()`, `reset()` and `resetHistory()` are all bound to fetchMock, and can be used directly as callbacks e.g. `afterEach(fetchMock.reset)` will work just fine. There is no need for `afterEach(function () {fetchMock.reset()})`_ + +## Inspecting how `fetch()` has been called + +### Filtering + +Most of the methods below accept two parameters, `(filter, options)` + +- `filter` Enables filtering fetch calls for the most commonly use cases. The behaviour can be counterintuitive. The following rules, applied in the order they are described, are used to try to retrieve calls. If any rule retrieves no calls the next rule will be tried. + - If `options` is defined (it can even be an empty object), `filter` is executed using the same execution plan as matchers used in `.mock()`. Any calls matched by it will be returned. `options` will be used in a similar way to the options used by `mock()`. `options` may be a string specifying a `method` to filter by + - If `filter` is `undefined` all calls, matched _and_ unmatched, are returned + - If `filter` is `true` (or `fetchMock.MATCHED`) all calls that matched some route are returned + - If `filter` is `false` (or `fetchMock.UNMATCHED`) all calls that did not match any route are returned (when `.spy()`, `catch()` or `config.fallThroughToNetwork` were used to prevent errors being thrown) + - If `filter` is the name of a named route, all calls handled by that route are returned + - If `filter` is equal to `matcher` or `matcher.toString()` for a route, all calls handled by that route are returned + - `filter` is executed using the same execution plan as matchers used in `.mock()`. Any calls matched by it will be returned. + +#### `called(filter, method)` + +Returns a Boolean indicating whether fetch was called and a route was matched. If `filter` is specified it only returns `true` if that particular route was matched. + +#### `done(filter, method)` + +Returns a Boolean indicating whether fetch was called the expected number of times (or at least once if the route defines no expectation is set for the route). _Unlike the other methods for inspecting calls, unmatched calls are irrelevant_. Therefore, if no `filter` is passed, `done()` returns `true` if every route has been called the number of expected times. + +#### `calls(filter, method)` + +Returns an array of all calls to fetch matchingthe given filters. Each call is returned as an array of length 2, `[url, options]`. If `fetch` was called using a `Request` instance, thsi will be available as a `request` property on this array. + +#### `lastCall(filter, method)` + +Returns the arguments for the last matched call to fetch + +#### `lastUrl(filter, method)` + +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, 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. 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 + +On either the global or sandboxed `fetchMock` instances, the following config options can be set by setting properties on `fetchMock.config`. Many can also be set on individual calls to `.mock()`. + +- `sendAsJson` [default `true`] - by default fetchMock will convert objects to JSON before sending. This is overrideable from each call but for some scenarios e.g. when dealing with a lot of array buffers, it can be useful to default to `false` +- `includeContentLength` [default `true`]: When set to true this will make fetchMock automatically add the `content-length` header. This is especially useful when combined with `sendAsJson` because then fetchMock does the conversion to JSON for you and knows the resulting length so you don’t have to compute this yourself by basically doing the same conversion to JSON. +- `fallbackToNetwork` [default `false`] If true then unmatched calls will transparently fall through to the network, if false an error will be thrown. If set to `always`, all calls will fall through, effectively disabling fetch-mock. to Within individual tests `.catch()` and `spy()` can be used for fine-grained control of this +- `overwriteRoutes`: If a new route clashes with an existing route, setting `true` here will overwrite the clashing route, `false` will add another route to the stack which will be used as a fallback (useful when using the `repeat` option). Adding a clashing route without specifying this option will throw an error. +- `warnOnFallback` [default `true`] If true then any unmatched calls that are caught by a fallback handler (either the network or a custom function set using `catch()`) will emit warnings +- `Headers`,`Request`,`Response`,`Promise`, `fetch` + When using non standard fetch (e.g. a ponyfill, or aversion of `node-fetch` other than the one bundled with `fetch-mock`) or an alternative Promise implementation, this will configure fetch-mock to use your chosen implementations. + +Note that `Object.assign(fetchMock.config, require('fetch-ponyfill')())` will configure fetch-mock to use all of fetch-ponyfill's classes. In most cases, it should only be necessary to set this once before any tests run. diff --git a/docs/basic-usage.md b/docs/basic-usage.md new file mode 100644 index 00000000..3f546624 --- /dev/null +++ b/docs/basic-usage.md @@ -0,0 +1,161 @@ +- [Introduction](/fetch-mock) +- [Quickstart](/fetch-mock/quickstart) +- [Installation and usage](/fetch-mock/installation) +- API documentation +- [Troubleshooting](/fetch-mock/troubleshooting) +- [Examples](/fetch-mock/examples) + +# Basic usage + +`fetch-mock` has a powerful API to cover all sorts of use cases, but most cases can be covered by usig only a relatively small subset of the API. These docs cover the minimum you will need to know to be productive. Power users my also refer to the [complete API docs](#power-users) + + +## Mocking calls to `fetch` + +#### `mock(matcher, response, options)` + +Replaces `fetch` with a stub which records its calls, grouped by route, and optionally returns a mocked `Response` object or passes the call through to `fetch()`. Calls to `.mock()` can be chained. _Note that once mocked, `fetch` will error on any unmatched calls. Use `.spy()` or `.catch()` to handle unmocked calls more gracefully_ + +- `matcher`: Condition for selecting which requests to mock. (For matching based on headers, query strings or other `fetch` options see the `options` parameter documented below). Accepts any of the following: + - `string`: Either + - an exact url to match e.g. 'http://www.site.com/page.html' + - `*` to match any url + - `begin:http://www.site.com/` to match urls beginning with a string + - `end:.jpg` to match urls ending with a string + - `path:/posts/2018/7/3` to match urls with a given path + - `glob:http://*.*` to match glob patterns + - `express:/user/:user` to match [express style paths](https://www.npmjs.com/package/path-to-regexp) + - `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 + - `string`: Creates a 200 response with the string as the response body + - `configObject` If an object _does not contain_ any properties aside from those listed below it is treated as config to build a `Response` + - `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 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) + - `object`: All objects that do not meet the criteria above are converted to `JSON` and returned as the body of a 200 response. + - `Function(url, opts)`: A function that is passed the url and opts `fetch()` is called with and that returns any of the responses listed above (or a `Promise` for any of them) +- `options`: A configuration object with all/additional properties to define a route to mock + - `name`: A unique string naming the route. Used to subsequently retrieve references to the calls, grouped by name. Defaults to `matcher.toString()` + - `method`: http method to match + - `headers`: key/value map of headers to match + - `query`: key/value map of query strings to match, in any order + - `params`: when the `express:` keyword is used in a string matcher, a key/value map `params` can be passed here, to match the parameters extracted by express path matching + - `matcher`: as specified above + - `response`: as specified above + - `repeat`: An integer, `n`, limiting the number of times the matcher can be used. If the route has already been called `n` times the route will be ignored and the call to `fetch()` will fall through to be handled by any other routes defined (which may eventually result in an error if nothing matches it) + - `overwriteRoutes`: If the route you're adding clashes with an existing route, setting `true` here will overwrite the clashing route, `false` will add another route to the stack which will be used as a fallback (useful when using the `repeat` option). Adding a clashing route without specifying this option will throw an error. It can also be set as a global option (see the **Config** section below) + +#### `sandbox()` + +This returns a drop-in mock for fetch which can be passed to other mocking libraries. It implements the full fetch-mock api and maintains its own state independent of other instances, so tests can be run in parallel. e.g. + +#### `once()` + +Shorthand for `mock()` which limits to being called one time only. (see `repeat` option above) + +#### `get()`, `post()`, `put()`, `delete()`, `head()`, `patch()` + +Shorthands for `mock()` restricted to a particular method _Tip: if you use some other method a lot you can easily define your own shorthands e.g.:_ + +``` +fetchMock.purge = function (matcher, response, options) { + return this.mock(matcher, response, Object.assign({}, options, {method: 'PURGE'})); +} +``` + +#### `getOnce()`, `postOnce()`, `putOnce()`, `deleteOnce()`, `headOnce()`, `patchOnce()` + +Shorthands for `mock()` restricted to a particular method and that will only respond once + +#### `catch(response)` + +This is used to define how to respond to calls to fetch that don't match any of the defined mocks. It accepts the same types of response as a normal call to `.mock()`. It can also take an arbitrary function to completely customise behaviour of unmatched calls. It is chainable and can be called before or after other calls to `.mock()`. If `.catch()` is called without any parameters then every unmatched call will receive a `200` response + +#### `spy()` + +Similar to `catch()`, this records the call history of unmatched calls, but instead of responding with a stubbed response, the request is passed through to native `fetch()` and is allowed to communicate over the network. + +To use `.spy()` on a sandboxed `fetchMock`, `fetchMock.config.fetch` must be set to a reference to the `fetch` implementation you use in your code. + +``` + fetchMock.sandbox().mock('http://domain.com', 200) +``` + +Existing sandboxed `fetchMock`s can also have `.sandbox()` called on them, thus building mocks that inherit some settings from a parent mock + +#### `restore()/reset()` + +Chainable method that restores `fetch()` to its unstubbed state and clears all data recorded for its calls. + +#### `resetHistory()` + +Chainable method that clears all data recorded for `fetch()`'s calls. _It will not restore fetch to its default implementation_ + +_Note that `restore()`, `reset()` and `resetHistory()` are all bound to fetchMock, and can be used directly as callbacks e.g. `afterEach(fetchMock.reset)` will work just fine. There is no need for `afterEach(function () {fetchMock.reset()})`_ + +## Inspecting how `fetch()` has been called + +### Filtering + +Most of the methods below accept two parameters, `(filter, options)` + +- `filter` Enables filtering fetch calls for the most commonly use cases. The behaviour can be counterintuitive. The following rules, applied in the order they are described, are used to try to retrieve calls. If any rule retrieves no calls the next rule will be tried. + - If `options` is defined (it can even be an empty object), `filter` is executed using the same execution plan as matchers used in `.mock()`. Any calls matched by it will be returned. `options` will be used in a similar way to the options used by `mock()`. `options` may be a string specifying a `method` to filter by + - If `filter` is `undefined` all calls, matched _and_ unmatched, are returned + - If `filter` is `true` (or `fetchMock.MATCHED`) all calls that matched some route are returned + - If `filter` is `false` (or `fetchMock.UNMATCHED`) all calls that did not match any route are returned (when `.spy()`, `catch()` or `config.fallThroughToNetwork` were used to prevent errors being thrown) + - If `filter` is the name of a named route, all calls handled by that route are returned + - If `filter` is equal to `matcher` or `matcher.toString()` for a route, all calls handled by that route are returned + - `filter` is executed using the same execution plan as matchers used in `.mock()`. Any calls matched by it will be returned. + +#### `called(filter, method)` + +Returns a Boolean indicating whether fetch was called and a route was matched. If `filter` is specified it only returns `true` if that particular route was matched. + +#### `done(filter, method)` + +Returns a Boolean indicating whether fetch was called the expected number of times (or at least once if the route defines no expectation is set for the route). _Unlike the other methods for inspecting calls, unmatched calls are irrelevant_. Therefore, if no `filter` is passed, `done()` returns `true` if every route has been called the number of expected times. + +#### `calls(filter, method)` + +Returns an array of all calls to fetch matchingthe given filters. Each call is returned as an array of length 2, `[url, options]`. If `fetch` was called using a `Request` instance, thsi will be available as a `request` property on this array. + +#### `lastCall(filter, method)` + +Returns the arguments for the last matched call to fetch + +#### `lastUrl(filter, method)` + +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, 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. 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 + +On either the global or sandboxed `fetchMock` instances, the following config options can be set by setting properties on `fetchMock.config`. Many can also be set on individual calls to `.mock()`. + +- `sendAsJson` [default `true`] - by default fetchMock will convert objects to JSON before sending. This is overrideable from each call but for some scenarios e.g. when dealing with a lot of array buffers, it can be useful to default to `false` +- `includeContentLength` [default `true`]: When set to true this will make fetchMock automatically add the `content-length` header. This is especially useful when combined with `sendAsJson` because then fetchMock does the conversion to JSON for you and knows the resulting length so you don’t have to compute this yourself by basically doing the same conversion to JSON. +- `fallbackToNetwork` [default `false`] If true then unmatched calls will transparently fall through to the network, if false an error will be thrown. If set to `always`, all calls will fall through, effectively disabling fetch-mock. to Within individual tests `.catch()` and `spy()` can be used for fine-grained control of this +- `overwriteRoutes`: If a new route clashes with an existing route, setting `true` here will overwrite the clashing route, `false` will add another route to the stack which will be used as a fallback (useful when using the `repeat` option). Adding a clashing route without specifying this option will throw an error. +- `warnOnFallback` [default `true`] If true then any unmatched calls that are caught by a fallback handler (either the network or a custom function set using `catch()`) will emit warnings +- `Headers`,`Request`,`Response`,`Promise`, `fetch` + When using non standard fetch (e.g. a ponyfill, or aversion of `node-fetch` other than the one bundled with `fetch-mock`) or an alternative Promise implementation, this will configure fetch-mock to use your chosen implementations. + +Note that `Object.assign(fetchMock.config, require('fetch-ponyfill')())` will configure fetch-mock to use all of fetch-ponyfill's classes. In most cases, it should only be necessary to set this once before any tests run. diff --git a/docs/installation.md b/docs/installation.md index d0048501..86fabf9a 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -7,6 +7,18 @@ # Installation +## Requirements + +fetch-mock requires the following to run: + +- [Node.js](https://nodejs.org/) 8+ for full feature operation +- [Node.js](https://nodejs.org/) 0.12+ with [limitations](http://www.wheresrhys.co.uk/fetch-mock/installation) +- [npm](https://www.npmjs.com/package/npm) (normally comes with Node.js) +- Either of the following + - [node-fetch](https://www.npmjs.com/package/node-fetch) when testing in a nodejs + - A browser that supports the `fetch` API when testing in a browser + +## Installation and importing Install fetch-mock using `npm install --save-dev fetch-mock` In most environments use one of the following to use it in your code. @@ -22,18 +34,26 @@ 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 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` +- For server side tests running in nodejs 6 or lower use `require('fetch-mock/es5/server')` + +## Global or library? +`fetch` can be used by your code in two different ways. It's important to determine which one applies to your codebase as it will impact how you use `fetch-mock` -## Global fetch +In the following scenarios `fetch` will be a global +- When using native `fetch` (or a polyfill) in the browser +- When `node-fetch` has been assigned to `global` in your nodejs process (a pattern sometiems used in isomorphic codebases) -<<<<<<< HEAD +Alternatively, `fetch` may be used by your js modules as an imported/required library. Scenarios where this holds true are varied, but include +- Using `node-fetch` in nodejs without assigning to `global` +- Using [fetch-ponyfill](https://www.npmjs.com/package/fetch-ponyfill) in the browser +- Using browser libraries which use [fetch-ponyfill](https://www.npmjs.com/package/fetch-ponyfill) +- Some build setups (e.g React native) sometimes follow this pattern, though it may not always be obvious that they do -======= -> > > > > > > 315bf4bee040aa243eaf3b2a418741d35444bccb -> > > > > > > By default fetch-mock assumes `fetch` is a global so once you've required fetch-mock refer to the quickstart and api docs. +## Usage with 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. ### Polyfilling fetch @@ -43,9 +63,9 @@ Many older browsers will require polyfilling the `fetch` global - In the browser `require('isomorphic-fetch')` can also be used, but it may be easier to `npm install whatwg-fetch` (the module isomorphic-fetch is built around) and load `./node_modules/whatwg-fetch/fetch.js` directly into the page, either in a script tag or by referencing in your test runner config. - When using karma-webpack it's best not to use the `webpack.ProvidePlugin` for this. Instead just add `node_modules/whatwg-fetch/fetch.js` to your list of files to include, or require it directly into your tests before requiring fetch-mock. -## Non-global fetch +## Usage with a required fetch library -When using a non-global fetch implementation (such as node-fetch or fetch-ponyfill) use the `sandbox()` method to return a function that can be used as a replacement for fetch, and be passed into your source code using your choice of mocking library. The function returned by `sandbox()` supports the full fetch-mock api so once generated it can be worked with as if it were the original `fetch-mock` object, e.g. +The `sandbox()` method returns a function that can be used as a drop-in replacement for `fetch`, and can be passed into your choice of mocking library. The function returned by `sandbox()` supports the full fetch-mock api so once generated it can be worked with as if it were the original `fetch-mock` object, e.g. ``` const fetchMock = require('fetch-mock'); @@ -71,4 +91,4 @@ fetchMock.config = Object.assign(fetchMock.config, { This should be done before running any tests. -Note that when using `node-fetch`, `fetch-mock` will use the instance you already have installed so there should be no need to set any of the above (apart from `fetch`, which is required if you intend to use the `.spy()` method) +_When using `node-fetch`, `fetch-mock` will use the instance you already have installed so there should be no need to set any of the above (apart from `fetch`, which is required if you intend to use the `.spy()` method)_ From a6e28b1a1510ceaea58c08c9ea0e0cfc5768ec72 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Sun, 26 Aug 2018 18:26:35 +0100 Subject: [PATCH 002/127] remote_theme --- docs/_config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_config.yml b/docs/_config.yml index 43fd5783..7f0926de 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,4 +1,4 @@ markdown: kramdown -theme: CloudCannon/aviator-jekyll-template +remote_theme: CloudCannon/aviator-jekyll-template title: fetch-mock description: Mock http requests made using fetch From 0b159407908ad2e2e817da44af4559f9aef68c5d Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Sun, 26 Aug 2018 18:34:17 +0100 Subject: [PATCH 003/127] carte theme --- docs/_config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_config.yml b/docs/_config.yml index 7f0926de..9cc9cbdf 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,4 +1,4 @@ markdown: kramdown -remote_theme: CloudCannon/aviator-jekyll-template +remote_theme: Wiredcraft/carte title: fetch-mock description: Mock http requests made using fetch From 58d6444568be70f458d883c33b519bf91cb5ec31 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Sun, 26 Aug 2018 18:37:57 +0100 Subject: [PATCH 004/127] dinky --- docs/_config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_config.yml b/docs/_config.yml index 9cc9cbdf..0c0d2cc9 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,4 +1,4 @@ markdown: kramdown -remote_theme: Wiredcraft/carte +theme: dinky title: fetch-mock description: Mock http requests made using fetch From 91528aa628bd915c0214f3730b6b6074393bf252 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Sun, 26 Aug 2018 18:40:31 +0100 Subject: [PATCH 005/127] dinky2 --- docs/_config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_config.yml b/docs/_config.yml index 0c0d2cc9..fd8fd07b 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,4 +1,4 @@ markdown: kramdown -theme: dinky +theme: jekyll-theme-dinky title: fetch-mock description: Mock http requests made using fetch From 18a0ba443fc157a4a953a6c7a030afd7e33768c0 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Sun, 26 Aug 2018 18:52:50 +0100 Subject: [PATCH 006/127] aviator --- docs/.gitignore | 2 + docs/Gemfile | 8 + docs/Gemfile.lock | 69 +++ docs/LICENSE | 21 + docs/README.md | 56 +++ docs/_api/_defaults.md | 16 + docs/_api/books_add.md | 46 ++ docs/_api/books_delete.md | 41 ++ docs/_api/books_get.md | 37 ++ docs/_api/books_list.md | 65 +++ docs/_api/books_update.md | 46 ++ docs/_config.yml | 82 +++- docs/_documentation/_defaults.md | 16 + docs/_documentation/authentication.md | 29 ++ docs/_documentation/errors.md | 28 ++ docs/_documentation/getting_started.md | 33 ++ docs/_includes/relative-src.html | 1 + docs/_includes/sidebar.html | 21 + docs/_includes/syntax-highlight.html | 8 + docs/_layouts/default.html | 53 +++ docs/_sass/_borland.scss | 58 +++ docs/_sass/_main.scss | 569 +++++++++++++++++++++++ docs/_sass/_mixins.scss | 34 ++ docs/_sass/_monaki.scss | 64 +++ docs/_sass/cloudcannon.scss | 26 ++ docs/apple-touch-icon.png | Bin 0 -> 1058 bytes docs/css/editor.css | 24 + docs/css/style.scss | 26 ++ docs/favicon.png | Bin 0 -> 300 bytes docs/images/_screenshot.png | Bin 0 -> 175182 bytes docs/images/emblem.svg | 4 + docs/images/logo.svg | 11 + docs/images/menu.svg | 4 + docs/index.html | 50 ++ docs/js/lunr.min.js | 6 + docs/js/main.js | 105 +++++ docs/js/search.js | 102 ++++ docs/robots.txt | 6 + docs/search.html | 39 ++ docs/siteicon.png | Bin 0 -> 2631 bytes docs/touch-icon.png | Bin 0 -> 9648 bytes old_docs/_config.yml | 4 + {docs => old_docs}/api-basic.md | 0 {docs => old_docs}/api.md | 0 {docs => old_docs}/basic-usage.md | 0 {docs => old_docs}/examples.md | 0 {docs => old_docs}/index.md | 0 {docs => old_docs}/installation.md | 0 {docs => old_docs}/quickstart.md | 0 {docs => old_docs}/troubleshooting.md | 0 {docs => old_docs}/v5-v6-upgrade.md | 0 {docs => old_docs}/v5/_config.yml | 0 {docs => old_docs}/v5/api.md | 0 {docs => old_docs}/v5/examples.md | 0 {docs => old_docs}/v5/index.md | 0 {docs => old_docs}/v5/installation.md | 0 {docs => old_docs}/v5/quickstart.md | 0 {docs => old_docs}/v5/troubleshooting.md | 0 {docs => old_docs}/v5/v4-v5-upgrade.md | 0 {docs => old_docs}/v6-v7-upgrade.md | 0 {docs => old_docs}/v6/_config.yml | 0 {docs => old_docs}/v6/api.md | 0 {docs => old_docs}/v6/examples.md | 0 {docs => old_docs}/v6/index.md | 0 {docs => old_docs}/v6/installation.md | 0 {docs => old_docs}/v6/quickstart.md | 0 {docs => old_docs}/v6/troubleshooting.md | 0 {docs => old_docs}/v6/v5-v6-upgrade.md | 0 68 files changed, 1806 insertions(+), 4 deletions(-) create mode 100644 docs/.gitignore create mode 100644 docs/Gemfile create mode 100644 docs/Gemfile.lock create mode 100644 docs/LICENSE create mode 100644 docs/README.md create mode 100644 docs/_api/_defaults.md create mode 100644 docs/_api/books_add.md create mode 100644 docs/_api/books_delete.md create mode 100644 docs/_api/books_get.md create mode 100644 docs/_api/books_list.md create mode 100644 docs/_api/books_update.md create mode 100644 docs/_documentation/_defaults.md create mode 100644 docs/_documentation/authentication.md create mode 100644 docs/_documentation/errors.md create mode 100644 docs/_documentation/getting_started.md create mode 100644 docs/_includes/relative-src.html create mode 100644 docs/_includes/sidebar.html create mode 100644 docs/_includes/syntax-highlight.html create mode 100644 docs/_layouts/default.html create mode 100644 docs/_sass/_borland.scss create mode 100644 docs/_sass/_main.scss create mode 100644 docs/_sass/_mixins.scss create mode 100644 docs/_sass/_monaki.scss create mode 100644 docs/_sass/cloudcannon.scss create mode 100644 docs/apple-touch-icon.png create mode 100644 docs/css/editor.css create mode 100644 docs/css/style.scss create mode 100644 docs/favicon.png create mode 100644 docs/images/_screenshot.png create mode 100644 docs/images/emblem.svg create mode 100644 docs/images/logo.svg create mode 100644 docs/images/menu.svg create mode 100644 docs/index.html create mode 100644 docs/js/lunr.min.js create mode 100644 docs/js/main.js create mode 100644 docs/js/search.js create mode 100644 docs/robots.txt create mode 100644 docs/search.html create mode 100644 docs/siteicon.png create mode 100644 docs/touch-icon.png create mode 100644 old_docs/_config.yml rename {docs => old_docs}/api-basic.md (100%) rename {docs => old_docs}/api.md (100%) rename {docs => old_docs}/basic-usage.md (100%) rename {docs => old_docs}/examples.md (100%) rename {docs => old_docs}/index.md (100%) rename {docs => old_docs}/installation.md (100%) rename {docs => old_docs}/quickstart.md (100%) rename {docs => old_docs}/troubleshooting.md (100%) rename {docs => old_docs}/v5-v6-upgrade.md (100%) rename {docs => old_docs}/v5/_config.yml (100%) rename {docs => old_docs}/v5/api.md (100%) rename {docs => old_docs}/v5/examples.md (100%) rename {docs => old_docs}/v5/index.md (100%) rename {docs => old_docs}/v5/installation.md (100%) rename {docs => old_docs}/v5/quickstart.md (100%) rename {docs => old_docs}/v5/troubleshooting.md (100%) rename {docs => old_docs}/v5/v4-v5-upgrade.md (100%) rename {docs => old_docs}/v6-v7-upgrade.md (100%) rename {docs => old_docs}/v6/_config.yml (100%) rename {docs => old_docs}/v6/api.md (100%) rename {docs => old_docs}/v6/examples.md (100%) rename {docs => old_docs}/v6/index.md (100%) rename {docs => old_docs}/v6/installation.md (100%) rename {docs => old_docs}/v6/quickstart.md (100%) rename {docs => old_docs}/v6/troubleshooting.md (100%) rename {docs => old_docs}/v6/v5-v6-upgrade.md (100%) diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 00000000..0c3e5abb --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1,2 @@ +_site/ +.sass-cache/ diff --git a/docs/Gemfile b/docs/Gemfile new file mode 100644 index 00000000..724febd0 --- /dev/null +++ b/docs/Gemfile @@ -0,0 +1,8 @@ +source 'https://rubygems.org' + +gem 'jekyll', '3.7.2' + +group :jekyll_plugins do + gem 'jekyll-seo-tag', '2.4.0' + gem 'jekyll-sitemap', '1.2.0' +end diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock new file mode 100644 index 00000000..0498c707 --- /dev/null +++ b/docs/Gemfile.lock @@ -0,0 +1,69 @@ +GEM + remote: https://rubygems.org/ + specs: + addressable (2.5.2) + public_suffix (>= 2.0.2, < 4.0) + colorator (1.1.0) + concurrent-ruby (1.0.5) + em-websocket (0.5.1) + eventmachine (>= 0.12.9) + http_parser.rb (~> 0.6.0) + eventmachine (1.2.5) + ffi (1.9.18) + forwardable-extended (2.6.0) + http_parser.rb (0.6.0) + i18n (0.9.3) + concurrent-ruby (~> 1.0) + jekyll (3.7.2) + addressable (~> 2.4) + colorator (~> 1.0) + em-websocket (~> 0.5) + i18n (~> 0.7) + jekyll-sass-converter (~> 1.0) + jekyll-watch (~> 2.0) + kramdown (~> 1.14) + liquid (~> 4.0) + mercenary (~> 0.3.3) + pathutil (~> 0.9) + rouge (>= 1.7, < 4) + safe_yaml (~> 1.0) + jekyll-sass-converter (1.5.2) + sass (~> 3.4) + jekyll-seo-tag (2.4.0) + jekyll (~> 3.3) + jekyll-sitemap (1.2.0) + jekyll (~> 3.3) + jekyll-watch (2.0.0) + listen (~> 3.0) + kramdown (1.16.2) + liquid (4.0.0) + listen (3.1.5) + rb-fsevent (~> 0.9, >= 0.9.4) + rb-inotify (~> 0.9, >= 0.9.7) + ruby_dep (~> 1.2) + mercenary (0.3.6) + pathutil (0.16.1) + forwardable-extended (~> 2.6) + public_suffix (3.0.1) + rb-fsevent (0.10.2) + rb-inotify (0.9.10) + ffi (>= 0.5.0, < 2) + rouge (3.1.1) + ruby_dep (1.5.0) + safe_yaml (1.0.4) + sass (3.5.5) + sass-listen (~> 4.0.0) + sass-listen (4.0.0) + rb-fsevent (~> 0.9, >= 0.9.4) + rb-inotify (~> 0.9, >= 0.9.7) + +PLATFORMS + ruby + +DEPENDENCIES + jekyll (= 3.7.2) + jekyll-seo-tag (= 2.4.0) + jekyll-sitemap (= 1.2.0) + +BUNDLED WITH + 1.16.0 diff --git a/docs/LICENSE b/docs/LICENSE new file mode 100644 index 00000000..3a4a2fb8 --- /dev/null +++ b/docs/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 CloudCannon + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 00000000..819b23af --- /dev/null +++ b/docs/README.md @@ -0,0 +1,56 @@ +# Aviator + +API documentation template for Jekyll. Browse through a [live demo](https://tangerine-lemon.cloudvent.net/). +Start documenting your API with this configurable theme. + +![Aviator template screenshot](images/_screenshot.png) + +Aviator was made by [CloudCannon](http://cloudcannon.com/), the Cloud CMS for Jekyll. + +Find more templates, themes and step-by-step Jekyll tutorials at [CloudCannon Academy](https://learn.cloudcannon.com/). + +## Features + +* Three column layout +* Fully responsive +* Full text search +* Pre-styled components +* Auto-generated navigation based on category +* Optimised for editing in [CloudCannon](http://cloudcannon.com/) +* SEO tags +* Google Analytics + +## Setup + +1. Add your site and author details in `_config.yml`. +2. Get a workflow going to see your site's output (with [CloudCannon](https://app.cloudcannon.com/) or Jekyll locally). + +## Develop + +Aviator was built with [Jekyll](http://jekyllrb.com/) version 3.7.2, but should support newer versions as well. + +Install the dependencies with [Bundler](http://bundler.io/): + +~~~bash +$ bundle install +~~~ + +Run `jekyll` commands through Bundler to ensure you're using the right versions: + +~~~bash +$ bundle exec jekyll serve +~~~ + +## Editing + +Aviator is already optimised for adding, updating and removing documentation pages in CloudCannon. + +### Usage + +* Each section is a different collection, this helps organise your content. +* Set the order of the collections with the position field in collection configuration in `_config.yml`. +* Set the order of the documents inside a collection by setting the position in front matter. + +### Search + +* Add `excluded_in_search: true` to any documentation page's front matter to exclude that page in the search results. diff --git a/docs/_api/_defaults.md b/docs/_api/_defaults.md new file mode 100644 index 00000000..0b832f22 --- /dev/null +++ b/docs/_api/_defaults.md @@ -0,0 +1,16 @@ +--- +title: +position: +parameters: + - name: + content: +content_markdown: +left_code_blocks: + - code_block: + title: + language: +right_code_blocks: + - code_block: + title: + language: +--- diff --git a/docs/_api/books_add.md b/docs/_api/books_add.md new file mode 100644 index 00000000..cd5748e4 --- /dev/null +++ b/docs/_api/books_add.md @@ -0,0 +1,46 @@ +--- +title: /books +position: 1.1 +type: post +description: Create Book +parameters: + - name: title + content: The title for the book + - name: score + content: The book's score between 0 and 5 +content_markdown: |- + The book will automatically be added to your reading list + {: .success} + + Adds a book to your collection. +left_code_blocks: + - code_block: |- + $.post("http://api.myapp.com/books/", { + "token": "YOUR_APP_KEY", + "title": "The Book Thief", + "score": 4.3 + }, function(data) { + alert(data); + }); + title: jQuery + language: javascript +right_code_blocks: + - code_block: |- + { + "id": 3, + "title": "The Book Thief", + "score": 4.3, + "dateAdded": "5/1/2015" + } + title: Response + language: json + - code_block: |- + { + "error": true, + "message": "Invalid score" + } + title: Error + language: json +--- + + diff --git a/docs/_api/books_delete.md b/docs/_api/books_delete.md new file mode 100644 index 00000000..007db9c8 --- /dev/null +++ b/docs/_api/books_delete.md @@ -0,0 +1,41 @@ +--- +title: /books/:id +position: 1.5 +type: delete +description: Deletes a book +parameters: + - name: + content: +content_markdown: |- + Deletes a book in your collection. +left_code_blocks: + - code_block: |- + $.ajax({ + "url": "http://api.myapp.com/books/3", + "type": "DELETE", + "data": { + "token": "YOUR_APP_KEY" + }, + "success": function(data) { + alert(data); + } + }); + title: jQuery + language: javascript +right_code_blocks: + - code_block: |2- + { + "id": 3, + "status": "deleted" + } + title: Response + language: json + - code_block: |2- + { + "error": true, + "message": "Book doesn't exist" + } + title: Error + language: json +--- + diff --git a/docs/_api/books_get.md b/docs/_api/books_get.md new file mode 100644 index 00000000..30df6faf --- /dev/null +++ b/docs/_api/books_get.md @@ -0,0 +1,37 @@ +--- +title: /books/:id +position: 1.3 +type: get +description: Get Book +parameters: + - name: + content: +content_markdown: |- + Returns a specific book from your collection +left_code_blocks: + - code_block: |- + $.get("http://api.myapp.com/books/3", { + token: "YOUR_APP_KEY", + }, function(data) { + alert(data); + }); + title: jQuery + language: javascript +right_code_blocks: + - code_block: |2- + { + "id": 3, + "title": "The Book Thief", + "score": 4.3, + "dateAdded": "5/1/2015" + } + title: Response + language: json + - code_block: |2- + { + "error": true, + "message": "Book doesn't exist" + } + title: Error + language: json +--- \ No newline at end of file diff --git a/docs/_api/books_list.md b/docs/_api/books_list.md new file mode 100644 index 00000000..065ab3da --- /dev/null +++ b/docs/_api/books_list.md @@ -0,0 +1,65 @@ +--- +title: /books +position: 1.0 +type: get +description: List all books +parameters: + - name: offset + content: Offset the results by this amount + - name: limit + content: Limit the number of books returned +content_markdown: |- + This call will return a maximum of 100 books + {: .info } + + Lists all the photos you have access to. You can paginate by using the parameters listed above. +left_code_blocks: + - code_block: |- + $.get("http://api.myapp.com/books/", { "token": "YOUR_APP_KEY"}, function(data) { + alert(data); + }); + title: jQuery + language: javascript + - code_block: |- + r = requests.get("http://api.myapp.com/books/", token="YOUR_APP_KEY") + print r.text + title: Python + language: python + - code_block: |- + var request = require("request"); + request("http://api.myapp.com/books?token=YOUR_APP_KEY", function (error, response, body) { + if (!error && response.statusCode == 200) { + console.log(body); + } + title: Node.js + language: javascript + - code_block: |- + curl http://sampleapi.readme.com/orders?key=YOUR_APP_KEY + title: Curl + language: bash +right_code_blocks: + - code_block: |2- + [ + { + "id": 1, + "title": "The Hunger Games", + "score": 4.5, + "dateAdded": "12/12/2013" + }, + { + "id": 1, + "title": "The Hunger Games", + "score": 4.7, + "dateAdded": "15/12/2013" + }, + ] + title: Response + language: json + - code_block: |2- + { + "error": true, + "message": "Invalid offset" + } + title: Error + language: json +--- \ No newline at end of file diff --git a/docs/_api/books_update.md b/docs/_api/books_update.md new file mode 100644 index 00000000..1b6ccfae --- /dev/null +++ b/docs/_api/books_update.md @@ -0,0 +1,46 @@ +--- +title: /books/:id +position: 1.4 +type: put +description: Update Book +parameters: + - name: title + content: The title for the book + - name: score + content: The book's score between 0 and 5 +content_markdown: |- + Update an existing book in your collection. +left_code_blocks: + - code_block: |- + $.ajax({ + "url": "http://api.myapp.com/books/3", + "type": "PUT", + "data": { + "token": "YOUR_APP_KEY", + "score": 5.0, + "title": "The Book Stealer" + }, + "success": function(data) { + alert(data); + } + }); + title: jQuery + language: javascript +right_code_blocks: + - code_block: |2- + { + "id": 3, + "title": "The Book Stealer", + "score": 5, + "dateAdded": "5/1/2015" + } + title: Response + language: json + - code_block: |2- + { + "error": true, + "message": "Book doesn't exist" + } + title: Error + language: json +--- \ No newline at end of file diff --git a/docs/_config.yml b/docs/_config.yml index fd8fd07b..a13938b7 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,4 +1,78 @@ -markdown: kramdown -theme: jekyll-theme-dinky -title: fetch-mock -description: Mock http requests made using fetch +# ---- +# Site + +title: Aviator +description: Jekyll template for API documentation. +url: https://example.com +google_analytics_key: +permalink: pretty + +# ----- +# Build + +timezone: Etc/UTC + +collections: + documentation: + title: Documentation + position: 1 + api: + title: APIs + position: 2 +plugins: + - jekyll-sitemap + - jekyll-seo-tag + +exclude: + - readme.md + - LICENSE + +defaults: + - + scope: + path: "" + values: + layout: default + - + scope: + type: "documentation" + values: + _hide_content: true + - + scope: + type: "api" + values: + _hide_content: true + +# ----------- +# CloudCannon + +types: + - get + - put + - delete + - post + +languages: + bash: Bash + c: C + css: CSS + html: HTML + java: Java + javascript: JavaScript + json: JSON + php: PHP + python: Python + ruby: Ruby + +_options: + content_markdown: + format: p h4 h5 h6 + bold: true + italic: true + link: true + bulletedlist: true + numberedlist: true + image: true + table: true + styles: /css/editor.css diff --git a/docs/_documentation/_defaults.md b/docs/_documentation/_defaults.md new file mode 100644 index 00000000..0b832f22 --- /dev/null +++ b/docs/_documentation/_defaults.md @@ -0,0 +1,16 @@ +--- +title: +position: +parameters: + - name: + content: +content_markdown: +left_code_blocks: + - code_block: + title: + language: +right_code_blocks: + - code_block: + title: + language: +--- diff --git a/docs/_documentation/authentication.md b/docs/_documentation/authentication.md new file mode 100644 index 00000000..ffe25d44 --- /dev/null +++ b/docs/_documentation/authentication.md @@ -0,0 +1,29 @@ +--- +title: Authentication +position: 2 +parameters: + - name: + content: +content_markdown: |- + You need to be authenticated for all API requests. You can generate an API key in your developer dashboard. + + Add the API key to all requests as a GET parameter. + + Nothing will work unless you include this API key + {: .error} +left_code_blocks: + - code_block: + title: + language: +right_code_blocks: + - code_block: |2- + $.get("http://api.myapp.com/books/", { "token": "YOUR_APP_KEY"}, function(data) { + alert(data); + }); + title: JQuery + language: javascript + - code_block: |2- + curl http://api.myapp.com/books?token=YOUR_APP_KEY + title: Curl + language: bash +--- \ No newline at end of file diff --git a/docs/_documentation/errors.md b/docs/_documentation/errors.md new file mode 100644 index 00000000..cada3600 --- /dev/null +++ b/docs/_documentation/errors.md @@ -0,0 +1,28 @@ +--- +title: Errors +position: 3 +parameters: + - name: + content: +content_markdown: |- + | Code | Name | Description | + | --- | --- | --- | + | 200 | OK | Success | + | 201 | Created | Creation Successful | + | 400 | Bad Request | We could not process that action | + | 403 | Forbidden | We couldn't authenticate you | + + All errors will return JSON in the following format: +left_code_blocks: + - code_block: |- + { + "error": true, + "message": "error message here" + } + title: Response + language: json +right_code_blocks: + - code_block: + title: + language: +--- \ No newline at end of file diff --git a/docs/_documentation/getting_started.md b/docs/_documentation/getting_started.md new file mode 100644 index 00000000..c9d41c77 --- /dev/null +++ b/docs/_documentation/getting_started.md @@ -0,0 +1,33 @@ +--- +title: Getting Started +position: 1 +parameters: + - name: + content: +content_markdown: |- + Welcome to our API. + + This API document is designed for those interested in developing for our platform. + + This API is still under development and will evolve. + + You'll succeed if you do this. + {: .success } + + Here's some useful information. + {: .info } + + Something may not happen if you try and do this. + {: .warning } + + Something bad will happen if you do this. + {: .error } +left_code_blocks: + - code_block: + title: + language: +right_code_blocks: + - code_block: + title: + language: +--- \ No newline at end of file diff --git a/docs/_includes/relative-src.html b/docs/_includes/relative-src.html new file mode 100644 index 00000000..45354481 --- /dev/null +++ b/docs/_includes/relative-src.html @@ -0,0 +1 @@ +{% assign prefix = include.src | slice: 0, 2 %}{% assign protocol = include.src | slice: 0, 4 %}{% unless protocol == 'http' or prefix == "//" %}{{ site.baseurl }}{% endunless %}{{ include.src }} \ No newline at end of file diff --git a/docs/_includes/sidebar.html b/docs/_includes/sidebar.html new file mode 100644 index 00000000..0d8ecfbb --- /dev/null +++ b/docs/_includes/sidebar.html @@ -0,0 +1,21 @@ + diff --git a/docs/_includes/syntax-highlight.html b/docs/_includes/syntax-highlight.html new file mode 100644 index 00000000..cfdf54ef --- /dev/null +++ b/docs/_includes/syntax-highlight.html @@ -0,0 +1,8 @@ +{% capture highlight %} +``` {{ include.block.language }} +{{ include.block.code_block }} +``` +{: title="{{ include.block.title }}" } +{% endcapture %} + +{{ highlight | markdownify }} \ No newline at end of file diff --git a/docs/_layouts/default.html b/docs/_layouts/default.html new file mode 100644 index 00000000..8f54326a --- /dev/null +++ b/docs/_layouts/default.html @@ -0,0 +1,53 @@ + + + + + + + {% seo %} + + + + + {% if jekyll.environment == 'production' and site.google_analytics_key != '' %} + + + {% endif %} + + + + + +
+

+ + {{ site.title }} logo +

+ +
+ + +
+ + {% include sidebar.html %} + + +
+
+ {{ content }} +
+ + + diff --git a/docs/_sass/_borland.scss b/docs/_sass/_borland.scss new file mode 100644 index 00000000..6ff9c632 --- /dev/null +++ b/docs/_sass/_borland.scss @@ -0,0 +1,58 @@ +code .hll { background-color: #ffffcc } +code .c { color: #aaaaaa; font-style: italic } /* Comment */ +code .err { color: #F00000; background-color: #F0A0A0 } /* Error */ +code .k { color: #0000aa } /* Keyword */ +code .cm { color: #aaaaaa; font-style: italic } /* Comment.Multiline */ +code .cp { color: #4c8317 } /* Comment.Preproc */ +code .c1 { color: #aaaaaa; font-style: italic } /* Comment.Single */ +code .cs { color: #0000aa; font-style: italic } /* Comment.Special */ +code .gd { color: #aa0000 } /* Generic.Deleted */ +code .ge { font-style: italic } /* Generic.Emph */ +code .gr { color: #aa0000 } /* Generic.Error */ +code .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +code .gi { color: #00aa00 } /* Generic.Inserted */ +code .go { color: #888888 } /* Generic.Output */ +code .gp { color: #555555 } /* Generic.Prompt */ +code .gs { font-weight: bold } /* Generic.Strong */ +code .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +code .gt { color: #aa0000 } /* Generic.Traceback */ +code .kc { color: #0000aa } /* Keyword.Constant */ +code .kd { color: #0000aa } /* Keyword.Declaration */ +code .kn { color: #0000aa } /* Keyword.Namespace */ +code .kp { color: #0000aa } /* Keyword.Pseudo */ +code .kr { color: #0000aa } /* Keyword.Reserved */ +code .kt { color: #00aaaa } /* Keyword.Type */ +code .m { color: #009999 } /* Literal.Number */ +code .s { color: #aa5500 } /* Literal.String */ +code .na { color: #1e90ff } /* Name.Attribute */ +code .nb { color: #00aaaa } /* Name.Builtin */ +code .nc { color: #00aa00; text-decoration: underline } /* Name.Class */ +code .no { color: #aa0000 } /* Name.Constant */ +code .nd { color: #888888 } /* Name.Decorator */ +code .ni { color: #800000; font-weight: bold } /* Name.Entity */ +code .nf { color: #00aa00 } /* Name.Function */ +code .nn { color: #00aaaa; text-decoration: underline } /* Name.Namespace */ +code .nt { color: #1e90ff; font-weight: bold } /* Name.Tag */ +code .nv { color: #aa0000 } /* Name.Variable */ +code .ow { color: #0000aa } /* Operator.Word */ +code .w { color: #bbbbbb } /* Text.Whitespace */ +code .mf { color: #009999 } /* Literal.Number.Float */ +code .mh { color: #009999 } /* Literal.Number.Hex */ +code .mi { color: #009999 } /* Literal.Number.Integer */ +code .mo { color: #009999 } /* Literal.Number.Oct */ +code .sb { color: #aa5500 } /* Literal.String.Backtick */ +code .sc { color: #aa5500 } /* Literal.String.Char */ +code .sd { color: #aa5500 } /* Literal.String.Doc */ +code .s2 { color: #aa5500 } /* Literal.String.Double */ +code .se { color: #aa5500 } /* Literal.String.Escape */ +code .sh { color: #aa5500 } /* Literal.String.Heredoc */ +code .si { color: #aa5500 } /* Literal.String.Interpol */ +code .sx { color: #aa5500 } /* Literal.String.Other */ +code .sr { color: #009999 } /* Literal.String.Regex */ +code .s1 { color: #aa5500 } /* Literal.String.Single */ +code .ss { color: #0000aa } /* Literal.String.Symbol */ +code .bp { color: #00aaaa } /* Name.Builtin.Pseudo */ +code .vc { color: #aa0000 } /* Name.Variable.Class */ +code .vg { color: #aa0000 } /* Name.Variable.Global */ +code .vi { color: #aa0000 } /* Name.Variable.Instance */ +code .il { color: #009999 } /* Literal.Number.Integer.Long */ diff --git a/docs/_sass/_main.scss b/docs/_sass/_main.scss new file mode 100644 index 00000000..47e12910 --- /dev/null +++ b/docs/_sass/_main.scss @@ -0,0 +1,569 @@ +html, body { + padding: 0; + margin: 0; +} + +body, .main { + box-sizing: border-box; + min-height: 100vh; +} + +html { + font-size: 62.5%; + color: #474a54; + background: #232323; + height: 100vh; +} + +img { + max-width: 100%; +} + +@media (max-width: $mobile-break) { + .sidebar, header > form { + display: none; + } + + .sidebar h6 { + font-size: 1.4em; + } + + .sidebar a { + padding: 10px 0; + } + + body .main { + margin: 45px 0 0 0; + } +} + +body { + font-size: 1.8em; + line-height: 1.6; + font-weight: 400; + font-family: system, -apple-system, BlinkMacSystemFont, "Helvetica Neue", "Lucida Grande", sans-serif; + background: #fbfbfb; + + &.nav-open { + overflow: hidden; + + .sidebar, + header > form { + display: block; + } + + header { + bottom: 0; + } + } +} + +table { + border: 1px solid #E1E1E1; + margin: 0 0 20px 0; + border-collapse: collapse; +} + +th, td { + border: 1px solid #ccc; + padding: 10px; + font-size: .9em; + text-align: left; +} + +th { + background: #f7f7f7; +} + +h1, h2, h3, h4, h5, h6 { + margin-top: 0; + font-weight: 300; +} + +h1 { font-size: 4.0rem; line-height: 1.2; letter-spacing: -.1rem;} +h2 { font-size: 3.6rem; line-height: 1.25; letter-spacing: -.1rem; } +h3 { font-size: 3.0rem; line-height: 1.3; letter-spacing: -.1rem; } + +h4 { + font-size: 2.4rem; + line-height: 1.35; + letter-spacing: -.08rem; + margin: 0 0 5px 0; +} + +h5 { + font-size: 1.8rem; + line-height: 1.5; + letter-spacing: -.05rem; +} + +p { + margin-top: 0; +} + +h3 a { + text-decoration: none; + color: #474a54; +} + +h3 a:hover { + text-decoration: none; + color: #474a54; +} +a { + color: #1EAEDB; text-decoration: none; +} + +a:hover { + color: #0FA0CE; text-decoration: underline; +} + +pre { + white-space: pre-wrap; + font-size: 1em; + margin: 22px 0; + word-wrap: break-word; +} + +dl { + border-top: 1px solid #eee; + border-bottom: 1px solid #eee; + padding: 0 0 20px 0; + margin: 0 0 20px 0; +} + +dl dt { + width: 30%; + float: left; + font-weight: bold; + position: relative; + top: 20px; +} + +dl dd { + margin-left: 30%; + padding-left: 15px; + margin-top: 20px; +} + +dl dd + dd { + margin-top: 0; +} + +dl dd:after { + visibility: hidden; + display: block; + content: ""; + clear: both; + height: 0; +} + +.sidebar h6 { + line-height: 1em; + font-size: 1.5rem; + letter-spacing: 1px; + color: #888; + font-weight: bold; +} + +.sidebar { + padding: 20px 20px 0 20px; + white-space:nowrap; + overflow-y: auto; + + section { + padding: 10px 0; + } + + ul { + padding: 0 0 0 10px; + margin: 0; + list-style: none; + } + + h6 { + padding: 0; + margin: 0 0 5px 0; + } + + a { + color: #777; + text-decoration: none; + font-size: .90em; + display: block; + width: 100%; + text-overflow: ellipsis; + overflow: hidden; + padding: 2px 0; + + &.active { + color: #2196F3; + text-decoration: none; + } + } +} + +.endpoint { + font-size: 10px; + padding: 0 2px; + position: relative; +} + +h3 .endpoint { + padding: 4px 6px; + font-size: 19px; +} + +.endpoint.put { + color: #7E57C2; + &:after { + content: "PUT"; + } +} + +.endpoint.delete { + color: #FF7043; + &:after { + content: "DELETE"; + } +} + +.endpoint.get { + color: #66BB6A; + &:after { + content: "GET"; + } +} + +.endpoint.post { + color: #42A5F5; + &:after { + content: "POST"; + } +} + +.main { + margin: 0 0 0 $nav-width; + border-left: 1px solid #eee; + h6 { + font-size: 1.01em; + padding: 0 0 6px 0; + margin: 0; + } + + .description { + color: #aaa; + margin-top: -11px; + } + + @media (max-width: $mobile-break) { + margin: 0; + } +} + +hr { + border: 0; + border-top: 1px solid #ddd; + margin: 20px 0; +} + +.error, .warning, .info, .success { + border-left: 5px solid #FD0; + padding: 10px 15px; + margin-left: -20px; + margin-right: -15px; + background-color: #FAFAFA; + border-radius: 2px; +} + +.warning { + border-color: #ffc107; +} + +.info { + border-color: #56ADEC; +} + +.error { + border-color: #F20; +} + +.success { + border-color: #6c0; +} + +.doc-content { + border: 0; + border-bottom: 1px solid transparent; + border-image: linear-gradient(to right, #eee 0%,#eee 60%,#333333 60%); + -moz-border-image: -moz-linear-gradient(left, #eee 0%, #eee 60%, #333333 60%); + -webkit-border-image: -webkit-linear-gradient(left, #eee 0%,#eee 60%,#333333 60%); + border-image-slice: 1; + padding: 30px 0; + background: #ffffff; /* Old browsers */ + background: -moz-linear-gradient(left, #ffffff 0%, #ffffff 60%, #232323 60%); /* FF3.6+ */ + background: -webkit-gradient(linear, left top, right top, color-stop(0%,#ffffff), color-stop(60%,#ffffff), color-stop(60%,#232323)); /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(left, #ffffff 0%,#ffffff 60%,#232323 60%); /* Chrome10+,Safari5.1+ */ + background: -o-linear-gradient(left, #ffffff 0%,#ffffff 60%,#232323 60%); /* Opera 11.10+ */ + background: -ms-linear-gradient(left, #ffffff 0%,#ffffff 60%,#232323 60%); /* IE10+ */ + background: linear-gradient(to right, #ffffff 0%,#ffffff 60%,#232323 60%); /* W3C */ + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#232323',GradientType=1 ); /* IE6-9 */ +} + +.doc-content:after { + visibility: hidden; + display: block; + content: ""; + clear: both; + height: 0; +} + +.doc-content:last-child { + border: 0; +} + +.left-docs { + width: 60%; + float: left; + padding: 0 50px; + -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */ + -moz-box-sizing: border-box; /* Firefox, other Gecko */ + box-sizing: border-box; /* Opera/IE 8+ */ + + pre { + border: 0px; + box-shadow: 0 0 0 1px #eee; + border-radius: 3px; + padding: 10px; + } +} + +.right-code { + width: 40%; + float: left; + padding: 0 50px; + -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */ + -moz-box-sizing: border-box; /* Firefox, other Gecko */ + box-sizing: border-box; /* Opera/IE 8+ */ + + code { + color: #fff; + } + + pre { + background: black; + padding: 10px; + border-radius: 5px; + } + + .code-viewer .languages li a:hover { + border-color: #555; + } +} + +.code-viewer { + .languages { + padding: 0; + margin: 0 0 5px 0; + list-style: none; + font-size: .9em; + + li { + display: inline-block; + + a { + display: block; + padding: 5px 10px; + z-index: 100; + border: 1px solid transparent; + + &:hover { + border-color: #eee; + border-radius: 5px; + } + + &.active:hover { + border-color: transparent; + } + } + } + } + + a { + text-decoration: none; + color: #aaa; + + &:hover { + color: #222; + } + + + } + + pre { + margin: 0 0 20px 0; + } +} + +.code-viewer a.active, .code-viewer a.active:hover, .right-code .code-viewer a.active:hover { + color: #1EAEDB; +} + + +.right-code .code-viewer a:hover { + color: #fff; +} + +@media (max-width: 1000px) { + .right-code { + float: none; + width: 100%; + background: #232323; + padding-top: 20px; + padding-bottom: 20px; + } + + .left-docs { + float: none; + width: 100%; + } + + .doc-content { + background: #fff; + padding-bottom: 0; + border-image: none; + -moz-border-image: none; + -webkit-border-image: none; + border-color: #eee; + } +} + +header { + max-height: 100vh; + position: fixed; + top: 0; + left: 0; + right: 0; + overflow-x: hidden; + z-index: 1; + background-color: $nav-background-color; + + h1 { + height: $nav-header-height; + box-sizing: border-box; + background-color: $brand-colour; + color: #fff; + margin: 0; + font-size: 1.7rem; + line-height: 0.8; + letter-spacing: 0; + font-weight: 600; + text-indent: 0; + @include display-flex(); + @include flex-direction(row); + @include align-items(center); + border-bottom: 1px solid rgba(0, 0, 0, 0.075); + + img { + height: 26px; + margin: 0 18px; + } + } + + .open-nav { + width: 25px; + height: 25px; + margin: 0 0 0 18px; + background-image: url($base-url + '/images/menu.svg'); + background-color: transparent; + background-repeat: no-repeat; + background-size: 100%; + border: 0; + position: relative; + border-radius: 2px; + cursor: pointer; + + &:focus { + outline: none; + background-color: rgba(0, 0, 0, 0.05); + } + + &:hover { + background-color: rgba(0, 0, 0, 0.1); + } + } + + @media (min-width: $mobile-break) { + background-color: transparent; + width: $nav-width; + right: auto; + bottom: auto; + + .copyright { + display: block; + } + + .open-nav { + display: none; + } + + h1 { + box-shadow: inset -10px 0 10px -10px rgba(0, 0, 0, 0.1); + } + } +} + +#search-input { + -webkit-appearance: none; + + display: block; + margin: 0; + padding: 10px 20px; + width: 100%; + box-sizing: border-box; + + border: 0; + border-bottom: 1px solid rgba(0, 0, 0, 0.075); + + font-size: 1.5rem; + font-weight: 600; + line-height: 1.8; + + &:focus { + outline: none; + border-left: 5px solid $brand-colour; + padding-left: 15px; + } +} + +.search-page { + max-width: 800px; + margin: 0 0 0 50px; + padding: 50px 20px 0 20px; +} + +#search-results { + margin: 0; + padding: 0; + + li { + list-style: none; + margin: 0; + padding: 0; + + h4 { + font-size: 2rem; + } + + p { + line-height: 1.5; + } + } +} + +.copyright { + text-align: center; + font-size: .6em; + margin: 30px 0 0 0; + display: none; +} diff --git a/docs/_sass/_mixins.scss b/docs/_sass/_mixins.scss new file mode 100644 index 00000000..e60b2361 --- /dev/null +++ b/docs/_sass/_mixins.scss @@ -0,0 +1,34 @@ +@mixin flex-direction($values) { + -webkit-flex-direction: $values; + flex-direction: $values; +} + +@mixin flex-flow($values) { + -webkit-flex-flow: $values; + flex-flow: $values; +} + +@mixin align-items($values) { + -webkit-align-items: $values; + align-items: $values; +} + +@mixin justify-content($values) { + -webkit-justify-content: $values; + justify-content: $values; +} + +@mixin flex($values) { + -webkit-flex: $values; + flex: $values; +} + +@mixin display-flex() { + display: -webkit-flex; + display: flex; +} + +@mixin display-inline-flex() { + display: -webkit-inline-flex; + display: inline-flex; +} diff --git a/docs/_sass/_monaki.scss b/docs/_sass/_monaki.scss new file mode 100644 index 00000000..6cae0d82 --- /dev/null +++ b/docs/_sass/_monaki.scss @@ -0,0 +1,64 @@ +.right-code code .hll { background-color: #49483e } +.right-code code .c { color: #75715e } /* Comment */ +.right-code code .err { color: #960050; background-color: #1e0010 } /* Error */ +.right-code code .k { color: #66d9ef } /* Keyword */ +.right-code code .l { color: #ae81ff } /* Literal */ +.right-code code .n { color: #f8f8f2 } /* Name */ +.right-code code .o { color: #f92672 } /* Operator */ +.right-code code .p { color: #f8f8f2 } /* Punctuation */ +.right-code code .cm { color: #75715e } /* Comment.Multiline */ +.right-code code .cp { color: #75715e } /* Comment.Preproc */ +.right-code code .c1 { color: #75715e } /* Comment.Single */ +.right-code code .cs { color: #75715e } /* Comment.Special */ +.right-code code .ge { font-style: italic } /* Generic.Emph */ +.right-code code .gs { font-weight: bold } /* Generic.Strong */ +.right-code code .kc { color: #66d9ef } /* Keyword.Constant */ +.right-code code .kd { color: #66d9ef } /* Keyword.Declaration */ +.right-code code .kn { color: #f92672 } /* Keyword.Namespace */ +.right-code code .kp { color: #66d9ef } /* Keyword.Pseudo */ +.right-code code .kr { color: #66d9ef } /* Keyword.Reserved */ +.right-code code .kt { color: #66d9ef } /* Keyword.Type */ +.right-code code .ld { color: #e6db74 } /* Literal.Date */ +.right-code code .m { color: #ae81ff } /* Literal.Number */ +.right-code code .s { color: #e6db74 } /* Literal.String */ +.right-code code .na { color: #a6e22e } /* Name.Attribute */ +.right-code code .nb { color: #f8f8f2 } /* Name.Builtin */ +.right-code code .nc { color: #a6e22e } /* Name.Class */ +.right-code code .no { color: #66d9ef } /* Name.Constant */ +.right-code code .nd { color: #a6e22e } /* Name.Decorator */ +.right-code code .ni { color: #f8f8f2 } /* Name.Entity */ +.right-code code .ne { color: #a6e22e } /* Name.Exception */ +.right-code code .nf { color: #a6e22e } /* Name.Function */ +.right-code code .nl { color: #f8f8f2 } /* Name.Label */ +.right-code code .nn { color: #f8f8f2 } /* Name.Namespace */ +.right-code code .nx { color: #a6e22e } /* Name.Other */ +.right-code code .py { color: #f8f8f2 } /* Name.Property */ +.right-code code .nt { color: #f92672 } /* Name.Tag */ +.right-code code .nv { color: #f8f8f2 } /* Name.Variable */ +.right-code code .ow { color: #f92672 } /* Operator.Word */ +.right-code code .w { color: #f8f8f2 } /* Text.Whitespace */ +.right-code code .mf { color: #ae81ff } /* Literal.Number.Float */ +.right-code code .mh { color: #ae81ff } /* Literal.Number.Hex */ +.right-code code .mi { color: #ae81ff } /* Literal.Number.Integer */ +.right-code code .mo { color: #ae81ff } /* Literal.Number.Oct */ +.right-code code .sb { color: #e6db74 } /* Literal.String.Backtick */ +.right-code code .sc { color: #e6db74 } /* Literal.String.Char */ +.right-code code .sd { color: #e6db74 } /* Literal.String.Doc */ +.right-code code .s2 { color: #e6db74 } /* Literal.String.Double */ +.right-code code .se { color: #ae81ff } /* Literal.String.Escape */ +.right-code code .sh { color: #e6db74 } /* Literal.String.Heredoc */ +.right-code code .si { color: #e6db74 } /* Literal.String.Interpol */ +.right-code code .sx { color: #e6db74 } /* Literal.String.Other */ +.right-code code .sr { color: #e6db74 } /* Literal.String.Regex */ +.right-code code .s1 { color: #e6db74 } /* Literal.String.Single */ +.right-code code .ss { color: #e6db74 } /* Literal.String.Symbol */ +.right-code code .bp { color: #f8f8f2 } /* Name.Builtin.Pseudo */ +.right-code code .vc { color: #f8f8f2 } /* Name.Variable.Class */ +.right-code code .vg { color: #f8f8f2 } /* Name.Variable.Global */ +.right-code code .vi { color: #f8f8f2 } /* Name.Variable.Instance */ +.right-code code .il { color: #ae81ff } /* Literal.Number.Integer.Long */ + +.right-code code .gh { } /* Generic Heading & Diff Header */ +.right-code code .gu { color: #75715e; } /* Generic.Subheading & Diff Unified/Comment? */ +.right-code code .gd { color: #f92672; } /* Generic.Deleted & Diff Deleted */ +.right-code code .gi { color: #a6e22e; } /* Generic.Inserted & Diff Inserted */ diff --git a/docs/_sass/cloudcannon.scss b/docs/_sass/cloudcannon.scss new file mode 100644 index 00000000..ee84b360 --- /dev/null +++ b/docs/_sass/cloudcannon.scss @@ -0,0 +1,26 @@ +.editor-link { + display: none; + float: right; + margin-top: 0; + border: 0; + border-radius: 2px; + box-sizing: border-box; + font-size: 2rem; + text-decoration: none; + padding: 10px 15px; + margin: 0; + font-size: 18px; + cursor: pointer; + background-color: #f7e064; + color: #333; + box-shadow: 1px 1px 5px 0 rgba(0, 0, 0, 0.2); + + &:hover { + background-color: #f4d525; + color: #333; + } +} + +.cms-editor-active .editor-link { + display: inline-block; +} \ No newline at end of file diff --git a/docs/apple-touch-icon.png b/docs/apple-touch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..815caab2f2a8384f68ab7ece2bcd16217aabe47c GIT binary patch literal 1058 zcmeAS@N?(olHy`uVBq!ia0vp^TR@nD8Ax&oe*=;X#sNMdu0UE@UV$X^!A?F3s7~)y?r}rj)F+*!`@~YmxJHy zZ#~=R8U49A+avb7TKtT&&kT;uv#I!~wWyo|$NpN&~-K6@=t$86OFVlx_}a-Y3A_qlzwvO|-t zRB(IVtD1v8SEKbyb|f5ob?NvVw==WfdVjrlc+Yp!|9^$lziYh6PFrVZ@oPucvsY7R zT|b?+?%PbU&sWBHD6u&+wNrK{v-NozHH3AXL5|E zy_v1~VDjNtcZwI7zn;7Id4TnXhph88q+hwsl8xu}+Ag>ER>zTRtHbjXYFU|Ec7^QQ zF!`aS{cO90YW7n+>kM}uKe*v&wSLO^)4KBFlJ7&$>Mi>)|KRgShgKiHd4a{I-RQ;a zzpJbs%rCh0pyrZ;(%uCp7hhE0yCZYQ)$+)5en0+X9TvXf@wRqV^Y+MZ6`Mas-Vpr7 zz|JYq-*u^ZDr<_fvEY=F`-|*O*d1Wz`nk8)rshsl-;!F9fatmDNo+5Q_=&;5loC-Slb&HPRomDF@9f*vZ#?p6mlf{SHwMByS*R7EL z!4x`8cu&2~X}&y#CA*j2oE69PetGul}5Q0+Cizz`K%{`_WuoQ zQ26l6;H>$Dv`FgeciP%Xb?vVfFU*lJNtg} zFZGvIccta_*KBRP`In>kgqg|dhC_aW4JP3=b=#$bqWwQld^_z(UGv-U-MXe6t7aar z^s`%acTR-D?nX|HB=+=0F4r9rUj$uF-DtmgrEu&HCBNN!-8bF-w{nlP0Kcbh`+wt# zv)}qoR^O~!zWuR|>8;u7*P~*8di?d+qV5mOUeo_DoynZm`C=vO6i}}BboFyt=akR{ E07OLQ@&Et; literal 0 HcmV?d00001 diff --git a/docs/css/editor.css b/docs/css/editor.css new file mode 100644 index 00000000..79e93da4 --- /dev/null +++ b/docs/css/editor.css @@ -0,0 +1,24 @@ +.error, .warning, .info, .success { + border-left: 5px solid #FD0; + padding: 10px 15px; + margin-left: -20px; + margin-right: -15px; + background-color: #FAFAFA; + border-radius: 2px; +} + +p.warning { + border-color: #ffc107; +} + +p.info { + border-color: #56ADEC; +} + +p.error { + border-color: #F20; +} + +p.success { + border-color: #6c0; +} \ No newline at end of file diff --git a/docs/css/style.scss b/docs/css/style.scss new file mode 100644 index 00000000..e8f30d35 --- /dev/null +++ b/docs/css/style.scss @@ -0,0 +1,26 @@ +--- +layout: null +sitemap: false +--- + +$brand-colour: #35d69b; + +$nav-header-height: 60px; +$nav-background-color: #f5f5f5; +$nav-width: 210px; + +$space: 20px; + +$mobile-break: 700px; + +{% if site.baseurl %} + $base-url: {{ site.baseurl }}; +{% else %} + $base-url: ''; +{% endif %} + +@import "mixins"; +@import "main"; +@import "borland"; +@import "monaki"; +@import "cloudcannon"; diff --git a/docs/favicon.png b/docs/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..9479bd34367ad33237d4b0d3b3e8324c9f2b865d GIT binary patch literal 300 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 + + + \ No newline at end of file diff --git a/docs/images/logo.svg b/docs/images/logo.svg new file mode 100644 index 00000000..1330422c --- /dev/null +++ b/docs/images/logo.svg @@ -0,0 +1,11 @@ + + + + + +aviator + diff --git a/docs/images/menu.svg b/docs/images/menu.svg new file mode 100644 index 00000000..f468dc47 --- /dev/null +++ b/docs/images/menu.svg @@ -0,0 +1,4 @@ + + + + diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 00000000..0f96537c --- /dev/null +++ b/docs/index.html @@ -0,0 +1,50 @@ +--- +title: API Docs +--- +{% assign sorted_collections = site.collections | sort: "position" %} +{% for collection in sorted_collections %} + {% assign sorted_docs = collection.docs | sort: "position" %} + {% for doc in sorted_docs %} + + {% endfor %} +{% endfor %} diff --git a/docs/js/lunr.min.js b/docs/js/lunr.min.js new file mode 100644 index 00000000..4fd086e7 --- /dev/null +++ b/docs/js/lunr.min.js @@ -0,0 +1,6 @@ +/** + * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 0.7.1 + * Copyright (C) 2016 Oliver Nightingale + * @license MIT + */ +!function(){var t=function(e){var n=new t.Index;return n.pipeline.add(t.trimmer,t.stopWordFilter,t.stemmer),e&&e.call(n,n),n};t.version="0.7.1",t.utils={},t.utils.warn=function(t){return function(e){t.console&&console.warn&&console.warn(e)}}(this),t.utils.asString=function(t){return void 0===t||null===t?"":t.toString()},t.EventEmitter=function(){this.events={}},t.EventEmitter.prototype.addListener=function(){var t=Array.prototype.slice.call(arguments),e=t.pop(),n=t;if("function"!=typeof e)throw new TypeError("last argument must be a function");n.forEach(function(t){this.hasHandler(t)||(this.events[t]=[]),this.events[t].push(e)},this)},t.EventEmitter.prototype.removeListener=function(t,e){if(this.hasHandler(t)){var n=this.events[t].indexOf(e);this.events[t].splice(n,1),this.events[t].length||delete this.events[t]}},t.EventEmitter.prototype.emit=function(t){if(this.hasHandler(t)){var e=Array.prototype.slice.call(arguments,1);this.events[t].forEach(function(t){t.apply(void 0,e)})}},t.EventEmitter.prototype.hasHandler=function(t){return t in this.events},t.tokenizer=function(e){return arguments.length&&null!=e&&void 0!=e?Array.isArray(e)?e.map(function(e){return t.utils.asString(e).toLowerCase()}):e.toString().trim().toLowerCase().split(t.tokenizer.seperator):[]},t.tokenizer.seperator=/[\s\-]+/,t.tokenizer.load=function(t){var e=this.registeredFunctions[t];if(!e)throw new Error("Cannot load un-registered function: "+t);return e},t.tokenizer.label="default",t.tokenizer.registeredFunctions={"default":t.tokenizer},t.tokenizer.registerFunction=function(e,n){n in this.registeredFunctions&&t.utils.warn("Overwriting existing tokenizer: "+n),e.label=n,this.registeredFunctions[n]=e},t.Pipeline=function(){this._stack=[]},t.Pipeline.registeredFunctions={},t.Pipeline.registerFunction=function(e,n){n in this.registeredFunctions&&t.utils.warn("Overwriting existing registered function: "+n),e.label=n,t.Pipeline.registeredFunctions[e.label]=e},t.Pipeline.warnIfFunctionNotRegistered=function(e){var n=e.label&&e.label in this.registeredFunctions;n||t.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},t.Pipeline.load=function(e){var n=new t.Pipeline;return e.forEach(function(e){var i=t.Pipeline.registeredFunctions[e];if(!i)throw new Error("Cannot load un-registered function: "+e);n.add(i)}),n},t.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach(function(e){t.Pipeline.warnIfFunctionNotRegistered(e),this._stack.push(e)},this)},t.Pipeline.prototype.after=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._stack.indexOf(e);if(-1==i)throw new Error("Cannot find existingFn");i+=1,this._stack.splice(i,0,n)},t.Pipeline.prototype.before=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._stack.indexOf(e);if(-1==i)throw new Error("Cannot find existingFn");this._stack.splice(i,0,n)},t.Pipeline.prototype.remove=function(t){var e=this._stack.indexOf(t);-1!=e&&this._stack.splice(e,1)},t.Pipeline.prototype.run=function(t){for(var e=[],n=t.length,i=this._stack.length,r=0;n>r;r++){for(var o=t[r],s=0;i>s&&(o=this._stack[s](o,r,t),void 0!==o&&""!==o);s++);void 0!==o&&""!==o&&e.push(o)}return e},t.Pipeline.prototype.reset=function(){this._stack=[]},t.Pipeline.prototype.toJSON=function(){return this._stack.map(function(e){return t.Pipeline.warnIfFunctionNotRegistered(e),e.label})},t.Vector=function(){this._magnitude=null,this.list=void 0,this.length=0},t.Vector.Node=function(t,e,n){this.idx=t,this.val=e,this.next=n},t.Vector.prototype.insert=function(e,n){this._magnitude=void 0;var i=this.list;if(!i)return this.list=new t.Vector.Node(e,n,i),this.length++;if(en.idx?n=n.next:(i+=e.val*n.val,e=e.next,n=n.next);return i},t.Vector.prototype.similarity=function(t){return this.dot(t)/(this.magnitude()*t.magnitude())},t.SortedSet=function(){this.length=0,this.elements=[]},t.SortedSet.load=function(t){var e=new this;return e.elements=t,e.length=t.length,e},t.SortedSet.prototype.add=function(){var t,e;for(t=0;t1;){if(o===t)return r;t>o&&(e=r),o>t&&(n=r),i=n-e,r=e+Math.floor(i/2),o=this.elements[r]}return o===t?r:-1},t.SortedSet.prototype.locationFor=function(t){for(var e=0,n=this.elements.length,i=n-e,r=e+Math.floor(i/2),o=this.elements[r];i>1;)t>o&&(e=r),o>t&&(n=r),i=n-e,r=e+Math.floor(i/2),o=this.elements[r];return o>t?r:t>o?r+1:void 0},t.SortedSet.prototype.intersect=function(e){for(var n=new t.SortedSet,i=0,r=0,o=this.length,s=e.length,a=this.elements,h=e.elements;;){if(i>o-1||r>s-1)break;a[i]!==h[r]?a[i]h[r]&&r++:(n.add(a[i]),i++,r++)}return n},t.SortedSet.prototype.clone=function(){var e=new t.SortedSet;return e.elements=this.toArray(),e.length=e.elements.length,e},t.SortedSet.prototype.union=function(t){var e,n,i;this.length>=t.length?(e=this,n=t):(e=t,n=this),i=e.clone();for(var r=0,o=n.toArray();rp;p++)c[p]===a&&d++;h+=d/f*l.boost}}this.tokenStore.add(a,{ref:o,tf:h})}n&&this.eventEmitter.emit("add",e,this)},t.Index.prototype.remove=function(t,e){var n=t[this._ref],e=void 0===e?!0:e;if(this.documentStore.has(n)){var i=this.documentStore.get(n);this.documentStore.remove(n),i.forEach(function(t){this.tokenStore.remove(t,n)},this),e&&this.eventEmitter.emit("remove",t,this)}},t.Index.prototype.update=function(t,e){var e=void 0===e?!0:e;this.remove(t,!1),this.add(t,!1),e&&this.eventEmitter.emit("update",t,this)},t.Index.prototype.idf=function(t){var e="@"+t;if(Object.prototype.hasOwnProperty.call(this._idfCache,e))return this._idfCache[e];var n=this.tokenStore.count(t),i=1;return n>0&&(i=1+Math.log(this.documentStore.length/n)),this._idfCache[e]=i},t.Index.prototype.search=function(e){var n=this.pipeline.run(this.tokenizerFn(e)),i=new t.Vector,r=[],o=this._fields.reduce(function(t,e){return t+e.boost},0),s=n.some(function(t){return this.tokenStore.has(t)},this);if(!s)return[];n.forEach(function(e,n,s){var a=1/s.length*this._fields.length*o,h=this,u=this.tokenStore.expand(e).reduce(function(n,r){var o=h.corpusTokens.indexOf(r),s=h.idf(r),u=1,l=new t.SortedSet;if(r!==e){var c=Math.max(3,r.length-e.length);u=1/Math.log(c)}o>-1&&i.insert(o,a*s*u);for(var f=h.tokenStore.get(r),d=Object.keys(f),p=d.length,v=0;p>v;v++)l.add(f[d[v]].ref);return n.union(l)},new t.SortedSet);r.push(u)},this);var a=r.reduce(function(t,e){return t.intersect(e)});return a.map(function(t){return{ref:t,score:i.similarity(this.documentVector(t))}},this).sort(function(t,e){return e.score-t.score})},t.Index.prototype.documentVector=function(e){for(var n=this.documentStore.get(e),i=n.length,r=new t.Vector,o=0;i>o;o++){var s=n.elements[o],a=this.tokenStore.get(s)[e].tf,h=this.idf(s);r.insert(this.corpusTokens.indexOf(s),a*h)}return r},t.Index.prototype.toJSON=function(){return{version:t.version,fields:this._fields,ref:this._ref,tokenizer:this.tokenizerFn.label,documentStore:this.documentStore.toJSON(),tokenStore:this.tokenStore.toJSON(),corpusTokens:this.corpusTokens.toJSON(),pipeline:this.pipeline.toJSON()}},t.Index.prototype.use=function(t){var e=Array.prototype.slice.call(arguments,1);e.unshift(this),t.apply(this,e)},t.Store=function(){this.store={},this.length=0},t.Store.load=function(e){var n=new this;return n.length=e.length,n.store=Object.keys(e.store).reduce(function(n,i){return n[i]=t.SortedSet.load(e.store[i]),n},{}),n},t.Store.prototype.set=function(t,e){this.has(t)||this.length++,this.store[t]=e},t.Store.prototype.get=function(t){return this.store[t]},t.Store.prototype.has=function(t){return t in this.store},t.Store.prototype.remove=function(t){this.has(t)&&(delete this.store[t],this.length--)},t.Store.prototype.toJSON=function(){return{store:this.store,length:this.length}},t.stemmer=function(){var t={ational:"ate",tional:"tion",enci:"ence",anci:"ance",izer:"ize",bli:"ble",alli:"al",entli:"ent",eli:"e",ousli:"ous",ization:"ize",ation:"ate",ator:"ate",alism:"al",iveness:"ive",fulness:"ful",ousness:"ous",aliti:"al",iviti:"ive",biliti:"ble",logi:"log"},e={icate:"ic",ative:"",alize:"al",iciti:"ic",ical:"ic",ful:"",ness:""},n="[^aeiou]",i="[aeiouy]",r=n+"[^aeiouy]*",o=i+"[aeiou]*",s="^("+r+")?"+o+r,a="^("+r+")?"+o+r+"("+o+")?$",h="^("+r+")?"+o+r+o+r,u="^("+r+")?"+i,l=new RegExp(s),c=new RegExp(h),f=new RegExp(a),d=new RegExp(u),p=/^(.+?)(ss|i)es$/,v=/^(.+?)([^s])s$/,g=/^(.+?)eed$/,m=/^(.+?)(ed|ing)$/,y=/.$/,S=/(at|bl|iz)$/,w=new RegExp("([^aeiouylsz])\\1$"),k=new RegExp("^"+r+i+"[^aeiouwxy]$"),x=/^(.+?[^aeiou])y$/,b=/^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/,E=/^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/,F=/^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/,_=/^(.+?)(s|t)(ion)$/,z=/^(.+?)e$/,O=/ll$/,P=new RegExp("^"+r+i+"[^aeiouwxy]$"),T=function(n){var i,r,o,s,a,h,u;if(n.length<3)return n;if(o=n.substr(0,1),"y"==o&&(n=o.toUpperCase()+n.substr(1)),s=p,a=v,s.test(n)?n=n.replace(s,"$1$2"):a.test(n)&&(n=n.replace(a,"$1$2")),s=g,a=m,s.test(n)){var T=s.exec(n);s=l,s.test(T[1])&&(s=y,n=n.replace(s,""))}else if(a.test(n)){var T=a.exec(n);i=T[1],a=d,a.test(i)&&(n=i,a=S,h=w,u=k,a.test(n)?n+="e":h.test(n)?(s=y,n=n.replace(s,"")):u.test(n)&&(n+="e"))}if(s=x,s.test(n)){var T=s.exec(n);i=T[1],n=i+"i"}if(s=b,s.test(n)){var T=s.exec(n);i=T[1],r=T[2],s=l,s.test(i)&&(n=i+t[r])}if(s=E,s.test(n)){var T=s.exec(n);i=T[1],r=T[2],s=l,s.test(i)&&(n=i+e[r])}if(s=F,a=_,s.test(n)){var T=s.exec(n);i=T[1],s=c,s.test(i)&&(n=i)}else if(a.test(n)){var T=a.exec(n);i=T[1]+T[2],a=c,a.test(i)&&(n=i)}if(s=z,s.test(n)){var T=s.exec(n);i=T[1],s=c,a=f,h=P,(s.test(i)||a.test(i)&&!h.test(i))&&(n=i)}return s=O,a=c,s.test(n)&&a.test(n)&&(s=y,n=n.replace(s,"")),"y"==o&&(n=o.toLowerCase()+n.substr(1)),n};return T}(),t.Pipeline.registerFunction(t.stemmer,"stemmer"),t.generateStopWordFilter=function(t){var e=t.reduce(function(t,e){return t[e]=e,t},{});return function(t){return t&&e[t]!==t?t:void 0}},t.stopWordFilter=t.generateStopWordFilter(["a","able","about","across","after","all","almost","also","am","among","an","and","any","are","as","at","be","because","been","but","by","can","cannot","could","dear","did","do","does","either","else","ever","every","for","from","get","got","had","has","have","he","her","hers","him","his","how","however","i","if","in","into","is","it","its","just","least","let","like","likely","may","me","might","most","must","my","neither","no","nor","not","of","off","often","on","only","or","other","our","own","rather","said","say","says","she","should","since","so","some","than","that","the","their","them","then","there","these","they","this","tis","to","too","twas","us","wants","was","we","were","what","when","where","which","while","who","whom","why","will","with","would","yet","you","your"]),t.Pipeline.registerFunction(t.stopWordFilter,"stopWordFilter"),t.trimmer=function(t){return t.replace(/^\W+/,"").replace(/\W+$/,"")},t.Pipeline.registerFunction(t.trimmer,"trimmer"),t.TokenStore=function(){this.root={docs:{}},this.length=0},t.TokenStore.load=function(t){var e=new this;return e.root=t.root,e.length=t.length,e},t.TokenStore.prototype.add=function(t,e,n){var n=n||this.root,i=t.charAt(0),r=t.slice(1);return i in n||(n[i]={docs:{}}),0===r.length?(n[i].docs[e.ref]=e,void(this.length+=1)):this.add(r,e,n[i])},t.TokenStore.prototype.has=function(t){if(!t)return!1;for(var e=this.root,n=0;n div.highlighter-rouge:first-of-type").each(function(i) { + + var $this = $(this).before("
    "), + $languages = $this.prev(), + $notFirst = $this.nextUntil(":not(div.highlighter-rouge)"), + $all = $this.add($notFirst); + + $all.add($languages).wrapAll("
    "); + + + listLanguages($all, $languages); + + $this.css('display', 'block'); + $notFirst.css('display', 'none'); + + $languages.find('a').first().addClass('active'); + + $languages.find('a').click(function() { + $all.css('display', 'none'); + $all.eq($(this).parent().index()).css('display', 'block'); + + $languages.find('a').removeClass('active'); + $(this).addClass('active'); + return false; + }); + + if ($languages.children().length === 0) { + $languages.remove(); + } + }); + + function listLanguages($el, $insert) { + $el.each(function(i) { + var title = $(this).attr('title'); + if (title) { + $insert.append("
  • " + title + "
  • "); + } + }); + } + + var href = $('.sidebar a').first().attr("href"); + + if (href !== undefined && href.charAt(0) === "#") { + setActiveSidebarLink(); + + $(window).on("scroll", function(evt) { + setActiveSidebarLink(); + }); + } + + function setActiveSidebarLink() { + $('.sidebar a').removeClass('active'); + var $closest = getClosestHeader(); + $closest.addClass('active'); + document.title = $closest.text(); + + } +}); + +function getClosestHeader() { + var $links = $('.sidebar a'), + top = window.scrollY, + $last = $links.first(); + + if (top < 300) { + return $last; + } + + if (top + window.innerHeight >= $(".main").height()) { + return $links.last(); + } + + for (var i = 0; i < $links.length; i++) { + var $link = $links.eq(i), + href = $link.attr("href"); + + if (href !== undefined && href.charAt(0) === "#" && href.length > 1) { + var $anchor = $(href); + + if ($anchor.length > 0) { + var offset = $anchor.offset(); + + if (top < offset.top - 300) { + return $last; + } + + $last = $link; + } + } + } + return $last; +} diff --git a/docs/js/search.js b/docs/js/search.js new file mode 100644 index 00000000..2ab9bb74 --- /dev/null +++ b/docs/js/search.js @@ -0,0 +1,102 @@ +(function () { + function getQueryVariable(variable) { + var query = window.location.search.substring(1), + vars = query.split("&"); + + for (var i = 0; i < vars.length; i++) { + var pair = vars[i].split("="); + + if (pair[0] === variable) { + return decodeURIComponent(pair[1].replace(/\+/g, '%20')).trim(); + } + } + } + + function getPreview(query, content, previewLength) { + previewLength = previewLength || (content.length * 2); + + var parts = query.split(" "), + match = content.toLowerCase().indexOf(query.toLowerCase()), + matchLength = query.length, + preview; + + // Find a relevant location in content + for (var i = 0; i < parts.length; i++) { + if (match >= 0) { + break; + } + + match = content.toLowerCase().indexOf(parts[i].toLowerCase()); + matchLength = parts[i].length; + } + + // Create preview + if (match >= 0) { + var start = match - (previewLength / 2), + end = start > 0 ? match + matchLength + (previewLength / 2) : previewLength; + + preview = content.substring(start, end).trim(); + + if (start > 0) { + preview = "..." + preview; + } + + if (end < content.length) { + preview = preview + "..."; + } + + // Highlight query parts + preview = preview.replace(new RegExp("(" + parts.join("|") + ")", "gi"), "$1"); + } else { + // Use start of content if no match found + preview = content.substring(0, previewLength).trim() + (content.length > previewLength ? "..." : ""); + } + + return preview; + } + + function displaySearchResults(results, query) { + var searchResultsEl = document.getElementById("search-results"), + searchProcessEl = document.getElementById("search-process"); + + if (results.length) { + var resultsHTML = ""; + results.forEach(function (result) { + var item = window.data[result.ref], + contentPreview = getPreview(query, item.content, 170), + titlePreview = getPreview(query, item.title); + + resultsHTML += "
  • " + titlePreview + "

    " + contentPreview + "

  • "; + }); + + searchResultsEl.innerHTML = resultsHTML; + searchProcessEl.innerText = "Showing"; + } else { + searchResultsEl.style.display = "none"; + searchProcessEl.innerText = "No"; + } + } + + window.index = lunr(function () { + this.field("id"); + this.field("title", {boost: 10}); + this.field("category"); + this.field("url"); + this.field("content"); + }); + + var query = decodeURIComponent((getQueryVariable("q") || "").replace(/\+/g, "%20")), + searchQueryContainerEl = document.getElementById("search-query-container"), + searchQueryEl = document.getElementById("search-query"), + searchInputEl = document.getElementById("search-input"); + + searchInputEl.value = query; + searchQueryEl.innerText = query; + searchQueryContainerEl.style.display = "inline"; + + for (var key in window.data) { + window.index.add(window.data[key]); + } + + displaySearchResults(window.index.search(query), query); // Hand the results off to be displayed +})(); diff --git a/docs/robots.txt b/docs/robots.txt new file mode 100644 index 00000000..780b5a3d --- /dev/null +++ b/docs/robots.txt @@ -0,0 +1,6 @@ +--- +layout: null +sitemap: false +--- +User-agent: * +Sitemap: {{ site.url }}/sitemap.xml \ No newline at end of file diff --git a/docs/search.html b/docs/search.html new file mode 100644 index 00000000..59e55c82 --- /dev/null +++ b/docs/search.html @@ -0,0 +1,39 @@ +--- +title: Search +sitemap: false +permalink: /search/ +--- + +
    +

    Search Results

    + +

    Loading results

    +
      +
      + + + + diff --git a/docs/siteicon.png b/docs/siteicon.png new file mode 100644 index 0000000000000000000000000000000000000000..fed4b7deb8faf6ae194f44bf1a50c359343a3923 GIT binary patch literal 2631 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 literal 0 HcmV?d00001 diff --git a/docs/touch-icon.png b/docs/touch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..624d181cf367c34e74e15e4a24c5f168135dfa55 GIT binary patch literal 9648 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 literal 0 HcmV?d00001 diff --git a/old_docs/_config.yml b/old_docs/_config.yml new file mode 100644 index 00000000..fd8fd07b --- /dev/null +++ b/old_docs/_config.yml @@ -0,0 +1,4 @@ +markdown: kramdown +theme: jekyll-theme-dinky +title: fetch-mock +description: Mock http requests made using fetch diff --git a/docs/api-basic.md b/old_docs/api-basic.md similarity index 100% rename from docs/api-basic.md rename to old_docs/api-basic.md diff --git a/docs/api.md b/old_docs/api.md similarity index 100% rename from docs/api.md rename to old_docs/api.md diff --git a/docs/basic-usage.md b/old_docs/basic-usage.md similarity index 100% rename from docs/basic-usage.md rename to old_docs/basic-usage.md diff --git a/docs/examples.md b/old_docs/examples.md similarity index 100% rename from docs/examples.md rename to old_docs/examples.md diff --git a/docs/index.md b/old_docs/index.md similarity index 100% rename from docs/index.md rename to old_docs/index.md diff --git a/docs/installation.md b/old_docs/installation.md similarity index 100% rename from docs/installation.md rename to old_docs/installation.md diff --git a/docs/quickstart.md b/old_docs/quickstart.md similarity index 100% rename from docs/quickstart.md rename to old_docs/quickstart.md diff --git a/docs/troubleshooting.md b/old_docs/troubleshooting.md similarity index 100% rename from docs/troubleshooting.md rename to old_docs/troubleshooting.md diff --git a/docs/v5-v6-upgrade.md b/old_docs/v5-v6-upgrade.md similarity index 100% rename from docs/v5-v6-upgrade.md rename to old_docs/v5-v6-upgrade.md diff --git a/docs/v5/_config.yml b/old_docs/v5/_config.yml similarity index 100% rename from docs/v5/_config.yml rename to old_docs/v5/_config.yml diff --git a/docs/v5/api.md b/old_docs/v5/api.md similarity index 100% rename from docs/v5/api.md rename to old_docs/v5/api.md diff --git a/docs/v5/examples.md b/old_docs/v5/examples.md similarity index 100% rename from docs/v5/examples.md rename to old_docs/v5/examples.md diff --git a/docs/v5/index.md b/old_docs/v5/index.md similarity index 100% rename from docs/v5/index.md rename to old_docs/v5/index.md diff --git a/docs/v5/installation.md b/old_docs/v5/installation.md similarity index 100% rename from docs/v5/installation.md rename to old_docs/v5/installation.md diff --git a/docs/v5/quickstart.md b/old_docs/v5/quickstart.md similarity index 100% rename from docs/v5/quickstart.md rename to old_docs/v5/quickstart.md diff --git a/docs/v5/troubleshooting.md b/old_docs/v5/troubleshooting.md similarity index 100% rename from docs/v5/troubleshooting.md rename to old_docs/v5/troubleshooting.md diff --git a/docs/v5/v4-v5-upgrade.md b/old_docs/v5/v4-v5-upgrade.md similarity index 100% rename from docs/v5/v4-v5-upgrade.md rename to old_docs/v5/v4-v5-upgrade.md diff --git a/docs/v6-v7-upgrade.md b/old_docs/v6-v7-upgrade.md similarity index 100% rename from docs/v6-v7-upgrade.md rename to old_docs/v6-v7-upgrade.md diff --git a/docs/v6/_config.yml b/old_docs/v6/_config.yml similarity index 100% rename from docs/v6/_config.yml rename to old_docs/v6/_config.yml diff --git a/docs/v6/api.md b/old_docs/v6/api.md similarity index 100% rename from docs/v6/api.md rename to old_docs/v6/api.md diff --git a/docs/v6/examples.md b/old_docs/v6/examples.md similarity index 100% rename from docs/v6/examples.md rename to old_docs/v6/examples.md diff --git a/docs/v6/index.md b/old_docs/v6/index.md similarity index 100% rename from docs/v6/index.md rename to old_docs/v6/index.md diff --git a/docs/v6/installation.md b/old_docs/v6/installation.md similarity index 100% rename from docs/v6/installation.md rename to old_docs/v6/installation.md diff --git a/docs/v6/quickstart.md b/old_docs/v6/quickstart.md similarity index 100% rename from docs/v6/quickstart.md rename to old_docs/v6/quickstart.md diff --git a/docs/v6/troubleshooting.md b/old_docs/v6/troubleshooting.md similarity index 100% rename from docs/v6/troubleshooting.md rename to old_docs/v6/troubleshooting.md diff --git a/docs/v6/v5-v6-upgrade.md b/old_docs/v6/v5-v6-upgrade.md similarity index 100% rename from docs/v6/v5-v6-upgrade.md rename to old_docs/v6/v5-v6-upgrade.md From b902fb472b85c694c99421f8f0ffebf6e0a33f72 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Sun, 26 Aug 2018 18:55:10 +0100 Subject: [PATCH 007/127] changed title etc --- docs/_config.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/_config.yml b/docs/_config.yml index a13938b7..49e4648f 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,9 +1,9 @@ # ---- # Site -title: Aviator -description: Jekyll template for API documentation. -url: https://example.com +title: fetch-mock +description: Mock http requets using fetch +url: https://www.wheresrhys.co.uk/fetch-mock-docs-workspace google_analytics_key: permalink: pretty From cd6bf8b071649d5ab549b2491c3f4cd78b67d7ae Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Sun, 26 Aug 2018 18:55:57 +0100 Subject: [PATCH 008/127] moved Gemfile --- docs/Gemfile => Gemfile | 0 docs/Gemfile.lock => Gemfile.lock | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename docs/Gemfile => Gemfile (100%) rename docs/Gemfile.lock => Gemfile.lock (100%) diff --git a/docs/Gemfile b/Gemfile similarity index 100% rename from docs/Gemfile rename to Gemfile diff --git a/docs/Gemfile.lock b/Gemfile.lock similarity index 100% rename from docs/Gemfile.lock rename to Gemfile.lock From 08a566b0d1c0927888896ec4f10a55faec972135 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Sun, 26 Aug 2018 19:05:58 +0100 Subject: [PATCH 009/127] documentation -> general --- docs/_config.yml | 14 +++---------- .../{_documentation => _general}/_defaults.md | 0 .../authentication.md | 0 docs/{_documentation => _general}/errors.md | 0 .../getting_started.md | 4 ++-- docs/_general/introduction.md | 21 +++++++++++++++++++ 6 files changed, 26 insertions(+), 13 deletions(-) rename docs/{_documentation => _general}/_defaults.md (100%) rename docs/{_documentation => _general}/authentication.md (100%) rename docs/{_documentation => _general}/errors.md (100%) rename docs/{_documentation => _general}/getting_started.md (97%) create mode 100644 docs/_general/introduction.md diff --git a/docs/_config.yml b/docs/_config.yml index 49e4648f..40acc196 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -14,10 +14,10 @@ timezone: Etc/UTC collections: documentation: - title: Documentation + title: General documentation position: 1 api: - title: APIs + title: API documentation position: 2 plugins: - jekyll-sitemap @@ -35,7 +35,7 @@ defaults: layout: default - scope: - type: "documentation" + type: "general" values: _hide_content: true - @@ -55,15 +55,7 @@ types: languages: bash: Bash - c: C - css: CSS - html: HTML - java: Java javascript: JavaScript - json: JSON - php: PHP - python: Python - ruby: Ruby _options: content_markdown: diff --git a/docs/_documentation/_defaults.md b/docs/_general/_defaults.md similarity index 100% rename from docs/_documentation/_defaults.md rename to docs/_general/_defaults.md diff --git a/docs/_documentation/authentication.md b/docs/_general/authentication.md similarity index 100% rename from docs/_documentation/authentication.md rename to docs/_general/authentication.md diff --git a/docs/_documentation/errors.md b/docs/_general/errors.md similarity index 100% rename from docs/_documentation/errors.md rename to docs/_general/errors.md diff --git a/docs/_documentation/getting_started.md b/docs/_general/getting_started.md similarity index 97% rename from docs/_documentation/getting_started.md rename to docs/_general/getting_started.md index c9d41c77..8d7d9900 100644 --- a/docs/_documentation/getting_started.md +++ b/docs/_general/getting_started.md @@ -1,6 +1,6 @@ --- title: Getting Started -position: 1 +position: 10 parameters: - name: content: @@ -30,4 +30,4 @@ right_code_blocks: - code_block: title: language: ---- \ No newline at end of file +--- diff --git a/docs/_general/introduction.md b/docs/_general/introduction.md new file mode 100644 index 00000000..0b195b7d --- /dev/null +++ b/docs/_general/introduction.md @@ -0,0 +1,21 @@ +--- +title: Introduction +position: 1 +parameters: + - name: + content: +content_markdown: |- + fetch-mock allows mocking http requests made using fetch, or any one of the many libraries imitating its api such as [isomorphic-fetch](https://www.npmjs.com/package/isomorphic-fetch), [node-fetch](https://www.npmjs.com/package/node-fetch) and [fetch-ponyfill](https://www.npmjs.com/package/fetch-ponyfill). + + The library will run in most JavaScript environments, including nodejs, web workers and service workers, and any browser that either supports fetch natively or that can have a fetch polyfill/ponyfill installed. + + As well as shorthand methods for the simplest use cases, it offers a flexible API for customising all aspects of mocking behaviour. +left_code_blocks: + - code_block: + title: + language: +right_code_blocks: + - code_block: + title: + language: +--- From 5e9ea73a38d14b5a56018a259aaa6c838a0e4742 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Sun, 26 Aug 2018 19:07:32 +0100 Subject: [PATCH 010/127] general docs --- docs/_config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_config.yml b/docs/_config.yml index 40acc196..fc8288a5 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -13,7 +13,7 @@ permalink: pretty timezone: Etc/UTC collections: - documentation: + general: title: General documentation position: 1 api: From 5e56aa4cea1e4c9bce9feff85f8b3a8685d06559 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Sun, 26 Aug 2018 19:12:00 +0100 Subject: [PATCH 011/127] 'no general titel' --- docs/_config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_config.yml b/docs/_config.yml index fc8288a5..f3e166bf 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -14,7 +14,7 @@ timezone: Etc/UTC collections: general: - title: General documentation + title: "" position: 1 api: title: API documentation From bea25ef9c42d8bf9ca3ebe42b28e851c60306b87 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Sun, 26 Aug 2018 19:16:02 +0100 Subject: [PATCH 012/127] 'usage section' --- docs/_config.yml | 12 +++++++++--- docs/{_general => _introduction}/introduction.md | 2 +- docs/{_general => _usage}/_defaults.md | 0 docs/{_general => _usage}/authentication.md | 0 docs/{_general => _usage}/errors.md | 0 docs/{_general => _usage}/getting_started.md | 0 6 files changed, 10 insertions(+), 4 deletions(-) rename docs/{_general => _introduction}/introduction.md (97%) rename docs/{_general => _usage}/_defaults.md (100%) rename docs/{_general => _usage}/authentication.md (100%) rename docs/{_general => _usage}/errors.md (100%) rename docs/{_general => _usage}/getting_started.md (100%) diff --git a/docs/_config.yml b/docs/_config.yml index f3e166bf..1044cf60 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -13,12 +13,15 @@ permalink: pretty timezone: Etc/UTC collections: - general: - title: "" + introduction: + title: "Introduction" position: 1 + usage: + title: "Usage" + position: 2 api: title: API documentation - position: 2 + position: 3 plugins: - jekyll-sitemap - jekyll-seo-tag @@ -33,6 +36,9 @@ defaults: path: "" values: layout: default + - + scope: + type: "introduction" - scope: type: "general" diff --git a/docs/_general/introduction.md b/docs/_introduction/introduction.md similarity index 97% rename from docs/_general/introduction.md rename to docs/_introduction/introduction.md index 0b195b7d..5f63973a 100644 --- a/docs/_general/introduction.md +++ b/docs/_introduction/introduction.md @@ -1,5 +1,5 @@ --- -title: Introduction +title: position: 1 parameters: - name: diff --git a/docs/_general/_defaults.md b/docs/_usage/_defaults.md similarity index 100% rename from docs/_general/_defaults.md rename to docs/_usage/_defaults.md diff --git a/docs/_general/authentication.md b/docs/_usage/authentication.md similarity index 100% rename from docs/_general/authentication.md rename to docs/_usage/authentication.md diff --git a/docs/_general/errors.md b/docs/_usage/errors.md similarity index 100% rename from docs/_general/errors.md rename to docs/_usage/errors.md diff --git a/docs/_general/getting_started.md b/docs/_usage/getting_started.md similarity index 100% rename from docs/_general/getting_started.md rename to docs/_usage/getting_started.md From edb1c265591778fa21d751a8e9603a07431e4f09 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Sun, 26 Aug 2018 19:19:53 +0100 Subject: [PATCH 013/127] 'requirements' --- docs/_usage/_defaults.md | 4 ++-- docs/_usage/requirements.md | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 docs/_usage/requirements.md diff --git a/docs/_usage/_defaults.md b/docs/_usage/_defaults.md index 0b832f22..1a8f516f 100644 --- a/docs/_usage/_defaults.md +++ b/docs/_usage/_defaults.md @@ -1,10 +1,10 @@ --- -title: +title: position: parameters: - name: content: -content_markdown: +content_markdown: |- left_code_blocks: - code_block: title: diff --git a/docs/_usage/requirements.md b/docs/_usage/requirements.md new file mode 100644 index 00000000..ff7bf5ea --- /dev/null +++ b/docs/_usage/requirements.md @@ -0,0 +1,24 @@ +--- +title: Requirements +position: 1 +parameters: + - name: + content: +content_markdown: |- + fetch-mock requires the following to run: + + - [Node.js](https://nodejs.org/) 8+ for full feature operation + - [Node.js](https://nodejs.org/) 0.12+ with [limitations](http://www.wheresrhys.co.uk/fetch-mock/installation) + - [npm](https://www.npmjs.com/package/npm) (normally comes with Node.js) + - Either of the following + - [node-fetch](https://www.npmjs.com/package/node-fetch) when testing in a nodejs + - A browser that supports the `fetch` API when testing in a browser +left_code_blocks: + - code_block: + title: + language: +right_code_blocks: + - code_block: + title: + language: +--- From 9e8f051947b79ed572188327c032993767e7469a Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Sun, 26 Aug 2018 19:24:32 +0100 Subject: [PATCH 014/127] 'installation' --- docs/_usage/authentication.md | 29 -------------------- docs/_usage/installation.md | 51 +++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 29 deletions(-) delete mode 100644 docs/_usage/authentication.md create mode 100644 docs/_usage/installation.md diff --git a/docs/_usage/authentication.md b/docs/_usage/authentication.md deleted file mode 100644 index ffe25d44..00000000 --- a/docs/_usage/authentication.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: Authentication -position: 2 -parameters: - - name: - content: -content_markdown: |- - You need to be authenticated for all API requests. You can generate an API key in your developer dashboard. - - Add the API key to all requests as a GET parameter. - - Nothing will work unless you include this API key - {: .error} -left_code_blocks: - - code_block: - title: - language: -right_code_blocks: - - code_block: |2- - $.get("http://api.myapp.com/books/", { "token": "YOUR_APP_KEY"}, function(data) { - alert(data); - }); - title: JQuery - language: javascript - - code_block: |2- - curl http://api.myapp.com/books?token=YOUR_APP_KEY - title: Curl - language: bash ---- \ No newline at end of file diff --git a/docs/_usage/installation.md b/docs/_usage/installation.md new file mode 100644 index 00000000..2085e682 --- /dev/null +++ b/docs/_usage/installation.md @@ -0,0 +1,51 @@ +--- +title: Authentication +position: 2 +parameters: + - name: + content: +content_markdown: |- + + Install fetch-mock using `npm install --save-dev fetch-mock` + + 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: + {: .info} + - 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')`. + {: .info} + - 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. + {: .info} + - For server side tests running in nodejs 6 or lower use `require('fetch-mock/es5/server')` + {: .info} + + +left_code_blocks: + - code_block: |2- + 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'); + title: Installation + language: javascript +sh +--- + From e7581d1e108554a75f361bec51bf1ffbd10f1dbd Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Sun, 26 Aug 2018 19:27:01 +0100 Subject: [PATCH 015/127] 'installation2' --- docs/_usage/installation.md | 37 ------------------------------------- docs/_usage/requirements.md | 9 ++------- 2 files changed, 2 insertions(+), 44 deletions(-) diff --git a/docs/_usage/installation.md b/docs/_usage/installation.md index 2085e682..053c51eb 100644 --- a/docs/_usage/installation.md +++ b/docs/_usage/installation.md @@ -8,44 +8,7 @@ content_markdown: |- Install fetch-mock using `npm install --save-dev fetch-mock` - 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: - {: .info} - - 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')`. - {: .info} - - 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. - {: .info} - - For server side tests running in nodejs 6 or lower use `require('fetch-mock/es5/server')` - {: .info} - - -left_code_blocks: - - code_block: |2- - 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'); - title: Installation - language: javascript -sh --- diff --git a/docs/_usage/requirements.md b/docs/_usage/requirements.md index ff7bf5ea..6a98901e 100644 --- a/docs/_usage/requirements.md +++ b/docs/_usage/requirements.md @@ -1,4 +1,4 @@ ---- +s--- title: Requirements position: 1 parameters: @@ -7,12 +7,7 @@ parameters: content_markdown: |- fetch-mock requires the following to run: - - [Node.js](https://nodejs.org/) 8+ for full feature operation - - [Node.js](https://nodejs.org/) 0.12+ with [limitations](http://www.wheresrhys.co.uk/fetch-mock/installation) - - [npm](https://www.npmjs.com/package/npm) (normally comes with Node.js) - - Either of the following - - [node-fetch](https://www.npmjs.com/package/node-fetch) when testing in a nodejs - - A browser that supports the `fetch` API when testing in a browser + left_code_blocks: - code_block: title: From 0cd2e9e76a010a1dcab08f7624867291ac698a81 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Sun, 26 Aug 2018 19:28:26 +0100 Subject: [PATCH 016/127] 'installation3' --- docs/_usage/installation.md | 38 ++++++++++++++++++++++++++++++++++++- docs/_usage/requirements.md | 2 +- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/docs/_usage/installation.md b/docs/_usage/installation.md index 053c51eb..2ef1cab8 100644 --- a/docs/_usage/installation.md +++ b/docs/_usage/installation.md @@ -1,5 +1,5 @@ --- -title: Authentication +title: Installation position: 2 parameters: - name: @@ -8,7 +8,43 @@ content_markdown: |- Install fetch-mock using `npm install --save-dev fetch-mock` + 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')`. + {: .warn} + 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. + {: .info} + For server side tests running in nodejs 6 or lower use `require('fetch-mock/es5/server')` + {: .info} + + +left_code_blocks: + - code_block: |2- + 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'); + title: Installation + language: javascript +sh --- diff --git a/docs/_usage/requirements.md b/docs/_usage/requirements.md index 6a98901e..3b8c4d4e 100644 --- a/docs/_usage/requirements.md +++ b/docs/_usage/requirements.md @@ -1,4 +1,4 @@ -s--- +--- title: Requirements position: 1 parameters: From 05b93254758c030c03520a1ab2adba2711e853b8 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Sun, 26 Aug 2018 19:30:23 +0100 Subject: [PATCH 017/127] 'installation4' --- docs/_usage/installation.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/docs/_usage/installation.md b/docs/_usage/installation.md index 2ef1cab8..dfcf6e74 100644 --- a/docs/_usage/installation.md +++ b/docs/_usage/installation.md @@ -10,18 +10,19 @@ content_markdown: |- 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 + ``` + ```js + // Exposes constants that will make tests 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')`. - {: .warn} + {: .warning} 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. {: .info} For server side tests running in nodejs 6 or lower use `require('fetch-mock/es5/server')` @@ -38,13 +39,13 @@ left_code_blocks: const { fetchMock, MATCHED, UNMATCHED } = require('fetch-mock'); title: Installation language: javascript -sh + language: ba --- From a2b99998b4835af27eed0836a5f00ebd65e28a5d Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Sun, 26 Aug 2018 19:30:46 +0100 Subject: [PATCH 018/127] 'installation4' --- docs/_usage/requirements.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/_usage/requirements.md b/docs/_usage/requirements.md index 3b8c4d4e..140271eb 100644 --- a/docs/_usage/requirements.md +++ b/docs/_usage/requirements.md @@ -4,10 +4,15 @@ position: 1 parameters: - name: content: -content_markdown: |- +content_markdown: |2- fetch-mock requires the following to run: - + - [Node.js](https://nodejs.org/) 8+ for full feature operation + - [Node.js](https://nodejs.org/) 0.12+ with [limitations](http://www.wheresrhys.co.uk/fetch-mock/installation) + - [npm](https://www.npmjs.com/package/npm) (normally comes with Node.js) + - Either of the following + - [node-fetch](https://www.npmjs.com/package/node-fetch) when testing in a nodejs + - A browser that supports the `fetch` API when testing in a browser left_code_blocks: - code_block: title: From 743c0c86c0eb0b8235c9dceb9112dfbb6c37308f Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Sun, 26 Aug 2018 19:31:38 +0100 Subject: [PATCH 019/127] 'installation4' --- docs/_usage/installation.md | 20 +------------------- docs/_usage/requirements.md | 10 ++-------- 2 files changed, 3 insertions(+), 27 deletions(-) diff --git a/docs/_usage/installation.md b/docs/_usage/installation.md index dfcf6e74..33779891 100644 --- a/docs/_usage/installation.md +++ b/docs/_usage/installation.md @@ -14,6 +14,7 @@ content_markdown: |- ```js const fetchMock = require('fetch-mock'); ``` + ```js // Exposes constants that will make tests more readable const { fetchMock, MATCHED, UNMATCHED } = require('fetch-mock'); @@ -28,24 +29,5 @@ content_markdown: |- For server side tests running in nodejs 6 or lower use `require('fetch-mock/es5/server')` {: .info} - -left_code_blocks: - - code_block: |2- - 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'); - title: Installation - language: javascript -right_code_blocks: - - code_block: |2- - title: JQuery - language: javascript - - code_block: |2- - curl http://api.myapp.com/books?token=YOUR_APP_KEY - title: Curl - language: ba --- diff --git a/docs/_usage/requirements.md b/docs/_usage/requirements.md index 140271eb..c4ad5a97 100644 --- a/docs/_usage/requirements.md +++ b/docs/_usage/requirements.md @@ -4,15 +4,9 @@ position: 1 parameters: - name: content: -content_markdown: |2- - fetch-mock requires the following to run: +content_markdown: |- + fetch-mock requires the following to run - - [Node.js](https://nodejs.org/) 8+ for full feature operation - - [Node.js](https://nodejs.org/) 0.12+ with [limitations](http://www.wheresrhys.co.uk/fetch-mock/installation) - - [npm](https://www.npmjs.com/package/npm) (normally comes with Node.js) - - Either of the following - - [node-fetch](https://www.npmjs.com/package/node-fetch) when testing in a nodejs - - A browser that supports the `fetch` API when testing in a browser left_code_blocks: - code_block: title: From c2988b806f15911d9004be82535f36ac5fe266ad Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Sun, 26 Aug 2018 19:33:23 +0100 Subject: [PATCH 020/127] 'installation4' --- docs/_usage/_defaults.md | 2 +- docs/_usage/requirements.md | 9 --------- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/docs/_usage/_defaults.md b/docs/_usage/_defaults.md index 1a8f516f..4c3e1fc8 100644 --- a/docs/_usage/_defaults.md +++ b/docs/_usage/_defaults.md @@ -4,7 +4,7 @@ position: parameters: - name: content: -content_markdown: |- +content_markdown: left_code_blocks: - code_block: title: diff --git a/docs/_usage/requirements.md b/docs/_usage/requirements.md index c4ad5a97..235cbf51 100644 --- a/docs/_usage/requirements.md +++ b/docs/_usage/requirements.md @@ -6,13 +6,4 @@ parameters: content: content_markdown: |- fetch-mock requires the following to run - -left_code_blocks: - - code_block: - title: - language: -right_code_blocks: - - code_block: - title: - language: --- From 24a324566b4289f6a88193fcc6dd2934dc7e49b6 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Sun, 26 Aug 2018 19:34:34 +0100 Subject: [PATCH 021/127] 'installation4' --- docs/_usage/installation.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/_usage/installation.md b/docs/_usage/installation.md index 33779891..35711c5a 100644 --- a/docs/_usage/installation.md +++ b/docs/_usage/installation.md @@ -8,8 +8,7 @@ content_markdown: |- Install fetch-mock using `npm install --save-dev fetch-mock` - In most environments use one of the following to use it in your code. - + In most environments use one of the following in your test files ```js const fetchMock = require('fetch-mock'); From f7dc6d32592c089c877175d938704527799dbdd2 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Sun, 26 Aug 2018 19:41:59 +0100 Subject: [PATCH 022/127] 'installation4' --- docs/_usage/requirements.md | 17 ++++++++++++++++- docs/siteicon.png | Bin 2631 -> 12810 bytes 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/docs/_usage/requirements.md b/docs/_usage/requirements.md index 235cbf51..74e9520c 100644 --- a/docs/_usage/requirements.md +++ b/docs/_usage/requirements.md @@ -5,5 +5,20 @@ parameters: - name: content: content_markdown: |- - fetch-mock requires the following to run + fetch-mock requires the following to run: + + - [Node.js](https://nodejs.org/) 8+ for full feature operation + - [Node.js](https://nodejs.org/) 0.12+ with [limitations](http://www.wheresrhys.co.uk/fetch-mock/installation) + - [npm](https://www.npmjs.com/package/npm) (normally comes with Node.js) + - Either of the following + - [node-fetch](https://www.npmjs.com/package/node-fetch) when testing in a nodejs + - A browser that supports the `fetch` API when testing in a browser +left_code_blocks: + - code_block: + title: + language: +right_code_blocks: + - code_block: + title: + language: --- diff --git a/docs/siteicon.png b/docs/siteicon.png index fed4b7deb8faf6ae194f44bf1a50c359343a3923..37d758b68d1e4c72f9ff5abb262d3204ff6f7aae 100644 GIT binary patch literal 12810 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 d1L&UeOYl?dJb%nB(? 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 From 5cbdced90abc9f20a1601c492e2084fb4ca452d6 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Sun, 26 Aug 2018 19:49:00 +0100 Subject: [PATCH 023/127] 'installation4' --- docs/_usage/errors.md | 28 ---------------------------- docs/_usage/getting_started.md | 33 --------------------------------- docs/_usage/global.md | 26 ++++++++++++++++++++++++++ docs/_usage/installation.md | 5 +++-- docs/_usage/library.md | 31 +++++++++++++++++++++++++++++++ docs/_usage/requirements.md | 2 +- 6 files changed, 61 insertions(+), 64 deletions(-) delete mode 100644 docs/_usage/errors.md delete mode 100644 docs/_usage/getting_started.md create mode 100644 docs/_usage/global.md create mode 100644 docs/_usage/library.md diff --git a/docs/_usage/errors.md b/docs/_usage/errors.md deleted file mode 100644 index cada3600..00000000 --- a/docs/_usage/errors.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: Errors -position: 3 -parameters: - - name: - content: -content_markdown: |- - | Code | Name | Description | - | --- | --- | --- | - | 200 | OK | Success | - | 201 | Created | Creation Successful | - | 400 | Bad Request | We could not process that action | - | 403 | Forbidden | We couldn't authenticate you | - - All errors will return JSON in the following format: -left_code_blocks: - - code_block: |- - { - "error": true, - "message": "error message here" - } - title: Response - language: json -right_code_blocks: - - code_block: - title: - language: ---- \ No newline at end of file diff --git a/docs/_usage/getting_started.md b/docs/_usage/getting_started.md deleted file mode 100644 index 8d7d9900..00000000 --- a/docs/_usage/getting_started.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: Getting Started -position: 10 -parameters: - - name: - content: -content_markdown: |- - Welcome to our API. - - This API document is designed for those interested in developing for our platform. - - This API is still under development and will evolve. - - You'll succeed if you do this. - {: .success } - - Here's some useful information. - {: .info } - - Something may not happen if you try and do this. - {: .warning } - - Something bad will happen if you do this. - {: .error } -left_code_blocks: - - code_block: - title: - language: -right_code_blocks: - - code_block: - title: - language: ---- diff --git a/docs/_usage/global.md b/docs/_usage/global.md new file mode 100644 index 00000000..ebad4b3c --- /dev/null +++ b/docs/_usage/global.md @@ -0,0 +1,26 @@ +--- +title: Global fetch +position: 3 +parameters: + - name: + content: +content_markdown: |- + In the following scenarios `fetch` will be a global + - When using native `fetch` (or a polyfill) in the browser + - When `node-fetch` has been assigned to `global` in your nodejs process (a pattern sometiems used in isomorphic codebases) + + By default fetch-mock assumes `fetch` is a global so once you've required fetch-mock, refer to the quickstart and api docs. + +left_code_blocks: + - code_block: |- + { + "error": true, + "message": "error message here" + } + title: Response + language: json +right_code_blocks: + - code_block: + title: + language: +--- diff --git a/docs/_usage/installation.md b/docs/_usage/installation.md index 35711c5a..cfe33142 100644 --- a/docs/_usage/installation.md +++ b/docs/_usage/installation.md @@ -12,9 +12,7 @@ content_markdown: |- ```js const fetchMock = require('fetch-mock'); - ``` - ```js // Exposes constants that will make tests more readable const { fetchMock, MATCHED, UNMATCHED } = require('fetch-mock'); ``` @@ -28,5 +26,8 @@ content_markdown: |- For server side tests running in nodejs 6 or lower use `require('fetch-mock/es5/server')` {: .info} + `fetch` can be used by your code in two different ways. It's important to determine which one applies to your codebase as it will impact how you use `fetch-mock` + {: .warning} + --- diff --git a/docs/_usage/library.md b/docs/_usage/library.md new file mode 100644 index 00000000..10477114 --- /dev/null +++ b/docs/_usage/library.md @@ -0,0 +1,31 @@ +--- +title: Non-global fetch +position: 4 +parameters: + - name: + content: +content_markdown: |- + `fetch` may be used by your js modules as an imported/required library. Scenarios where this holds true are varied, but include + - Using `node-fetch` in nodejs without assigning to `global` + - Using [fetch-ponyfill](https://www.npmjs.com/package/fetch-ponyfill) in the browser + - Using browser libraries which use [fetch-ponyfill](https://www.npmjs.com/package/fetch-ponyfill) + - Some build setups (e.g React native) sometimes follow this pattern, though it may not always be obvious that they do + + The `sandbox()` method returns a function that can be used as a drop-in replacement for `fetch`, and can be passed into your choice of mocking library. The function returned by `sandbox()` supports the full fetch-mock api so once generated it can be worked with as if it were the original `fetch-mock` object, e.g. + + ``` + const fetchMock = require('fetch-mock'); + const myMock = fetchMock.sandbox().mock('/home', 200); + // pass myMock in to your application code, instead of fetch, run it, then... + expect(myMock.called('/home')).to.be.true; + ``` + +left_code_blocks: + - code_block: + title: + language: +right_code_blocks: + - code_block: + title: + language: +--- diff --git a/docs/_usage/requirements.md b/docs/_usage/requirements.md index 74e9520c..55153f4a 100644 --- a/docs/_usage/requirements.md +++ b/docs/_usage/requirements.md @@ -12,7 +12,7 @@ content_markdown: |- - [npm](https://www.npmjs.com/package/npm) (normally comes with Node.js) - Either of the following - [node-fetch](https://www.npmjs.com/package/node-fetch) when testing in a nodejs - - A browser that supports the `fetch` API when testing in a browser + - A browser that supports the `fetch` API either natively or via a [polyfill/ponyfill](https://ponyfoo.com/articles/polyfills-or-ponyfills) left_code_blocks: - code_block: title: From 65f92b05f1779af6c79d2183c9d8eb65eb3426d2 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Sun, 26 Aug 2018 19:53:43 +0100 Subject: [PATCH 024/127] 'installation4' --- docs/_introduction/introduction.md | 5 +++-- docs/_usage/global.md | 13 ------------- docs/_usage/library.md | 20 ++++++-------------- 3 files changed, 9 insertions(+), 29 deletions(-) diff --git a/docs/_introduction/introduction.md b/docs/_introduction/introduction.md index 5f63973a..cdcd287e 100644 --- a/docs/_introduction/introduction.md +++ b/docs/_introduction/introduction.md @@ -5,11 +5,12 @@ parameters: - name: content: content_markdown: |- - fetch-mock allows mocking http requests made using fetch, or any one of the many libraries imitating its api such as [isomorphic-fetch](https://www.npmjs.com/package/isomorphic-fetch), [node-fetch](https://www.npmjs.com/package/node-fetch) and [fetch-ponyfill](https://www.npmjs.com/package/fetch-ponyfill). + fetch-mock allows mocking http requests made using fetch, or one of the many libraries imitating its api such as [node-fetch](https://www.npmjs.com/package/node-fetch) and [fetch-ponyfill](https://www.npmjs.com/package/fetch-ponyfill). - The library will run in most JavaScript environments, including nodejs, web workers and service workers, and any browser that either supports fetch natively or that can have a fetch polyfill/ponyfill installed. + It supports most JavaScript environments, including nodejs, web workers and service workers, and any browser that either supports fetch natively or that can have a fetch polyfill/ponyfill installed. As well as shorthand methods for the simplest use cases, it offers a flexible API for customising all aspects of mocking behaviour. + left_code_blocks: - code_block: title: diff --git a/docs/_usage/global.md b/docs/_usage/global.md index ebad4b3c..d21bcc67 100644 --- a/docs/_usage/global.md +++ b/docs/_usage/global.md @@ -10,17 +10,4 @@ content_markdown: |- - When `node-fetch` has been assigned to `global` in your nodejs process (a pattern sometiems used in isomorphic codebases) By default fetch-mock assumes `fetch` is a global so once you've required fetch-mock, refer to the quickstart and api docs. - -left_code_blocks: - - code_block: |- - { - "error": true, - "message": "error message here" - } - title: Response - language: json -right_code_blocks: - - code_block: - title: - language: --- diff --git a/docs/_usage/library.md b/docs/_usage/library.md index 10477114..0a727450 100644 --- a/docs/_usage/library.md +++ b/docs/_usage/library.md @@ -5,11 +5,12 @@ parameters: - name: content: content_markdown: |- - `fetch` may be used by your js modules as an imported/required library. Scenarios where this holds true are varied, but include - - Using `node-fetch` in nodejs without assigning to `global` + In the following scenarios `fetch` will not be a global + + - Using [node-fetch](https://www.npmjs.com/package/node-fetch) in nodejs without assigning to `global` - Using [fetch-ponyfill](https://www.npmjs.com/package/fetch-ponyfill) in the browser - - Using browser libraries which use [fetch-ponyfill](https://www.npmjs.com/package/fetch-ponyfill) - - Some build setups (e.g React native) sometimes follow this pattern, though it may not always be obvious that they do + - Using libraries which use fetch-ponyfill internally + - Some build setups result in a non-global `fetch`, though it may not always be obvious that this is the case The `sandbox()` method returns a function that can be used as a drop-in replacement for `fetch`, and can be passed into your choice of mocking library. The function returned by `sandbox()` supports the full fetch-mock api so once generated it can be worked with as if it were the original `fetch-mock` object, e.g. @@ -19,13 +20,4 @@ content_markdown: |- // pass myMock in to your application code, instead of fetch, run it, then... expect(myMock.called('/home')).to.be.true; ``` - -left_code_blocks: - - code_block: - title: - language: -right_code_blocks: - - code_block: - title: - language: ---- +-- From d9223d52e756003a4d96bd6ad32de403789b2866 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Sun, 26 Aug 2018 20:00:26 +0100 Subject: [PATCH 025/127] 'polyfill' --- docs/_troubleshooting/sadsad | 1 + docs/_usage/global.md | 3 --- docs/_usage/installation.md | 3 --- docs/_usage/library.md | 3 --- docs/_usage/polyfilling.md | 12 ++++++++++++ docs/_usage/requirements.md | 3 --- 6 files changed, 13 insertions(+), 12 deletions(-) create mode 100644 docs/_troubleshooting/sadsad create mode 100644 docs/_usage/polyfilling.md diff --git a/docs/_troubleshooting/sadsad b/docs/_troubleshooting/sadsad new file mode 100644 index 00000000..d518e464 --- /dev/null +++ b/docs/_troubleshooting/sadsad @@ -0,0 +1 @@ +- When using karma-webpack it's best not to use the `webpack.ProvidePlugin` for this. Instead just add `node_modules/whatwg-fetch/fetch.js` to your list of files to include, or require it directly into your tests before requiring fetch-mock. diff --git a/docs/_usage/global.md b/docs/_usage/global.md index d21bcc67..28d480f5 100644 --- a/docs/_usage/global.md +++ b/docs/_usage/global.md @@ -1,9 +1,6 @@ --- title: Global fetch position: 3 -parameters: - - name: - content: content_markdown: |- In the following scenarios `fetch` will be a global - When using native `fetch` (or a polyfill) in the browser diff --git a/docs/_usage/installation.md b/docs/_usage/installation.md index cfe33142..c5baa036 100644 --- a/docs/_usage/installation.md +++ b/docs/_usage/installation.md @@ -1,9 +1,6 @@ --- title: Installation position: 2 -parameters: - - name: - content: content_markdown: |- Install fetch-mock using `npm install --save-dev fetch-mock` diff --git a/docs/_usage/library.md b/docs/_usage/library.md index 0a727450..7ad3809b 100644 --- a/docs/_usage/library.md +++ b/docs/_usage/library.md @@ -1,9 +1,6 @@ --- title: Non-global fetch position: 4 -parameters: - - name: - content: content_markdown: |- In the following scenarios `fetch` will not be a global diff --git a/docs/_usage/polyfilling.md b/docs/_usage/polyfilling.md new file mode 100644 index 00000000..448f04b4 --- /dev/null +++ b/docs/_usage/polyfilling.md @@ -0,0 +1,12 @@ +--- +title: Polyfilling fetch +position: 5 +content_markdown: |- + Many older browsers require polyfilling the `fetch` global. The following approaches can be used + + Add the following [polyfill.io](https://polyfill.io/v2/docs/) script to your test page `` + {: .info} + `npm install whatwg-fetch` and load `./node_modules/whatwg-fetch/fetch.js` into the page, either in a script tag or by referencing in your test runner config. + {: .info} + +--- diff --git a/docs/_usage/requirements.md b/docs/_usage/requirements.md index 55153f4a..5d034aad 100644 --- a/docs/_usage/requirements.md +++ b/docs/_usage/requirements.md @@ -1,9 +1,6 @@ --- title: Requirements position: 1 -parameters: - - name: - content: content_markdown: |- fetch-mock requires the following to run: From 09e3d31c2b2dfeb4aa21c5bfb8c21f632098637f Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Sun, 26 Aug 2018 20:01:18 +0100 Subject: [PATCH 026/127] 'polyfill' --- docs/_usage/global.md | 3 +++ docs/_usage/installation.md | 3 +++ docs/_usage/library.md | 3 +++ docs/_usage/polyfilling.md | 3 +++ docs/_usage/requirements.md | 3 +++ 5 files changed, 15 insertions(+) diff --git a/docs/_usage/global.md b/docs/_usage/global.md index 28d480f5..d21bcc67 100644 --- a/docs/_usage/global.md +++ b/docs/_usage/global.md @@ -1,6 +1,9 @@ --- title: Global fetch position: 3 +parameters: + - name: + content: content_markdown: |- In the following scenarios `fetch` will be a global - When using native `fetch` (or a polyfill) in the browser diff --git a/docs/_usage/installation.md b/docs/_usage/installation.md index c5baa036..cfe33142 100644 --- a/docs/_usage/installation.md +++ b/docs/_usage/installation.md @@ -1,6 +1,9 @@ --- title: Installation position: 2 +parameters: + - name: + content: content_markdown: |- Install fetch-mock using `npm install --save-dev fetch-mock` diff --git a/docs/_usage/library.md b/docs/_usage/library.md index 7ad3809b..0a727450 100644 --- a/docs/_usage/library.md +++ b/docs/_usage/library.md @@ -1,6 +1,9 @@ --- title: Non-global fetch position: 4 +parameters: + - name: + content: content_markdown: |- In the following scenarios `fetch` will not be a global diff --git a/docs/_usage/polyfilling.md b/docs/_usage/polyfilling.md index 448f04b4..1e638c3a 100644 --- a/docs/_usage/polyfilling.md +++ b/docs/_usage/polyfilling.md @@ -1,6 +1,9 @@ --- title: Polyfilling fetch position: 5 +parameters: + - name: + content: content_markdown: |- Many older browsers require polyfilling the `fetch` global. The following approaches can be used diff --git a/docs/_usage/requirements.md b/docs/_usage/requirements.md index 5d034aad..55153f4a 100644 --- a/docs/_usage/requirements.md +++ b/docs/_usage/requirements.md @@ -1,6 +1,9 @@ --- title: Requirements position: 1 +parameters: + - name: + content: content_markdown: |- fetch-mock requires the following to run: From c94ad0988e801649bdfaa4d6b075d41bc5b6b373 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Sun, 26 Aug 2018 20:03:12 +0100 Subject: [PATCH 027/127] 'polyfill' --- docs/_usage/installation.md | 1 - docs/_usage/polyfilling.md | 1 - 2 files changed, 2 deletions(-) diff --git a/docs/_usage/installation.md b/docs/_usage/installation.md index cfe33142..d9d3466f 100644 --- a/docs/_usage/installation.md +++ b/docs/_usage/installation.md @@ -28,6 +28,5 @@ content_markdown: |- `fetch` can be used by your code in two different ways. It's important to determine which one applies to your codebase as it will impact how you use `fetch-mock` {: .warning} - --- diff --git a/docs/_usage/polyfilling.md b/docs/_usage/polyfilling.md index 1e638c3a..ac2fc408 100644 --- a/docs/_usage/polyfilling.md +++ b/docs/_usage/polyfilling.md @@ -11,5 +11,4 @@ content_markdown: |- {: .info} `npm install whatwg-fetch` and load `./node_modules/whatwg-fetch/fetch.js` into the page, either in a script tag or by referencing in your test runner config. {: .info} - --- From da20d9f9679edd796be61c2ad8245c21d82d7eba Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Sun, 26 Aug 2018 20:03:54 +0100 Subject: [PATCH 028/127] 'polyfill' --- docs/_usage/polyfilling.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/_usage/polyfilling.md b/docs/_usage/polyfilling.md index ac2fc408..daab110b 100644 --- a/docs/_usage/polyfilling.md +++ b/docs/_usage/polyfilling.md @@ -5,10 +5,10 @@ parameters: - name: content: content_markdown: |- - Many older browsers require polyfilling the `fetch` global. The following approaches can be used + Many older browsers require polyfilling the `fetch` global. The following approaches can be used - Add the following [polyfill.io](https://polyfill.io/v2/docs/) script to your test page `` - {: .info} - `npm install whatwg-fetch` and load `./node_modules/whatwg-fetch/fetch.js` into the page, either in a script tag or by referencing in your test runner config. - {: .info} + Add the following [polyfill.io](https://polyfill.io/v2/docs/) script to your test page `` + {: .info} + `npm install whatwg-fetch` and load `./node_modules/whatwg-fetch/fetch.js` into the page, either in a script tag or by referencing in your test runner config. + {: .info} --- From 6a8a18cd841f8f428549a18be695ff995ea3f5d5 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Sun, 26 Aug 2018 20:05:19 +0100 Subject: [PATCH 029/127] 'polyfill' --- docs/_usage/library.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_usage/library.md b/docs/_usage/library.md index 0a727450..bee74145 100644 --- a/docs/_usage/library.md +++ b/docs/_usage/library.md @@ -20,4 +20,4 @@ content_markdown: |- // pass myMock in to your application code, instead of fetch, run it, then... expect(myMock.called('/home')).to.be.true; ``` --- +--- From 341c15777a07828829e2cf7130450d32999a8474 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Sun, 26 Aug 2018 20:06:17 +0100 Subject: [PATCH 030/127] 'polyfill' --- docs/_usage/library.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_usage/library.md b/docs/_usage/library.md index bee74145..33cb07fe 100644 --- a/docs/_usage/library.md +++ b/docs/_usage/library.md @@ -14,7 +14,7 @@ content_markdown: |- The `sandbox()` method returns a function that can be used as a drop-in replacement for `fetch`, and can be passed into your choice of mocking library. The function returned by `sandbox()` supports the full fetch-mock api so once generated it can be worked with as if it were the original `fetch-mock` object, e.g. - ``` + ```js const fetchMock = require('fetch-mock'); const myMock = fetchMock.sandbox().mock('/home', 200); // pass myMock in to your application code, instead of fetch, run it, then... From 2365ffeb7f5ade5699ca070419646638e630b053 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Sun, 26 Aug 2018 23:43:02 +0100 Subject: [PATCH 031/127] 'mock' --- docs/_api/books_add.md | 46 --------------------- docs/_api/mock.md | 92 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+), 46 deletions(-) delete mode 100644 docs/_api/books_add.md create mode 100644 docs/_api/mock.md diff --git a/docs/_api/books_add.md b/docs/_api/books_add.md deleted file mode 100644 index cd5748e4..00000000 --- a/docs/_api/books_add.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -title: /books -position: 1.1 -type: post -description: Create Book -parameters: - - name: title - content: The title for the book - - name: score - content: The book's score between 0 and 5 -content_markdown: |- - The book will automatically be added to your reading list - {: .success} - - Adds a book to your collection. -left_code_blocks: - - code_block: |- - $.post("http://api.myapp.com/books/", { - "token": "YOUR_APP_KEY", - "title": "The Book Thief", - "score": 4.3 - }, function(data) { - alert(data); - }); - title: jQuery - language: javascript -right_code_blocks: - - code_block: |- - { - "id": 3, - "title": "The Book Thief", - "score": 4.3, - "dateAdded": "5/1/2015" - } - title: Response - language: json - - code_block: |- - { - "error": true, - "message": "Invalid score" - } - title: Error - language: json ---- - - diff --git a/docs/_api/mock.md b/docs/_api/mock.md new file mode 100644 index 00000000..6fd5f39f --- /dev/null +++ b/docs/_api/mock.md @@ -0,0 +1,92 @@ +--- +title: .mock() +position: 1.1 +description: Create Book +parameters: + - name: matcher + content: `String`|`Regex`|`Function`: Rule for matching calls to `fetch` + - name: response + content: `String`|`Object`|`Function`|`Promise`: Response to send matched calls + - name: options + content: `Object`: More options configuring [mainly] matching behaviour +content_markdown: |- + Alternatively a single parameters, `options`, and `Object` with `matcher`, `response` and other options defined on it, can be passed + {: .info} + + Adds a book to your collection. +left_code_blocks: + - code_block: |- + $.post("http://api.myapp.com/books/", { + "token": "YOUR_APP_KEY", + "title": "The Book Thief", + "score": 4.3 + }, function(data) { + alert(data); + }); + title: jQuery + language: javascript +right_code_blocks: + - code_block: |- + { + "id": 3, + "title": "The Book Thief", + "score": 4.3, + "dateAdded": "5/1/2015" + } + title: Response + language: json + - code_block: |- + { + "error": true, + "message": "Invalid score" + } + title: Error + language: json +--- + + + + + +#### `mock(matcher, response, options)` or `mock(options)` + +Replaces `fetch` with a stub which records its calls, grouped by route, and optionally returns a mocked `Response` object or passes the call through to `fetch()`. Calls to `.mock()` can be chained. _Note that once mocked, `fetch` will error on any unmatched calls. Use `.spy()` or `.catch()` to handle unmocked calls more gracefully_ + +- `matcher`: Condition for selecting which requests to mock. (For matching based on headers, query strings or other `fetch` options see the `options` parameter documented below). Accepts any of the following: + - `string`: Either + - an exact url to match e.g. 'http://www.site.com/page.html' + - `*` to match any url + - `begin:http://www.site.com/` to match urls beginning with a string + - `end:.jpg` to match urls ending with a string + - `path:/posts/2018/7/3` to match urls with a given path + - `glob:http://*.*` to match glob patterns + - `express:/user/:user` to match [express style paths](https://www.npmjs.com/package/path-to-regexp) + - `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 + - `string`: Creates a 200 response with the string as the response body + - `configObject` If an object _does not contain_ any properties aside from those listed below it is treated as config to build a `Response` + - `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 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) + - `object`: All objects that do not meet the criteria above are converted to `JSON` and returned as the body of a 200 response. + - `Function(url, opts)`: A function that is passed the url and opts `fetch()` is called with and that returns any of the responses listed above (or a `Promise` for any of them) +- `options`: A configuration object with all/additional properties to define a route to mock + - `name`: A unique string naming the route. Used to subsequently retrieve references to the calls, grouped by name. Defaults to `matcher.toString()` + - `method`: http method to match + - `headers`: key/value map of headers to match + - `query`: key/value map of query strings to match, in any order + - `params`: when the `express:` keyword is used in a string matcher, a key/value map `params` can be passed here, to match the parameters extracted by express path matching + - `matcher`: as specified above + - `response`: as specified above + - `repeat`: An integer, `n`, limiting the number of times the matcher can be used. If the route has already been called `n` times the route will be ignored and the call to `fetch()` will fall through to be handled by any other routes defined (which may eventually result in an error if nothing matches it) + - `overwriteRoutes`: If the route you're adding clashes with an existing route, setting `true` here will overwrite the clashing route, `false` will add another route to the stack which will be used as a fallback (useful when using the `repeat` option). Adding a clashing route without specifying this option will throw an error. It can also be set as a global option (see the **Config** section below) From 170de356cd258c1d329b50d0a6581656d1130b13 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Sun, 26 Aug 2018 23:45:31 +0100 Subject: [PATCH 032/127] 'mock' --- docs/_api/mock.md | 49 +++--------------------------------- docs/_troubleshooting/sadsad | 2 ++ 2 files changed, 5 insertions(+), 46 deletions(-) diff --git a/docs/_api/mock.md b/docs/_api/mock.md index 6fd5f39f..a41ac3dd 100644 --- a/docs/_api/mock.md +++ b/docs/_api/mock.md @@ -10,10 +10,12 @@ parameters: - name: options content: `Object`: More options configuring [mainly] matching behaviour content_markdown: |- + Alternatively a single parameters, `options`, and `Object` with `matcher`, `response` and other options defined on it, can be passed {: .info} - Adds a book to your collection. + Replaces `fetch` with a stub which records its calls, grouped by route, and returns a `Response` instance. + left_code_blocks: - code_block: |- $.post("http://api.myapp.com/books/", { @@ -45,48 +47,3 @@ right_code_blocks: --- - - - -#### `mock(matcher, response, options)` or `mock(options)` - -Replaces `fetch` with a stub which records its calls, grouped by route, and optionally returns a mocked `Response` object or passes the call through to `fetch()`. Calls to `.mock()` can be chained. _Note that once mocked, `fetch` will error on any unmatched calls. Use `.spy()` or `.catch()` to handle unmocked calls more gracefully_ - -- `matcher`: Condition for selecting which requests to mock. (For matching based on headers, query strings or other `fetch` options see the `options` parameter documented below). Accepts any of the following: - - `string`: Either - - an exact url to match e.g. 'http://www.site.com/page.html' - - `*` to match any url - - `begin:http://www.site.com/` to match urls beginning with a string - - `end:.jpg` to match urls ending with a string - - `path:/posts/2018/7/3` to match urls with a given path - - `glob:http://*.*` to match glob patterns - - `express:/user/:user` to match [express style paths](https://www.npmjs.com/package/path-to-regexp) - - `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 - - `string`: Creates a 200 response with the string as the response body - - `configObject` If an object _does not contain_ any properties aside from those listed below it is treated as config to build a `Response` - - `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 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) - - `object`: All objects that do not meet the criteria above are converted to `JSON` and returned as the body of a 200 response. - - `Function(url, opts)`: A function that is passed the url and opts `fetch()` is called with and that returns any of the responses listed above (or a `Promise` for any of them) -- `options`: A configuration object with all/additional properties to define a route to mock - - `name`: A unique string naming the route. Used to subsequently retrieve references to the calls, grouped by name. Defaults to `matcher.toString()` - - `method`: http method to match - - `headers`: key/value map of headers to match - - `query`: key/value map of query strings to match, in any order - - `params`: when the `express:` keyword is used in a string matcher, a key/value map `params` can be passed here, to match the parameters extracted by express path matching - - `matcher`: as specified above - - `response`: as specified above - - `repeat`: An integer, `n`, limiting the number of times the matcher can be used. If the route has already been called `n` times the route will be ignored and the call to `fetch()` will fall through to be handled by any other routes defined (which may eventually result in an error if nothing matches it) - - `overwriteRoutes`: If the route you're adding clashes with an existing route, setting `true` here will overwrite the clashing route, `false` will add another route to the stack which will be used as a fallback (useful when using the `repeat` option). Adding a clashing route without specifying this option will throw an error. It can also be set as a global option (see the **Config** section below) diff --git a/docs/_troubleshooting/sadsad b/docs/_troubleshooting/sadsad index d518e464..7cd186aa 100644 --- a/docs/_troubleshooting/sadsad +++ b/docs/_troubleshooting/sadsad @@ -1 +1,3 @@ - When using karma-webpack it's best not to use the `webpack.ProvidePlugin` for this. Instead just add `node_modules/whatwg-fetch/fetch.js` to your list of files to include, or require it directly into your tests before requiring fetch-mock. + +- chaining From 89a38f8ae16a8cf46473a9cee5c18544b0149c0d Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Sun, 26 Aug 2018 23:47:18 +0100 Subject: [PATCH 033/127] 'mock' --- docs/{_introduction => _about}/introduction.md | 0 docs/_api/mock.md | 4 ++-- docs/_config.yml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) rename docs/{_introduction => _about}/introduction.md (100%) diff --git a/docs/_introduction/introduction.md b/docs/_about/introduction.md similarity index 100% rename from docs/_introduction/introduction.md rename to docs/_about/introduction.md diff --git a/docs/_api/mock.md b/docs/_api/mock.md index a41ac3dd..74e0f9af 100644 --- a/docs/_api/mock.md +++ b/docs/_api/mock.md @@ -1,7 +1,7 @@ --- title: .mock() position: 1.1 -description: Create Book +description: Replaces `fetch` with a stub which records its calls and returns a `Response` instance. parameters: - name: matcher content: `String`|`Regex`|`Function`: Rule for matching calls to `fetch` @@ -14,7 +14,7 @@ content_markdown: |- Alternatively a single parameters, `options`, and `Object` with `matcher`, `response` and other options defined on it, can be passed {: .info} - Replaces `fetch` with a stub which records its calls, grouped by route, and returns a `Response` instance. + left_code_blocks: - code_block: |- diff --git a/docs/_config.yml b/docs/_config.yml index 1044cf60..f5533d1e 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -13,8 +13,8 @@ permalink: pretty timezone: Etc/UTC collections: - introduction: - title: "Introduction" + about: + title: "About" position: 1 usage: title: "Usage" From 3d50774e69886a03a37f0e5f7f958dd3e15b6551 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Sun, 26 Aug 2018 23:48:48 +0100 Subject: [PATCH 034/127] 'mock' --- docs/_api/mock.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/_api/mock.md b/docs/_api/mock.md index 74e0f9af..f7bb1f35 100644 --- a/docs/_api/mock.md +++ b/docs/_api/mock.md @@ -1,14 +1,14 @@ --- -title: .mock() +title: ".mock()" position: 1.1 -description: Replaces `fetch` with a stub which records its calls and returns a `Response` instance. +description: "Replaces `fetch` with a stub which records its calls and returns a `Response` instance." parameters: - name: matcher - content: `String`|`Regex`|`Function`: Rule for matching calls to `fetch` + content: "`String`|`Regex`|`Function`: Rule for matching calls to `fetch`" - name: response - content: `String`|`Object`|`Function`|`Promise`: Response to send matched calls + content: "`String`|`Object`|`Function`|`Promise`: Response to send matched calls" - name: options - content: `Object`: More options configuring [mainly] matching behaviour + content: "`Object`: More options configuring [mainly] matching behaviour" content_markdown: |- Alternatively a single parameters, `options`, and `Object` with `matcher`, `response` and other options defined on it, can be passed From da93dd24e6b9b7b1b16d725a41d8954faa8d24a0 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Sun, 26 Aug 2018 23:53:25 +0100 Subject: [PATCH 035/127] 'mock' --- docs/_api/mock.md | 26 ++++++++++++-------------- docs/_troubleshooting/sadsad | 2 ++ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/docs/_api/mock.md b/docs/_api/mock.md index f7bb1f35..389f4af1 100644 --- a/docs/_api/mock.md +++ b/docs/_api/mock.md @@ -4,18 +4,16 @@ position: 1.1 description: "Replaces `fetch` with a stub which records its calls and returns a `Response` instance." parameters: - name: matcher - content: "`String`|`Regex`|`Function`: Rule for matching calls to `fetch`" + content: "String|Regex|Function: Rule for matching calls to `fetch`" - name: response - content: "`String`|`Object`|`Function`|`Promise`: Response to send matched calls" + content: "String|Object|Function|Promise: Response to send matched calls" - name: options - content: "`Object`: More options configuring [mainly] matching behaviour" + content: "Object: More options configuring [mainly] matching behaviour" content_markdown: |- - Alternatively a single parameters, `options`, and `Object` with `matcher`, `response` and other options defined on it, can be passed + Alternatively a single parameter, `options`, an `Object` with `matcher`, `response` and other options defined, can be passed {: .info} - - left_code_blocks: - code_block: |- $.post("http://api.myapp.com/books/", { @@ -29,14 +27,14 @@ left_code_blocks: language: javascript right_code_blocks: - code_block: |- - { - "id": 3, - "title": "The Book Thief", - "score": 4.3, - "dateAdded": "5/1/2015" - } - title: Response - language: json + fetchMock + .mock('http://it.at.there/route') + .mock('begin:http://it') + .mock('end:there/route') + .mock('path:/route') + .mock('*') + title: Strings + language: javascript - code_block: |- { "error": true, diff --git a/docs/_troubleshooting/sadsad b/docs/_troubleshooting/sadsad index 7cd186aa..01a3df11 100644 --- a/docs/_troubleshooting/sadsad +++ b/docs/_troubleshooting/sadsad @@ -1,3 +1,5 @@ - When using karma-webpack it's best not to use the `webpack.ProvidePlugin` for this. Instead just add `node_modules/whatwg-fetch/fetch.js` to your list of files to include, or require it directly into your tests before requiring fetch-mock. - chaining + +- note that end matches qs, path matches only path From f2d848e99800564205a7c696204284ea9c534daa Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 00:00:17 +0100 Subject: [PATCH 036/127] 'mock' --- docs/_api/mock.md | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/docs/_api/mock.md b/docs/_api/mock.md index 389f4af1..8d9b9c27 100644 --- a/docs/_api/mock.md +++ b/docs/_api/mock.md @@ -28,20 +28,33 @@ left_code_blocks: right_code_blocks: - code_block: |- fetchMock - .mock('http://it.at.there/route') - .mock('begin:http://it') - .mock('end:there/route') - .mock('path:/route') - .mock('*') + .mock('http://it.at.here/route', 200) + .mock('begin:http://it', 200) + .mock('end:here/route', 200) + .mock('path:/route', 200) + .mock('*', 200) title: Strings language: javascript - code_block: |- - { - "error": true, - "message": "Invalid score" - } - title: Error - language: json + fetchMock + .mock(/.*\.here.*/, 200) + .mock((url, opts) => opts.method === 'patch', 200) + .mock('express:/:type/:id', 200, { + params: { + type: 'shoe' + } + }) + title: Complex Matchers + language: javascript + - code_block: |- + fetchMock + .mock('*', 'ok') + .mock('*', 404) + .mock('*', {results: []}) + .mock('*', {throw: new Error('Bad kitty'))) + .mock('*', new Promise(res => setTimeout(res, 1000, 404))) + title: Responses + language: javascript --- From fb526f2e92d00d7946cc7d38d79b662adaa78125 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 00:08:19 +0100 Subject: [PATCH 037/127] 'mock' --- docs/_api/mock.md | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/docs/_api/mock.md b/docs/_api/mock.md index 8d9b9c27..fdad7a21 100644 --- a/docs/_api/mock.md +++ b/docs/_api/mock.md @@ -14,18 +14,24 @@ content_markdown: |- Alternatively a single parameter, `options`, an `Object` with `matcher`, `response` and other options defined, can be passed {: .info} -left_code_blocks: - - code_block: |- - $.post("http://api.myapp.com/books/", { - "token": "YOUR_APP_KEY", - "title": "The Book Thief", - "score": 4.3 - }, function(data) { - alert(data); - }); - title: jQuery - language: javascript right_code_blocks: + - title: Example + language: javascript + code_block: |- + fetchMock + .mock('begin:http://it.at.here/api', 200, { + headers: { + authorization: 'Basic dummy-token' + } + }) + .mock('begin:http://it.at.here/api', 403) + + callApi('/endpoint', 'dummy-token') + .then(res => { + expect(res.status).to.equal(200) + }) + +left_code_blocks: - code_block: |- fetchMock .mock('http://it.at.here/route', 200) From 03976fdfcf316cf23853fa5fe9d3e0b8f34c5e7a Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 00:13:35 +0100 Subject: [PATCH 038/127] 'mock' --- docs/_api/mock.md | 4 +- docs/_api/mock_matcher.md | 77 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 docs/_api/mock_matcher.md diff --git a/docs/_api/mock.md b/docs/_api/mock.md index fdad7a21..cc46373e 100644 --- a/docs/_api/mock.md +++ b/docs/_api/mock.md @@ -1,6 +1,6 @@ --- title: ".mock()" -position: 1.1 +position: 1.0 description: "Replaces `fetch` with a stub which records its calls and returns a `Response` instance." parameters: - name: matcher @@ -14,6 +14,8 @@ content_markdown: |- Alternatively a single parameter, `options`, an `Object` with `matcher`, `response` and other options defined, can be passed {: .info} + + right_code_blocks: - title: Example language: javascript diff --git a/docs/_api/mock_matcher.md b/docs/_api/mock_matcher.md new file mode 100644 index 00000000..64fd1e2b --- /dev/null +++ b/docs/_api/mock_matcher.md @@ -0,0 +1,77 @@ +--- +title: ".mock() - matcher " +position: 1.1 +description: String|Regex|Function: Rule for matching calls to `fetch` +parameters: + - name: * + content: Matches any url + - name: url, e.g. 'http://www.site.com/page.html' + content: Match an exact url +content_markdown: |- + + - `matcher`: Condition for selecting which requests to mock. (For matching based on headers, query strings or other `fetch` options see the `options` parameter documented below). Accepts any of the following: + - `string`: Either + - an exact url to match e.g. 'http://www.site.com/page.html' + - `*` to match any url + - `begin:http://www.site.com/` to match urls beginning with a string + - `end:.jpg` to match urls ending with a string + - `path:/posts/2018/7/3` to match urls with a given path + - `glob:http://*.*` to match glob patterns + - `express:/user/:user` to match [express style paths](https://www.npmjs.com/package/path-to-regexp) + - `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/`_ + + + +right_code_blocks: + - title: Example + language: javascript + code_block: |- + fetchMock + .mock('begin:http://it.at.here/api', 200, { + headers: { + authorization: 'Basic dummy-token' + } + }) + .mock('begin:http://it.at.here/api', 403) + + callApi('/endpoint', 'dummy-token') + .then(res => { + expect(res.status).to.equal(200) + }) + +left_code_blocks: + - code_block: |- + fetchMock + .mock('http://it.at.here/route', 200) + .mock('begin:http://it', 200) + .mock('end:here/route', 200) + .mock('path:/route', 200) + .mock('*', 200) + title: Strings + language: javascript + - code_block: |- + fetchMock + .mock(/.*\.here.*/, 200) + .mock((url, opts) => opts.method === 'patch', 200) + .mock('express:/:type/:id', 200, { + params: { + type: 'shoe' + } + }) + title: Complex Matchers + language: javascript + - code_block: |- + fetchMock + .mock('*', 'ok') + .mock('*', 404) + .mock('*', {results: []}) + .mock('*', {throw: new Error('Bad kitty'))) + .mock('*', new Promise(res => setTimeout(res, 1000, 404))) + title: Responses + language: javascript +--- + + From 3261897f26dcd62de822baf8910b53f2f94d6299 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 00:14:12 +0100 Subject: [PATCH 039/127] 'mock' --- docs/_api/mock.md | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/docs/_api/mock.md b/docs/_api/mock.md index cc46373e..e88848e5 100644 --- a/docs/_api/mock.md +++ b/docs/_api/mock.md @@ -16,22 +16,7 @@ content_markdown: |- -right_code_blocks: - - title: Example - language: javascript - code_block: |- - fetchMock - .mock('begin:http://it.at.here/api', 200, { - headers: { - authorization: 'Basic dummy-token' - } - }) - .mock('begin:http://it.at.here/api', 403) - callApi('/endpoint', 'dummy-token') - .then(res => { - expect(res.status).to.equal(200) - }) left_code_blocks: - code_block: |- @@ -63,6 +48,21 @@ left_code_blocks: .mock('*', new Promise(res => setTimeout(res, 1000, 404))) title: Responses language: javascript + - title: End to end example + language: javascript + code_block: |- + fetchMock + .mock('begin:http://it.at.here/api', 200, { + headers: { + authorization: 'Basic dummy-token' + } + }) + .mock('begin:http://it.at.here/api', 403) + + callApi('/endpoint', 'dummy-token') + .then(res => { + expect(res.status).to.equal(200) + }) --- From b95bc18b2bfde8a90fc636e29dd7cc0d2e9b2858 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 00:14:42 +0100 Subject: [PATCH 040/127] 'mock' --- docs/_api/books_list.md | 65 ----------------------------------------- 1 file changed, 65 deletions(-) delete mode 100644 docs/_api/books_list.md diff --git a/docs/_api/books_list.md b/docs/_api/books_list.md deleted file mode 100644 index 065ab3da..00000000 --- a/docs/_api/books_list.md +++ /dev/null @@ -1,65 +0,0 @@ ---- -title: /books -position: 1.0 -type: get -description: List all books -parameters: - - name: offset - content: Offset the results by this amount - - name: limit - content: Limit the number of books returned -content_markdown: |- - This call will return a maximum of 100 books - {: .info } - - Lists all the photos you have access to. You can paginate by using the parameters listed above. -left_code_blocks: - - code_block: |- - $.get("http://api.myapp.com/books/", { "token": "YOUR_APP_KEY"}, function(data) { - alert(data); - }); - title: jQuery - language: javascript - - code_block: |- - r = requests.get("http://api.myapp.com/books/", token="YOUR_APP_KEY") - print r.text - title: Python - language: python - - code_block: |- - var request = require("request"); - request("http://api.myapp.com/books?token=YOUR_APP_KEY", function (error, response, body) { - if (!error && response.statusCode == 200) { - console.log(body); - } - title: Node.js - language: javascript - - code_block: |- - curl http://sampleapi.readme.com/orders?key=YOUR_APP_KEY - title: Curl - language: bash -right_code_blocks: - - code_block: |2- - [ - { - "id": 1, - "title": "The Hunger Games", - "score": 4.5, - "dateAdded": "12/12/2013" - }, - { - "id": 1, - "title": "The Hunger Games", - "score": 4.7, - "dateAdded": "15/12/2013" - }, - ] - title: Response - language: json - - code_block: |2- - { - "error": true, - "message": "Invalid offset" - } - title: Error - language: json ---- \ No newline at end of file From c48b660c7ce58edcd23b47903d67a3a1aed78f9b Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 00:16:19 +0100 Subject: [PATCH 041/127] 'mock' --- docs/_api/mock_matcher.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_api/mock_matcher.md b/docs/_api/mock_matcher.md index 64fd1e2b..7aca769e 100644 --- a/docs/_api/mock_matcher.md +++ b/docs/_api/mock_matcher.md @@ -1,7 +1,7 @@ --- title: ".mock() - matcher " position: 1.1 -description: String|Regex|Function: Rule for matching calls to `fetch` +description: "String|Regex|Function: Rule for matching calls to `fetch`" parameters: - name: * content: Matches any url From 8463bce49f5be25c42d34b605d80d0c50594eed7 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 00:17:07 +0100 Subject: [PATCH 042/127] 'mock' --- docs/_api/mock_matcher.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/_api/mock_matcher.md b/docs/_api/mock_matcher.md index 7aca769e..e8d14bda 100644 --- a/docs/_api/mock_matcher.md +++ b/docs/_api/mock_matcher.md @@ -3,13 +3,13 @@ title: ".mock() - matcher " position: 1.1 description: "String|Regex|Function: Rule for matching calls to `fetch`" parameters: - - name: * + - name: "*" content: Matches any url - - name: url, e.g. 'http://www.site.com/page.html' + - name: "url, e.g. 'http://www.site.com/page.html'" content: Match an exact url content_markdown: |- - - `matcher`: Condition for selecting which requests to mock. (For matching based on headers, query strings or other `fetch` options see the `options` parameter documented below). Accepts any of the following: + "- `matcher`: Condition for selecting which requests to mock. (For matching based on headers, query strings or other `fetch` options see the `options` parameter documented below). Accepts any of the following: - `string`: Either - an exact url to match e.g. 'http://www.site.com/page.html' - `*` to match any url @@ -21,7 +21,7 @@ content_markdown: |- - `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/`_ + _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/`_" From f3a8c98cb0283b33a4389d79e31f84ad46c5f95c Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 00:18:31 +0100 Subject: [PATCH 043/127] 'mock' --- docs/_api/mock_matcher.md | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/docs/_api/mock_matcher.md b/docs/_api/mock_matcher.md index e8d14bda..b81bf779 100644 --- a/docs/_api/mock_matcher.md +++ b/docs/_api/mock_matcher.md @@ -1,5 +1,5 @@ --- -title: ".mock() - matcher " +title: ".mock() - matcher" position: 1.1 description: "String|Regex|Function: Rule for matching calls to `fetch`" parameters: @@ -8,20 +8,7 @@ parameters: - name: "url, e.g. 'http://www.site.com/page.html'" content: Match an exact url content_markdown: |- - - "- `matcher`: Condition for selecting which requests to mock. (For matching based on headers, query strings or other `fetch` options see the `options` parameter documented below). Accepts any of the following: - - `string`: Either - - an exact url to match e.g. 'http://www.site.com/page.html' - - `*` to match any url - - `begin:http://www.site.com/` to match urls beginning with a string - - `end:.jpg` to match urls ending with a string - - `path:/posts/2018/7/3` to match urls with a given path - - `glob:http://*.*` to match glob patterns - - `express:/user/:user` to match [express style paths](https://www.npmjs.com/package/path-to-regexp) - - `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/`_" + asdasd From d309f0ccd8053e9fe261f3388b83846c23cc45f0 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 00:21:26 +0100 Subject: [PATCH 044/127] 'mock' --- docs/_api/mock_matcher.md | 3 ++- docs/index.html | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/_api/mock_matcher.md b/docs/_api/mock_matcher.md index b81bf779..94966ca6 100644 --- a/docs/_api/mock_matcher.md +++ b/docs/_api/mock_matcher.md @@ -1,7 +1,8 @@ --- -title: ".mock() - matcher" +title: ".mock() - #matcher" position: 1.1 description: "String|Regex|Function: Rule for matching calls to `fetch`" +parametersBlockTitle: Variants parameters: - name: "*" content: Matches any url diff --git a/docs/index.html b/docs/index.html index 0f96537c..d5171df6 100644 --- a/docs/index.html +++ b/docs/index.html @@ -21,7 +21,7 @@

      {% endif %} {% if doc.parameters and doc.parameters[0].name %} -

      Parameters
      +
      {% if doc.parametersBlockTitle %}{{ doc.parametersBlockTitle }}{% else %}Parameters{% endif %}
      {% for parameter in doc.parameters %}
      {{ parameter.name }}
      From 387f3b2fee16b6014deb7e4601a6cc9de4b19588 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 17:48:22 +0100 Subject: [PATCH 045/127] 'config' --- docs/_troubleshooting/sadsad | 5 +++++ docs/_usage/configuration.md | 32 ++++++++++++++++++++++++++++++++ docs/_usage/custom-classes.md | 20 ++++++++++++++++++++ docs/_usage/library.md | 1 + 4 files changed, 58 insertions(+) create mode 100644 docs/_usage/configuration.md create mode 100644 docs/_usage/custom-classes.md diff --git a/docs/_troubleshooting/sadsad b/docs/_troubleshooting/sadsad index 01a3df11..80d428f6 100644 --- a/docs/_troubleshooting/sadsad +++ b/docs/_troubleshooting/sadsad @@ -3,3 +3,8 @@ - chaining - note that end matches qs, path matches only path + + +Put this with the spy() docs +When using `node-fetch`, `fetch-mock` will use the instance you have installed. The one exception is that a reference to `fetchMock.config.fetch = require('node-fetch')` is required if you intend to use the `.spy()` method) +{: .info} diff --git a/docs/_usage/configuration.md b/docs/_usage/configuration.md new file mode 100644 index 00000000..425e45c0 --- /dev/null +++ b/docs/_usage/configuration.md @@ -0,0 +1,32 @@ +--- +title: Configuration +position: 7 +description: On either the global or sandboxed `fetchMock` instances, the following config options can be set by setting properties on `fetchMock.config`. Many can also be set on individual calls to `.mock()` +parameters: + - name: sendAsJson + content: [default `true`] - by default fetchMock will convert objects to JSON before sending. This is overrideable from each call but for some scenarios e.g. when dealing with a lot of array buffers, it can be useful to default to `false` + - name: includeContentLength + content: [default `true`]: When set to true this will make fetchMock automatically add the `content-length` header. This is especially useful when combined with `sendAsJson` because then fetchMock does the conversion to JSON for you and knows the resulting length so you don’t have to compute this yourself by basically doing the same conversion to JSON. + - name: fallbackToNetwork + content: [default `false`] If true then unmatched calls will transparently fall through to the network, if false an error will be thrown. If set to `always`, all calls will fall through, effectively disabling fetch-mock. to Within individual tests `.catch()` and `spy()` can be used for fine-grained control of this + - name: overwriteRoutes + content: : If a new route clashes with an existing route, setting `true` here will overwrite the clashing route, `false` will add another route to the stack which will be used as a fallback (useful when using the `repeat` option). Adding a clashing route without specifying this option will throw an error. + - name: warnOnFallback + content: [default `true`] If true then any unmatched calls that are caught by a fallback handler (either the network or a custom function set using `catch()`) will emit warnings + - name: Headers + content: + - name: Request + content: + - name: Response + content: + - name: Promise + content: + - name: fetch + content: +content_markdown: |- + +- When using non standard fetch (e.g. a ponyfill, or aversion of `node-fetch` other than the one bundled with `fetch-mock`) or an alternative Promise implementation, this will configure fetch-mock to use your chosen implementations. + +Note that `Object.assign(fetchMock.config, require('fetch-ponyfill')())` will configure fetch-mock to use all of fetch-ponyfill's classes. In most cases, it should only be necessary to set this once before any tests run. + +--- diff --git a/docs/_usage/custom-classes.md b/docs/_usage/custom-classes.md new file mode 100644 index 00000000..6bdae981 --- /dev/null +++ b/docs/_usage/custom-classes.md @@ -0,0 +1,20 @@ +--- +title: Configuring fetch subclasses +position: 6 +parameters: + - name: + content: +content_markdown: |- + Some fetch-mock internals require access to the `Request`, `Response` and `Headers` constructors provided by your chosen `fetch` implementation. These should be set on the `fetchMock.config` object + {: .warning} + + ```javascript + const ponyfill = require('fetch-ponyfill')(); + fetchMock.config = Object.assign(fetchMock.config, { + Headers: ponyfill.Headers, + Request: ponyfill.Request, + Response: ponyfill.Response, + fetch: ponyfill + }) +``` +--- diff --git a/docs/_usage/library.md b/docs/_usage/library.md index 33cb07fe..57dd28b0 100644 --- a/docs/_usage/library.md +++ b/docs/_usage/library.md @@ -21,3 +21,4 @@ content_markdown: |- expect(myMock.called('/home')).to.be.true; ``` --- + From 136b46189f2d6879b376e0fb467e90c65bef4e47 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 17:50:47 +0100 Subject: [PATCH 046/127] 'config' --- docs/_usage/configuration.md | 5 ++--- docs/_usage/custom-classes.md | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/_usage/configuration.md b/docs/_usage/configuration.md index 425e45c0..feb8cb0a 100644 --- a/docs/_usage/configuration.md +++ b/docs/_usage/configuration.md @@ -24,9 +24,8 @@ parameters: - name: fetch content: content_markdown: |- + When using non standard fetch (e.g. a ponyfill, or aversion of `node-fetch` other than the one bundled with `fetch-mock`) or an alternative Promise implementation, this will configure fetch-mock to use your chosen implementations. -- When using non standard fetch (e.g. a ponyfill, or aversion of `node-fetch` other than the one bundled with `fetch-mock`) or an alternative Promise implementation, this will configure fetch-mock to use your chosen implementations. - -Note that `Object.assign(fetchMock.config, require('fetch-ponyfill')())` will configure fetch-mock to use all of fetch-ponyfill's classes. In most cases, it should only be necessary to set this once before any tests run. + Note that `Object.assign(fetchMock.config, require('fetch-ponyfill')())` will configure fetch-mock to use all of fetch-ponyfill's classes. In most cases, it should only be necessary to set this once before any tests run. --- diff --git a/docs/_usage/custom-classes.md b/docs/_usage/custom-classes.md index 6bdae981..cb3f893d 100644 --- a/docs/_usage/custom-classes.md +++ b/docs/_usage/custom-classes.md @@ -16,5 +16,5 @@ content_markdown: |- Response: ponyfill.Response, fetch: ponyfill }) -``` + ``` --- From 3c167af22b71c59772af49727646ddf11a294ae4 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 17:52:23 +0100 Subject: [PATCH 047/127] 'config' --- docs/_usage/configuration.md | 2 +- docs/_usage/custom-classes.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/_usage/configuration.md b/docs/_usage/configuration.md index feb8cb0a..9fe7b890 100644 --- a/docs/_usage/configuration.md +++ b/docs/_usage/configuration.md @@ -1,7 +1,7 @@ --- title: Configuration position: 7 -description: On either the global or sandboxed `fetchMock` instances, the following config options can be set by setting properties on `fetchMock.config`. Many can also be set on individual calls to `.mock()` +description: "On either the global or sandboxed `fetchMock` instances, the following config options can be set by setting properties on `fetchMock.config`. Many can also be set on individual calls to `.mock()`" parameters: - name: sendAsJson content: [default `true`] - by default fetchMock will convert objects to JSON before sending. This is overrideable from each call but for some scenarios e.g. when dealing with a lot of array buffers, it can be useful to default to `false` diff --git a/docs/_usage/custom-classes.md b/docs/_usage/custom-classes.md index cb3f893d..9b92c63e 100644 --- a/docs/_usage/custom-classes.md +++ b/docs/_usage/custom-classes.md @@ -1,5 +1,5 @@ --- -title: Configuring fetch subclasses +title: Custom subclasses position: 6 parameters: - name: From a6e960c3fad42dca02fe8bedafd1373f6d058fc5 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 17:54:18 +0100 Subject: [PATCH 048/127] 'config' --- docs/_usage/configuration.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/_usage/configuration.md b/docs/_usage/configuration.md index 9fe7b890..b4446a13 100644 --- a/docs/_usage/configuration.md +++ b/docs/_usage/configuration.md @@ -4,25 +4,25 @@ position: 7 description: "On either the global or sandboxed `fetchMock` instances, the following config options can be set by setting properties on `fetchMock.config`. Many can also be set on individual calls to `.mock()`" parameters: - name: sendAsJson - content: [default `true`] - by default fetchMock will convert objects to JSON before sending. This is overrideable from each call but for some scenarios e.g. when dealing with a lot of array buffers, it can be useful to default to `false` + content: "[default `true`] - by default fetchMock will convert objects to JSON before sending. This is overrideable from each call but for some scenarios e.g. when dealing with a lot of array buffers, it can be useful to default to `false`" - name: includeContentLength - content: [default `true`]: When set to true this will make fetchMock automatically add the `content-length` header. This is especially useful when combined with `sendAsJson` because then fetchMock does the conversion to JSON for you and knows the resulting length so you don’t have to compute this yourself by basically doing the same conversion to JSON. + content: "[default `true`]: When set to true this will make fetchMock automatically add the `content-length` header. This is especially useful when combined with `sendAsJson` because then fetchMock does the conversion to JSON for you and knows the resulting length so you don’t have to compute this yourself by basically doing the same conversion to JSON." - name: fallbackToNetwork - content: [default `false`] If true then unmatched calls will transparently fall through to the network, if false an error will be thrown. If set to `always`, all calls will fall through, effectively disabling fetch-mock. to Within individual tests `.catch()` and `spy()` can be used for fine-grained control of this + content: "[default `false`] If true then unmatched calls will transparently fall through to the network, if false an error will be thrown. If set to `always`, all calls will fall through, effectively disabling fetch-mock. to Within individual tests `.catch()` and `spy()` can be used for fine-grained control of this" - name: overwriteRoutes - content: : If a new route clashes with an existing route, setting `true` here will overwrite the clashing route, `false` will add another route to the stack which will be used as a fallback (useful when using the `repeat` option). Adding a clashing route without specifying this option will throw an error. + content: : "If a new route clashes with an existing route, setting `true` here will overwrite the clashing route, `false` will add another route to the stack which will be used as a fallback (useful when using the `repeat` option). Adding a clashing route without specifying this option will throw an error." - name: warnOnFallback - content: [default `true`] If true then any unmatched calls that are caught by a fallback handler (either the network or a custom function set using `catch()`) will emit warnings + content: "[default `true`] If true then any unmatched calls that are caught by a fallback handler (either the network or a custom function set using `catch()`) will emit warnings" - name: Headers - content: + content: a - name: Request - content: + content: b - name: Response - content: + content: c - name: Promise - content: + content: d - name: fetch - content: + content: e content_markdown: |- When using non standard fetch (e.g. a ponyfill, or aversion of `node-fetch` other than the one bundled with `fetch-mock`) or an alternative Promise implementation, this will configure fetch-mock to use your chosen implementations. From c49428530fef594b7c6ab8a5fe1a0fdb06bc03eb Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 17:55:40 +0100 Subject: [PATCH 049/127] 'config' --- docs/_about/introduction.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/docs/_about/introduction.md b/docs/_about/introduction.md index cdcd287e..6509aa6c 100644 --- a/docs/_about/introduction.md +++ b/docs/_about/introduction.md @@ -16,7 +16,11 @@ left_code_blocks: title: language: right_code_blocks: - - code_block: - title: - language: + - code_block: |- + fetchMock.mock('http://example.com', 200); + const res = await fetch('http://example.com'); + assert(res.ok); + fetchMock.restore(); + title: Example + language: javascript --- From 57bd66d28734ca09930335f48a23be1bf0020e6b Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 17:56:29 +0100 Subject: [PATCH 050/127] 'config' --- docs/_api/mock.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_api/mock.md b/docs/_api/mock.md index e88848e5..9bdef13d 100644 --- a/docs/_api/mock.md +++ b/docs/_api/mock.md @@ -1,5 +1,5 @@ --- -title: ".mock()" +title: ".mock(matcher, response, options)" position: 1.0 description: "Replaces `fetch` with a stub which records its calls and returns a `Response` instance." parameters: From 652a77b9e2c993aede51da0461f229075c66b7cb Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 17:57:37 +0100 Subject: [PATCH 051/127] 'config' --- docs/_about/introduction.md | 4 ---- docs/_usage/configuration.md | 5 ++--- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/docs/_about/introduction.md b/docs/_about/introduction.md index 6509aa6c..28a69800 100644 --- a/docs/_about/introduction.md +++ b/docs/_about/introduction.md @@ -12,10 +12,6 @@ content_markdown: |- As well as shorthand methods for the simplest use cases, it offers a flexible API for customising all aspects of mocking behaviour. left_code_blocks: - - code_block: - title: - language: -right_code_blocks: - code_block: |- fetchMock.mock('http://example.com', 200); const res = await fetch('http://example.com'); diff --git a/docs/_usage/configuration.md b/docs/_usage/configuration.md index b4446a13..dcb8cd5c 100644 --- a/docs/_usage/configuration.md +++ b/docs/_usage/configuration.md @@ -24,8 +24,7 @@ parameters: - name: fetch content: e content_markdown: |- - When using non standard fetch (e.g. a ponyfill, or aversion of `node-fetch` other than the one bundled with `fetch-mock`) or an alternative Promise implementation, this will configure fetch-mock to use your chosen implementations. - - Note that `Object.assign(fetchMock.config, require('fetch-ponyfill')())` will configure fetch-mock to use all of fetch-ponyfill's classes. In most cases, it should only be necessary to set this once before any tests run. + "When using non standard fetch (e.g. a ponyfill, or aversion of `node-fetch` other than the one bundled with `fetch-mock`) or an alternative Promise implementation, this will configure fetch-mock to use your chosen implementations. + Note that `Object.assign(fetchMock.config, require('fetch-ponyfill')())` will configure fetch-mock to use all of fetch-ponyfill's classes. In most cases, it should only be necessary to set this once before any tests run." --- From a662b60c39c1fce1ad62f12c4a1714fc8cb72175 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 17:58:20 +0100 Subject: [PATCH 052/127] 'config' --- docs/_usage/configuration.md | 26 +++----------------------- 1 file changed, 3 insertions(+), 23 deletions(-) diff --git a/docs/_usage/configuration.md b/docs/_usage/configuration.md index dcb8cd5c..bc480af0 100644 --- a/docs/_usage/configuration.md +++ b/docs/_usage/configuration.md @@ -2,29 +2,9 @@ title: Configuration position: 7 description: "On either the global or sandboxed `fetchMock` instances, the following config options can be set by setting properties on `fetchMock.config`. Many can also be set on individual calls to `.mock()`" -parameters: - - name: sendAsJson - content: "[default `true`] - by default fetchMock will convert objects to JSON before sending. This is overrideable from each call but for some scenarios e.g. when dealing with a lot of array buffers, it can be useful to default to `false`" - - name: includeContentLength - content: "[default `true`]: When set to true this will make fetchMock automatically add the `content-length` header. This is especially useful when combined with `sendAsJson` because then fetchMock does the conversion to JSON for you and knows the resulting length so you don’t have to compute this yourself by basically doing the same conversion to JSON." - - name: fallbackToNetwork - content: "[default `false`] If true then unmatched calls will transparently fall through to the network, if false an error will be thrown. If set to `always`, all calls will fall through, effectively disabling fetch-mock. to Within individual tests `.catch()` and `spy()` can be used for fine-grained control of this" - - name: overwriteRoutes - content: : "If a new route clashes with an existing route, setting `true` here will overwrite the clashing route, `false` will add another route to the stack which will be used as a fallback (useful when using the `repeat` option). Adding a clashing route without specifying this option will throw an error." - - name: warnOnFallback - content: "[default `true`] If true then any unmatched calls that are caught by a fallback handler (either the network or a custom function set using `catch()`) will emit warnings" - - name: Headers - content: a - - name: Request - content: b - - name: Response - content: c - - name: Promise - content: d - - name: fetch - content: e + content_markdown: |- - "When using non standard fetch (e.g. a ponyfill, or aversion of `node-fetch` other than the one bundled with `fetch-mock`) or an alternative Promise implementation, this will configure fetch-mock to use your chosen implementations. + When using non standard fetch (e.g. a ponyfill, or aversion of `node-fetch` other than the one bundled with `fetch-mock`) or an alternative Promise implementation, this will configure fetch-mock to use your chosen implementations. - Note that `Object.assign(fetchMock.config, require('fetch-ponyfill')())` will configure fetch-mock to use all of fetch-ponyfill's classes. In most cases, it should only be necessary to set this once before any tests run." + Note that `Object.assign(fetchMock.config, require('fetch-ponyfill')())` will configure fetch-mock to use all of fetch-ponyfill's classes. In most cases, it should only be necessary to set this once before any tests run. --- From 0fe028118198863c7408254ce27af21e7fa75994 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 17:59:32 +0100 Subject: [PATCH 053/127] 'config' --- docs/_usage/configuration.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/_usage/configuration.md b/docs/_usage/configuration.md index bc480af0..ad6084d9 100644 --- a/docs/_usage/configuration.md +++ b/docs/_usage/configuration.md @@ -2,6 +2,9 @@ title: Configuration position: 7 description: "On either the global or sandboxed `fetchMock` instances, the following config options can be set by setting properties on `fetchMock.config`. Many can also be set on individual calls to `.mock()`" +parameters: + - name: sendAsJson + content: [default `true`] - by default fetchMock will convert objects to JSON before sending. This is overrideable from each call but for some scenarios e.g. when dealing with a lot of array buffers, it can be useful to default to `false` content_markdown: |- When using non standard fetch (e.g. a ponyfill, or aversion of `node-fetch` other than the one bundled with `fetch-mock`) or an alternative Promise implementation, this will configure fetch-mock to use your chosen implementations. From 226d8b777d9788c5209203762a92cdc0edd966f9 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 18:02:13 +0100 Subject: [PATCH 054/127] 'config' --- Gemfile | 2 +- Gemfile.lock | 69 ------------------------------------ docs/_usage/configuration.md | 2 +- 3 files changed, 2 insertions(+), 71 deletions(-) delete mode 100644 Gemfile.lock diff --git a/Gemfile b/Gemfile index 724febd0..34ff721e 100644 --- a/Gemfile +++ b/Gemfile @@ -1,4 +1,4 @@ -source 'https://rubygems.org' +source 'http://rubygems.org' gem 'jekyll', '3.7.2' diff --git a/Gemfile.lock b/Gemfile.lock deleted file mode 100644 index 0498c707..00000000 --- a/Gemfile.lock +++ /dev/null @@ -1,69 +0,0 @@ -GEM - remote: https://rubygems.org/ - specs: - addressable (2.5.2) - public_suffix (>= 2.0.2, < 4.0) - colorator (1.1.0) - concurrent-ruby (1.0.5) - em-websocket (0.5.1) - eventmachine (>= 0.12.9) - http_parser.rb (~> 0.6.0) - eventmachine (1.2.5) - ffi (1.9.18) - forwardable-extended (2.6.0) - http_parser.rb (0.6.0) - i18n (0.9.3) - concurrent-ruby (~> 1.0) - jekyll (3.7.2) - addressable (~> 2.4) - colorator (~> 1.0) - em-websocket (~> 0.5) - i18n (~> 0.7) - jekyll-sass-converter (~> 1.0) - jekyll-watch (~> 2.0) - kramdown (~> 1.14) - liquid (~> 4.0) - mercenary (~> 0.3.3) - pathutil (~> 0.9) - rouge (>= 1.7, < 4) - safe_yaml (~> 1.0) - jekyll-sass-converter (1.5.2) - sass (~> 3.4) - jekyll-seo-tag (2.4.0) - jekyll (~> 3.3) - jekyll-sitemap (1.2.0) - jekyll (~> 3.3) - jekyll-watch (2.0.0) - listen (~> 3.0) - kramdown (1.16.2) - liquid (4.0.0) - listen (3.1.5) - rb-fsevent (~> 0.9, >= 0.9.4) - rb-inotify (~> 0.9, >= 0.9.7) - ruby_dep (~> 1.2) - mercenary (0.3.6) - pathutil (0.16.1) - forwardable-extended (~> 2.6) - public_suffix (3.0.1) - rb-fsevent (0.10.2) - rb-inotify (0.9.10) - ffi (>= 0.5.0, < 2) - rouge (3.1.1) - ruby_dep (1.5.0) - safe_yaml (1.0.4) - sass (3.5.5) - sass-listen (~> 4.0.0) - sass-listen (4.0.0) - rb-fsevent (~> 0.9, >= 0.9.4) - rb-inotify (~> 0.9, >= 0.9.7) - -PLATFORMS - ruby - -DEPENDENCIES - jekyll (= 3.7.2) - jekyll-seo-tag (= 2.4.0) - jekyll-sitemap (= 1.2.0) - -BUNDLED WITH - 1.16.0 diff --git a/docs/_usage/configuration.md b/docs/_usage/configuration.md index ad6084d9..0dcfa6f6 100644 --- a/docs/_usage/configuration.md +++ b/docs/_usage/configuration.md @@ -4,7 +4,7 @@ position: 7 description: "On either the global or sandboxed `fetchMock` instances, the following config options can be set by setting properties on `fetchMock.config`. Many can also be set on individual calls to `.mock()`" parameters: - name: sendAsJson - content: [default `true`] - by default fetchMock will convert objects to JSON before sending. This is overrideable from each call but for some scenarios e.g. when dealing with a lot of array buffers, it can be useful to default to `false` + content: "[default `true`] - by default fetchMock will convert objects to JSON before sending. This is overrideable from each call but for some scenarios e.g. when dealing with a lot of array buffers, it can be useful to default to `false`" content_markdown: |- When using non standard fetch (e.g. a ponyfill, or aversion of `node-fetch` other than the one bundled with `fetch-mock`) or an alternative Promise implementation, this will configure fetch-mock to use your chosen implementations. From a29ccf27200d11546d63881fb6267581bda3da03 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 18:07:50 +0100 Subject: [PATCH 055/127] 'config' --- docs/_usage/configuration.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/_usage/configuration.md b/docs/_usage/configuration.md index 0dcfa6f6..14184694 100644 --- a/docs/_usage/configuration.md +++ b/docs/_usage/configuration.md @@ -1,10 +1,10 @@ --- title: Configuration position: 7 -description: "On either the global or sandboxed `fetchMock` instances, the following config options can be set by setting properties on `fetchMock.config`. Many can also be set on individual calls to `.mock()`" +description: "On either the global or sandboxed `fetchMock` instances, the following config options can be set by setting properties on `fetchMock.config`. Many can also be overridden on individual calls to `.mock()`" parameters: - name: sendAsJson - content: "[default `true`] - by default fetchMock will convert objects to JSON before sending. This is overrideable from each call but for some scenarios e.g. when dealing with a lot of array buffers, it can be useful to default to `false`" + content: Convert any object provided to fetch-mock as a stub response into a JSON string with `content-type: application/json`. Can be useful to set to `false` globally if e.g. dealing with a lot of non-text responses [default: `true`] attempts to convert "[default `true`] content_markdown: |- When using non standard fetch (e.g. a ponyfill, or aversion of `node-fetch` other than the one bundled with `fetch-mock`) or an alternative Promise implementation, this will configure fetch-mock to use your chosen implementations. From a3a129cc30f780bcb44e780a5f8bdf3041f555bc Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 18:11:19 +0100 Subject: [PATCH 056/127] 'config' --- docs/_usage/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_usage/configuration.md b/docs/_usage/configuration.md index 14184694..dfce62cb 100644 --- a/docs/_usage/configuration.md +++ b/docs/_usage/configuration.md @@ -4,7 +4,7 @@ position: 7 description: "On either the global or sandboxed `fetchMock` instances, the following config options can be set by setting properties on `fetchMock.config`. Many can also be overridden on individual calls to `.mock()`" parameters: - name: sendAsJson - content: Convert any object provided to fetch-mock as a stub response into a JSON string with `content-type: application/json`. Can be useful to set to `false` globally if e.g. dealing with a lot of non-text responses [default: `true`] attempts to convert "[default `true`] + content: Convert objects into JSON before delivering as stub reponses. Can be useful to set to `false` globally if e.g. dealing with a lot of non-text responses. If `true`, will also add a `content-type: application/json` header [default: `true`] content_markdown: |- When using non standard fetch (e.g. a ponyfill, or aversion of `node-fetch` other than the one bundled with `fetch-mock`) or an alternative Promise implementation, this will configure fetch-mock to use your chosen implementations. From bdfeaf3abc0b8e94a6ffa44c5602a359c959e404 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 18:12:29 +0100 Subject: [PATCH 057/127] 'config' --- docs/_usage/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_usage/configuration.md b/docs/_usage/configuration.md index dfce62cb..125b0ea6 100644 --- a/docs/_usage/configuration.md +++ b/docs/_usage/configuration.md @@ -4,7 +4,7 @@ position: 7 description: "On either the global or sandboxed `fetchMock` instances, the following config options can be set by setting properties on `fetchMock.config`. Many can also be overridden on individual calls to `.mock()`" parameters: - name: sendAsJson - content: Convert objects into JSON before delivering as stub reponses. Can be useful to set to `false` globally if e.g. dealing with a lot of non-text responses. If `true`, will also add a `content-type: application/json` header [default: `true`] + content: "Convert objects into JSON before delivering as stub reponses. Can be useful to set to `false` globally if e.g. dealing with a lot of non-text responses. If `true`, will also add a `content-type: application/json` header [default: `true`]" content_markdown: |- When using non standard fetch (e.g. a ponyfill, or aversion of `node-fetch` other than the one bundled with `fetch-mock`) or an alternative Promise implementation, this will configure fetch-mock to use your chosen implementations. From a9230e6fb9f1501835929a3e574648c29fa8fdfd Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 18:14:11 +0100 Subject: [PATCH 058/127] 'config' --- docs/_usage/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_usage/configuration.md b/docs/_usage/configuration.md index 125b0ea6..66374b1b 100644 --- a/docs/_usage/configuration.md +++ b/docs/_usage/configuration.md @@ -4,7 +4,7 @@ position: 7 description: "On either the global or sandboxed `fetchMock` instances, the following config options can be set by setting properties on `fetchMock.config`. Many can also be overridden on individual calls to `.mock()`" parameters: - name: sendAsJson - content: "Convert objects into JSON before delivering as stub reponses. Can be useful to set to `false` globally if e.g. dealing with a lot of non-text responses. If `true`, will also add a `content-type: application/json` header [default: `true`]" + content: Convert objects into JSON before delivering as stub reponses. Can be content_markdown: |- When using non standard fetch (e.g. a ponyfill, or aversion of `node-fetch` other than the one bundled with `fetch-mock`) or an alternative Promise implementation, this will configure fetch-mock to use your chosen implementations. From 8828ebbb509c3e8b5c620e036a3f67b73a45a81d Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 18:15:49 +0100 Subject: [PATCH 059/127] 'config' --- docs/_usage/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_usage/configuration.md b/docs/_usage/configuration.md index 66374b1b..bd24bcbc 100644 --- a/docs/_usage/configuration.md +++ b/docs/_usage/configuration.md @@ -4,7 +4,7 @@ position: 7 description: "On either the global or sandboxed `fetchMock` instances, the following config options can be set by setting properties on `fetchMock.config`. Many can also be overridden on individual calls to `.mock()`" parameters: - name: sendAsJson - content: Convert objects into JSON before delivering as stub reponses. Can be + content: asdasdsad content_markdown: |- When using non standard fetch (e.g. a ponyfill, or aversion of `node-fetch` other than the one bundled with `fetch-mock`) or an alternative Promise implementation, this will configure fetch-mock to use your chosen implementations. From c34108282bfb90721580973258d8ba886dbd59c0 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 18:19:51 +0100 Subject: [PATCH 060/127] 'config' --- docs/_usage/configuration.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/_usage/configuration.md b/docs/_usage/configuration.md index bd24bcbc..2c2b7134 100644 --- a/docs/_usage/configuration.md +++ b/docs/_usage/configuration.md @@ -4,8 +4,7 @@ position: 7 description: "On either the global or sandboxed `fetchMock` instances, the following config options can be set by setting properties on `fetchMock.config`. Many can also be overridden on individual calls to `.mock()`" parameters: - name: sendAsJson - content: asdasdsad - + content: Convert objects into JSON before delivering as stub reponses content_markdown: |- When using non standard fetch (e.g. a ponyfill, or aversion of `node-fetch` other than the one bundled with `fetch-mock`) or an alternative Promise implementation, this will configure fetch-mock to use your chosen implementations. From c1bad3ae5cdca19a27baa5bd2b3a3ff128f03c73 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 18:22:13 +0100 Subject: [PATCH 061/127] 'config' --- docs/_usage/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_usage/configuration.md b/docs/_usage/configuration.md index 2c2b7134..ed31d7e7 100644 --- a/docs/_usage/configuration.md +++ b/docs/_usage/configuration.md @@ -4,7 +4,7 @@ position: 7 description: "On either the global or sandboxed `fetchMock` instances, the following config options can be set by setting properties on `fetchMock.config`. Many can also be overridden on individual calls to `.mock()`" parameters: - name: sendAsJson - content: Convert objects into JSON before delivering as stub reponses + content: Convert objects into JSON before delivering as stub reponses. Can be useful to set to `false` globally if e.g. dealing with a lot of array buffers content_markdown: |- When using non standard fetch (e.g. a ponyfill, or aversion of `node-fetch` other than the one bundled with `fetch-mock`) or an alternative Promise implementation, this will configure fetch-mock to use your chosen implementations. From 6018d0dc4bb1bd39e79fda29c1a089c3b2190624 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 18:23:46 +0100 Subject: [PATCH 062/127] 'config' --- docs/_usage/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_usage/configuration.md b/docs/_usage/configuration.md index ed31d7e7..2fdcf867 100644 --- a/docs/_usage/configuration.md +++ b/docs/_usage/configuration.md @@ -4,7 +4,7 @@ position: 7 description: "On either the global or sandboxed `fetchMock` instances, the following config options can be set by setting properties on `fetchMock.config`. Many can also be overridden on individual calls to `.mock()`" parameters: - name: sendAsJson - content: Convert objects into JSON before delivering as stub reponses. Can be useful to set to `false` globally if e.g. dealing with a lot of array buffers + content: Convert objects into JSON before delivering as stub reponses. Can be useful to set to `false` globally if e.g. dealing with a lot of array buffers. If `true`, will also add a `content-type: application/json` header content_markdown: |- When using non standard fetch (e.g. a ponyfill, or aversion of `node-fetch` other than the one bundled with `fetch-mock`) or an alternative Promise implementation, this will configure fetch-mock to use your chosen implementations. From 0f1f737dbb425896e145937c0dc2220461016419 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 18:27:30 +0100 Subject: [PATCH 063/127] 'config' --- docs/_usage/configuration.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/_usage/configuration.md b/docs/_usage/configuration.md index 2fdcf867..cacaf273 100644 --- a/docs/_usage/configuration.md +++ b/docs/_usage/configuration.md @@ -1,11 +1,15 @@ --- title: Configuration position: 7 -description: "On either the global or sandboxed `fetchMock` instances, the following config options can be set by setting properties on `fetchMock.config`. Many can also be overridden on individual calls to `.mock()`" +description: "On any `fetchMock` instance, config can be set by setting properties on `fetchMock.config`." +parametersBlockTitle: Options parameters: - name: sendAsJson - content: Convert objects into JSON before delivering as stub reponses. Can be useful to set to `false` globally if e.g. dealing with a lot of array buffers. If `true`, will also add a `content-type: application/json` header + content: Convert objects into JSON before delivering as stub reponses. Can be useful to set to `false` globally if e.g. dealing with a lot of array buffers content_markdown: |- + Many of the options above can be set for individual calls to `.mock(matcher, response, options)` by setting as properties on the third parameter, `options` + {: .info} + When using non standard fetch (e.g. a ponyfill, or aversion of `node-fetch` other than the one bundled with `fetch-mock`) or an alternative Promise implementation, this will configure fetch-mock to use your chosen implementations. Note that `Object.assign(fetchMock.config, require('fetch-ponyfill')())` will configure fetch-mock to use all of fetch-ponyfill's classes. In most cases, it should only be necessary to set this once before any tests run. From bcf7aa845588984de29079f28a06a33db40dd426 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 18:29:21 +0100 Subject: [PATCH 064/127] 'config' --- docs/_usage/configuration.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/_usage/configuration.md b/docs/_usage/configuration.md index cacaf273..b457485b 100644 --- a/docs/_usage/configuration.md +++ b/docs/_usage/configuration.md @@ -5,9 +5,10 @@ description: "On any `fetchMock` instance, config can be set by setting properti parametersBlockTitle: Options parameters: - name: sendAsJson - content: Convert objects into JSON before delivering as stub reponses. Can be useful to set to `false` globally if e.g. dealing with a lot of array buffers + content: Convert objects into JSON before delivering as stub reponses. Can be useful to set to `false` globally if e.g. dealing with a lot of array buffers. If `true`, will also add a `content-type: application/json` header + content_markdown: |- - Many of the options above can be set for individual calls to `.mock(matcher, response, options)` by setting as properties on the third parameter, `options` + Many of the options above can be overridden for individual calls to `.mock(matcher, response, options)` by setting as properties on the third parameter, `options` {: .info} When using non standard fetch (e.g. a ponyfill, or aversion of `node-fetch` other than the one bundled with `fetch-mock`) or an alternative Promise implementation, this will configure fetch-mock to use your chosen implementations. From f47f39856f944cd51de4248f47860aeab087a25a Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 18:30:42 +0100 Subject: [PATCH 065/127] 'config' --- docs/_usage/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_usage/configuration.md b/docs/_usage/configuration.md index b457485b..b0ab2f51 100644 --- a/docs/_usage/configuration.md +++ b/docs/_usage/configuration.md @@ -5,7 +5,7 @@ description: "On any `fetchMock` instance, config can be set by setting properti parametersBlockTitle: Options parameters: - name: sendAsJson - content: Convert objects into JSON before delivering as stub reponses. Can be useful to set to `false` globally if e.g. dealing with a lot of array buffers. If `true`, will also add a `content-type: application/json` header + content: Convert objects into JSON before delivering as stub reponses. Can be useful to set to `false` globally if e.g. dealing with a lot of array buffers. If `true`, will also add a content_markdown: |- Many of the options above can be overridden for individual calls to `.mock(matcher, response, options)` by setting as properties on the third parameter, `options` From 2cd70ad1d755fedb479a5818a64386501c104bc4 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 18:32:10 +0100 Subject: [PATCH 066/127] 'config' --- docs/_usage/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_usage/configuration.md b/docs/_usage/configuration.md index b0ab2f51..e6c62512 100644 --- a/docs/_usage/configuration.md +++ b/docs/_usage/configuration.md @@ -5,7 +5,7 @@ description: "On any `fetchMock` instance, config can be set by setting properti parametersBlockTitle: Options parameters: - name: sendAsJson - content: Convert objects into JSON before delivering as stub reponses. Can be useful to set to `false` globally if e.g. dealing with a lot of array buffers. If `true`, will also add a + content: Convert objects into JSON before delivering as stub reponses. Can be useful to set to `false` globally if e.g. dealing with a lot of array buffers. If `true`, will also add a `content-type: application/json` content_markdown: |- Many of the options above can be overridden for individual calls to `.mock(matcher, response, options)` by setting as properties on the third parameter, `options` From 46236dce6fef6f0dad7f5494bf97f3ca4a9a1631 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 18:33:39 +0100 Subject: [PATCH 067/127] 'config' --- docs/_usage/configuration.md | 2 +- docs/index.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/_usage/configuration.md b/docs/_usage/configuration.md index e6c62512..bdc3386f 100644 --- a/docs/_usage/configuration.md +++ b/docs/_usage/configuration.md @@ -5,7 +5,7 @@ description: "On any `fetchMock` instance, config can be set by setting properti parametersBlockTitle: Options parameters: - name: sendAsJson - content: Convert objects into JSON before delivering as stub reponses. Can be useful to set to `false` globally if e.g. dealing with a lot of array buffers. If `true`, will also add a `content-type: application/json` + content: Convert objects into JSON before delivering as stub reponses. Can be useful to set to `false` globally if e.g. dealing with a lot of array buffers. If `true`, will also add a `content-type`. content_markdown: |- Many of the options above can be overridden for individual calls to `.mock(matcher, response, options)` by setting as properties on the third parameter, `options` diff --git a/docs/index.html b/docs/index.html index d5171df6..b84dc472 100644 --- a/docs/index.html +++ b/docs/index.html @@ -25,7 +25,7 @@
      {% if doc.parametersBlockTitle %}{{ doc.parametersBlockTitle }}{% else %}Par
      {% for parameter in doc.parameters %}
      {{ parameter.name }}
      -
      {{ parameter.content }}
      +
      {{ parameter.content | markdownify }}
      {% endfor %}
      {% endif %} From 2f1db80a4e74d23482fd3bd2c6308b26f835e695 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 18:34:32 +0100 Subject: [PATCH 068/127] 'config' --- docs/_usage/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_usage/configuration.md b/docs/_usage/configuration.md index bdc3386f..c3963c93 100644 --- a/docs/_usage/configuration.md +++ b/docs/_usage/configuration.md @@ -5,7 +5,7 @@ description: "On any `fetchMock` instance, config can be set by setting properti parametersBlockTitle: Options parameters: - name: sendAsJson - content: Convert objects into JSON before delivering as stub reponses. Can be useful to set to `false` globally if e.g. dealing with a lot of array buffers. If `true`, will also add a `content-type`. + content: Convert objects into JSON before delivering as stub reponses. Can be useful to set to `false` globally if e.g. dealing with a lot of array buffers. If `true`, will also add a content-type. content_markdown: |- Many of the options above can be overridden for individual calls to `.mock(matcher, response, options)` by setting as properties on the third parameter, `options` From c376cdc456a90094a0fa92236399797e09d308d0 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 18:35:45 +0100 Subject: [PATCH 069/127] 'config' --- docs/_usage/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_usage/configuration.md b/docs/_usage/configuration.md index c3963c93..b144b060 100644 --- a/docs/_usage/configuration.md +++ b/docs/_usage/configuration.md @@ -5,7 +5,7 @@ description: "On any `fetchMock` instance, config can be set by setting properti parametersBlockTitle: Options parameters: - name: sendAsJson - content: Convert objects into JSON before delivering as stub reponses. Can be useful to set to `false` globally if e.g. dealing with a lot of array buffers. If `true`, will also add a content-type. + content: Convert objects into JSON before delivering as stub reponses. Can be useful to set to `false` globally if e.g. dealing with a lot of array buffers. If `true`, will also add a `content-type: application/json` header. content_markdown: |- Many of the options above can be overridden for individual calls to `.mock(matcher, response, options)` by setting as properties on the third parameter, `options` From b0b8ea8641ab8dff58c05d023ec78f89e5b8f19e Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 18:37:21 +0100 Subject: [PATCH 070/127] 'config' --- docs/_usage/configuration.md | 1 + docs/index.html | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/_usage/configuration.md b/docs/_usage/configuration.md index b144b060..2381040a 100644 --- a/docs/_usage/configuration.md +++ b/docs/_usage/configuration.md @@ -5,6 +5,7 @@ description: "On any `fetchMock` instance, config can be set by setting properti parametersBlockTitle: Options parameters: - name: sendAsJson + default: true content: Convert objects into JSON before delivering as stub reponses. Can be useful to set to `false` globally if e.g. dealing with a lot of array buffers. If `true`, will also add a `content-type: application/json` header. content_markdown: |- diff --git a/docs/index.html b/docs/index.html index b84dc472..69540c8f 100644 --- a/docs/index.html +++ b/docs/index.html @@ -24,7 +24,7 @@

      {% if doc.parametersBlockTitle %}{{ doc.parametersBlockTitle }}{% else %}Parameters{% endif %}
      {% for parameter in doc.parameters %} -
      {{ parameter.name }}
      +
      {{ parameter.name }}{%if parameter.default %}
      {{ parameter.default}}
      {% endif %}
      {{ parameter.content | markdownify }}
      {% endfor %}
      From d94551624c2677d69e903f7d46ef7f877d17bcb7 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 18:38:26 +0100 Subject: [PATCH 071/127] 'config' --- docs/_usage/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_usage/configuration.md b/docs/_usage/configuration.md index 2381040a..86ee4e5d 100644 --- a/docs/_usage/configuration.md +++ b/docs/_usage/configuration.md @@ -6,7 +6,7 @@ parametersBlockTitle: Options parameters: - name: sendAsJson default: true - content: Convert objects into JSON before delivering as stub reponses. Can be useful to set to `false` globally if e.g. dealing with a lot of array buffers. If `true`, will also add a `content-type: application/json` header. + content: Convert objects into JSON before delivering as stub reponses. Can be useful to set to `false` globally if e.g. dealing with a lot of array buffers. If `true`, will also add a `content-type: application\/json` header. content_markdown: |- Many of the options above can be overridden for individual calls to `.mock(matcher, response, options)` by setting as properties on the third parameter, `options` From d385c26aaa4b19171cfd0642fe06ca7ff1bcc52e Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 18:41:37 +0100 Subject: [PATCH 072/127] 'config' --- docs/_usage/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_usage/configuration.md b/docs/_usage/configuration.md index 86ee4e5d..a41c59a0 100644 --- a/docs/_usage/configuration.md +++ b/docs/_usage/configuration.md @@ -6,7 +6,7 @@ parametersBlockTitle: Options parameters: - name: sendAsJson default: true - content: Convert objects into JSON before delivering as stub reponses. Can be useful to set to `false` globally if e.g. dealing with a lot of array buffers. If `true`, will also add a `content-type: application\/json` header. + content: Convert objects into JSON before delivering as stub reponses. Can be useful to set to `false` globally if e.g. dealing with a lot of array buffers. If `true`, will also add a `content-type` header. content_markdown: |- Many of the options above can be overridden for individual calls to `.mock(matcher, response, options)` by setting as properties on the third parameter, `options` From 12a0588bb3278c539d909c422d1b55cb51971ef0 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 18:42:53 +0100 Subject: [PATCH 073/127] 'config' --- docs/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.html b/docs/index.html index 69540c8f..63b8d755 100644 --- a/docs/index.html +++ b/docs/index.html @@ -24,7 +24,7 @@

      {% if doc.parametersBlockTitle %}{{ doc.parametersBlockTitle }}{% else %}Parameters{% endif %}
      {% for parameter in doc.parameters %} -
      {{ parameter.name }}{%if parameter.default %}
      {{ parameter.default}}
      {% endif %}
      +
      {{ parameter.name }}{%if parameter.default %}
      [{{ parameter.default}}]
      {% endif %}
      {{ parameter.content | markdownify }}
      {% endfor %}
      From f1ae48608932def670986fe93996279ecab9fe79 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 18:44:23 +0100 Subject: [PATCH 074/127] 'config' --- docs/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.html b/docs/index.html index 63b8d755..dbf77987 100644 --- a/docs/index.html +++ b/docs/index.html @@ -24,7 +24,7 @@

      {% if doc.parametersBlockTitle %}{{ doc.parametersBlockTitle }}{% else %}Parameters{% endif %}
      {% for parameter in doc.parameters %} -
      {{ parameter.name }}{%if parameter.default %}
      [{{ parameter.default}}]
      {% endif %}
      +
      {{ parameter.name }}{%if parameter.default %} [{{ parameter.default}}]{% endif %}
      {{ parameter.content | markdownify }}
      {% endfor %}
      From 703f13ca050a2e0aba6af7099320f8a8ae6a599a Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 18:45:29 +0100 Subject: [PATCH 075/127] 'config' --- docs/_usage/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_usage/configuration.md b/docs/_usage/configuration.md index a41c59a0..a35a1f66 100644 --- a/docs/_usage/configuration.md +++ b/docs/_usage/configuration.md @@ -6,7 +6,7 @@ parametersBlockTitle: Options parameters: - name: sendAsJson default: true - content: Convert objects into JSON before delivering as stub reponses. Can be useful to set to `false` globally if e.g. dealing with a lot of array buffers. If `true`, will also add a `content-type` header. + content: Convert objects into JSON before delivering as stub reponses. Can be useful to set to `false` globally if e.g. dealing with a lot of array buffers. If `true`, will also add a `content-type: application` header. content_markdown: |- Many of the options above can be overridden for individual calls to `.mock(matcher, response, options)` by setting as properties on the third parameter, `options` From 5353c3d1989ea1acff8765d024a1293984dba11c Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 18:45:54 +0100 Subject: [PATCH 076/127] 'config' --- docs/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.html b/docs/index.html index dbf77987..11d27160 100644 --- a/docs/index.html +++ b/docs/index.html @@ -24,7 +24,7 @@

      {% if doc.parametersBlockTitle %}{{ doc.parametersBlockTitle }}{% else %}Parameters{% endif %}
      {% for parameter in doc.parameters %} -
      {{ parameter.name }}{%if parameter.default %} [{{ parameter.default}}]{% endif %}
      +
      {{ parameter.name }}{%if parameter.default %} [{{ parameter.default}}]{% endif %}
      {{ parameter.content | markdownify }}
      {% endfor %}
      From 8ad12cb2d0f0919509e4521abd8ec0956aeab033 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 18:46:14 +0100 Subject: [PATCH 077/127] 'config' --- docs/_usage/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_usage/configuration.md b/docs/_usage/configuration.md index a35a1f66..a41c59a0 100644 --- a/docs/_usage/configuration.md +++ b/docs/_usage/configuration.md @@ -6,7 +6,7 @@ parametersBlockTitle: Options parameters: - name: sendAsJson default: true - content: Convert objects into JSON before delivering as stub reponses. Can be useful to set to `false` globally if e.g. dealing with a lot of array buffers. If `true`, will also add a `content-type: application` header. + content: Convert objects into JSON before delivering as stub reponses. Can be useful to set to `false` globally if e.g. dealing with a lot of array buffers. If `true`, will also add a `content-type` header. content_markdown: |- Many of the options above can be overridden for individual calls to `.mock(matcher, response, options)` by setting as properties on the third parameter, `options` From f9c42fc593c5987753f8840ab9565eedafa4c0a8 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 18:47:43 +0100 Subject: [PATCH 078/127] 'config' --- docs/_usage/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_usage/configuration.md b/docs/_usage/configuration.md index a41c59a0..8ec47b71 100644 --- a/docs/_usage/configuration.md +++ b/docs/_usage/configuration.md @@ -6,7 +6,7 @@ parametersBlockTitle: Options parameters: - name: sendAsJson default: true - content: Convert objects into JSON before delivering as stub reponses. Can be useful to set to `false` globally if e.g. dealing with a lot of array buffers. If `true`, will also add a `content-type` header. + content: Convert objects into JSON before delivering as stub reponses. Can be useful to set to `false` globally if e.g. dealing with a lot of array buffers. If `true`, will also add a `content-type:` header. content_markdown: |- Many of the options above can be overridden for individual calls to `.mock(matcher, response, options)` by setting as properties on the third parameter, `options` From 5ca96a30841bb4d860d47edd87180876453d0e90 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 18:49:10 +0100 Subject: [PATCH 079/127] 'config' --- docs/_usage/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_usage/configuration.md b/docs/_usage/configuration.md index 8ec47b71..d497a815 100644 --- a/docs/_usage/configuration.md +++ b/docs/_usage/configuration.md @@ -6,7 +6,7 @@ parametersBlockTitle: Options parameters: - name: sendAsJson default: true - content: Convert objects into JSON before delivering as stub reponses. Can be useful to set to `false` globally if e.g. dealing with a lot of array buffers. If `true`, will also add a `content-type:` header. + content: Convert objects into JSON before delivering as stub reponses. Can be useful to set to `false` globally if e.g. dealing with a lot of array buffers. If `true`, will also add a `content-type: as` header. content_markdown: |- Many of the options above can be overridden for individual calls to `.mock(matcher, response, options)` by setting as properties on the third parameter, `options` From db3a02c29d2696ef04c48142826d354e014e4654 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 18:52:13 +0100 Subject: [PATCH 080/127] 'config' --- docs/_usage/configuration.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/_usage/configuration.md b/docs/_usage/configuration.md index d497a815..7ff4034e 100644 --- a/docs/_usage/configuration.md +++ b/docs/_usage/configuration.md @@ -6,7 +6,8 @@ parametersBlockTitle: Options parameters: - name: sendAsJson default: true - content: Convert objects into JSON before delivering as stub reponses. Can be useful to set to `false` globally if e.g. dealing with a lot of array buffers. If `true`, will also add a `content-type: as` header. + content: |- + Convert objects into JSON before delivering as stub reponses. Can be useful to set to `false` globally if e.g. dealing with a lot of array buffers. If `true`, will also add a `content-type: as` header. content_markdown: |- Many of the options above can be overridden for individual calls to `.mock(matcher, response, options)` by setting as properties on the third parameter, `options` From e55643aa4299f61fd32ecee825de0463c1556a54 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 18:53:25 +0100 Subject: [PATCH 081/127] 'config' --- docs/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.html b/docs/index.html index 11d27160..facc83ce 100644 --- a/docs/index.html +++ b/docs/index.html @@ -24,7 +24,7 @@

      {% if doc.parametersBlockTitle %}{{ doc.parametersBlockTitle }}{% else %}Parameters{% endif %}
      {% for parameter in doc.parameters %} -
      {{ parameter.name }}{%if parameter.default %} [{{ parameter.default}}]{% endif %}
      +
      {{ parameter.name }}{%if parameter.type %} {{ parameter.type}}{% endif %}{%if parameter.default %} [{{ parameter.default}}]{% endif %}
      {{ parameter.content | markdownify }}
      {% endfor %}
      From 5d3712a20f2abfbc491812f1380859f48df5cc88 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 18:55:04 +0100 Subject: [PATCH 082/127] 'config' --- docs/_usage/configuration.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/_usage/configuration.md b/docs/_usage/configuration.md index 7ff4034e..82968ffc 100644 --- a/docs/_usage/configuration.md +++ b/docs/_usage/configuration.md @@ -7,8 +7,10 @@ parameters: - name: sendAsJson default: true content: |- - Convert objects into JSON before delivering as stub reponses. Can be useful to set to `false` globally if e.g. dealing with a lot of array buffers. If `true`, will also add a `content-type: as` header. - + Convert objects into JSON before delivering as stub reponses. Can be useful to set to `false` globally if e.g. dealing with a lot of array buffers. If `true`, will also add `content-type: application/json` header. + - name: includeContentLength + default: true + content: Automatically sets a `content-length` header on each response. content_markdown: |- Many of the options above can be overridden for individual calls to `.mock(matcher, response, options)` by setting as properties on the third parameter, `options` {: .info} From 9ba21d4721a8b593cd7c8e3bbc7e22ad26a7d7b2 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 19:00:07 +0100 Subject: [PATCH 083/127] 'config' --- docs/_troubleshooting/sadsad | 3 +++ docs/_usage/configuration.md | 7 +++++++ docs/index.html | 2 +- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/docs/_troubleshooting/sadsad b/docs/_troubleshooting/sadsad index 80d428f6..401a0e13 100644 --- a/docs/_troubleshooting/sadsad +++ b/docs/_troubleshooting/sadsad @@ -8,3 +8,6 @@ Put this with the spy() docs When using `node-fetch`, `fetch-mock` will use the instance you have installed. The one exception is that a reference to `fetchMock.config.fetch = require('node-fetch')` is required if you intend to use the `.spy()` method) {: .info} + + + to Within individual tests `.catch()` and `spy()` can be used for fine-grained control of this" diff --git a/docs/_usage/configuration.md b/docs/_usage/configuration.md index 82968ffc..7b7bb5f6 100644 --- a/docs/_usage/configuration.md +++ b/docs/_usage/configuration.md @@ -11,6 +11,13 @@ parameters: - name: includeContentLength default: true content: Automatically sets a `content-length` header on each response. + - name: fallbackToNetwork + default: false + content: |- + `true` - Unhandled calls transparently fall through to the network + `false` - Unhandled calls throw an error + `'always'` - All calls fall through to the network, effectively disabling fetch-mock. + content_markdown: |- Many of the options above can be overridden for individual calls to `.mock(matcher, response, options)` by setting as properties on the third parameter, `options` {: .info} diff --git a/docs/index.html b/docs/index.html index facc83ce..6fd92ec8 100644 --- a/docs/index.html +++ b/docs/index.html @@ -24,7 +24,7 @@

      {% if doc.parametersBlockTitle %}{{ doc.parametersBlockTitle }}{% else %}Parameters{% endif %}
      {% for parameter in doc.parameters %} -
      {{ parameter.name }}{%if parameter.type %} {{ parameter.type}}{% endif %}{%if parameter.default %} [{{ parameter.default}}]{% endif %}
      +
      {{ parameter.name }}{%if parameter.type %} {{ parameter.type}}{% endif %}{%if parameter.default %} [{{ parameter.default}}]{% endif %}
      {{ parameter.content | markdownify }}
      {% endfor %}
      From f08f5a7154d52869b404924b43a2641aadba2bea Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 19:02:08 +0100 Subject: [PATCH 084/127] 'config' --- docs/_usage/configuration.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/_usage/configuration.md b/docs/_usage/configuration.md index 7b7bb5f6..71bf2ddf 100644 --- a/docs/_usage/configuration.md +++ b/docs/_usage/configuration.md @@ -14,9 +14,9 @@ parameters: - name: fallbackToNetwork default: false content: |- - `true` - Unhandled calls transparently fall through to the network - `false` - Unhandled calls throw an error - `'always'` - All calls fall through to the network, effectively disabling fetch-mock. + - `true`: Unhandled calls transparently fall through to the network + - `false`: Unhandled calls throw an error + - `'always'`: All calls fall through to the network, effectively disabling fetch-mock. content_markdown: |- Many of the options above can be overridden for individual calls to `.mock(matcher, response, options)` by setting as properties on the third parameter, `options` From 4ac5096ee1b704ac333f151bbcba875aee411b2f Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 19:03:07 +0100 Subject: [PATCH 085/127] 'config' --- docs/_usage/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_usage/configuration.md b/docs/_usage/configuration.md index 71bf2ddf..ca1a8cec 100644 --- a/docs/_usage/configuration.md +++ b/docs/_usage/configuration.md @@ -12,7 +12,7 @@ parameters: default: true content: Automatically sets a `content-length` header on each response. - name: fallbackToNetwork - default: false + default: "false" content: |- - `true`: Unhandled calls transparently fall through to the network - `false`: Unhandled calls throw an error From 3e0c9e0aa3d667fdca2de4e9e675171be5137f2c Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 19:03:35 +0100 Subject: [PATCH 086/127] 'config' --- docs/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.html b/docs/index.html index 6fd92ec8..5062eefb 100644 --- a/docs/index.html +++ b/docs/index.html @@ -24,7 +24,7 @@

      {% if doc.parametersBlockTitle %}{{ doc.parametersBlockTitle }}{% else %}Parameters{% endif %}
      {% for parameter in doc.parameters %} -
      {{ parameter.name }}{%if parameter.type %} {{ parameter.type}}{% endif %}{%if parameter.default %} [{{ parameter.default}}]{% endif %}
      +
      {{ parameter.name }}{%if parameter.type %} {{ parameter.type}}{% endif %}{%if parameter.default %} [default {{ parameter.default}}]{% endif %}
      {{ parameter.content | markdownify }}
      {% endfor %}
      From 8bbc0efca9800840227ff12554c550b1bff9ed1c Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 19:09:17 +0100 Subject: [PATCH 087/127] 'config' --- docs/_usage/configuration.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/docs/_usage/configuration.md b/docs/_usage/configuration.md index ca1a8cec..2a0d3b2f 100644 --- a/docs/_usage/configuration.md +++ b/docs/_usage/configuration.md @@ -14,10 +14,20 @@ parameters: - name: fallbackToNetwork default: "false" content: |- - - `true`: Unhandled calls transparently fall through to the network + - `true`: Unhandled calls fall through to the network - `false`: Unhandled calls throw an error - `'always'`: All calls fall through to the network, effectively disabling fetch-mock. - + - name: overwriteRoutes + default: "undefined" + content: |- + Determines behaviour if a new route has the same name (or inferred name) as an existing one + - `undefined`: An error will be throw when routes clash + - `true`: Overwrites the existing route + - `false`: Appends the new route to the list of routes + - name: warnOnFallback + default: true + content: |- + Print a warning if any call is caught by a fallback handler (set using the `fallbackToNetwork` option or `catch()`) content_markdown: |- Many of the options above can be overridden for individual calls to `.mock(matcher, response, options)` by setting as properties on the third parameter, `options` {: .info} From 439e5b531f73c2abe6df56301bedb81ed0c6e046 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 19:14:10 +0100 Subject: [PATCH 088/127] 'config' --- docs/_usage/configuration.md | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/docs/_usage/configuration.md b/docs/_usage/configuration.md index 2a0d3b2f..0af622a8 100644 --- a/docs/_usage/configuration.md +++ b/docs/_usage/configuration.md @@ -28,11 +28,18 @@ parameters: default: true content: |- Print a warning if any call is caught by a fallback handler (set using the `fallbackToNetwork` option or `catch()`) + - name: Promise + content: Reference to the `Promise` constructor of a custom `Promise` implementation + - name: fetch + content: Reference to a custom `fetch` implementation + - name: Headers + content: Reference to the `Headers` constructor of a custom `fetch` implementation + - name: Request + content: Reference to the `Request` constructor of a custom `fetch` implementation + - name: Response + content: Reference to the `Response` constructor of a custom `fetch` implementation + content_markdown: |- Many of the options above can be overridden for individual calls to `.mock(matcher, response, options)` by setting as properties on the third parameter, `options` {: .info} - - When using non standard fetch (e.g. a ponyfill, or aversion of `node-fetch` other than the one bundled with `fetch-mock`) or an alternative Promise implementation, this will configure fetch-mock to use your chosen implementations. - - Note that `Object.assign(fetchMock.config, require('fetch-ponyfill')())` will configure fetch-mock to use all of fetch-ponyfill's classes. In most cases, it should only be necessary to set this once before any tests run. --- From aeaafffde830a98c3ff94e58e3d8750f8fe34e4a Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 19:23:14 +0100 Subject: [PATCH 089/127] 'config' --- docs/_sass/_main.scss | 12 +++--------- docs/index.html | 2 +- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/docs/_sass/_main.scss b/docs/_sass/_main.scss index 47e12910..d3cb03f0 100644 --- a/docs/_sass/_main.scss +++ b/docs/_sass/_main.scss @@ -301,13 +301,6 @@ hr { border-image-slice: 1; padding: 30px 0; background: #ffffff; /* Old browsers */ - background: -moz-linear-gradient(left, #ffffff 0%, #ffffff 60%, #232323 60%); /* FF3.6+ */ - background: -webkit-gradient(linear, left top, right top, color-stop(0%,#ffffff), color-stop(60%,#ffffff), color-stop(60%,#232323)); /* Chrome,Safari4+ */ - background: -webkit-linear-gradient(left, #ffffff 0%,#ffffff 60%,#232323 60%); /* Chrome10+,Safari5.1+ */ - background: -o-linear-gradient(left, #ffffff 0%,#ffffff 60%,#232323 60%); /* Opera 11.10+ */ - background: -ms-linear-gradient(left, #ffffff 0%,#ffffff 60%,#232323 60%); /* IE10+ */ - background: linear-gradient(to right, #ffffff 0%,#ffffff 60%,#232323 60%); /* W3C */ - filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#232323',GradientType=1 ); /* IE6-9 */ } .doc-content:after { @@ -323,9 +316,9 @@ hr { } .left-docs { - width: 60%; + width: 80%; float: left; - padding: 0 50px; + padding: 0 150px; -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */ -moz-box-sizing: border-box; /* Firefox, other Gecko */ box-sizing: border-box; /* Opera/IE 8+ */ @@ -339,6 +332,7 @@ hr { } .right-code { + display: none; width: 40%; float: left; padding: 0 50px; diff --git a/docs/index.html b/docs/index.html index 5062eefb..60d5354a 100644 --- a/docs/index.html +++ b/docs/index.html @@ -24,7 +24,7 @@

      {% if doc.parametersBlockTitle %}{{ doc.parametersBlockTitle }}{% else %}Parameters{% endif %}
      {% for parameter in doc.parameters %} -
      {{ parameter.name }}{%if parameter.type %} {{ parameter.type}}{% endif %}{%if parameter.default %} [default {{ parameter.default}}]{% endif %}
      +
      {{ parameter.name }}{%if parameter.type %} {{ parameter.type}}{% endif %}{%if parameter.default %} [default {{ parameter.default}}]{% endif %}
      {{ parameter.content | markdownify }}
      {% endfor %}
      From c198a0e66b6ea250b03a46f9738d157a88d894e6 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 19:28:31 +0100 Subject: [PATCH 090/127] 'config' --- docs/_sass/_main.scss | 8 ++---- docs/_sass/_monaki.scss | 64 ----------------------------------------- docs/css/style.scss | 1 - 3 files changed, 3 insertions(+), 70 deletions(-) delete mode 100644 docs/_sass/_monaki.scss diff --git a/docs/_sass/_main.scss b/docs/_sass/_main.scss index d3cb03f0..5c2d88df 100644 --- a/docs/_sass/_main.scss +++ b/docs/_sass/_main.scss @@ -295,9 +295,7 @@ hr { .doc-content { border: 0; border-bottom: 1px solid transparent; - border-image: linear-gradient(to right, #eee 0%,#eee 60%,#333333 60%); - -moz-border-image: -moz-linear-gradient(left, #eee 0%, #eee 60%, #333333 60%); - -webkit-border-image: -webkit-linear-gradient(left, #eee 0%,#eee 60%,#333333 60%); + border-image: linear-gradient(to right, #eee 0%,#eee 100%); border-image-slice: 1; padding: 30px 0; background: #ffffff; /* Old browsers */ @@ -316,9 +314,9 @@ hr { } .left-docs { - width: 80%; + width: 100%; float: left; - padding: 0 150px; + padding: 0 200px; -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */ -moz-box-sizing: border-box; /* Firefox, other Gecko */ box-sizing: border-box; /* Opera/IE 8+ */ diff --git a/docs/_sass/_monaki.scss b/docs/_sass/_monaki.scss deleted file mode 100644 index 6cae0d82..00000000 --- a/docs/_sass/_monaki.scss +++ /dev/null @@ -1,64 +0,0 @@ -.right-code code .hll { background-color: #49483e } -.right-code code .c { color: #75715e } /* Comment */ -.right-code code .err { color: #960050; background-color: #1e0010 } /* Error */ -.right-code code .k { color: #66d9ef } /* Keyword */ -.right-code code .l { color: #ae81ff } /* Literal */ -.right-code code .n { color: #f8f8f2 } /* Name */ -.right-code code .o { color: #f92672 } /* Operator */ -.right-code code .p { color: #f8f8f2 } /* Punctuation */ -.right-code code .cm { color: #75715e } /* Comment.Multiline */ -.right-code code .cp { color: #75715e } /* Comment.Preproc */ -.right-code code .c1 { color: #75715e } /* Comment.Single */ -.right-code code .cs { color: #75715e } /* Comment.Special */ -.right-code code .ge { font-style: italic } /* Generic.Emph */ -.right-code code .gs { font-weight: bold } /* Generic.Strong */ -.right-code code .kc { color: #66d9ef } /* Keyword.Constant */ -.right-code code .kd { color: #66d9ef } /* Keyword.Declaration */ -.right-code code .kn { color: #f92672 } /* Keyword.Namespace */ -.right-code code .kp { color: #66d9ef } /* Keyword.Pseudo */ -.right-code code .kr { color: #66d9ef } /* Keyword.Reserved */ -.right-code code .kt { color: #66d9ef } /* Keyword.Type */ -.right-code code .ld { color: #e6db74 } /* Literal.Date */ -.right-code code .m { color: #ae81ff } /* Literal.Number */ -.right-code code .s { color: #e6db74 } /* Literal.String */ -.right-code code .na { color: #a6e22e } /* Name.Attribute */ -.right-code code .nb { color: #f8f8f2 } /* Name.Builtin */ -.right-code code .nc { color: #a6e22e } /* Name.Class */ -.right-code code .no { color: #66d9ef } /* Name.Constant */ -.right-code code .nd { color: #a6e22e } /* Name.Decorator */ -.right-code code .ni { color: #f8f8f2 } /* Name.Entity */ -.right-code code .ne { color: #a6e22e } /* Name.Exception */ -.right-code code .nf { color: #a6e22e } /* Name.Function */ -.right-code code .nl { color: #f8f8f2 } /* Name.Label */ -.right-code code .nn { color: #f8f8f2 } /* Name.Namespace */ -.right-code code .nx { color: #a6e22e } /* Name.Other */ -.right-code code .py { color: #f8f8f2 } /* Name.Property */ -.right-code code .nt { color: #f92672 } /* Name.Tag */ -.right-code code .nv { color: #f8f8f2 } /* Name.Variable */ -.right-code code .ow { color: #f92672 } /* Operator.Word */ -.right-code code .w { color: #f8f8f2 } /* Text.Whitespace */ -.right-code code .mf { color: #ae81ff } /* Literal.Number.Float */ -.right-code code .mh { color: #ae81ff } /* Literal.Number.Hex */ -.right-code code .mi { color: #ae81ff } /* Literal.Number.Integer */ -.right-code code .mo { color: #ae81ff } /* Literal.Number.Oct */ -.right-code code .sb { color: #e6db74 } /* Literal.String.Backtick */ -.right-code code .sc { color: #e6db74 } /* Literal.String.Char */ -.right-code code .sd { color: #e6db74 } /* Literal.String.Doc */ -.right-code code .s2 { color: #e6db74 } /* Literal.String.Double */ -.right-code code .se { color: #ae81ff } /* Literal.String.Escape */ -.right-code code .sh { color: #e6db74 } /* Literal.String.Heredoc */ -.right-code code .si { color: #e6db74 } /* Literal.String.Interpol */ -.right-code code .sx { color: #e6db74 } /* Literal.String.Other */ -.right-code code .sr { color: #e6db74 } /* Literal.String.Regex */ -.right-code code .s1 { color: #e6db74 } /* Literal.String.Single */ -.right-code code .ss { color: #e6db74 } /* Literal.String.Symbol */ -.right-code code .bp { color: #f8f8f2 } /* Name.Builtin.Pseudo */ -.right-code code .vc { color: #f8f8f2 } /* Name.Variable.Class */ -.right-code code .vg { color: #f8f8f2 } /* Name.Variable.Global */ -.right-code code .vi { color: #f8f8f2 } /* Name.Variable.Instance */ -.right-code code .il { color: #ae81ff } /* Literal.Number.Integer.Long */ - -.right-code code .gh { } /* Generic Heading & Diff Header */ -.right-code code .gu { color: #75715e; } /* Generic.Subheading & Diff Unified/Comment? */ -.right-code code .gd { color: #f92672; } /* Generic.Deleted & Diff Deleted */ -.right-code code .gi { color: #a6e22e; } /* Generic.Inserted & Diff Inserted */ diff --git a/docs/css/style.scss b/docs/css/style.scss index e8f30d35..a41447af 100644 --- a/docs/css/style.scss +++ b/docs/css/style.scss @@ -22,5 +22,4 @@ $mobile-break: 700px; @import "mixins"; @import "main"; @import "borland"; -@import "monaki"; @import "cloudcannon"; From 0e4512734c814918f06bcfcc445fbd6b4ba15263 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 19:31:12 +0100 Subject: [PATCH 091/127] 'config' --- docs/css/style.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/css/style.scss b/docs/css/style.scss index a41447af..9e71c2b1 100644 --- a/docs/css/style.scss +++ b/docs/css/style.scss @@ -7,7 +7,7 @@ $brand-colour: #35d69b; $nav-header-height: 60px; $nav-background-color: #f5f5f5; -$nav-width: 210px; +$nav-width: 300px; $space: 20px; From 3dd9d9d6f71b1438ba07955a86a4a052b09e0d12 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 19:40:23 +0100 Subject: [PATCH 092/127] 'config' --- Gemfile | 2 +- docs/_about/introduction.md | 2 +- docs/css/style.scss | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index 34ff721e..724febd0 100644 --- a/Gemfile +++ b/Gemfile @@ -1,4 +1,4 @@ -source 'http://rubygems.org' +source 'https://rubygems.org' gem 'jekyll', '3.7.2' diff --git a/docs/_about/introduction.md b/docs/_about/introduction.md index 28a69800..88275e9a 100644 --- a/docs/_about/introduction.md +++ b/docs/_about/introduction.md @@ -5,7 +5,7 @@ parameters: - name: content: content_markdown: |- - fetch-mock allows mocking http requests made using fetch, or one of the many libraries imitating its api such as [node-fetch](https://www.npmjs.com/package/node-fetch) and [fetch-ponyfill](https://www.npmjs.com/package/fetch-ponyfill). + fetch-mock allows mocking http requests made using [fetch](https://fetch.spec.whatwg.org/), or one of the many libraries imitating its api, such as [node-fetch](https://www.npmjs.com/package/node-fetch) and [fetch-ponyfill](https://www.npmjs.com/package/fetch-ponyfill). It supports most JavaScript environments, including nodejs, web workers and service workers, and any browser that either supports fetch natively or that can have a fetch polyfill/ponyfill installed. diff --git a/docs/css/style.scss b/docs/css/style.scss index 9e71c2b1..385de919 100644 --- a/docs/css/style.scss +++ b/docs/css/style.scss @@ -11,6 +11,7 @@ $nav-width: 300px; $space: 20px; + $mobile-break: 700px; {% if site.baseurl %} From 5a5d79ae07a022a29eb03d5e69b40f3619123f53 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 19:41:37 +0100 Subject: [PATCH 093/127] 'config' --- docs/_sass/_main.scss | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/docs/_sass/_main.scss b/docs/_sass/_main.scss index 5c2d88df..28cc7775 100644 --- a/docs/_sass/_main.scss +++ b/docs/_sass/_main.scss @@ -294,11 +294,8 @@ hr { .doc-content { border: 0; - border-bottom: 1px solid transparent; - border-image: linear-gradient(to right, #eee 0%,#eee 100%); - border-image-slice: 1; + border-bottom: 1px solid #eee; padding: 30px 0; - background: #ffffff; /* Old browsers */ } .doc-content:after { From 64fcef687dc1e6596e69c9e0edf40dcbeaa8c044 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 19:43:57 +0100 Subject: [PATCH 094/127] 'config' --- docs/_sass/_main.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_sass/_main.scss b/docs/_sass/_main.scss index 28cc7775..a0c376d3 100644 --- a/docs/_sass/_main.scss +++ b/docs/_sass/_main.scss @@ -313,7 +313,7 @@ hr { .left-docs { width: 100%; float: left; - padding: 0 200px; + padding: 0 180px; -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */ -moz-box-sizing: border-box; /* Firefox, other Gecko */ box-sizing: border-box; /* Opera/IE 8+ */ From 2ca1aca307e5b5cabcb2434fc9a78f8020346f6c Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 19:46:08 +0100 Subject: [PATCH 095/127] 'config' --- docs/_usage/{global.md => global-non-global.md} | 5 ++++- docs/_usage/installation.md | 3 --- 2 files changed, 4 insertions(+), 4 deletions(-) rename docs/_usage/{global.md => global-non-global.md} (65%) diff --git a/docs/_usage/global.md b/docs/_usage/global-non-global.md similarity index 65% rename from docs/_usage/global.md rename to docs/_usage/global-non-global.md index d21bcc67..74338eb2 100644 --- a/docs/_usage/global.md +++ b/docs/_usage/global-non-global.md @@ -1,10 +1,13 @@ --- -title: Global fetch +title: Global or non-global fetch position: 3 parameters: - name: content: content_markdown: |- + `fetch` can be used by your code in two different ways. It's important to determine which one applies to your codebase as it will impact how you use `fetch-mock` + {: .warning} + #### Global fetch In the following scenarios `fetch` will be a global - When using native `fetch` (or a polyfill) in the browser - When `node-fetch` has been assigned to `global` in your nodejs process (a pattern sometiems used in isomorphic codebases) diff --git a/docs/_usage/installation.md b/docs/_usage/installation.md index d9d3466f..6d3adf94 100644 --- a/docs/_usage/installation.md +++ b/docs/_usage/installation.md @@ -25,8 +25,5 @@ content_markdown: |- {: .info} For server side tests running in nodejs 6 or lower use `require('fetch-mock/es5/server')` {: .info} - - `fetch` can be used by your code in two different ways. It's important to determine which one applies to your codebase as it will impact how you use `fetch-mock` - {: .warning} --- From d97153f8eb10349aad903eedf2556142708b6cdb Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 19:47:10 +0100 Subject: [PATCH 096/127] 'config' --- docs/_usage/global-non-global.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/_usage/global-non-global.md b/docs/_usage/global-non-global.md index 74338eb2..c66b587c 100644 --- a/docs/_usage/global-non-global.md +++ b/docs/_usage/global-non-global.md @@ -1,13 +1,14 @@ --- -title: Global or non-global fetch +title: Global or non-global position: 3 parameters: - name: content: content_markdown: |- - `fetch` can be used by your code in two different ways. It's important to determine which one applies to your codebase as it will impact how you use `fetch-mock` + `fetch` can be used by your code in two different ways. It's important to determine which one applies to your codebase as it will impact how you use `fetch-mock` {: .warning} - #### Global fetch + + #### Global fetch In the following scenarios `fetch` will be a global - When using native `fetch` (or a polyfill) in the browser - When `node-fetch` has been assigned to `global` in your nodejs process (a pattern sometiems used in isomorphic codebases) From 074b1359cfd3e71bc5b2dd5b889f3c18f104bbc3 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 19:49:38 +0100 Subject: [PATCH 097/127] 'config' --- Gemfile | 2 +- docs/_usage/global-non-global.md | 19 ++++++++++++++++++- docs/_usage/installation.md | 4 ++-- docs/_usage/library.md | 24 ------------------------ 4 files changed, 21 insertions(+), 28 deletions(-) delete mode 100644 docs/_usage/library.md diff --git a/Gemfile b/Gemfile index 724febd0..34ff721e 100644 --- a/Gemfile +++ b/Gemfile @@ -1,4 +1,4 @@ -source 'https://rubygems.org' +source 'http://rubygems.org' gem 'jekyll', '3.7.2' diff --git a/docs/_usage/global-non-global.md b/docs/_usage/global-non-global.md index c66b587c..7bbd5e23 100644 --- a/docs/_usage/global-non-global.md +++ b/docs/_usage/global-non-global.md @@ -5,7 +5,7 @@ parameters: - name: content: content_markdown: |- - `fetch` can be used by your code in two different ways. It's important to determine which one applies to your codebase as it will impact how you use `fetch-mock` + `fetch` can be used by your code globally or locally. It's important to determine which one applies to your codebase as it will impact how you use `fetch-mock` {: .warning} #### Global fetch @@ -14,4 +14,21 @@ content_markdown: |- - When `node-fetch` has been assigned to `global` in your nodejs process (a pattern sometiems used in isomorphic codebases) By default fetch-mock assumes `fetch` is a global so once you've required fetch-mock, refer to the quickstart and api docs. + + #### Non-global fetch library + In the following scenarios `fetch` will not be a global + + - Using [node-fetch](https://www.npmjs.com/package/node-fetch) in nodejs without assigning to `global` + - Using [fetch-ponyfill](https://www.npmjs.com/package/fetch-ponyfill) in the browser + - Using libraries which use fetch-ponyfill internally + - Some build setups result in a non-global `fetch`, though it may not always be obvious that this is the case + + The `sandbox()` method returns a function that can be used as a drop-in replacement for `fetch`, and can be passed into your choice of mocking library. The function returned by `sandbox()` supports the full fetch-mock api so once generated it can be worked with as if it were the original `fetch-mock` object, e.g. + + ```js + const fetchMock = require('fetch-mock'); + const myMock = fetchMock.sandbox().mock('/home', 200); + // pass myMock in to your application code, instead of fetch, run it, then... + expect(myMock.called('/home')).to.be.true; + ``` --- diff --git a/docs/_usage/installation.md b/docs/_usage/installation.md index 6d3adf94..f41ed43d 100644 --- a/docs/_usage/installation.md +++ b/docs/_usage/installation.md @@ -22,8 +22,8 @@ content_markdown: |- 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')`. {: .warning} 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. - {: .info} + {: .warning} For server side tests running in nodejs 6 or lower use `require('fetch-mock/es5/server')` - {: .info} + {: .warning} --- diff --git a/docs/_usage/library.md b/docs/_usage/library.md deleted file mode 100644 index 57dd28b0..00000000 --- a/docs/_usage/library.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: Non-global fetch -position: 4 -parameters: - - name: - content: -content_markdown: |- - In the following scenarios `fetch` will not be a global - - - Using [node-fetch](https://www.npmjs.com/package/node-fetch) in nodejs without assigning to `global` - - Using [fetch-ponyfill](https://www.npmjs.com/package/fetch-ponyfill) in the browser - - Using libraries which use fetch-ponyfill internally - - Some build setups result in a non-global `fetch`, though it may not always be obvious that this is the case - - The `sandbox()` method returns a function that can be used as a drop-in replacement for `fetch`, and can be passed into your choice of mocking library. The function returned by `sandbox()` supports the full fetch-mock api so once generated it can be worked with as if it were the original `fetch-mock` object, e.g. - - ```js - const fetchMock = require('fetch-mock'); - const myMock = fetchMock.sandbox().mock('/home', 200); - // pass myMock in to your application code, instead of fetch, run it, then... - expect(myMock.called('/home')).to.be.true; - ``` ---- - From ee215718ce2b935c3f3aea725f6df8d3452b4dc5 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 19:51:58 +0100 Subject: [PATCH 098/127] 'config' --- docs/_sass/_main.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_sass/_main.scss b/docs/_sass/_main.scss index a0c376d3..ab0ffe57 100644 --- a/docs/_sass/_main.scss +++ b/docs/_sass/_main.scss @@ -313,7 +313,7 @@ hr { .left-docs { width: 100%; float: left; - padding: 0 180px; + padding: 0 150px; -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */ -moz-box-sizing: border-box; /* Firefox, other Gecko */ box-sizing: border-box; /* Opera/IE 8+ */ From d44115e24f9431c7a27bef132834e8c213361e93 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 19:53:40 +0100 Subject: [PATCH 099/127] 'config' --- docs/_about/quickstart.md | 56 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 docs/_about/quickstart.md diff --git a/docs/_about/quickstart.md b/docs/_about/quickstart.md new file mode 100644 index 00000000..eaeeac63 --- /dev/null +++ b/docs/_about/quickstart.md @@ -0,0 +1,56 @@ +--- +title: Quickstart +position: 2 + +content_markdown: |- + + #### Setting up your mock + + The commonest use case is `fetchMock.mock(matcher, response)`, where `matcher` is a string or regex to match and `response` is a statusCode, string or object literal. You can also use `fetchMock.once(url ...)` to limit to a single call or `fetchMock.get()`, `fetchMock.post()` etc. to limit to a method. All these methods are chainable so you can easily define several mocks in a single test. + + #### Analysing calls to your mock + + `fetchMock.called(matcher)` reports if any calls matched your mock (or leave `matcher` out if you just want to check `fetch` was called at all). `fetchMock.lastCall()`, `fetchMock.lastUrl()` or `fetchMock.lastOptions()` give you access to the parameters last passed in to `fetch`. `fetchMock.done()` will tell you if `fetch` was called the expected number of times. + + #### Tearing down your mock + + `fetchMock.reset()` resets the call history. `fetchMock.restore()` will also restore `fetch()` to its native implementation + + #### Example + + Example with node: suppose we have a file `make-request.js` with a function that calls `fetch`: + + ```js + module.exports = function makeRequest() { + return fetch('http://httpbin.org/get').then(function(response) { + return response.json(); + }); + }; + ``` + + We can use fetch-mock to mock `fetch`. In `mocked.js`: + + ```js + var fetchMock = require('fetch-mock'); + var makeRequest = require('./make-request'); + + // Mock the fetch() global to always return the same value for GET + // requests to all URLs. + fetchMock.get('*', { hello: 'world' }); + + makeRequest().then(function(data) { + console.log('got data', data); + }); + + // Unmock. + fetchMock.restore(); + ``` + + Result: + + ```bash + $ node mocked.js + 'got data' { hello: 'world' } + ``` + +--- From 156519577452eaf86bddd4b7c050b1813fda9094 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 19:56:05 +0100 Subject: [PATCH 100/127] 'config' --- docs/_about/quickstart.md | 6 +++--- docs/_config.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/_about/quickstart.md b/docs/_about/quickstart.md index eaeeac63..4caf0a2b 100644 --- a/docs/_about/quickstart.md +++ b/docs/_about/quickstart.md @@ -6,7 +6,7 @@ content_markdown: |- #### Setting up your mock - The commonest use case is `fetchMock.mock(matcher, response)`, where `matcher` is a string or regex to match and `response` is a statusCode, string or object literal. You can also use `fetchMock.once(url ...)` to limit to a single call or `fetchMock.get()`, `fetchMock.post()` etc. to limit to a method. All these methods are chainable so you can easily define several mocks in a single test. + The commonest use case is `fetchMock.mock(matcher, response)`, where `matcher` is an exact url or regex to match, and `response` is a statusCode, string or object literal. You can also use `fetchMock.once(url ...)` to limit to a single call or `fetchMock.get()`, `fetchMock.post()` etc. to limit to a method. All these methods are chainable so you can easily define several mocks in a single test. #### Analysing calls to your mock @@ -14,7 +14,7 @@ content_markdown: |- #### Tearing down your mock - `fetchMock.reset()` resets the call history. `fetchMock.restore()` will also restore `fetch()` to its native implementation + `fetchMock.resetHistory()` resets the call history. `fetchMock.reset()` will also restore `fetch()` to its native implementation #### Example @@ -43,7 +43,7 @@ content_markdown: |- }); // Unmock. - fetchMock.restore(); + fetchMock.reset(); ``` Result: diff --git a/docs/_config.yml b/docs/_config.yml index f5533d1e..da86b1de 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -20,7 +20,7 @@ collections: title: "Usage" position: 2 api: - title: API documentation + title: API position: 3 plugins: - jekyll-sitemap From 49ea168da02f2fb0beacd3a980476dc679265e13 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 19:57:08 +0100 Subject: [PATCH 101/127] 'config' --- docs/_about/introduction.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/_about/introduction.md b/docs/_about/introduction.md index 88275e9a..af3b8e6e 100644 --- a/docs/_about/introduction.md +++ b/docs/_about/introduction.md @@ -5,9 +5,9 @@ parameters: - name: content: content_markdown: |- - fetch-mock allows mocking http requests made using [fetch](https://fetch.spec.whatwg.org/), or one of the many libraries imitating its api, such as [node-fetch](https://www.npmjs.com/package/node-fetch) and [fetch-ponyfill](https://www.npmjs.com/package/fetch-ponyfill). + fetch-mock allows mocking http requests made using [fetch](https://fetch.spec.whatwg.org/), or one of the many libraries imitating its api, such as [node-fetch](https://www.npmjs.com/package/node-fetch) or [fetch-ponyfill](https://www.npmjs.com/package/fetch-ponyfill). - It supports most JavaScript environments, including nodejs, web workers and service workers, and any browser that either supports fetch natively or that can have a fetch polyfill/ponyfill installed. + It supports most JavaScript environments, including nodejs, web workers and service workers, and any browser that either supports fetch natively or that can have a fetch polyfill installed. As well as shorthand methods for the simplest use cases, it offers a flexible API for customising all aspects of mocking behaviour. From 7b4fd821a4e61b1d6b61e726690eb28c420123a4 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 20:11:02 +0100 Subject: [PATCH 102/127] 'config' --- docs/_sass/_main.scss | 1 + docs/css/style.scss | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_sass/_main.scss b/docs/_sass/_main.scss index ab0ffe57..2df6b12e 100644 --- a/docs/_sass/_main.scss +++ b/docs/_sass/_main.scss @@ -313,6 +313,7 @@ hr { .left-docs { width: 100%; float: left; + padding: 0 150px; -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */ -moz-box-sizing: border-box; /* Firefox, other Gecko */ diff --git a/docs/css/style.scss b/docs/css/style.scss index 385de919..9e71c2b1 100644 --- a/docs/css/style.scss +++ b/docs/css/style.scss @@ -11,7 +11,6 @@ $nav-width: 300px; $space: 20px; - $mobile-break: 700px; {% if site.baseurl %} From c473bc3130dfb7e2a51aa1d3ad6dd528489bbd3b Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 20:20:07 +0100 Subject: [PATCH 103/127] 'remove search' --- docs/_layouts/default.html | 7 +- docs/{siteicon.png => images/logo.png} | Bin docs/js/search.js | 102 ------------------------- docs/search.html | 39 ---------- 4 files changed, 1 insertion(+), 147 deletions(-) rename docs/{siteicon.png => images/logo.png} (100%) delete mode 100644 docs/js/search.js delete mode 100644 docs/search.html diff --git a/docs/_layouts/default.html b/docs/_layouts/default.html index 8f54326a..4928d499 100644 --- a/docs/_layouts/default.html +++ b/docs/_layouts/default.html @@ -25,14 +25,9 @@

      - {{ site.title }} logo + fetch-mock

      -
      - - -
      - {% include sidebar.html %}
    • " + titlePreview + "

      " + contentPreview + "

    • "; - }); - - searchResultsEl.innerHTML = resultsHTML; - searchProcessEl.innerText = "Showing"; - } else { - searchResultsEl.style.display = "none"; - searchProcessEl.innerText = "No"; - } - } - - window.index = lunr(function () { - this.field("id"); - this.field("title", {boost: 10}); - this.field("category"); - this.field("url"); - this.field("content"); - }); - - var query = decodeURIComponent((getQueryVariable("q") || "").replace(/\+/g, "%20")), - searchQueryContainerEl = document.getElementById("search-query-container"), - searchQueryEl = document.getElementById("search-query"), - searchInputEl = document.getElementById("search-input"); - - searchInputEl.value = query; - searchQueryEl.innerText = query; - searchQueryContainerEl.style.display = "inline"; - - for (var key in window.data) { - window.index.add(window.data[key]); - } - - displaySearchResults(window.index.search(query), query); // Hand the results off to be displayed -})(); diff --git a/docs/search.html b/docs/search.html deleted file mode 100644 index 59e55c82..00000000 --- a/docs/search.html +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: Search -sitemap: false -permalink: /search/ ---- - -
      -

      Search Results

      - -

      Loading results

      -
        -
        - - - - From 5aefc0ed73b614d0672876e5ff263bca3ac35c4b Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 20:22:28 +0100 Subject: [PATCH 104/127] 'config' --- docs/_sass/_main.scss | 85 +------------------------------------------ 1 file changed, 1 insertion(+), 84 deletions(-) diff --git a/docs/_sass/_main.scss b/docs/_sass/_main.scss index 2df6b12e..37b331b9 100644 --- a/docs/_sass/_main.scss +++ b/docs/_sass/_main.scss @@ -313,11 +313,8 @@ hr { .left-docs { width: 100%; float: left; - padding: 0 150px; - -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */ - -moz-box-sizing: border-box; /* Firefox, other Gecko */ - box-sizing: border-box; /* Opera/IE 8+ */ + box-sizing: border-box; pre { border: 0px; @@ -326,31 +323,6 @@ hr { padding: 10px; } } - -.right-code { - display: none; - width: 40%; - float: left; - padding: 0 50px; - -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */ - -moz-box-sizing: border-box; /* Firefox, other Gecko */ - box-sizing: border-box; /* Opera/IE 8+ */ - - code { - color: #fff; - } - - pre { - background: black; - padding: 10px; - border-radius: 5px; - } - - .code-viewer .languages li a:hover { - border-color: #555; - } -} - .code-viewer { .languages { padding: 0; @@ -405,13 +377,6 @@ hr { } @media (max-width: 1000px) { - .right-code { - float: none; - width: 100%; - background: #232323; - padding-top: 20px; - padding-bottom: 20px; - } .left-docs { float: none; @@ -503,54 +468,6 @@ header { } } -#search-input { - -webkit-appearance: none; - - display: block; - margin: 0; - padding: 10px 20px; - width: 100%; - box-sizing: border-box; - - border: 0; - border-bottom: 1px solid rgba(0, 0, 0, 0.075); - - font-size: 1.5rem; - font-weight: 600; - line-height: 1.8; - - &:focus { - outline: none; - border-left: 5px solid $brand-colour; - padding-left: 15px; - } -} - -.search-page { - max-width: 800px; - margin: 0 0 0 50px; - padding: 50px 20px 0 20px; -} - -#search-results { - margin: 0; - padding: 0; - - li { - list-style: none; - margin: 0; - padding: 0; - - h4 { - font-size: 2rem; - } - - p { - line-height: 1.5; - } - } -} - .copyright { text-align: center; font-size: .6em; From 831f9affd96a4d2871414f0e92a3279f25991ca0 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 20:22:48 +0100 Subject: [PATCH 105/127] 'config' --- docs/_usage/configuration.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/_usage/configuration.md b/docs/_usage/configuration.md index 0af622a8..278083a3 100644 --- a/docs/_usage/configuration.md +++ b/docs/_usage/configuration.md @@ -42,4 +42,5 @@ parameters: content_markdown: |- Many of the options above can be overridden for individual calls to `.mock(matcher, response, options)` by setting as properties on the third parameter, `options` {: .info} + --- From 30feeda1386ea6b2c6bda44381c09708b11f10d5 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 20:44:40 +0100 Subject: [PATCH 106/127] 'config' --- docs/_sass/_main.scss | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/_sass/_main.scss b/docs/_sass/_main.scss index 37b331b9..e654b60b 100644 --- a/docs/_sass/_main.scss +++ b/docs/_sass/_main.scss @@ -130,20 +130,21 @@ dl { border-bottom: 1px solid #eee; padding: 0 0 20px 0; margin: 0 0 20px 0; + display: grid; + grid-gap: 1rem; + grid-template-columns: 30% 1fr; } dl dt { - width: 30%; - float: left; + grid-column-start: 1; + girid-column-end: 2 font-weight: bold; - position: relative; - top: 20px; } dl dd { - margin-left: 30%; + grid-column-start: 2; + grid-column-end: 3; padding-left: 15px; - margin-top: 20px; } dl dd + dd { From b871db37373ed8f8c5a0af3da6824f07aefb9315 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 20:45:43 +0100 Subject: [PATCH 107/127] 'config' --- docs/_sass/_main.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_sass/_main.scss b/docs/_sass/_main.scss index e654b60b..e3284bf4 100644 --- a/docs/_sass/_main.scss +++ b/docs/_sass/_main.scss @@ -137,7 +137,7 @@ dl { dl dt { grid-column-start: 1; - girid-column-end: 2 + grid-column-end: 2 font-weight: bold; } From fbced51cb4b528665d06b051817550234ffbf903 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 27 Aug 2018 20:48:11 +0100 Subject: [PATCH 108/127] 'restyle' --- docs/_about/quickstart.md | 1 + docs/_sass/_main.scss | 12 ------------ 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/docs/_about/quickstart.md b/docs/_about/quickstart.md index 4caf0a2b..808a09ad 100644 --- a/docs/_about/quickstart.md +++ b/docs/_about/quickstart.md @@ -28,6 +28,7 @@ content_markdown: |- }; ``` + We can use fetch-mock to mock `fetch`. In `mocked.js`: ```js diff --git a/docs/_sass/_main.scss b/docs/_sass/_main.scss index e3284bf4..1e764b88 100644 --- a/docs/_sass/_main.scss +++ b/docs/_sass/_main.scss @@ -147,18 +147,6 @@ dl dd { padding-left: 15px; } -dl dd + dd { - margin-top: 0; -} - -dl dd:after { - visibility: hidden; - display: block; - content: ""; - clear: both; - height: 0; -} - .sidebar h6 { line-height: 1em; font-size: 1.5rem; From d41c500d8bc1d50a1524c2594784abd1e18ad348 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Tue, 28 Aug 2018 23:06:45 +0100 Subject: [PATCH 109/127] 'mainly styling' --- Gemfile.lock | 69 ++++++++++++++++++++ docs/_api/mock.md | 10 ++- docs/_api/mock_matcher.md | 109 ++++++++++++++++---------------- docs/_config.yml | 4 +- docs/_includes/sidebar.html | 4 +- docs/_includes/tiny-syntax.html | 7 ++ docs/_sass/_main.scss | 7 +- docs/_usage/requirements.md | 3 + docs/index.html | 10 ++- 9 files changed, 159 insertions(+), 64 deletions(-) create mode 100644 Gemfile.lock create mode 100644 docs/_includes/tiny-syntax.html diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 00000000..cafd634f --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,69 @@ +GEM + remote: http://rubygems.org/ + specs: + addressable (2.5.2) + public_suffix (>= 2.0.2, < 4.0) + colorator (1.1.0) + concurrent-ruby (1.0.5) + em-websocket (0.5.1) + eventmachine (>= 0.12.9) + http_parser.rb (~> 0.6.0) + eventmachine (1.2.7) + ffi (1.9.25) + forwardable-extended (2.6.0) + http_parser.rb (0.6.0) + i18n (0.9.5) + concurrent-ruby (~> 1.0) + jekyll (3.7.2) + addressable (~> 2.4) + colorator (~> 1.0) + em-websocket (~> 0.5) + i18n (~> 0.7) + jekyll-sass-converter (~> 1.0) + jekyll-watch (~> 2.0) + kramdown (~> 1.14) + liquid (~> 4.0) + mercenary (~> 0.3.3) + pathutil (~> 0.9) + rouge (>= 1.7, < 4) + safe_yaml (~> 1.0) + jekyll-sass-converter (1.5.2) + sass (~> 3.4) + jekyll-seo-tag (2.4.0) + jekyll (~> 3.3) + jekyll-sitemap (1.2.0) + jekyll (~> 3.3) + jekyll-watch (2.0.0) + listen (~> 3.0) + kramdown (1.17.0) + liquid (4.0.0) + listen (3.1.5) + rb-fsevent (~> 0.9, >= 0.9.4) + rb-inotify (~> 0.9, >= 0.9.7) + ruby_dep (~> 1.2) + mercenary (0.3.6) + pathutil (0.16.1) + forwardable-extended (~> 2.6) + public_suffix (3.0.3) + rb-fsevent (0.10.3) + rb-inotify (0.9.10) + ffi (>= 0.5.0, < 2) + rouge (3.2.1) + ruby_dep (1.5.0) + safe_yaml (1.0.4) + sass (3.5.7) + sass-listen (~> 4.0.0) + sass-listen (4.0.0) + rb-fsevent (~> 0.9, >= 0.9.4) + rb-inotify (~> 0.9, >= 0.9.7) + +PLATFORMS + ruby + +DEPENDENCIES + jekyll (= 3.7.2) + jekyll-seo-tag (= 2.4.0) + jekyll-sitemap (= 1.2.0) + +BUNDLED WITH + 1.16.1 diff --git a/docs/_api/mock.md b/docs/_api/mock.md index 9bdef13d..54bd9d6d 100644 --- a/docs/_api/mock.md +++ b/docs/_api/mock.md @@ -1,14 +1,18 @@ --- title: ".mock(matcher, response, options)" +navTitle: .mock() position: 1.0 description: "Replaces `fetch` with a stub which records its calls and returns a `Response` instance." parameters: - name: matcher - content: "String|Regex|Function: Rule for matching calls to `fetch`" + content: |- + String\|Regex\|Function: Rule for matching calls to `fetch` - name: response - content: "String|Object|Function|Promise: Response to send matched calls" + content: |- + String\|Object\|Function\|Promise: Response to send matched calls - name: options - content: "Object: More options configuring [mainly] matching behaviour" + content: |- + Object: More options configuring [mainly] matching behaviour content_markdown: |- Alternatively a single parameter, `options`, an `Object` with `matcher`, `response` and other options defined, can be passed diff --git a/docs/_api/mock_matcher.md b/docs/_api/mock_matcher.md index 94966ca6..2e606525 100644 --- a/docs/_api/mock_matcher.md +++ b/docs/_api/mock_matcher.md @@ -1,65 +1,66 @@ --- -title: ".mock() - #matcher" +title: "matcher" position: 1.1 -description: "String|Regex|Function: Rule for matching calls to `fetch`" -parametersBlockTitle: Variants +description: "String|Regex|Function: Rule for matching calls to `fetch`." +parametersBlockTitle: Values +method: mock parameters: - name: "*" content: Matches any url - - name: "url, e.g. 'http://www.site.com/page.html'" - content: Match an exact url -content_markdown: |- - asdasd - + examples: + - '"*"' + - name: url + examples: + - |- + "http://www.site.com/page.html" + content: Matches an exact url + - name: |- + begin: + examples: + - |- + "begin:http://www.site.com" + content: Matches a url beginning with a string + - name: |- + end: + examples: + - |- + "end:.jpg" + content: Matches a url ending with a string + - name: |- + path: + examples: + - |- + "path:/posts/2018/7/3" + content: Matches a url which has a given path + - name: |- + glob: + examples: + - |- + "glob:http://*.*" + content: Matches a url using a glob pattern + - name: |- + express: + examples: + - |- + "express:/user/:user" + content: |- + Matches a [relative] url that matches an [express style path](https://www.npmjs.com/package/path-to-regexp) + - name: RegExp + examples: + - |- + /(article|post)/\d+/ + content: Matches a url that matches a regular expression + - name: Function + examples: + - |- + (url, {headers}) => !!headers.Authorization + - |- + (_, _, request) => !!request.headers.get('Authorization') + content: Matches if a function returns something truthy. the function will receive the `url` and `options` arguments `fetch` was called with. If `fetch` was called with a `Request` instance, it will be passed `url` and `options` inferred from the `Request` instance. The original `Request` will be passed as a third argument. -right_code_blocks: - - title: Example - language: javascript - code_block: |- - fetchMock - .mock('begin:http://it.at.here/api', 200, { - headers: { - authorization: 'Basic dummy-token' - } - }) - .mock('begin:http://it.at.here/api', 403) - - callApi('/endpoint', 'dummy-token') - .then(res => { - expect(res.status).to.equal(200) - }) +content_markdown: |- -left_code_blocks: - - code_block: |- - fetchMock - .mock('http://it.at.here/route', 200) - .mock('begin:http://it', 200) - .mock('end:here/route', 200) - .mock('path:/route', 200) - .mock('*', 200) - title: Strings - language: javascript - - code_block: |- - fetchMock - .mock(/.*\.here.*/, 200) - .mock((url, opts) => opts.method === 'patch', 200) - .mock('express:/:type/:id', 200, { - params: { - type: 'shoe' - } - }) - title: Complex Matchers - language: javascript - - code_block: |- - fetchMock - .mock('*', 'ok') - .mock('*', 404) - .mock('*', {results: []}) - .mock('*', {throw: new Error('Bad kitty'))) - .mock('*', new Promise(res => setTimeout(res, 1000, 404))) - title: Responses - language: javascript --- diff --git a/docs/_config.yml b/docs/_config.yml index da86b1de..ed081f3e 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -38,7 +38,9 @@ defaults: layout: default - scope: - type: "introduction" + type: "about" + values: + _hide_content: true - scope: type: "general" diff --git a/docs/_includes/sidebar.html b/docs/_includes/sidebar.html index 0d8ecfbb..7ca97107 100644 --- a/docs/_includes/sidebar.html +++ b/docs/_includes/sidebar.html @@ -7,9 +7,9 @@
        {{ collection.title }}
        {% endif %} {{ doc.content_markdown | markdownify | replace: "
        ", "
        Parameters
        " }} @@ -39,16 +76,9 @@
        {% if doc.parametersBlockTitle %}{{ doc.parametersBlockTitle }}{% else %}Par {% if doc.left_code_blocks and doc.left_code_blocks[0].code_block %} {% for block in doc.left_code_blocks %} {% include syntax-highlight.html block=block %} - {% endfor %} - {% endif %} - - {% if doc.right_code_blocks and doc.right_code_blocks[0].code_block %} -
        - {% for block in doc.right_code_blocks %} - {% include syntax-highlight.html block=block %} {% endfor %} -
        - {% endif %} + {% endif %} + {% endfor %} {% endfor %} diff --git a/docs/js/main.js b/docs/js/main.js index db6927e8..3a135f7f 100644 --- a/docs/js/main.js +++ b/docs/js/main.js @@ -12,7 +12,6 @@ jQuery(function() { }); $("section > div.highlighter-rouge:first-of-type").each(function(i) { - var $this = $(this).before("
          "), $languages = $this.prev(), $notFirst = $this.nextUntil(":not(div.highlighter-rouge)"), From be0ecf0efe88ad8b48f52b4e48366bea36f20e76 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Wed, 29 Aug 2018 22:40:15 +0100 Subject: [PATCH 112/127] 'restyle' --- docs/_usage/custom-classes.md | 3 --- docs/_usage/global-non-global.md | 3 --- docs/_usage/installation.md | 3 --- docs/_usage/polyfilling.md | 3 --- docs/_usage/requirements.md | 3 --- 5 files changed, 15 deletions(-) diff --git a/docs/_usage/custom-classes.md b/docs/_usage/custom-classes.md index 9b92c63e..6c496f88 100644 --- a/docs/_usage/custom-classes.md +++ b/docs/_usage/custom-classes.md @@ -1,9 +1,6 @@ --- title: Custom subclasses position: 6 -parameters: - - name: - content: content_markdown: |- Some fetch-mock internals require access to the `Request`, `Response` and `Headers` constructors provided by your chosen `fetch` implementation. These should be set on the `fetchMock.config` object {: .warning} diff --git a/docs/_usage/global-non-global.md b/docs/_usage/global-non-global.md index 7bbd5e23..564f606a 100644 --- a/docs/_usage/global-non-global.md +++ b/docs/_usage/global-non-global.md @@ -1,9 +1,6 @@ --- title: Global or non-global position: 3 -parameters: - - name: - content: content_markdown: |- `fetch` can be used by your code globally or locally. It's important to determine which one applies to your codebase as it will impact how you use `fetch-mock` {: .warning} diff --git a/docs/_usage/installation.md b/docs/_usage/installation.md index 9f659197..d757c034 100644 --- a/docs/_usage/installation.md +++ b/docs/_usage/installation.md @@ -1,9 +1,6 @@ --- title: Installation position: 2 -parameters: - - name: - content: content_markdown: |- Install fetch-mock using diff --git a/docs/_usage/polyfilling.md b/docs/_usage/polyfilling.md index 4f72279a..6209e90a 100644 --- a/docs/_usage/polyfilling.md +++ b/docs/_usage/polyfilling.md @@ -1,9 +1,6 @@ --- title: Polyfilling fetch position: 5 -parameters: - - name: - content: content_markdown: |- Many older browsers require polyfilling the `fetch` global. The following approaches can be used diff --git a/docs/_usage/requirements.md b/docs/_usage/requirements.md index 9fbd33dd..f1c0108f 100644 --- a/docs/_usage/requirements.md +++ b/docs/_usage/requirements.md @@ -1,9 +1,6 @@ --- title: Requirements position: 1 -parameters: - - name: - content: content_markdown: |- fetch-mock requires the following to run: From da293fdedead30ceae6264edffa553107896f35a Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Thu, 30 Aug 2018 20:39:23 +0100 Subject: [PATCH 113/127] started documenting mock options --- docs/_about/quickstart.md | 2 +- docs/_api/books_delete.md | 41 ---------------- docs/_api/books_get.md | 37 -------------- docs/_api/books_update.md | 46 ------------------ docs/_api/mock_matcher.md | 6 +-- docs/_api/mock_options.md | 93 ++++++++++++++++++++++++++++++++++++ docs/_api/mock_response.md | 60 +++++++++++++---------- docs/_includes/types.html | 3 +- docs/_sass/_main.scss | 17 +++++-- docs/_usage/configuration.md | 12 ++--- docs/index.html | 8 +--- 11 files changed, 155 insertions(+), 170 deletions(-) delete mode 100644 docs/_api/books_delete.md delete mode 100644 docs/_api/books_get.md delete mode 100644 docs/_api/books_update.md create mode 100644 docs/_api/mock_options.md diff --git a/docs/_about/quickstart.md b/docs/_about/quickstart.md index a16c46ff..bf9c1991 100644 --- a/docs/_about/quickstart.md +++ b/docs/_about/quickstart.md @@ -6,7 +6,7 @@ content_markdown: |- #### Setting up your mock - The commonest use case is `fetchMock.mock(matcher, response)`, where `matcher` is an exact url or regex to match, and `response` is a statusCode, string or object literal. You can also use `fetchMock.once(url ...)` to limit to a single call or `fetchMock.get()`, `fetchMock.post()` etc. to limit to a method. All these methods are chainable so you can easily define several mocks in a single test. + The commonest use case is `fetchMock.mock(matcher, response)`, where `matcher` is an exact url or regex to match, and `response` is a status code, string or object literal. You can also use `fetchMock.once()` to limit to a single call or `fetchMock.get()`, `fetchMock.post()` etc. to limit to a method. All these methods are chainable so you can easily define several mocks in a single test. ```javascript fetchMock diff --git a/docs/_api/books_delete.md b/docs/_api/books_delete.md deleted file mode 100644 index 007db9c8..00000000 --- a/docs/_api/books_delete.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -title: /books/:id -position: 1.5 -type: delete -description: Deletes a book -parameters: - - name: - content: -content_markdown: |- - Deletes a book in your collection. -left_code_blocks: - - code_block: |- - $.ajax({ - "url": "http://api.myapp.com/books/3", - "type": "DELETE", - "data": { - "token": "YOUR_APP_KEY" - }, - "success": function(data) { - alert(data); - } - }); - title: jQuery - language: javascript -right_code_blocks: - - code_block: |2- - { - "id": 3, - "status": "deleted" - } - title: Response - language: json - - code_block: |2- - { - "error": true, - "message": "Book doesn't exist" - } - title: Error - language: json ---- - diff --git a/docs/_api/books_get.md b/docs/_api/books_get.md deleted file mode 100644 index 30df6faf..00000000 --- a/docs/_api/books_get.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: /books/:id -position: 1.3 -type: get -description: Get Book -parameters: - - name: - content: -content_markdown: |- - Returns a specific book from your collection -left_code_blocks: - - code_block: |- - $.get("http://api.myapp.com/books/3", { - token: "YOUR_APP_KEY", - }, function(data) { - alert(data); - }); - title: jQuery - language: javascript -right_code_blocks: - - code_block: |2- - { - "id": 3, - "title": "The Book Thief", - "score": 4.3, - "dateAdded": "5/1/2015" - } - title: Response - language: json - - code_block: |2- - { - "error": true, - "message": "Book doesn't exist" - } - title: Error - language: json ---- \ No newline at end of file diff --git a/docs/_api/books_update.md b/docs/_api/books_update.md deleted file mode 100644 index 1b6ccfae..00000000 --- a/docs/_api/books_update.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -title: /books/:id -position: 1.4 -type: put -description: Update Book -parameters: - - name: title - content: The title for the book - - name: score - content: The book's score between 0 and 5 -content_markdown: |- - Update an existing book in your collection. -left_code_blocks: - - code_block: |- - $.ajax({ - "url": "http://api.myapp.com/books/3", - "type": "PUT", - "data": { - "token": "YOUR_APP_KEY", - "score": 5.0, - "title": "The Book Stealer" - }, - "success": function(data) { - alert(data); - } - }); - title: jQuery - language: javascript -right_code_blocks: - - code_block: |2- - { - "id": 3, - "title": "The Book Stealer", - "score": 5, - "dateAdded": "5/1/2015" - } - title: Response - language: json - - code_block: |2- - { - "error": true, - "message": "Book doesn't exist" - } - title: Error - language: json ---- \ No newline at end of file diff --git a/docs/_api/mock_matcher.md b/docs/_api/mock_matcher.md index df5e0a97..98cda43c 100644 --- a/docs/_api/mock_matcher.md +++ b/docs/_api/mock_matcher.md @@ -2,13 +2,13 @@ title: "matcher" position: 1.1 description: |- - Rule for matching calls to `fetch`. - Condition for selecting which requests to mock. (For matching based on headers, query strings or other `fetch` options see the `options` parameter documented below). Accepts any of the following: + Condition for selecting which requests to mock. For matching based on headers, query strings or other `fetch` options see the `options` parameter documented below types: - String - Regex - Function type: parameter +parametersBlockTitle: Argument values parentMethod: mock parameters: - name: "*" @@ -78,7 +78,7 @@ parameters: (url, {headers}) => !!headers.Authorization - |- (_, _, request) => !!request.headers.get('Authorization') - content: Matches if a function returns something truthy. the function will receive the `url` and `options` arguments `fetch` was called with. If `fetch` was called with a `Request` instance, it will be passed `url` and `options` inferred from the `Request` instance. The original `Request` will be passed as a third argument. + content: Matches if a function returns something truthy. The function will be passed the arguments `fetch` was called with. If `fetch` was called with a `Request` instance, it will be passed `url` and `options` inferred from the `Request` instance. The original `Request` will be passed as a third argument. content_markdown: |- diff --git a/docs/_api/mock_options.md b/docs/_api/mock_options.md new file mode 100644 index 00000000..03b940a7 --- /dev/null +++ b/docs/_api/mock_options.md @@ -0,0 +1,93 @@ +--- +title: "options" +position: 1.3 +description: |- + A configuration object with properties to define a route to mock +types: + - Object +type: parameter +parametersBlockTitle: Options +parentMethod: mock +parameters: + - name: name + types: + - String + content: |- + A unique string naming the route. Used to subsequently retrieve references to the calls, grouped by name. Defaults to `matcher.toString()` + - name: method + types: + - String + content: |- + http method to match + - name: headers + types: + - Object | Headers + content: |- + key/value map of headers to match + - name: query + types: + - Object + content: |- + key/value map of query strings to match, in any order + - name: params + types: + - Object + content: |- + when the `express:` keyword is used in a string matcher, a key/value map `params` can be passed here, to match the parameters extracted by express path matching + - name: repeat + type: + - Integer + content: |- + An integer, `n`, limiting the number of times the matcher can be used. If the route has already been called `n` times the route will be ignored and the call to `fetch()` will fall through to be handled by any other routes defined (which may eventually result in an error if nothing matches it) + - name: overwriteRoutes + content: |- + If the route you're adding clashes with an existing route, setting `true` here will overwrite the clashing route, `false` will add another route to the stack which will be used as a fallback (useful when using the `repeat` option). Adding a clashing route without specifying this option will throw an error. It can also be set as a global option (see the **Config** section below) + - name: sendAsJson + default: true + types: + - Boolean + content: See [global configuration](#usageconfiguration) + - name: includeContentLength + default: true + types: + - Boolean + content: See [global configuration](#usageconfiguration) +--- + + + - name: matcher + content: |- + as specified above + - name: response + content: |- + as specified above + + + + - name: sendAsJson + default: true + content: |- + Convert objects into JSON before delivering as stub reponses. Can be useful to set to `false` globally if e.g. dealing with a lot of array buffers. If `true`, will also add `content-type: application/json` header. + - name: includeContentLength + default: true + content: Automatically sets a `content-length` header on each response. + - name: fallbackToNetwork + default: "false" + content: |- + - `true`: Unhandled calls fall through to the network + - `false`: Unhandled calls throw an error + - `'always'`: All calls fall through to the network, effectively disabling fetch-mock. + - name: overwriteRoutes + default: "undefined" + content: |- + Determines behaviour if a new route has the same name (or inferred name) as an existing one + - `undefined`: An error will be throw when routes clash + - `true`: Overwrites the existing route + - `false`: Appends the new route to the list of routes + - name: warnOnFallback + default: true + content: |- + Print a warning if any call is caught by a fallback handler (set using the `fallbackToNetwork` option or `catch()`) + + + diff --git a/docs/_api/mock_response.md b/docs/_api/mock_response.md index f69cbbd5..cc63b407 100644 --- a/docs/_api/mock_response.md +++ b/docs/_api/mock_response.md @@ -11,6 +11,7 @@ types: - Promise - Response type: parameter +parametersBlockTitle: Argument values parentMethod: mock parameters: - types: @@ -18,7 +19,7 @@ parameters: examples: - "new Response('ok', {status: 200})" content: A `Response` instance - will be used unaltered - - name: Status code + - name: status code types: - String examples: @@ -30,52 +31,61 @@ parameters: examples: - Server responded ok - Bad Response - - types: + - name: config + types: - Object - content: If an object _only_ contains properties listed below it used to configure a `Response` + content: If an object _only_ contains properties listed below it is used to configure a `Response` options: - name: body types: - String - Object content: |- - Set the response body + Set the response body. For behaviour for `Object`s, see the non-config `Object` section of the docs below examples: - Server responded ok - { token: 'abcdef' } - name: status + types: + - Integer content: Set the response status examples: - 200, 404, 503 - name: headers + types: + - Object content: Set the response headers examples: - {'Content-Type': 'text/html'} + - name: redirectUrl + types: + - String + content: |- + The url the response should claim to originate from (to imitate followed directs). Will also set `redirected: true` on the response - name: throws + types: + - Error content: |- `fetch` will return a `Promise` rejected with the value of `throws` examples: - "new TypeError('Failed to fetch')" - + - types: + - Object + - ArrayBuffer + content: |- + All objects that do not meet the criteria above will be converted to JSON and set as the response `body` if the `sendAsJson` option is on. Otherwise, they will be set as the response `body` (useful for array buffers etc.) + - types: + - Promise + content: |- + A `Promise` that resolves to any of the options documented above + examples: + - "new Promise(res => setTimeout(() => res(200), 50))" + - types: + - Function + content: |- + A function that is passed the arguments `fetch` is called with and that returns any of the responses listed above + examples: + - "(url, opts) => opts.headers.Authorization ? 200 : 403" + - "(_, _, request) => request.headers.get('Authorization') ? 200 : 403" --- - - - -content: |- - - `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) -content_markdown: |- - - - - `configObject` If an object _does not contain_ any properties aside from those listed below it is treated as config to build a `Response` - - `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 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) - - `object`: All objects that do not meet the criteria above are converted to `JSON` and returned as the body of a 200 response. - - `Function(url, opts)`: A function that is passed the url and opts `fetch()` is called with and that returns any of the responses listed above (or a `Promise` for any of them) diff --git a/docs/_includes/types.html b/docs/_includes/types.html index f1f5da15..4b3a3a88 100644 --- a/docs/_includes/types.html +++ b/docs/_includes/types.html @@ -1,5 +1,6 @@ - +{{ include.block.name }} {% if include.block.types %} +{% if include.block.name %}
          {% endif %} {% for type in include.block.types %} {{type}}
          {% if forloop.last != true %}|{% endif %} diff --git a/docs/_sass/_main.scss b/docs/_sass/_main.scss index b9662cf8..f6d8de5c 100644 --- a/docs/_sass/_main.scss +++ b/docs/_sass/_main.scss @@ -132,13 +132,16 @@ dl.parameters { margin: 0 0 20px 0; display: grid; grid-gap: 1rem; - grid-template-columns: 25% 1fr; + grid-template-columns: 20% 1fr; } dl.options { display: grid; grid-gap: 1rem; grid-template-columns: 15% 1fr; + margin-right: -30%; + background: #f3f3f3; + padding: 10px; } dl dt { @@ -147,7 +150,7 @@ dl dt { font-weight: bold; } -dl dd { +dl dd > *:not(dl) { grid-column-start: 2; grid-column-end: 3; } @@ -333,7 +336,7 @@ hr { .left-docs { width: 100%; float: left; - padding: 0 150px; + padding: 0 50px; box-sizing: border-box; pre { @@ -342,6 +345,14 @@ hr { border-radius: 3px; padding: 10px; } + + p, pre, ul, dd { + max-width: 560px + } + + dd { + max-width: 400px + } } .code-viewer { .languages { diff --git a/docs/_usage/configuration.md b/docs/_usage/configuration.md index 4b4d558b..a1396116 100644 --- a/docs/_usage/configuration.md +++ b/docs/_usage/configuration.md @@ -5,27 +5,27 @@ description: |- On any `fetchMock` instance, config can be set by setting properties on `fetchMock.config`. parametersBlockTitle: Options parameters: - - name: sendAsJson + - name: sendAsJson default: true content: |- Convert objects into JSON before delivering as stub reponses. Can be useful to set to `false` globally if e.g. dealing with a lot of array buffers. If `true`, will also add `content-type: application/json` header. - - name: includeContentLength + - name: includeContentLength default: true content: Automatically sets a `content-length` header on each response. - - name: fallbackToNetwork + - name: fallbackToNetwork default: "false" content: |- - `true`: Unhandled calls fall through to the network - `false`: Unhandled calls throw an error - `'always'`: All calls fall through to the network, effectively disabling fetch-mock. - - name: overwriteRoutes + - name: overwriteRoutes default: "undefined" content: |- Determines behaviour if a new route has the same name (or inferred name) as an existing one - `undefined`: An error will be throw when routes clash - `true`: Overwrites the existing route - `false`: Appends the new route to the list of routes - - name: warnOnFallback + - name: warnOnFallback default: true content: |- Print a warning if any call is caught by a fallback handler (set using the `fallbackToNetwork` option or `catch()`) @@ -41,7 +41,7 @@ parameters: content: Reference to the `Response` constructor of a custom `fetch` implementation content_markdown: |- - Many of the options above can be overridden for individual calls to `.mock(matcher, response, options)` by setting as properties on the third parameter, `options` + Options marked with a `†` can also be overridden for individual calls to `.mock(matcher, response, options)` by setting as properties on the `options` parameter {: .info} --- diff --git a/docs/index.html b/docs/index.html index ad619945..ca102bba 100644 --- a/docs/index.html +++ b/docs/index.html @@ -25,9 +25,7 @@

          {% endif %} {% if doc.parameters %} - {% if doc.type == "parameter" %} -

          Values
          - {% elsif doc.parametersBlockTitle %} + {% if doc.parametersBlockTitle %}
          {{ doc.parametersBlockTitle }}
          {% else %}
          Parameters
          @@ -36,11 +34,9 @@
          Parameters
          {% for parameter in doc.parameters %}
          - {{ parameter.name }} {% include types.html block=parameter %}
          - {{ parameter.content | markdownify }} {% if parameter.examples %} {% for example in parameter.examples %} @@ -51,11 +47,9 @@
          Parameters
          {% for option in parameter.options %}
          - {{ option.name }} {% include types.html block=option %}
          - {{ option.content | markdownify }} {% if option.examples %} {% for example in option.examples %} From 6aef711a67ccec625d256385f58e91b454ab7118 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Thu, 30 Aug 2018 20:45:09 +0100 Subject: [PATCH 114/127] erm --- docs/_usage/configuration.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/_usage/configuration.md b/docs/_usage/configuration.md index a1396116..aa1d0ca5 100644 --- a/docs/_usage/configuration.md +++ b/docs/_usage/configuration.md @@ -12,20 +12,20 @@ parameters: - name: includeContentLength default: true content: Automatically sets a `content-length` header on each response. - - name: fallbackToNetwork + - name: fallbackToNetwork default: "false" content: |- - `true`: Unhandled calls fall through to the network - `false`: Unhandled calls throw an error - `'always'`: All calls fall through to the network, effectively disabling fetch-mock. - - name: overwriteRoutes + - name: overwriteRoutes default: "undefined" content: |- Determines behaviour if a new route has the same name (or inferred name) as an existing one - `undefined`: An error will be throw when routes clash - `true`: Overwrites the existing route - `false`: Appends the new route to the list of routes - - name: warnOnFallback + - name: warnOnFallback default: true content: |- Print a warning if any call is caught by a fallback handler (set using the `fallbackToNetwork` option or `catch()`) From e5071afe4c32df02756558e90c71835f19f8dd3f Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Thu, 30 Aug 2018 22:31:54 +0100 Subject: [PATCH 115/127] document mock options --- .gitignore | 2 ++ docs/.gitignore | 2 -- docs/_api/mock_options.md | 58 ++++++++---------------------------- docs/_usage/configuration.md | 4 +-- 4 files changed, 17 insertions(+), 49 deletions(-) delete mode 100644 docs/.gitignore diff --git a/.gitignore b/.gitignore index 9b9d7e8d..b778f969 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,5 @@ coverage/ /test/fixtures/built-sw.js .nyc_output .eslintcache +/docs/_site/ +/docs/.sass-cache/ diff --git a/docs/.gitignore b/docs/.gitignore deleted file mode 100644 index 0c3e5abb..00000000 --- a/docs/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -_site/ -.sass-cache/ diff --git a/docs/_api/mock_options.md b/docs/_api/mock_options.md index 03b940a7..0f80af7c 100644 --- a/docs/_api/mock_options.md +++ b/docs/_api/mock_options.md @@ -18,30 +18,32 @@ parameters: types: - String content: |- - http method to match + Http method to match - name: headers types: - - Object | Headers + - Object + - Headers content: |- - key/value map of headers to match + Key/value map of headers to match - name: query types: - Object content: |- - key/value map of query strings to match, in any order + Key/value map of query strings to match, in any order - name: params types: - Object content: |- - when the `express:` keyword is used in a string matcher, a key/value map `params` can be passed here, to match the parameters extracted by express path matching + When the `express:` keyword is used in a string matcher, a key/value map `params` can be passed here, to match the parameters extracted by express path matching - name: repeat - type: + types: - Integer content: |- An integer, `n`, limiting the number of times the matcher can be used. If the route has already been called `n` times the route will be ignored and the call to `fetch()` will fall through to be handled by any other routes defined (which may eventually result in an error if nothing matches it) - name: overwriteRoutes - content: |- - If the route you're adding clashes with an existing route, setting `true` here will overwrite the clashing route, `false` will add another route to the stack which will be used as a fallback (useful when using the `repeat` option). Adding a clashing route without specifying this option will throw an error. It can also be set as a global option (see the **Config** section below) + types: + - Boolean + content: See [global configuration](#usageconfiguration) - name: sendAsJson default: true types: @@ -52,42 +54,8 @@ parameters: types: - Boolean content: See [global configuration](#usageconfiguration) ---- - - - name: matcher - content: |- - as specified above + content: When using the single argument variant of `.mock()`, any valid matcher as [defined above](#usageapimock_matcher) can be assigned to the options object - name: response - content: |- - as specified above - - - - - name: sendAsJson - default: true - content: |- - Convert objects into JSON before delivering as stub reponses. Can be useful to set to `false` globally if e.g. dealing with a lot of array buffers. If `true`, will also add `content-type: application/json` header. - - name: includeContentLength - default: true - content: Automatically sets a `content-length` header on each response. - - name: fallbackToNetwork - default: "false" - content: |- - - `true`: Unhandled calls fall through to the network - - `false`: Unhandled calls throw an error - - `'always'`: All calls fall through to the network, effectively disabling fetch-mock. - - name: overwriteRoutes - default: "undefined" - content: |- - Determines behaviour if a new route has the same name (or inferred name) as an existing one - - `undefined`: An error will be throw when routes clash - - `true`: Overwrites the existing route - - `false`: Appends the new route to the list of routes - - name: warnOnFallback - default: true - content: |- - Print a warning if any call is caught by a fallback handler (set using the `fallbackToNetwork` option or `catch()`) - - - + content: When using the single argument variant of `.mock()`, any valid response as [defined above](#usageapimock_response) can be assigned to the options object +--- diff --git a/docs/_usage/configuration.md b/docs/_usage/configuration.md index aa1d0ca5..1fd4d87f 100644 --- a/docs/_usage/configuration.md +++ b/docs/_usage/configuration.md @@ -9,7 +9,7 @@ parameters: default: true content: |- Convert objects into JSON before delivering as stub reponses. Can be useful to set to `false` globally if e.g. dealing with a lot of array buffers. If `true`, will also add `content-type: application/json` header. - - name: includeContentLength + - name: includeContentLength default: true content: Automatically sets a `content-length` header on each response. - name: fallbackToNetwork @@ -18,7 +18,7 @@ parameters: - `true`: Unhandled calls fall through to the network - `false`: Unhandled calls throw an error - `'always'`: All calls fall through to the network, effectively disabling fetch-mock. - - name: overwriteRoutes + - name: overwriteRoutes default: "undefined" content: |- Determines behaviour if a new route has the same name (or inferred name) as an existing one From 5a777737ec9b2636b542a58731315d2e2d8fc6e2 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Thu, 30 Aug 2018 22:46:58 +0100 Subject: [PATCH 116/127] 'sandbox' --- docs/_api-lifecycle/sandbox.md | 33 +++++++++ docs/{_api => _api-mocking}/_defaults.md | 0 docs/{_api => _api-mocking}/mock.md | 0 docs/{_api => _api-mocking}/mock_matcher.md | 1 + docs/{_api => _api-mocking}/mock_options.md | 1 + docs/{_api => _api-mocking}/mock_response.md | 1 + docs/_config.yml | 7 +- docs/_sass/_main.scss | 28 +------- docs/index.html | 6 +- old_docs/api.md | 75 ++------------------ 10 files changed, 50 insertions(+), 102 deletions(-) create mode 100644 docs/_api-lifecycle/sandbox.md rename docs/{_api => _api-mocking}/_defaults.md (100%) rename docs/{_api => _api-mocking}/mock.md (100%) rename docs/{_api => _api-mocking}/mock_matcher.md (98%) rename docs/{_api => _api-mocking}/mock_options.md (98%) rename docs/{_api => _api-mocking}/mock_response.md (99%) diff --git a/docs/_api-lifecycle/sandbox.md b/docs/_api-lifecycle/sandbox.md new file mode 100644 index 00000000..257778c2 --- /dev/null +++ b/docs/_api-lifecycle/sandbox.md @@ -0,0 +1,33 @@ +--- +title: ".sandbox()" +position: 1.0 +description: |- + Returns a drop-in mock for fetch which can be passed to other mocking libraries. It implements the full fetch-mock api and maintains its own state independent of other instances, so tests can be run in parallel. +left_code_blocks: + - code_block: |- + fetchMock + .sandbox() + .mock('http://domain.com', 200) + title: Example + language: javascript + +--- + + +#### `sandbox()` + +This returns a drop-in mock for fetch which can be passed to other mocking libraries. It implements the full fetch-mock api and maintains its own state independent of other instances, so tests can be run in parallel. e.g. + +#### `restore()/reset()` + +Chainable method that restores `fetch()` to its unstubbed state and clears all data recorded for its calls. + +#### `resetHistory()` + +Chainable method that clears all data recorded for `fetch()`'s calls. _It will not restore fetch to its default implementation_ + +_Note that `restore()`, `reset()` and `resetHistory()` are all bound to fetchMock, and can be used directly as callbacks e.g. `afterEach(fetchMock.reset)` will work just fine. There is no need for `afterEach(function () {fetchMock.reset()})`_ + +#### `flush()` + +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. diff --git a/docs/_api/_defaults.md b/docs/_api-mocking/_defaults.md similarity index 100% rename from docs/_api/_defaults.md rename to docs/_api-mocking/_defaults.md diff --git a/docs/_api/mock.md b/docs/_api-mocking/mock.md similarity index 100% rename from docs/_api/mock.md rename to docs/_api-mocking/mock.md diff --git a/docs/_api/mock_matcher.md b/docs/_api-mocking/mock_matcher.md similarity index 98% rename from docs/_api/mock_matcher.md rename to docs/_api-mocking/mock_matcher.md index 98cda43c..8e8083b4 100644 --- a/docs/_api/mock_matcher.md +++ b/docs/_api-mocking/mock_matcher.md @@ -10,6 +10,7 @@ types: type: parameter parametersBlockTitle: Argument values parentMethod: mock +parentMethodGroup: mocking parameters: - name: "*" types: diff --git a/docs/_api/mock_options.md b/docs/_api-mocking/mock_options.md similarity index 98% rename from docs/_api/mock_options.md rename to docs/_api-mocking/mock_options.md index 0f80af7c..cdfda10a 100644 --- a/docs/_api/mock_options.md +++ b/docs/_api-mocking/mock_options.md @@ -8,6 +8,7 @@ types: type: parameter parametersBlockTitle: Options parentMethod: mock +parentMethodGroup: mocking parameters: - name: name types: diff --git a/docs/_api/mock_response.md b/docs/_api-mocking/mock_response.md similarity index 99% rename from docs/_api/mock_response.md rename to docs/_api-mocking/mock_response.md index cc63b407..a7bc5486 100644 --- a/docs/_api/mock_response.md +++ b/docs/_api-mocking/mock_response.md @@ -13,6 +13,7 @@ types: type: parameter parametersBlockTitle: Argument values parentMethod: mock +parentMethodGroup: mocking parameters: - types: - Response diff --git a/docs/_config.yml b/docs/_config.yml index ed081f3e..d995d631 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -19,9 +19,12 @@ collections: usage: title: "Usage" position: 2 - api: - title: API + api-mocking: + title: Mocking API position: 3 + api-lifecycle: + title: Lifecycle methods + position: 5 plugins: - jekyll-sitemap - jekyll-seo-tag diff --git a/docs/_sass/_main.scss b/docs/_sass/_main.scss index f6d8de5c..b5a61abe 100644 --- a/docs/_sass/_main.scss +++ b/docs/_sass/_main.scss @@ -237,32 +237,8 @@ h3 .endpoint { font-size: 19px; } -.endpoint.put { - color: #7E57C2; - &:after { - content: "PUT"; - } -} - -.endpoint.delete { - color: #FF7043; - &:after { - content: "DELETE"; - } -} - -.endpoint.get { - color: #66BB6A; - &:after { - content: "GET"; - } -} - -.endpoint.post { +.endpoint a { color: #42A5F5; - &:after { - content: "POST"; - } } .main { @@ -275,7 +251,7 @@ h3 .endpoint { } .description { - color: #aaa; + color: #666; margin-top: -11px; } diff --git a/docs/index.html b/docs/index.html index ca102bba..1ce5ffc1 100644 --- a/docs/index.html +++ b/docs/index.html @@ -11,6 +11,9 @@

          {{ doc.title }} + {% if doc.parentMethod %} + Parameter for {{doc.parentMethod}}() + {% endif %}

          @@ -18,9 +21,6 @@

          {% include types.html block=doc %} {{ doc.description }} - {% if doc.parentMethod %} -
          Parameter for {{doc.parentMethod}}() - {% endif %}

          {% endif %} diff --git a/old_docs/api.md b/old_docs/api.md index 19be9fb6..6b2f1da1 100644 --- a/old_docs/api.md +++ b/old_docs/api.md @@ -1,60 +1,3 @@ -- [Introduction](/fetch-mock) -- [Quickstart](/fetch-mock/quickstart) -- [Installation and usage](/fetch-mock/installation) -- API documentation -- [Troubleshooting](/fetch-mock/troubleshooting) -- [Examples](/fetch-mock/examples) - -# API Documentation - -## Mocking calls to `fetch` - -#### `mock(matcher, response, options)` or `mock(options)` - -Replaces `fetch` with a stub which records its calls, grouped by route, and optionally returns a mocked `Response` object or passes the call through to `fetch()`. Calls to `.mock()` can be chained. _Note that once mocked, `fetch` will error on any unmatched calls. Use `.spy()` or `.catch()` to handle unmocked calls more gracefully_ - -- `matcher`: Condition for selecting which requests to mock. (For matching based on headers, query strings or other `fetch` options see the `options` parameter documented below). Accepts any of the following: - - `string`: Either - - an exact url to match e.g. 'http://www.site.com/page.html' - - `*` to match any url - - `begin:http://www.site.com/` to match urls beginning with a string - - `end:.jpg` to match urls ending with a string - - `path:/posts/2018/7/3` to match urls with a given path - - `glob:http://*.*` to match glob patterns - - `express:/user/:user` to match [express style paths](https://www.npmjs.com/package/path-to-regexp) - - `RegExp`: A regular expression to test the url against - - `Function(url, options, [request])`: A function (returning a Boolean) that is passed the url and options `fetch()` is called with. If `fetch()` was called with a `Request` instance, `url` and some basic `options` will be extracted from teh `Request`, but if more fine graned examination of it is needed, it is available as the third parameter - -_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 - - `string`: Creates a 200 response with the string as the response body - - `configObject` If an object _does not contain_ any properties aside from those listed below it is treated as config to build a `Response` - - `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 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) - - `object`: All objects that do not meet the criteria above are converted to `JSON` and returned as the body of a 200 response. - - `Function(url, opts)`: A function that is passed the url and opts `fetch()` is called with and that returns any of the responses listed above (or a `Promise` for any of them) -- `options`: A configuration object with all/additional properties to define a route to mock - - `name`: A unique string naming the route. Used to subsequently retrieve references to the calls, grouped by name. Defaults to `matcher.toString()` - - `method`: http method to match - - `headers`: key/value map of headers to match - - `query`: key/value map of query strings to match, in any order - - `params`: when the `express:` keyword is used in a string matcher, a key/value map `params` can be passed here, to match the parameters extracted by express path matching - - `matcher`: as specified above - - `response`: as specified above - - `repeat`: An integer, `n`, limiting the number of times the matcher can be used. If the route has already been called `n` times the route will be ignored and the call to `fetch()` will fall through to be handled by any other routes defined (which may eventually result in an error if nothing matches it) - - `overwriteRoutes`: If the route you're adding clashes with an existing route, setting `true` here will overwrite the clashing route, `false` will add another route to the stack which will be used as a fallback (useful when using the `repeat` option). Adding a clashing route without specifying this option will throw an error. It can also be set as a global option (see the **Config** section below) - -#### `sandbox()` - -This returns a drop-in mock for fetch which can be passed to other mocking libraries. It implements the full fetch-mock api and maintains its own state independent of other instances, so tests can be run in parallel. e.g. #### `once()` @@ -90,6 +33,10 @@ To use `.spy()` on a sandboxed `fetchMock`, `fetchMock.config.fetch` must be set Existing sandboxed `fetchMock`s can also have `.sandbox()` called on them, thus building mocks that inherit some settings from a parent mock +#### `sandbox()` + +This returns a drop-in mock for fetch which can be passed to other mocking libraries. It implements the full fetch-mock api and maintains its own state independent of other instances, so tests can be run in parallel. e.g. + #### `restore()/reset()` Chainable method that restores `fetch()` to its unstubbed state and clears all data recorded for its calls. @@ -142,17 +89,3 @@ Returns the options for the last matched call to fetch. When `fetch` was last ca #### `flush()` 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 - -On either the global or sandboxed `fetchMock` instances, the following config options can be set by setting properties on `fetchMock.config`. Many can also be set on individual calls to `.mock()`. - -- `sendAsJson` [default `true`] - by default fetchMock will convert objects to JSON before sending. This is overrideable from each call but for some scenarios e.g. when dealing with a lot of array buffers, it can be useful to default to `false` -- `includeContentLength` [default `true`]: When set to true this will make fetchMock automatically add the `content-length` header. This is especially useful when combined with `sendAsJson` because then fetchMock does the conversion to JSON for you and knows the resulting length so you don’t have to compute this yourself by basically doing the same conversion to JSON. -- `fallbackToNetwork` [default `false`] If true then unmatched calls will transparently fall through to the network, if false an error will be thrown. If set to `always`, all calls will fall through, effectively disabling fetch-mock. to Within individual tests `.catch()` and `spy()` can be used for fine-grained control of this -- `overwriteRoutes`: If a new route clashes with an existing route, setting `true` here will overwrite the clashing route, `false` will add another route to the stack which will be used as a fallback (useful when using the `repeat` option). Adding a clashing route without specifying this option will throw an error. -- `warnOnFallback` [default `true`] If true then any unmatched calls that are caught by a fallback handler (either the network or a custom function set using `catch()`) will emit warnings -- `Headers`,`Request`,`Response`,`Promise`, `fetch` - When using non standard fetch (e.g. a ponyfill, or aversion of `node-fetch` other than the one bundled with `fetch-mock`) or an alternative Promise implementation, this will configure fetch-mock to use your chosen implementations. - -Note that `Object.assign(fetchMock.config, require('fetch-ponyfill')())` will configure fetch-mock to use all of fetch-ponyfill's classes. In most cases, it should only be necessary to set this once before any tests run. From a2c17b1189e62416504dcecc4bf96593a3b32a57 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Thu, 30 Aug 2018 23:32:09 +0100 Subject: [PATCH 117/127] 'headings' --- docs/_config.yml | 18 +++++++----------- docs/_troubleshooting/{sadsad => it.md} | 1 + docs/index.html | 7 ++++++- 3 files changed, 14 insertions(+), 12 deletions(-) rename docs/_troubleshooting/{sadsad => it.md} (99%) diff --git a/docs/_config.yml b/docs/_config.yml index d995d631..ae7b58f4 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -15,16 +15,19 @@ timezone: Etc/UTC collections: about: title: "About" - position: 1 + position: 0 usage: title: "Usage" - position: 2 + position: 1 api-mocking: title: Mocking API - position: 3 + position: 2 api-lifecycle: title: Lifecycle methods - position: 5 + position: 3 + troubleshooting: + title: Troubleshooting + position: 4 plugins: - jekyll-sitemap - jekyll-seo-tag @@ -57,13 +60,6 @@ defaults: # ----------- # CloudCannon - -types: - - get - - put - - delete - - post - languages: bash: Bash javascript: JavaScript diff --git a/docs/_troubleshooting/sadsad b/docs/_troubleshooting/it.md similarity index 99% rename from docs/_troubleshooting/sadsad rename to docs/_troubleshooting/it.md index 401a0e13..c4168646 100644 --- a/docs/_troubleshooting/sadsad +++ b/docs/_troubleshooting/it.md @@ -1,3 +1,4 @@ +it.md - When using karma-webpack it's best not to use the `webpack.ProvidePlugin` for this. Instead just add `node_modules/whatwg-fetch/fetch.js` to your list of files to include, or require it directly into your tests before requiring fetch-mock. - chaining diff --git a/docs/index.html b/docs/index.html index 1ce5ffc1..21558fbf 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1,8 +1,13 @@ --- title: API Docs --- -{% assign sorted_collections = site.collections | sort: "position" %} +{% assign sorted_collections = site.collections | sort: "position" %} {% for collection in sorted_collections %} + {% if collection.title %} + {% unless collection.title == "About" %} +

          {{collection.title}}

          + {% endunless %} + {% endif %} {% assign sorted_docs = collection.docs | sort: "position" %} {% for doc in sorted_docs %}
          From 2e88e398431f792c63f07e483efb0abdcda1c032 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Fri, 31 Aug 2018 08:05:14 +0100 Subject: [PATCH 118/127] 'style tweaks' --- docs/_about/quickstart.md | 11 ++++++++--- docs/_api-mocking/mock_matcher.md | 10 +++++----- docs/_includes/types.html | 2 +- docs/_sass/_main.scss | 15 +++++++++++++-- docs/_usage/configuration.md | 21 +++++++++++++++++++++ 5 files changed, 48 insertions(+), 11 deletions(-) diff --git a/docs/_about/quickstart.md b/docs/_about/quickstart.md index bf9c1991..e40d1df5 100644 --- a/docs/_about/quickstart.md +++ b/docs/_about/quickstart.md @@ -6,7 +6,9 @@ content_markdown: |- #### Setting up your mock - The commonest use case is `fetchMock.mock(matcher, response)`, where `matcher` is an exact url or regex to match, and `response` is a status code, string or object literal. You can also use `fetchMock.once()` to limit to a single call or `fetchMock.get()`, `fetchMock.post()` etc. to limit to a method. All these methods are chainable so you can easily define several mocks in a single test. + - The commonest use case is `fetchMock.mock(matcher, response)`, where `matcher` is an exact url or regex to match, and `response` is a status code, string or object literal. + - You can also use `fetchMock.once()` to limit to a single call or `fetchMock.get()`, `fetchMock.post()` etc. to limit to a method. + - All these methods are chainable so you can easily define several mocks in a single test. ```javascript fetchMock @@ -16,11 +18,14 @@ content_markdown: |- ``` #### Analysing calls to your mock - `fetchMock.called(matcher)` reports if any calls matched your mock (or leave `matcher` out if you just want to check `fetch` was called at all). `fetchMock.lastCall()`, `fetchMock.lastUrl()` or `fetchMock.lastOptions()` give you access to the parameters last passed in to `fetch`. `fetchMock.done()` will tell you if `fetch` was called the expected number of times. + - `fetchMock.called(matcher)` reports if any calls matched your mock (or leave `matcher` out if you just want to check `fetch` was called at all). + - `fetchMock.lastCall()`, `fetchMock.lastUrl()` or `fetchMock.lastOptions()` give you access to the parameters last passed in to `fetch`. + - `fetchMock.done()` will tell you if `fetch` was called the expected number of times. #### Tearing down your mock - `fetchMock.resetHistory()` resets the call history. `fetchMock.reset()` will also restore `fetch()` to its native implementation + - `fetchMock.resetHistory()` resets the call history. + - `fetchMock.reset()` or `fetchMock.restore()` will also restore `fetch()` to its native implementation #### Example diff --git a/docs/_api-mocking/mock_matcher.md b/docs/_api-mocking/mock_matcher.md index 8e8083b4..c5cd57eb 100644 --- a/docs/_api-mocking/mock_matcher.md +++ b/docs/_api-mocking/mock_matcher.md @@ -26,7 +26,7 @@ parameters: "http://www.site.com/page.html" content: Matches an exact url - name: |- - begin: + begin:... types: - String examples: @@ -34,7 +34,7 @@ parameters: "begin:http://www.site.com" content: Matches a url beginning with a string - name: |- - end: + end:... types: - String examples: @@ -42,7 +42,7 @@ parameters: "end:.jpg" content: Matches a url ending with a string - name: |- - path: + path:... types: - String examples: @@ -50,7 +50,7 @@ parameters: "path:/posts/2018/7/3" content: Matches a url which has a given path - name: |- - glob: + glob:... types: - String examples: @@ -58,7 +58,7 @@ parameters: "glob:http://*.*" content: Matches a url using a glob pattern - name: |- - express: + express:... types: - String examples: diff --git a/docs/_includes/types.html b/docs/_includes/types.html index 4b3a3a88..334bf609 100644 --- a/docs/_includes/types.html +++ b/docs/_includes/types.html @@ -7,5 +7,5 @@ {% endfor %} {% endif %} {%if include.block.default %} - [default {{ include.block.default}}] + [default {{ include.block.default}}] {% endif %} diff --git a/docs/_sass/_main.scss b/docs/_sass/_main.scss index b5a61abe..39178125 100644 --- a/docs/_sass/_main.scss +++ b/docs/_sass/_main.scss @@ -155,11 +155,22 @@ dl dd > *:not(dl) { grid-column-end: 3; } -dt > code { - color: #aa5500; +.default, +dt code { + color: #888; font-family: monospace; } +dt code, +dt sup { + color: #aa5500; +} + +.default, +dt > code { + font-size: 0.9em; +} + p > code, dt > code.name, dd > code, diff --git a/docs/_usage/configuration.md b/docs/_usage/configuration.md index 1fd4d87f..5c9ac7be 100644 --- a/docs/_usage/configuration.md +++ b/docs/_usage/configuration.md @@ -7,19 +7,28 @@ parametersBlockTitle: Options parameters: - name: sendAsJson default: true + types: + - Boolean content: |- Convert objects into JSON before delivering as stub reponses. Can be useful to set to `false` globally if e.g. dealing with a lot of array buffers. If `true`, will also add `content-type: application/json` header. - name: includeContentLength default: true + types: + - Boolean content: Automatically sets a `content-length` header on each response. - name: fallbackToNetwork default: "false" + types: + - Boolean + - String content: |- - `true`: Unhandled calls fall through to the network - `false`: Unhandled calls throw an error - `'always'`: All calls fall through to the network, effectively disabling fetch-mock. - name: overwriteRoutes default: "undefined" + types: + - Boolean content: |- Determines behaviour if a new route has the same name (or inferred name) as an existing one - `undefined`: An error will be throw when routes clash @@ -27,17 +36,29 @@ parameters: - `false`: Appends the new route to the list of routes - name: warnOnFallback default: true + types: + - Boolean content: |- Print a warning if any call is caught by a fallback handler (set using the `fallbackToNetwork` option or `catch()`) - name: Promise + types: + - Constructor content: Reference to the `Promise` constructor of a custom `Promise` implementation - name: fetch + types: + - Function content: Reference to a custom `fetch` implementation - name: Headers + types: + - Constructor content: Reference to the `Headers` constructor of a custom `fetch` implementation - name: Request + types: + - Constructor content: Reference to the `Request` constructor of a custom `fetch` implementation - name: Response + types: + - Constructor content: Reference to the `Response` constructor of a custom `fetch` implementation content_markdown: |- From 1d771de8682fe1e5a3d5b5d696c191d61463b401 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Fri, 31 Aug 2018 08:06:50 +0100 Subject: [PATCH 119/127] 'correct type for status code' --- docs/_api-mocking/mock_response.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_api-mocking/mock_response.md b/docs/_api-mocking/mock_response.md index a7bc5486..c5c0d936 100644 --- a/docs/_api-mocking/mock_response.md +++ b/docs/_api-mocking/mock_response.md @@ -22,7 +22,7 @@ parameters: content: A `Response` instance - will be used unaltered - name: status code types: - - String + - Integer examples: - 200, 404, 503 content: Creates a response with the given status code. The response's `statusText` will also be set to the [default value corresponding to the status](https://fetch.spec.whatwg.org/#dom-response-statustext) From 8042083f4fff8fd2148e4a7b447232d78dd6964c Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Sun, 2 Sep 2018 21:49:01 +0100 Subject: [PATCH 120/127] style reconciliation --- docs/_api-mocking/mock_matcher.md | 2 +- docs/_includes/types.html | 3 ++- docs/_sass/_main.scss | 21 +++++++++++++++------ docs/index.html | 6 +++--- 4 files changed, 21 insertions(+), 11 deletions(-) diff --git a/docs/_api-mocking/mock_matcher.md b/docs/_api-mocking/mock_matcher.md index c5cd57eb..c4146360 100644 --- a/docs/_api-mocking/mock_matcher.md +++ b/docs/_api-mocking/mock_matcher.md @@ -5,7 +5,7 @@ description: |- Condition for selecting which requests to mock. For matching based on headers, query strings or other `fetch` options see the `options` parameter documented below types: - String - - Regex + - RegExp - Function type: parameter parametersBlockTitle: Argument values diff --git a/docs/_includes/types.html b/docs/_includes/types.html index 334bf609..3030c697 100644 --- a/docs/_includes/types.html +++ b/docs/_includes/types.html @@ -1,6 +1,6 @@ {{ include.block.name }} +
          {% if include.block.types %} -{% if include.block.name %}
          {% endif %} {% for type in include.block.types %} {{type}} {% if forloop.last != true %}|{% endif %} @@ -9,3 +9,4 @@ {%if include.block.default %} [default {{ include.block.default}}] {% endif %} +
          diff --git a/docs/_sass/_main.scss b/docs/_sass/_main.scss index 39178125..c67c7da1 100644 --- a/docs/_sass/_main.scss +++ b/docs/_sass/_main.scss @@ -155,20 +155,29 @@ dl dd > *:not(dl) { grid-column-end: 3; } +.types-zone { + // font-family: monospace; + font-size: 0.9em; +} .default, dt code { - color: #888; font-family: monospace; } -dt code, -dt sup { +.types-zone code { + font-family: monospace; + font-weight: bold; + background: none; color: #aa5500; } -.default, -dt > code { - font-size: 0.9em; +.default { + color: #888; +} + +dt code, +dt sup { + color: #aa5500; } p > code, diff --git a/docs/index.html b/docs/index.html index 21558fbf..f803f7ef 100644 --- a/docs/index.html +++ b/docs/index.html @@ -21,11 +21,11 @@

          {% endif %}

          - + {% include types.html block=doc %} {% if doc.description %}

          - {% include types.html block=doc %} - {{ doc.description }} + + {{ doc.description | markdownify }}

          {% endif %} From a57e15548a31cd2f8fee8412e5eb962774866250 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Tue, 4 Sep 2018 07:44:17 +0100 Subject: [PATCH 121/127] more api methods --- docs/_api-inspection/filtering.md | 47 +++++++++++++++++++++++++++ docs/_api-lifecycle/flush.md | 12 +++++++ docs/_api-lifecycle/resetHistory.md | 6 ++++ docs/_api-lifecycle/restore_reset.md | 20 ++++++++++++ docs/_api-lifecycle/sandbox.md | 19 ----------- docs/_api-mocking/catch.md | 12 +++++++ docs/_api-mocking/getOnce_postOnce.md | 8 +++++ docs/_api-mocking/get_post.md | 21 ++++++++++++ docs/_api-mocking/mock_once.md | 7 ++++ docs/_api-mocking/spy.md | 11 +++++++ docs/_config.yml | 7 ++-- docs/_sass/_main.scss | 20 +++++++++--- docs/index.html | 2 +- 13 files changed, 166 insertions(+), 26 deletions(-) create mode 100644 docs/_api-inspection/filtering.md create mode 100644 docs/_api-lifecycle/flush.md create mode 100644 docs/_api-lifecycle/resetHistory.md create mode 100644 docs/_api-lifecycle/restore_reset.md create mode 100644 docs/_api-mocking/catch.md create mode 100644 docs/_api-mocking/getOnce_postOnce.md create mode 100644 docs/_api-mocking/get_post.md create mode 100644 docs/_api-mocking/mock_once.md create mode 100644 docs/_api-mocking/spy.md diff --git a/docs/_api-inspection/filtering.md b/docs/_api-inspection/filtering.md new file mode 100644 index 00000000..4b831414 --- /dev/null +++ b/docs/_api-inspection/filtering.md @@ -0,0 +1,47 @@ +--- +title: "Filtering basics" +position: 1 +description: |- + Most inspection methods take two arguments — `filter` and `options` — which allow groups of fetch calls to be extracted and inspected. +parameters: + - name: filter + types: + - String + - RegExp + - Function + content: |- + Enables filtering fetch calls for the most commonly use cases. The behaviour can be counterintuitive. The following rules, applied in the order they are described, are used to try to retrieve calls. If any rule retrieves no calls the next rule will be tried. + options: + - name: matcher + content: |- + If `options` is defined (it can even be an empty object), `filter` will be executed using the same execution plan as [matchers](#api-mockingmock_matcher). Any calls matched by it will be returned. + types: + - String + - RegExp + - Function + - types: + - undefined + content: |- + Retrieves all calls made to `fetch`, whether fetch-mock matched them or not + - types: + - true + content: |- + Retrieves all calls matched by `fetch`. `fetchMock.MATCHED` is an alias for `true` and may be used to make tests more readable + - types: + - false + content: |- + Retrieves all calls not matched by `fetch` (i.e. those handled by `catch()` or `spy()`. `fetchMock.UNMATCHED` is an alias for `false` and may be used to make tests more readable + - name: route + types: + - String + content: Retrieves calls handled by a named route (see [mocking options](#api-mockingmock_options). Failing that, a route whose matcher, when coerced to a string, is equal to the string provided + - name: asdkash d + content: Do I want to fallback to a matcher again?? Seems confusing as hell + + - name: options + types: + - Object + - String + content: |- + Either an object compatible with the [mocking api](#api-mockingmock_options) or a string specifying a http `method` to filter by +--- diff --git a/docs/_api-lifecycle/flush.md b/docs/_api-lifecycle/flush.md new file mode 100644 index 00000000..8716ae35 --- /dev/null +++ b/docs/_api-lifecycle/flush.md @@ -0,0 +1,12 @@ +--- +title: .flush(waitForBody) +navTitle: ".flush()" +position: 2 +description: |- + Returns a `Promise` that resolves once all fetches handled by fetch-mock have resolved +content_markdown: |- + Useful for testing code that uses `fetch` but doesn't return a promise. + + Pass in `true` to wait for all body parsing methods (`res.json()`, `res.text()`, etc.) to resolve too. + {: .info} +--- diff --git a/docs/_api-lifecycle/resetHistory.md b/docs/_api-lifecycle/resetHistory.md new file mode 100644 index 00000000..0e2a8baa --- /dev/null +++ b/docs/_api-lifecycle/resetHistory.md @@ -0,0 +1,6 @@ +--- +title: .resetHistory() +position: 4 +description: |- + Clears all data recorded for `fetch()`'s calls. It _will not_ restore fetch to its default implementation +--- diff --git a/docs/_api-lifecycle/restore_reset.md b/docs/_api-lifecycle/restore_reset.md new file mode 100644 index 00000000..c710228b --- /dev/null +++ b/docs/_api-lifecycle/restore_reset.md @@ -0,0 +1,20 @@ +--- +title: .restore(), .reset() +navTitle: .restore(), .reset() +position: 3 +description: |- + Restores `fetch()` to its unstubbed state and clears all data recorded for its calls. `reset()` is an alias for `restore()` +--- + +#### `` + +Chainable method that . + +#### `resetHistory()` + +Chainable method that clears all data recorded for `fetch()`'s calls. _It will not restore fetch to its default implementation_ + +_Note that `restore()`, `reset()` and `resetHistory()` are all bound to fetchMock, and can be used directly as callbacks e.g. `afterEach(fetchMock.reset)` will work just fine. There is no need for `afterEach(function () {fetchMock.reset()})`_ + +#### `flush()` + diff --git a/docs/_api-lifecycle/sandbox.md b/docs/_api-lifecycle/sandbox.md index 257778c2..c9d23e2a 100644 --- a/docs/_api-lifecycle/sandbox.md +++ b/docs/_api-lifecycle/sandbox.md @@ -12,22 +12,3 @@ left_code_blocks: language: javascript --- - - -#### `sandbox()` - -This returns a drop-in mock for fetch which can be passed to other mocking libraries. It implements the full fetch-mock api and maintains its own state independent of other instances, so tests can be run in parallel. e.g. - -#### `restore()/reset()` - -Chainable method that restores `fetch()` to its unstubbed state and clears all data recorded for its calls. - -#### `resetHistory()` - -Chainable method that clears all data recorded for `fetch()`'s calls. _It will not restore fetch to its default implementation_ - -_Note that `restore()`, `reset()` and `resetHistory()` are all bound to fetchMock, and can be used directly as callbacks e.g. `afterEach(fetchMock.reset)` will work just fine. There is no need for `afterEach(function () {fetchMock.reset()})`_ - -#### `flush()` - -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. diff --git a/docs/_api-mocking/catch.md b/docs/_api-mocking/catch.md new file mode 100644 index 00000000..1bf42875 --- /dev/null +++ b/docs/_api-mocking/catch.md @@ -0,0 +1,12 @@ +--- +title: ".catch(response)" +navTitle: .catch() +position: 5 +description: |- + Specifies how to respond to calls to `fetch` that don't match any mocks. +parentMethodGroup: mocking +content_markdown: |- + It accepts any valid [fetch-mock response](/#api-mockingmock_response), and can also take an arbitrary function to completely customise behaviour. If no argument is passed, then every unmatched call will receive a `200` response +--- + + diff --git a/docs/_api-mocking/getOnce_postOnce.md b/docs/_api-mocking/getOnce_postOnce.md new file mode 100644 index 00000000..98ea7b8a --- /dev/null +++ b/docs/_api-mocking/getOnce_postOnce.md @@ -0,0 +1,8 @@ +--- +title: ".getOnce(), .postOnce(), .putOnce(), .deleteOnce(), .headOnce(), .patchOnce()" +navTitle: .getOnce(), .postOnce() ... +position: 4 +description: |- + Shorthands for `mock()` restricted to a particular method and that will only respond once +parentMethodGroup: mocking +--- diff --git a/docs/_api-mocking/get_post.md b/docs/_api-mocking/get_post.md new file mode 100644 index 00000000..15b3cd34 --- /dev/null +++ b/docs/_api-mocking/get_post.md @@ -0,0 +1,21 @@ +--- +title: ".get(), .post(), .put(), .delete(), .head(), .patch()" +navTitle: .get(), .post() ... +position: 3 +description: |- + Shorthands for `mock()` restricted to a particular method. +parentMethodGroup: mocking +content_markdown: |- + If you use some other method a lot you can easily define your own shorthands e.g. + {: .info} + + ```javascript + fetchMock.purge = function (matcher, response, options) { + return this.mock( + matcher, + response, + Object.assign({}, options, {method: 'PURGE'}) + ); + } + ``` +--- diff --git a/docs/_api-mocking/mock_once.md b/docs/_api-mocking/mock_once.md new file mode 100644 index 00000000..4f961d83 --- /dev/null +++ b/docs/_api-mocking/mock_once.md @@ -0,0 +1,7 @@ +--- +title: ".once()" +position: 2 +description: |- + Shorthand for `mock()` which limits to being called one time only. (see `repeat` option above) +parentMethodGroup: mocking +--- diff --git a/docs/_api-mocking/spy.md b/docs/_api-mocking/spy.md new file mode 100644 index 00000000..ed66821b --- /dev/null +++ b/docs/_api-mocking/spy.md @@ -0,0 +1,11 @@ +--- +title: ".spy()" +navTitle: .spy() +position: 6 +description: |- + Records call history while passing each call on to `fetch` to be handled by the network +parentMethodGroup: mocking +content_markdown: |- + To use `.spy()` on a sandboxed `fetchMock`, `fetchMock.config.fetch` must be set to a reference to the `fetch` implementation you use in your code. + {: .warning} +--- diff --git a/docs/_config.yml b/docs/_config.yml index ae7b58f4..37308f92 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -14,10 +14,10 @@ timezone: Etc/UTC collections: about: - title: "About" + title: About position: 0 usage: - title: "Usage" + title: Usage position: 1 api-mocking: title: Mocking API @@ -25,6 +25,9 @@ collections: api-lifecycle: title: Lifecycle methods position: 3 + api-inspection: + title: Inspection methods + position: 3 troubleshooting: title: Troubleshooting position: 4 diff --git a/docs/_sass/_main.scss b/docs/_sass/_main.scss index c67c7da1..aede5f89 100644 --- a/docs/_sass/_main.scss +++ b/docs/_sass/_main.scss @@ -132,16 +132,19 @@ dl.parameters { margin: 0 0 20px 0; display: grid; grid-gap: 1rem; - grid-template-columns: 20% 1fr; + grid-template-columns: 25% 1fr; } dl.options { display: grid; grid-gap: 1rem; - grid-template-columns: 15% 1fr; - margin-right: -30%; - background: #f3f3f3; + grid-template-columns: 25% 1fr; + border-color: #eee; + border-top-width: 1px; + border-top-style: solid; padding: 10px; + margin-left: -39%; + font-size: 0.85em; } dl dt { @@ -150,6 +153,10 @@ dl dt { font-weight: bold; } +dd { + margin-left: 0 +} + dl dd > *:not(dl) { grid-column-start: 2; grid-column-end: 3; @@ -159,6 +166,11 @@ dl dd > *:not(dl) { // font-family: monospace; font-size: 0.9em; } + +dl.options .types-zone { + // font-family: monospace; + font-size: 1em; +} .default, dt code { font-family: monospace; diff --git a/docs/index.html b/docs/index.html index f803f7ef..cea8a385 100644 --- a/docs/index.html +++ b/docs/index.html @@ -49,7 +49,7 @@
          Parameters
          {% endfor %} {% endif %} {% if parameter.options %} -
          +
          {% for option in parameter.options %}
          {% include types.html block=option %} From 3f600bd4f985da4db35d3b373947745917be9cec Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Tue, 4 Sep 2018 21:48:02 +0100 Subject: [PATCH 122/127] inspection methods --- docs/_api-inspection/called.md | 7 +++++++ docs/_api-inspection/calls.md | 7 +++++++ docs/_api-inspection/done.md | 10 ++++++++++ docs/_api-inspection/filtering.md | 2 +- docs/_api-inspection/lastCall.md | 7 +++++++ docs/_api-inspection/lastOptions.md | 7 +++++++ docs/_api-inspection/lastUrl.md | 7 +++++++ 7 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 docs/_api-inspection/called.md create mode 100644 docs/_api-inspection/calls.md create mode 100644 docs/_api-inspection/done.md create mode 100644 docs/_api-inspection/lastCall.md create mode 100644 docs/_api-inspection/lastOptions.md create mode 100644 docs/_api-inspection/lastUrl.md diff --git a/docs/_api-inspection/called.md b/docs/_api-inspection/called.md new file mode 100644 index 00000000..de9eb9aa --- /dev/null +++ b/docs/_api-inspection/called.md @@ -0,0 +1,7 @@ +--- +title: .called(filter, options) +navTitle: .called() +position: 1 +description: |- + Returns a Boolean indicating whether any calls to `fetch` matched the given filter +--- diff --git a/docs/_api-inspection/calls.md b/docs/_api-inspection/calls.md new file mode 100644 index 00000000..d16e3a95 --- /dev/null +++ b/docs/_api-inspection/calls.md @@ -0,0 +1,7 @@ +--- +title: .calls(filter, options) +navTitle: .calls() +position: 2 +description: |- + Returns an array of all calls to fetch matching the given filters. Each call is returned as a `[url, options]` array. If `fetch` was called using a `Request` instance, this will be available as a `request` property on this array. +--- diff --git a/docs/_api-inspection/done.md b/docs/_api-inspection/done.md new file mode 100644 index 00000000..936c6252 --- /dev/null +++ b/docs/_api-inspection/done.md @@ -0,0 +1,10 @@ +--- +title: .done(filter, options) +navTitle: .done() +position: 6 +description: |- + Returns a Boolean indicating whether `fetch` was called the expected number of times (or has been called at least once if `repeat` is undefined for the route) +content_markdown: |- + Unlike the other methods for inspecting calls, unmatched calls are irrelevant. If no `filter` is passed, `done()` returns `true` if every route has been called the number of expected times. + {: .warning} +--- diff --git a/docs/_api-inspection/filtering.md b/docs/_api-inspection/filtering.md index 4b831414..aceb3eab 100644 --- a/docs/_api-inspection/filtering.md +++ b/docs/_api-inspection/filtering.md @@ -1,6 +1,6 @@ --- title: "Filtering basics" -position: 1 +position: 0 description: |- Most inspection methods take two arguments — `filter` and `options` — which allow groups of fetch calls to be extracted and inspected. parameters: diff --git a/docs/_api-inspection/lastCall.md b/docs/_api-inspection/lastCall.md new file mode 100644 index 00000000..5776173c --- /dev/null +++ b/docs/_api-inspection/lastCall.md @@ -0,0 +1,7 @@ +--- +title: .lastCall(filter, options) +navTitle: .lastCall() +position: 3 +description: |- + Returns the arguments for the last call to `fetch` matching the given filter +--- diff --git a/docs/_api-inspection/lastOptions.md b/docs/_api-inspection/lastOptions.md new file mode 100644 index 00000000..bd2ffc2d --- /dev/null +++ b/docs/_api-inspection/lastOptions.md @@ -0,0 +1,7 @@ +--- +title: .lastOptions(filter, options) +navTitle: .lastOptions() +position: 5 +description: |- + Returns the options for the call to `fetch` matching the given filter. If `fetch` was last called using a `Request` instance, a set of `options` inferred from the `Request` will be returned +--- diff --git a/docs/_api-inspection/lastUrl.md b/docs/_api-inspection/lastUrl.md new file mode 100644 index 00000000..88436a42 --- /dev/null +++ b/docs/_api-inspection/lastUrl.md @@ -0,0 +1,7 @@ +--- +title: .lastUrl(filter, options) +navTitle: .lastUrl() +position: 4 +description: |- + Returns the url for the last call to `fetch` matching the given filter. If `fetch` was last called using a `Request` instance, the url will be extracted from this +--- From dc5d7e3f83946a16e9ea7acd5aaa2eb4542dcc9d Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Tue, 4 Sep 2018 21:53:40 +0100 Subject: [PATCH 123/127] 'first draft' --- docs/_troubleshooting/it.md | 14 ------ docs/_troubleshooting/troubleshooting.md | 54 ++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 14 deletions(-) delete mode 100644 docs/_troubleshooting/it.md create mode 100644 docs/_troubleshooting/troubleshooting.md diff --git a/docs/_troubleshooting/it.md b/docs/_troubleshooting/it.md deleted file mode 100644 index c4168646..00000000 --- a/docs/_troubleshooting/it.md +++ /dev/null @@ -1,14 +0,0 @@ -it.md -- When using karma-webpack it's best not to use the `webpack.ProvidePlugin` for this. Instead just add `node_modules/whatwg-fetch/fetch.js` to your list of files to include, or require it directly into your tests before requiring fetch-mock. - -- chaining - -- note that end matches qs, path matches only path - - -Put this with the spy() docs -When using `node-fetch`, `fetch-mock` will use the instance you have installed. The one exception is that a reference to `fetchMock.config.fetch = require('node-fetch')` is required if you intend to use the `.spy()` method) -{: .info} - - - to Within individual tests `.catch()` and `spy()` can be used for fine-grained control of this" diff --git a/docs/_troubleshooting/troubleshooting.md b/docs/_troubleshooting/troubleshooting.md new file mode 100644 index 00000000..0cc841d8 --- /dev/null +++ b/docs/_troubleshooting/troubleshooting.md @@ -0,0 +1,54 @@ +--- +title: General +position: 1 +content_markdown: |- + ### `fetch` is assigned to a local variable, not a global + + First of all, consider whether you could just use `fetch` as a global. Here are 3 reasons why this is a good idea: + + - The `fetch` standard defines it as a global (and in some cases it won't work unless bound to `window`), so to write isomorphic code it's probably best to stick to this pattern + - [`isomorphic-fetch`](https://www.npmjs.com/package/isomorphic-fetch) takes care of installing it as a global in nodejs or the browser, so there's no effort on your part to do so. + - `fetch-mock` is primarily designed to work with `fetch` as a global and your experience of using it will be far more straightforward if you follow this pattern + + Still not convinced? + + In that case `fetchMock.sandbox()` can be used to generate a function which you can pass in to a mock loading library such as [`mockery`](https://www.npmjs.com/package/mockery) instead of `fetch` + + ### `fetch` doesn't seem to be getting mocked? + + - If using a mock loading library such as `mockery`, are you requiring the module you're testing after registering `fetch-mock` with the mock loader? You probably should be ([Example incorrect usage](https://github.com/wheresrhys/fetch-mock/issues/70)). If you're using ES6 `import` it may not be possible to do this without reverting to using `require()` sometimes. + - If using `isomorphic-fetch` in your source, are you assigning it to a `fetch` variable? You _shouldn't_ be i.e. + - `import 'isomorphic-fetch'`, not `import fetch from 'isomorphic-fetch'` + - `require('isomorphic-fetch')`, not `const fetch = require('isomorphic-fetch')` + + ### Environment doesn't support requiring fetch-mock? + + - 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-browserified.js` in a script tag. This loads fetch-mock into the `fetchMock` global variable. + - For server side tests running in nodejs 0.12 or lower use `require('fetch-mock/es5/server')` + + ### Matching `Request` objects in node fails + + In node, if using npm at a version less than 2 the `Request` constructor used by `fetch-mock` won't necessarily be the same as the one used by `node-fetch`. To fix this either: + + - upgrade to npm@3 + - use `fetchMock.config.Request = myRequest`, where `myRequest` is a reference to the Request constructor used in your application code. + + +--- + + +it.md +- When using karma-webpack it's best not to use the `webpack.ProvidePlugin` for this. Instead just add `node_modules/whatwg-fetch/fetch.js` to your list of files to include, or require it directly into your tests before requiring fetch-mock. + +- chaining + +- note that end matches qs, path matches only path + + +Put this with the spy() docs +When using `node-fetch`, `fetch-mock` will use the instance you have installed. The one exception is that a reference to `fetchMock.config.fetch = require('node-fetch')` is required if you intend to use the `.spy()` method) +{: .info} + + + to Within individual tests `.catch()` and `spy()` can be used for fine-grained control of this" From ced7aeaef0c2bf5cf256688e92963360f951a5d0 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Wed, 5 Sep 2018 20:52:24 +0100 Subject: [PATCH 124/127] WIP grid layout --- docs/_includes/sidebar.html | 4 +- docs/_layouts/default.html | 9 +- docs/_sass/_docs.scss | 74 +++++++++++++ docs/_sass/_layout.scss | 86 ++++++++++++++++ docs/_sass/_main.scss | 200 +----------------------------------- docs/_sass/_navigation.scss | 113 ++++++++++++++++++++ docs/_sass/_tables.scss | 79 ++++++++++++++ docs/_sass/_typography.scss | 0 docs/css/style.scss | 11 +- docs/index.html | 8 +- docs/js/main.js | 5 +- 11 files changed, 375 insertions(+), 214 deletions(-) create mode 100644 docs/_sass/_docs.scss create mode 100644 docs/_sass/_layout.scss create mode 100644 docs/_sass/_navigation.scss create mode 100644 docs/_sass/_tables.scss create mode 100644 docs/_sass/_typography.scss diff --git a/docs/_includes/sidebar.html b/docs/_includes/sidebar.html index cc9a7cd7..a0c69958 100644 --- a/docs/_includes/sidebar.html +++ b/docs/_includes/sidebar.html @@ -1,4 +1,4 @@ -
          {% endif %} {% endfor %} - + diff --git a/docs/_layouts/default.html b/docs/_layouts/default.html index 4928d499..76ecdaea 100644 --- a/docs/_layouts/default.html +++ b/docs/_layouts/default.html @@ -22,12 +22,13 @@ +

          +
          +

          + + {{ doc.title }} + {% if doc.type %} + + {% endif %} + + Edit +

          + {% if doc.description %} +

          {{ doc.description }}

          + {% endif %} + + {% if doc.parameters and doc.parameters[0].name %} +
          Parameters
          +
          + {% for parameter in doc.parameters %} +
          {{ parameter.name }}
          +
          {{ parameter.content }}
          + {% endfor %} +
          + {% endif %} + + {{ doc.content_markdown | markdownify | replace: "
          ", "
          Parameters
          " }} + + {% if doc.left_code_blocks and doc.left_code_blocks[0].code_block %} + {% for block in doc.left_code_blocks %} + {% include syntax-highlight.html block=block %} + {% endfor %} + {% endif %} +
          + {% if doc.right_code_blocks and doc.right_code_blocks[0].code_block %} +
          + {% for block in doc.right_code_blocks %} + {% include syntax-highlight.html block=block %} + {% endfor %} +
          + {% endif %} +