From 31b4db7233e018c9c74c7da2de96ec429501f8e2 Mon Sep 17 00:00:00 2001 From: Horiuchi_H Date: Fri, 9 Sep 2016 17:33:04 +0900 Subject: [PATCH] rewrite nock type definition --- nock/nock-tests.ts | 696 +++++++++++++++++++++++++++++++++++++++++---- nock/nock.d.ts | 237 ++++++++------- 2 files changed, 772 insertions(+), 161 deletions(-) diff --git a/nock/nock-tests.ts b/nock/nock-tests.ts index ffb456b420..20dbf6d04e 100644 --- a/nock/nock-tests.ts +++ b/nock/nock-tests.ts @@ -1,113 +1,118 @@ /// -import nock = require('nock'); +import * as nock from 'nock'; +import * as fs from 'fs'; -var inst: nock.Scope; +var scope: nock.Scope; +var inst: nock.Interceptor; var str: string; var strings: string[]; var bool: boolean; var data: string; var num: number; var obj: {}; -var objects: Object[]; +var defs: nock.NockDefinition[]; var value: any; var regex: RegExp; var options: nock.Options; -var headers: Object; +var headers: { [key: string]: string; }; -inst = inst.head(str); +inst = scope.head(str); -inst = inst.get(str); -inst = inst.get(str, data); +inst = scope.get(str); +inst = scope.get(str, data); -inst = inst.patch(str); -inst = inst.patch(str, str); -inst = inst.patch(str, obj); -inst = inst.patch(str, regex); +inst = scope.patch(str); +inst = scope.patch(str, str); +inst = scope.patch(str, obj); +inst = scope.patch(str, regex); -inst = inst.post(str); -inst = inst.post(str, data); -inst = inst.post(str, obj); -inst = inst.post(str, regex); +inst = scope.post(str); +inst = scope.post(str, data); +inst = scope.post(str, obj); +inst = scope.post(str, regex); -inst = inst.put(str); -inst = inst.put(str, data); -inst = inst.put(str, obj); -inst = inst.put(str, regex); +inst = scope.put(str); +inst = scope.put(str, data); +inst = scope.put(str, obj); +inst = scope.put(str, regex); -inst = inst.delete(str); -inst = inst.delete(str, data); -inst = inst.delete(str, obj); -inst = inst.delete(str, regex); +inst = scope.delete(str); +inst = scope.delete(str, data); +inst = scope.delete(str, obj); +inst = scope.delete(str, regex); -inst = inst.merge(str); -inst = inst.merge(str, data); -inst = inst.merge(str, obj); -inst = inst.merge(str, regex); +inst = scope.merge(str); +inst = scope.merge(str, data); +inst = scope.merge(str, obj); +inst = scope.merge(str, regex); inst = inst.query(obj); inst = inst.query(bool); -inst = inst.intercept(str, str); -inst = inst.intercept(str, str, str); -inst = inst.intercept(str, str, obj); -inst = inst.intercept(str, str, regex); -inst = inst.intercept(str, str, str, value); -inst = inst.intercept(str, str, obj, value); -inst = inst.intercept(str, str, regex, value); +inst = scope.intercept(str, str); +inst = scope.intercept(str, str, str); +inst = scope.intercept(str, str, obj); +inst = scope.intercept(str, str, regex); +inst = scope.intercept(str, str, str, value); +inst = scope.intercept(str, str, obj, value); +inst = scope.intercept(str, str, regex, value); -inst = inst.reply(num); -inst = inst.reply(num, str); +scope = inst.reply(num); +scope = inst.reply(num, str); -inst = inst.reply(num, str, headers); -inst = inst.reply(num, obj, headers); -inst = inst.reply(num, (uri: string, body: string) => { +scope = inst.reply(num, str, headers); +scope = inst.reply(num, obj, headers); +scope = inst.reply(num, (uri: string, body: string) => { return str; }); -inst = inst.reply(num, (uri: string, body: string) => { +scope = inst.reply(num, (uri: string, body: string) => { return str; }, headers); -inst = inst.replyWithFile(num, str); +scope = inst.replyWithFile(num, str); inst = inst.times(4); inst = inst.once(); inst = inst.twice(); inst = inst.thrice(); -inst = inst.defaultReplyHeaders(value); +scope = scope.defaultReplyHeaders(value); -inst = inst.matchHeader(str, str); -inst = inst.matchHeader(str, regex); -inst = inst.matchHeader(str, (val: string) => true); +scope = scope.matchHeader(str, str); +scope = scope.matchHeader(str, regex); +scope = scope.matchHeader(str, (val: string) => true); inst = inst.delay(num); inst = inst.delayConnection(num); -inst = inst.filteringPath(regex, str); -inst = inst.filteringPath((path: string) => { +scope = scope.filteringPath(regex, str); +scope = scope.filteringPath((path: string) => { return str; }); -inst = inst.filteringRequestBody(regex, str); -inst = inst.filteringRequestBody((path: string) => { +scope = scope.filteringRequestBody(regex, str); +scope = scope.filteringRequestBody((path: string) => { return str; }); -inst = inst.persist(); -inst = inst.log(() => { - -}); +scope = scope.log(() => { }); +scope = scope.persist(); +bool = scope.shouldPersist(); +scope = scope.replyContentLength(); +scope = scope.replyDate(); +scope = scope.replyDate(new Date()); inst = inst.delay(2000); +inst = inst.delay({ head: 1000, body: 1000 }); inst = inst.delayBody(2000); inst = inst.delayConnection(2000); inst.getTotalDelay(); inst = inst.socketDelay(2000); -inst.done(); -bool = inst.isDone(); -inst.restore(); +scope.done(); +bool = scope.isDone(); +scope.restore(); -objects = inst.pendingMocks(); +strings = scope.pendingMocks(); nock.recorder.rec(); nock.recorder.rec(true); @@ -115,6 +120,579 @@ nock.recorder.rec({ dont_print: true, output_objects: true }); +nock.recorder.clear(); +strings = nock.recorder.play() as string[]; +defs = nock.recorder.play() as nock.NockDefinition[]; + + +// Usage +var couchdb = nock('http://myapp.iriscouch.com') + .get('/users/1') + .reply(200, { + _id: '123ABC', + _rev: '946B7D1C', + username: 'pgte', + email: 'pedro.teixeira@gmail.com' + }); + +// Specifying hostname +var scope = nock('http://www.example.com') + .get('/resource') + .reply(200, 'domain matched'); +var scope = nock(/example\.com/) + .get('/resource') + .reply(200, 'domain regex matched'); + +// Specifying path +var scope = nock('http://www.example.com') + .get('/resource') + .reply(200, 'path matched'); + +var scope = nock('http://www.example.com') + .get(/source$/) + .reply(200, 'path using regex matched'); + +var scope = nock('http://www.example.com') + .get((uri) => { + return uri.indexOf('cats') >= 0; + }) + .reply(200, 'path using function matched'); + +// Specifying request body +var scope = nock('http://myapp.iriscouch.com') + .post('/users', { + username: 'pgte', + email: 'pedro.teixeira@gmail.com' + }) + .reply(201, { + ok: true, + id: '123ABC', + rev: '946B7D1C' + }); + +var scope = nock('http://myapp.iriscouch.com') + .post('/users', /email=.?@gmail.com/gi) + .reply(201, { + ok: true, + id: '123ABC', + rev: '946B7D1C' + }); + +var scope = nock('http://myapp.iriscouch.com') + .post('/users', { + username: 'pgte', + password: /a.+/, + email: 'pedro.teixeira@gmail.com' + }) + .reply(201, { + ok: true, + id: '123ABC', + rev: '946B7D1C' + }); + +var scope = nock('http://myapp.iriscouch.com') + .post('/users', (body: any) => { + return body.id === '123ABC'; + }) + .reply(201, { + ok: true, + id: '123ABC', + rev: '946B7D1C' + }); + +// Specifying request query string +nock('http://example.com') + .get('/users') + .query({name: 'pedro', surname: 'teixeira'}) + .reply(200, {results: [{id: 'pgte'}]}); + +nock('http://example.com') + .get('/users') + .query({ + names: ['alice', 'bob'], + tags: { + alice: ['admin', 'tester'], + bob: ['tester'] + } + }) + .reply(200, {results: [{id: 'pgte'}]}); + +nock('http://example.com') + .get('/users') + .query((actualQueryObject: any) => { + // do some compare with the actual Query Object + // return true for matched + // return false for not matched + return true; + }) + .reply(200, {results: [{id: 'pgte'}]}); + +nock('http://example.com') + .get('/users') + .query(true) + .reply(200, {results: [{id: 'pgte'}]}); + +// Specifying replies +var scope = nock('http://myapp.iriscouch.com') + .get('/users/1') + .reply(404); + +var scope = nock('http://www.google.com') + .get('/') + .reply(200, 'Hello from Google!'); + +var scope = nock('http://myapp.iriscouch.com') + .get('/') + .reply(200, { + username: 'pgte', + email: 'pedro.teixeira@gmail.com', + _id: '4324243fsd' + }); + +var scope = nock('http://myapp.iriscouch.com') + .get('/') + .replyWithFile(200, __dirname + '/replies/user.json'); + +var scope = nock('http://www.google.com') + .filteringRequestBody(/.*/, '*') + .post('/echo', '*') + .reply(201, (uri: string, requestBody: string) => { + return requestBody; + }); + +var scope = nock('http://www.google.com') + .filteringRequestBody(/.*/, '*') + .post('/echo', '*') + .reply(201, (uri: string, requestBody: string, cb: nock.ReplyCallback) => { + fs.readFile('cat-poems.txt' , cb); // Error-first callback + }); + +var scope = nock('http://www.google.com') + .filteringRequestBody(/.*/, '*') + .post('/echo', '*') + .reply((uri, requestBody) => { + return [ + 201, + 'THIS IS THE REPLY BODY', + {'header': 'value'} // optional headers + ]; + }); + +var scope = nock('http://www.google.com') + .filteringRequestBody(/.*/, '*') + .post('/echo', '*') + .reply((uri, requestBody, cb) => { + setTimeout(() => { + cb(null, [201, 'THIS IS THE REPLY BODY']) + }, 1e3); + }); + +var scope = nock('http://www.google.com') + .get('/cat-poems') + .reply(200, (uri: string, requestBody: string) => { + return fs.createReadStream('cat-poems.txt'); + }); + +/// Access original request and headers +var scope = nock('http://www.google.com') + .get('/cat-poems') + .reply((uri, requestBody) => { + console.log('path:', this.req.path); + console.log('headers:', this.req.headers); + // ... + }); + +// Replying with errors +nock('http://www.google.com') + .get('/cat-poems') + .replyWithError('something awful happened'); + +nock('http://www.google.com') + .get('/cat-poems') + .replyWithError({'message': 'something awful happened', 'code': 'AWFUL_ERROR'}); + +// Specifying headers + +/// Specifying Request Headers +var scope = nock('http://www.example.com', { + reqheaders: { + 'authorization': 'Basic Auth' + } + }) + .get('/') + .reply(200); + +var scope = nock('http://www.example.com', { + reqheaders: { + 'X-My-Headers': (headerValue) => { + if (headerValue) { + return true; + } + return false; + }, + 'X-My-Awesome-Header': /Awesome/i + } + }) + .get('/') + .reply(200); + +var scope = nock('http://www.example.com', { + badheaders: ['cookie', 'x-forwarded-for'] + }) + .get('/') + .reply(200); + +var scope = nock('http://www.example.com') + .get('/') + .basicAuth({ + user: 'john', + pass: 'doe' + }) + .reply(200); + +/// Specifying Reply Headers +var scope = nock('http://www.headdy.com') + .get('/') + .reply(200, 'Hello World!', { + 'X-My-Headers': 'My Header value' + }); + +var scope = nock('http://www.headdy.com') + .get('/') + .reply(200, 'Hello World!', { + 'X-My-Headers': (req, res, body) => { + return body.toString(); + } + }); + +// Default Reply Headers +var scope = nock('http://www.headdy.com') + .defaultReplyHeaders({ + 'X-Powered-By': 'Rails', + 'Content-Type': 'application/json' + }) + .get('/') + .reply(200, 'The default headers should come too'); + +var scope = nock('http://www.headdy.com') + .defaultReplyHeaders({ + 'Content-Length': (req, res, body) => { + return body.length; + } + }) + .get('/') + .reply(200, 'The default headers should come too'); + +// Including Content-Length Header Automatically +var scope = nock('http://www.headdy.com') + .replyContentLength() + .get('/') + .reply(200, { hello: 'world' }); + +// Including Date Header Automatically +var scope = nock('http://www.headdy.com') + .replyDate(new Date(2015, 0, 1)) // defaults to now, must use a Date object + .get('/') + .reply(200, { hello: 'world' }); + +// HTTP Verbs +nock('http://my.domain.com') + .intercept('/path', 'PATCH') + .reply(304); + +// Support for HTTP and HTTPS +var scope = nock('https://secure.my.server.com'); + +// Non-standard ports +var scope = nock('http://my.server.com:8081'); + +// Repeat response n times +nock('http://zombo.com').get('/').times(4).reply(200, 'Ok'); +nock('http://zombo.com').get('/').once().reply(200, 'Ok'); +nock('http://zombo.com').get('/').twice().reply(200, 'Ok'); +nock('http://zombo.com').get('/').thrice().reply(200, 'Ok'); + +// Delay the response body +nock('http://my.server.com') + .get('/') + .delayBody(2000) // 2 seconds + .reply(200, '') + +// Delay the response +nock('http://my.server.com') + .get('/') + .delay(2000) // 2 seconds delay will be applied to the response header. + .reply(200, '') + +nock('http://my.server.com') + .get('/') + .delay({ + head: 2000, // header will be delayed for 2 seconds, i.e. the whole response will be delayed for 2 seconds. + body: 3000 // body will be delayed for another 3 seconds after header is sent out. + }) + .reply(200, '') + +// Delay the connection +nock('http://my.server.com') + .get('/') + .socketDelay(2000) // 2 seconds + .delayConnection(1000) + .reply(200, '') + +// Chaining +var scope = nock('http://myapp.iriscouch.com') + .get('/users/1') + .reply(404) + .post('/users', { + username: 'pgte', + email: 'pedro.teixeira@gmail.com' + }) + .reply(201, { + ok: true, + id: '123ABC', + rev: '946B7D1C' + }) + .get('/users/123ABC') + .reply(200, { + _id: '123ABC', + _rev: '946B7D1C', + username: 'pgte', + email: 'pedro.teixeira@gmail.com' + }); + +// Scope filtering +var scope = nock('https://api.dropbox.com', { +filteringScope: (scope: string) => { + return /^https:\/\/api[0-9]*.dropbox.com/.test(scope); + } + }) + .get('/1/metadata/auto/Photos?include_deleted=false&list=true') + .reply(200); + +// Path filtering +var scope = nock('http://api.myservice.com') + .filteringPath(/password=[^&]*/g, 'password=XXX') + .get('/users/1?password=XXX') + .reply(200, 'user'); + +var scope = nock('http://api.myservice.com') + .filteringPath((path) => { + return '/ABC'; + }) + .get('/ABC') + .reply(200, 'user'); + +// Request Body filtering +var scope = nock('http://api.myservice.com') + .filteringRequestBody(/password=[^&]*/g, 'password=XXX') + .post('/users/1', 'data=ABC&password=XXX') + .reply(201, 'OK'); + +var scope = nock('http://api.myservice.com') + .filteringRequestBody((body) => { + return 'ABC'; + }) + .post('/', 'ABC') + .reply(201, 'OK'); + +// Request Headers Matching +var scope = nock('http://api.myservice.com') + .matchHeader('accept', 'application/json') + .get('/') + .reply(200, { + data: 'hello world' + }) + +var scope = nock('http://api.myservice.com') + .matchHeader('User-Agent', /Mozilla\/.*/) + .get('/') + .reply(200, { + data: 'hello world' + }) + +var scope = nock('http://api.myservice.com') + .matchHeader('content-length', (val) => { + return Number(val) >= 1000; + }) + .get('/') + .reply(200, { + data: 'hello world' + }) + +// Allow unmocked requests on a mocked hostname +options = {allowUnmocked: true}; +var scope = nock('http://my.existing.service.com', options) + .get('/my/url') + .reply(200, 'OK!'); + +// Expectations +var google = nock('http://google.com') + .get('/') + .reply(200, 'Hello from Google!'); +setTimeout(() => { + google.done(); // will throw an assertion error if meanwhile a "GET http://google.com" was not performed. +}, 5000); + +/// .isDone() +var scope = nock('http://google.com') + .get('/') + .reply(200); +scope.isDone(); // will return false + +nock.isDone(); + +/// .cleanAll() +nock.cleanAll(); + +/// .persist() +var scope = nock('http://persisssists.con') + .persist() + .get('/') + .reply(200, 'Persisting all the way'); + +/// .pendingMocks() +if (!scope.isDone()) { + console.error('pending mocks: %j', scope.pendingMocks()); +} +console.error('pending mocks: %j', nock.pendingMocks()); + +// Logging +var google = nock('http://google.com') + .log(console.log); + +// Restoring +nock.restore(); + +// Enable/Disable real HTTP request +nock.disableNetConnect(); +nock.enableNetConnect(); + +// using a string +nock.enableNetConnect('amazon.com'); + +// or a RegExp +nock.enableNetConnect(/(amazon|github).com/); + +nock.disableNetConnect(); +nock.enableNetConnect('127.0.0.1'); //Allow localhost connections so we can test local routes and mock servers. + +nock.cleanAll(); +nock.enableNetConnect(); + + +// Recording +nock.recorder.rec(); + +/// dont_print option +nock.recorder.rec({ + dont_print: true +}); +// ... some HTTP calls +var nockCalls = nock.recorder.play(); + +/// output_objects option +nock.recorder.rec({ + output_objects: true +}); +// ... some HTTP calls +var nockCallObjects = nock.recorder.play(); + +var pathToJson: string; +var nocks = nock.load(pathToJson); +nocks.forEach((nock) => { + nock = nock.filteringRequestBody((body: string) => { + return body; + }); +}); + +// Pre-process the nock definitions as scope filtering has to be defined before the nocks are defined (due to its very hacky nature). +var nockDefs = nock.loadDefs(pathToJson); +nockDefs.forEach((def) => { + // Do something with the definition object e.g. scope filtering. + def.options = def.options || {}; + def.options.filteringScope = (scope: string) => { + return /^https:\/\/api[0-9]*.dropbox.com/.test(scope); + }; +}); +// Load the nocks from pre-processed definitions. +var nocks = nock.define(nockDefs); + +/// enable_reqheaders_recording option +nock.recorder.rec({ + dont_print: true, + output_objects: true, + enable_reqheaders_recording: true +}); + +/// logging option +var nullAppender = (content: string) => { }; +nock.recorder.rec({ + logging: nullAppender +}); + +/// use_separator option +nock.recorder.rec({ + use_separator: false +}); + + +// .removeInterceptor() +nock.removeInterceptor({ + hostname : 'localhost', + path : '/mockedResource' +}); +nock.removeInterceptor({ + hostname : 'localhost', + path : '/login', + method: 'POST', + proto : 'https' +}); + +var interceptor = nock('http://example.org') + .get('somePath'); +nock.removeInterceptor(interceptor); + + +// Events +/// Global no match event +nock.emitter.on('no match', (req: any) => { }); + + +// Nock Back +/// Setup +import { back as nockBack } from 'nock'; + +nockBack.fixtures = '/path/to/fixtures/'; +nockBack.setMode('record'); + +/// Usage +nockBack.setMode('record'); +nockBack.fixtures = './nockFixtures'; //this only needs to be set once in your test helper + +var before = (def: nock.NockDefinition) => { + def.options = def.options || {}; + def.options.filteringScope = (scope: string) => { + return /^https:\/\/api[0-9]*.dropbox.com/.test(scope); + }; +}; +var after = (scope: nock.Scope) => { + scope = scope.filteringRequestBody((body: string): string => { + return body; + }); +}; + +// recording of the fixture +declare var request: any; +nockBack('zomboFixture.json', { before, after }, (nockDone: () => void) => { + request.get('http://zombo.com', (err: any, res: any, body: string) => { + nockDone(); + // usage of the created fixture + nockBack('zomboFixture.json', (nockDone: () => void) => { + nockDone(); //never gets here + }); + }); +}); + + + -strings = nock.recorder.play(); -objects = nock.recorder.play(); diff --git a/nock/nock.d.ts b/nock/nock.d.ts index 615ec0d3ca..d98d390b10 100644 --- a/nock/nock.d.ts +++ b/nock/nock.d.ts @@ -1,131 +1,164 @@ -// Type definitions for nock v0.54.0 -// Project: https://github.com/pgte/nock -// Definitions by: bonnici +// Type definitions for nock v8.0.0 +// Project: https://github.com/node-nock/nock +// Definitions by: bonnici , Horiuchi_H // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped -// Imported from: https://github.com/soywiz/typescript-node-definitions/nock.d.ts +/// declare module "nock" { - export = nock; + export = nock; - function nock (host: string, options?: nock.Options): nock.Scope; + function nock(basePath: string | RegExp, options?: nock.Options): nock.Scope; - namespace nock { - export function cleanAll(): void; + namespace nock { + export function cleanAll(): void; - export function disableNetConnect(): void; - export function enableNetConnect(): void; - export function enableNetConnect(regex: RegExp): void; - export function enableNetConnect(domain: string): void; - - export function load(path: string): Object[]; - export function restore(): void; + export function activate(): void; + export function isActive(): boolean; + export function isDone(): boolean; + export function pendingMocks(): void; + export function removeInterceptor(interceptor: Interceptor | RequestOptions): boolean; + export function disableNetConnect(): void; + export function enableNetConnect(matcher?: string | RegExp): void; - export var recorder: Recorder; + export function load(path: string): Scope[]; + export function loadDefs(path: string): NockDefinition[]; + export function define(defs: NockDefinition[]): Scope[]; - export interface Scope { - get(path: string, data?: string): Scope; - get(path: RegExp, data?: string): Scope; + export var emitter: NodeJS.EventEmitter; - post(path: string, data?: string): Scope; - post(path: string, data?: Object): Scope; - post(path: string, regex?: RegExp): Scope; - post(path: RegExp, data?: string): Scope; - post(path: RegExp, data?: Object): Scope; - post(path: RegExp, regex?: RegExp): Scope; + export var recorder: Recorder; + export function restore(): void; - patch(path: string, data?: string): Scope; - patch(path: string, data?: Object): Scope; - patch(path: string, regex?: RegExp): Scope; - patch(path: RegExp, data?: string): Scope; - patch(path: RegExp, data?: Object): Scope; - patch(path: RegExp, regex?: RegExp): Scope; + export var back: NockBack; - put(path: string, data?: string): Scope; - put(path: string, data?: Object): Scope; - put(path: string, regex?: RegExp): Scope; - put(path: RegExp, data?: string): Scope; - put(path: RegExp, data?: Object): Scope; - put(path: RegExp, regex?: RegExp): Scope; + type HttpHeaders = { [key: string]: string | { (req: any, res: any, body: string): any; }; }; + type InterceptFunction = ( + uri: string | RegExp | { (uri: string): boolean; }, + requestBody?: string | RegExp | { (body: any): boolean; } | any + ) => Interceptor; + export type ReplyCallback = (err: any, result: ReplyCallbackResult) => void; + type ReplyCallbackResult = string | [number, string | any] | [number, string | any, HttpHeaders] | any; - head(path: string): Scope; - head(path: RegExp): Scope; - delete(path: string, data?: string): Scope; - delete(path: string, data?: Object): Scope; - delete(path: string, regex?: RegExp): Scope; - delete(path: RegExp, data?: string): Scope; - delete(path: RegExp, data?: Object): Scope; - delete(path: RegExp, regex?: RegExp): Scope; + export interface Scope extends NodeJS.EventEmitter { + get: InterceptFunction; + post: InterceptFunction; + put: InterceptFunction; + head: InterceptFunction; + patch: InterceptFunction; + merge: InterceptFunction; + delete: InterceptFunction; - merge(path: string, data?: string): Scope; - merge(path: string, data?: Object): Scope; - merge(path: string, regex?: RegExp): Scope; - merge(path: RegExp, data?: string): Scope; - merge(path: RegExp, data?: Object): Scope; - merge(path: RegExp, regex?: RegExp): Scope; + intercept: ( + uri: string | RegExp | { (uri: string): boolean; }, + method: string, + requestBody?: string | RegExp | { (body: any): boolean; } | any, + options?: Options + ) => Interceptor; - query(params: any): Scope; - query(acceptAnyParams: boolean): Scope; - intercept(path: string, verb: string, body?: string, options?: any): Scope; - intercept(path: string, verb: string, body?: Object, options?: any): Scope; - intercept(path: string, verb: string, body?: RegExp, options?: any): Scope; - intercept(path: RegExp, verb: string, body?: string, options?: any): Scope; - intercept(path: RegExp, verb: string, body?: Object, options?: any): Scope; - intercept(path: RegExp, verb: string, body?: RegExp, options?: any): Scope; + defaultReplyHeaders(headers: HttpHeaders): this; + matchHeader(name: string, value: string | RegExp | { (value: string): boolean; }): this; + filteringPath(regex: RegExp, replace: string): this; + filteringPath(fn: (path: string) => string): this; + filteringRequestBody(regex: RegExp, replace: string): this; + filteringRequestBody(fn: (body: string) => string): this; - reply(responseCode: number, body?: string, headers?: Object): Scope; - reply(responseCode: number, body?: Object, headers?: Object): Scope; - reply(responseCode: number, callback: (uri: string, body: string) => string, headers?: Object): Scope; - replyWithFile(responseCode: number, fileName: string): Scope; - replyWithError(errorMessage: string): Scope; + log(out: () => void): this; + persist(): this; + shouldPersist(): boolean; + replyContentLength(): this; + replyDate(d?: Date): this; - defaultReplyHeaders(headers: Object): Scope; + done(): void; + isDone(): boolean; + restore(): void; + pendingMocks(): string[]; + } - matchHeader(name: string, value: string): Scope; - matchHeader(name: string, regex: RegExp): Scope; - matchHeader(name: string, fn: (value: string) => boolean): Scope; + export interface Interceptor { + query(params: boolean | { (querObject: any): boolean; } | any): this; - filteringPath(regex: RegExp, replace: string): Scope; - filteringPath(fn: (path: string) => string): Scope; - filteringRequestBody(regex: RegExp, replace: string): Scope; - filteringRequestBody(fn: (path: string) => string): Scope; + reply(responseCode: number, body?: string | any, headers?: HttpHeaders): Scope; + reply(responseCode: number, callback: (uri: string, body: string, cb?: ReplyCallback) => ReplyCallbackResult, headers?: HttpHeaders): Scope; + reply(callback: (uri: string, body: string, cb?: ReplyCallback) => ReplyCallbackResult, headers?: HttpHeaders): Scope; + replyWithError(errorMessage: string | any): Scope; + replyWithFile(responseCode: number, fileName: string, headers?: HttpHeaders): Scope; - persist(): Scope; - log(out: () => void): Scope; + basicAuth(options: { user: string; pass?: string; }): this; - delay(timeMs: number): Scope; - delayBody(timeMs: number): Scope; - delayConnection(timeMs: number): Scope; - getTotalDelay(): number; - socketDelay(timeMs: number): Scope; + times(newCounter: number): this; + once(): this; + twice(): this; + thrice(): this; - times(repeats: number): Scope; - once(): Scope; - twice(): Scope; - thrice(): Scope; + delay(opts: number | { head?: number; body?: number; }): this; + delayBody(timeMs: number): this; + delayConnection(timeMs: number): this; + getTotalDelay(): number; + socketDelay(timeMs: number): this; + } - done(): void; - isDone(): boolean; - restore(): void; - pendingMocks(): Object[]; - } + export interface Options { + allowUnmocked?: boolean; + reqheaders?: { [key: string]: string | RegExp | { (headerValue: string): boolean; }; }; + badheaders?: string[]; + filteringScope?: { (scope: string): boolean; }; + } - export interface Recorder { - rec(capture?: boolean): void; - rec(options?: RecorderOptions): void; - play(): any[]; - } + export interface RequestOptions { + proto?: string; + _https_?: boolean; + hostname?: string; + host?: string; + port?: number; + method?: string; + path?: string; + } - export interface Options { - allowUnmocked?: boolean; - } + export interface Recorder { + rec(options?: boolean | RecorderOptions): void; + clear(): void; + play(): string[] | NockDefinition[]; + } - export interface RecorderOptions { - dont_print?: boolean; - output_objects?: boolean; - enable_reqheaders_recording?: boolean; - } - } + export interface RecorderOptions { + dont_print?: boolean; + output_objects?: boolean; + enable_reqheaders_recording?: boolean; + logging?: (content: string) => void; + use_separator?: boolean; + } + + export interface NockDefinition { + scope: string; + port?: number | string; + method?: string; + path: string; + body?: string | any; + status?: number; + response?: string | any; + headers?: HttpHeaders; + reqheaders?: { [key: string]: string | RegExp | { (headerValue: string): boolean; }; }; + options?: Options; + } + + export type NockBackMode = "wild" | "dryrun" | "record" | "lockdown"; + + export interface NockBack { + fixtures: string; + setMode(mode: NockBackMode): void; + + (fixtureName: string, nockedFn: (nockDone: () => void) => void): void; + (fixtureName: string, options: NockBackOptions, nockedFn: (nockDone: () => void) => void): void; + } + + export interface NockBackOptions { + before?: (def: NockDefinition) => void; + after?: (scope: Scope) => void; + afterRecord?: (defs: NockDefinition[]) => NockDefinition[]; + recorder?: RecorderOptions; + } + } }