Skip to content

Commit

Permalink
fix(types): data matcher for body and query. (#1725)
Browse files Browse the repository at this point in the history
* fix(types): data matcher for body and query.

Fixes: #1724
Closes: #1723

Updates the JSONish type using inspiration from the thread on adding a
JSON type to TS. microsoft/TypeScript#1897 (comment)

This change does a couple sublet things:
- Adds `undefined` to scalar values allowed in arrays or as values in objects.
  This allows for interfaces with optional keys to be passed in. ref #1723
- Splits out top-level array and objects into their interfaces so they could be used directly.
  Allows enforcing non-arrays for `.query`.
- `RequestBodyMatcher` now extends the array and map types instead of the raw `DataMatcher`.
  Allowing arrays fixes #1724.
  This also ensures that booleans, numbers, and `null` are not considered valid.
  • Loading branch information
mastermatt committed Sep 20, 2019
1 parent 6b88dff commit 59b345c
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 14 deletions.
30 changes: 18 additions & 12 deletions types/index.d.ts
Expand Up @@ -37,23 +37,29 @@ declare namespace nock {
interceptorOptions?: Options
) => Interceptor

// essentially valid decoded JSON with the addition of possible RegExp
interface DataMatcher {
[k: string]:
| boolean
| null
| number
| string
| RegExp
| DataMatcher
| Array<boolean | null | number | string | RegExp | DataMatcher>
// Essentially valid, decoded JSON with the addition of possible RegExp. TS doesn't currently have
// a great way to represent JSON type data, this data matcher design is based off this comment.
// https://github.com/microsoft/TypeScript/issues/1897#issuecomment-338650717
type DataMatcher =
| boolean
| number
| string
| null
| undefined
| RegExp
| DataMatcherArray
| DataMatcherMap
interface DataMatcherArray extends Array<DataMatcher> {}
interface DataMatcherMap {
[key: string]: DataMatcher
}

type RequestBodyMatcher =
| string
| Buffer
| RegExp
| DataMatcher
| DataMatcherArray
| DataMatcherMap
| { (body: any): boolean }

type RequestHeaderMatcher =
Expand Down Expand Up @@ -128,7 +134,7 @@ declare namespace nock {
matcher:
| boolean
| string
| DataMatcher
| DataMatcherMap
| URLSearchParams
| { (parsedObj: ParsedUrlQuery): boolean }
): this
Expand Down
21 changes: 19 additions & 2 deletions types/tests.ts
Expand Up @@ -5,12 +5,14 @@ import { URL, URLSearchParams } from 'url'
let scope: nock.Scope = nock('http://example.test')
let inst: nock.Interceptor
let str = 'foo'
let strings: string[]
let strings = ['foo', 'bar']
let defs: nock.Definition[]
let options: nock.Options = {}

const buffer = Buffer.from('')
const num = 42
const obj: { [k: string]: any } = {}
const objWithUndefinedValue: { a: string; b?: string } = { a: 'a' }
const regex = /test/

scope.head(str) // $ExpectType Interceptor
Expand All @@ -34,6 +36,16 @@ inst = scope.post(str, str)
inst = scope.post(str, str, options)
inst = scope.post(str, obj)
inst = scope.post(str, regex)
inst = scope.post(str, objWithUndefinedValue)
inst = scope.post(str, str)
inst = scope.post(str, strings)
inst = scope.post(str, [num, str, regex])
inst = scope.post(str, [num, num, num])
inst = scope.post(str, regex)
inst = scope.post(str, buffer)
inst = scope.post(str, true) // $ExpectError
inst = scope.post(str, null) // $ExpectError
inst = scope.post(str, num) // $ExpectError

inst = scope.put(str)
inst = scope.put(str, str)
Expand All @@ -53,8 +65,13 @@ inst = scope.merge(str, str, options)
inst = scope.merge(str, obj)
inst = scope.merge(str, regex)

inst = inst.query(obj)
inst = inst.query(true)
inst = inst.query(obj)
inst = inst.query(objWithUndefinedValue)
inst = inst.query({ foo: regex })
inst = inst.query(strings) // $ExpectError
inst = inst.query(buffer) // $ExpectError
inst = inst.query(regex) // $ExpectError

inst = scope.intercept(str, str)
inst = scope.intercept(str, str, str)
Expand Down

0 comments on commit 59b345c

Please sign in to comment.