Skip to content

Commit

Permalink
chore(docs): Add migration guides. (#2006)
Browse files Browse the repository at this point in the history
  • Loading branch information
mastermatt authored May 28, 2020
1 parent 46e004c commit 7550772
Show file tree
Hide file tree
Showing 5 changed files with 327 additions and 1 deletion.
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Changelog

Nock’s changelog can be found directly in the [GitHub release notes](https://github.com/nock/nock/releases). These are automatically created by [semantic-release](https://github.com/semantic-release/semantic-release) based on their [commit message conventions](https://semantic-release.gitbook.io/semantic-release#commit-message-format).
Nock’s changelog can be found directly in the [GitHub release notes](https://github.com/nock/nock/releases).
These are automatically created by [semantic-release](https://github.com/semantic-release/semantic-release) based on their [commit message conventions](https://semantic-release.gitbook.io/semantic-release#commit-message-format).

Migration guides are available for major versions in the [migration guides directory](https://github.com/nock/nock/tree/master/migration_guides).
10 changes: 10 additions & 0 deletions migration_guides/migrating_to_10.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
## Upgrading from Nock 9 to Nock 10

[Release Tag](https://github.com/nock/nock/releases/tag/v10.0.0)

### Breaking changes

Support for Node < 6 was dropped.

To upgrade Nock, ensure your version of Node is also updated.
At the time of release, Node 6.x, 8.x, and 9.x were supported.
212 changes: 212 additions & 0 deletions migration_guides/migrating_to_11.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
## Upgrading from Nock 10 to Nock 11

[Release Tag](https://github.com/nock/nock/releases/tag/v11.3.2)

### Bug fixes and internal improvements

Nock 11 includes many under-the-hood improvements, including a fully offline
test suite and 100% test coverage. The codebase was also converted to ES6
syntax and formatted with Prettier. Leaning on the test coverage, some
substantial refactors have begun.

Many bug fixes are included. See the detailed changelog below or the
[compare view][compare] for details.

### Fabulous new features for developers

1. The library ships with TypeScript definitions. (Added in v11.3)
1. Add support for the `http.request` signatures added in Node 10.9
1. Scopes can be filtered using the system environment or any external factor
using e.g. `.conditionally(() => true)`
1. In-flight modifications to headers are preserved in mock requests.
1. Recorded mocks can be stringified using custom code in the `afterRecord()`
post-processing hook. When `afterRecord()` returns a string, the
recorder will no longer attempt to re-stringify it. (Added in v11.3)
1. Reply functions passed to `.reply()` can now be async/promise-returning.
1. Specifying reply headers, either via `.reply()` or `.defaultReplyHeaders()`,
can now be done consistently using an object, Map, or flat array.

### Breaking changes

For many developers no code changes will be needed. However, there are several
minor changes to the API, and it's possible that you will need to update your
code for Nock to keep working properly. It's unlikely that your tests will
falsely pass; what's more probable is that your tests will fail until the
necessary changes are made.

1. Nock 11 requires Node 8 or later. Nock supports and tests all the "current"
and "maintenance" versions of Node. As of release, that's Node 8, 10, and 12.

1. In Nock 10, when `reply()` was invoked with a function, the return values were
handled ambiguously depending on their types.

Consider the following example:

```js
const scope = nock('http://example.com')
.get('/')
.reply(200, () => [500, 'hello world'])
```

In Nock 10, the 200 was ignored, the 500 was interpreted as the status
code, and the body would contain `'hello world'`. This caused problems
when the goal was to return a numeric array, so in Nock 11, the 200 is
properly interpreted as the status code, and `[500, 'hello world']` as the
body.

These are the correct calls for Nock 11:

```js
const scope = nock('http://example.com').get('/').reply(500, 'hello world')

const scope = nock('http://example.com')
.get('/')
.reply(500, () => 'hello world')
```

The `.reply()` method can be called with explicit arguments:

```js
.reply() // `statusCode` defaults to `200`.
.reply(statusCode) // `responseBody` defaults to `''`.
.reply(statusCode, responseBody) // `headers` defaults to `{}`.
.reply(statusCode, responseBody, headers)
```

It can be called with a status code and a function that returns an array:

```js
.reply(statusCode, (path, requestBody) => responseBody)
.reply(statusCode, (path, requestBody) => responseBody, headers)
```

Alternatively the status code can be included in the array:

```js
.reply((path, requestBody) => [statusCode])
.reply((path, requestBody) => [statusCode, responseBody])
.reply((path, requestBody) => [statusCode, responseBody, headers])
.reply((path, requestBody) => [statusCode, responseBody], headers)
```

`.reply()` can also be called with an `async` or promise-returning function. The
signatures are identical, e.g.

```js
.reply(async (path, requestBody) => [statusCode, responseBody])
.reply(statusCode, async (path, requestBody) => responseBody)
```

Finally, an error-first callback can be used, e.g.:

```js
.reply((path, requestBody, cb) => cb(undefined, [statusCode, responseBody]))
.reply(statusCode, (path, requestBody, cb) => cb(undefined, responseBody))
```

1. In Nock 10, errors in user-provided reply functions were caught by Nock, and
generated HTTP responses with status codes of 500. In Nock 11 these errors
are not caught, and instead are re-emitted through the request, like any
other error that occurs during request processing.

Consider the following example:

```js
const scope = nock('http://example.com')
.post('/echo')
.reply(201, (uri, requestBody, cb) => {
fs.readFile('cat-poems.txt', cb) // Error-first callback
})
```

When `fs.readFile()` errors in Nock 10, a 500 error was emitted. To get the
same effect in Nock 11, the example would need to be rewritten to:

```js
const scope = nock('http://example.com')
.post('/echo')
.reply((uri, requestBody, cb) => {
fs.readFile('cat-poems.txt', (err, contents) => {
if (err) {
cb([500, err.stack])
} else {
cb([201, contents])
}
})
})
```

1. When `.reply()` is invoked with something other than a whole number status
code or a function, Nock 11 raises a new error **Invalid ... value for status code**.

1. Callback functions provided to the `.query` method now receive the result of [`querystring.parse`](https://nodejs.org/api/querystring.html#querystring_querystring_parse_str_sep_eq_options) instead of [`qs.parse`](https://github.com/ljharb/qs#parsing-objects).

In particular, `querystring.parse` does not interpret keys with JSON
path notation:

```js
querystring.parse('foo[bar]=baz') // { "foo[bar]": 'baz' }
qs.parse('foo[bar]=baz') // { foo: { bar: 'baz' } }
```

1. In Nock 10, duplicate field names provided to the `.query()` method were
silently ignored. We decided this was probably hiding unintentionally bugs
and causing frustration with users. In Nock 11, attempts to provide query
params more than once will throw a new error
**Query parameters have aleady been defined**. This could happen by calling
`.query()` twice, or by calling `.query()` after specifying a literal query
string via the path.

```js
nock('http://example.com')
.get('/path')
.query({ foo: 'bar' })
.query({ baz: 'qux' }) // <-- will throw
.reply()

nock('http://example.com')
.get('/path?foo=bar')
.query({ baz: 'qux' }) // <-- will throw
.reply()
```

1. Paths in Nock have always required a leading slash. e.g.

```js
const scope = nock('http://example.com').get('/path').reply()
```

In Nock 10, if the leading slash was missing the mock would never match. In
Nock 11, this raises an error.

1. The `reqheaders` parameter should be provided as a plain object, e.g.
`nock('http://example.com', { reqheaders: { X-Foo: 'bar' }})`. When the
headers are specified incorrectly as e.g. `{ reqheaders: 1 }`, Nock 10 would
behave in unpredictable ways. In Nock 11, a new error
**Headers must be provided as an object** is thrown.

```js
nock('http://example.com', { reqheaders: 1 }).get('/').reply()
```

1. In Nock 10, the `ClientRequest` instance wrapped the native `on` method
and aliased `once` to it. In Nock 11, this been removed and `request.once`
will correctly call registered listeners...once.

1. In Nock 10, when the method was not specified in a call to `nock.define()`,
the method would default to `GET`. In Nock 11, this raises an error.

1. In very old versions of nock, recordings may include a response status
code encoded as a string in the `reply` field. In Nock 10 these strings could
be non-numeric. In Nock 11 this raises an error.

### Updates to the mock surface

1. For parity with a real response, a mock request correctly supports all
the overrides to `request.end()`, including `request.end(cb)` in Node 12.
1. For parity with a real response, errors from the `.destroy()` method
are propagated correctly. (Added in v11.3)
1. For parity with a real response, the `.complete` property is set when
ending the response.
1. For parity with a real Socket, the mock Socket has an `unref()` function
(which does nothing).
33 changes: 33 additions & 0 deletions migration_guides/migrating_to_12.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
## Upgrading from Nock 11 to Nock 12

[Release Tag](https://github.com/nock/nock/releases/tag/v12.0.0)

### Breaking changes

1. Support for Node < 10 was dropped.
To upgrade Nock, ensure your version of Node is also updated.
At the time of release, Node 10.x, 12.x, and 13.x were supported.

1. [`cleanAll()`](https://github.com/nock/nock#cleanall) no longer returns the global `nock` instance ([#1872](https://github.com/nock/nock/pull/1872)).

```js
// before
nock.cleanAll().restore() // Uncaught TypeError: Cannot read property 'restore' of undefined

// upgraded
nock.cleanAll()
nock.restore()
```

1. Support was dropped for the String constructor ([#1873](https://github.com/nock/nock/pull/1873)).
Only string primitive are supported. All strings passed to Nock for options should not use `new String` syntax.
[MDN web docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String#String_primitives_and_String_objects).

### New features for developers

1. [`enableNetConnect()`](https://github.com/nock/nock#enabling-requests) now accepts a function.
```js
nock.enableNetConnect(
host => host.includes('amazon.com') || host.includes('github.com')
)
```
68 changes: 68 additions & 0 deletions migration_guides/migrating_to_13.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
## Upgrading from Nock 12 to Nock 13

[Release Tag](https://github.com/nock/nock/releases/tag/v13.0.0)

### Breaking changes

1. `Scope.log` has been removed. Use the `debug` library when [debugging](https://github.com/nock/nock#debugging) failed matches.

1. `socketDelay` has been removed. Use [`delayConnection`](https://github.com/nock/nock#delay-the-connection) instead.

1. `delay`, `delayConnection`, and `delayBody` are now setters instead of additive.

```js
nock('http://example.com')
.get('/')
.delay(1)
.delay({ head: 2, body: 3 })
.delayConnection(4)
.delayBody(5)
.delayBody(6)
.reply()
```

Previously, the connection would have been delayed by 7 and the body delayed by 14.
Now, the connection will be delayed by 4 and the body delayed by 6.

1. [When recording](https://github.com/nock/nock#recording), skipping body matching using `*` is no longer supported by `nock.define`.
Set the definition body to `undefined` instead.

```js
nock.define([
{
scope: 'http://example.test',
method: 'POST',
path: '/',
body: '*', // remove this line or set to undefined
response: 'matched',
},
])
```

1. `ClientRequest.abort()` has been updated to align with Node's native behavior.

- Nock use to always emit a 'socket hang up' error. Now it only emits the error if `abort` is called between the 'socket' and 'response' events.
- The emitted 'abort' event now happens on `nextTick`.
- The socket is now only destroyed if the 'socket' event has fired, and now emits a 'close' event on `nextTick` that propagates though the request object.
- `request.aborted` attribute is set to `true` instead of a timestamp. [Changed in Node v11.0](https://github.com/nodejs/node/pull/20230).
- Calling `write`, `end`, or `flushHeaders` on an aborted request no longer emits an error.
However, writing to a request that is already finished (ended) will emit a 'write after end' error.

1. Playback of a mocked responses will now never happen until the 'socket' event is emitted.
The 'socket' event is still artificially set to emit on `nextTick` when a ClientRequest is created.
This means in the following code the Scope will never be done because at least one tick needs
to happen before any matched Interceptor is considered consumed.
```js
const scope = nock(...).get('/').reply()
const req = http.get(...)
scope.done()
```
The correct way to verify such an action is to call [`scope.done`](https://github.com/nock/nock#expectations) after waiting for a 'response', 'timeout', or 'socket' event on the request.
For example:
```js
const scope = nock(...).get('/').reply()
const req = http.get(...)
req.on('response', () => {
scope.done()
})
```

0 comments on commit 7550772

Please sign in to comment.