From 13f375626137874c84d4fabb0834d662614f14ae Mon Sep 17 00:00:00 2001 From: Asuka Ito Date: Thu, 13 Apr 2017 11:15:32 +0900 Subject: [PATCH] Add moxios definition file --- types/moxios/index.d.ts | 192 ++++++++++++++++++++++ types/moxios/moxios-tests.ts | 308 +++++++++++++++++++++++++++++++++++ types/moxios/package.json | 5 + types/moxios/tsconfig.json | 22 +++ types/moxios/tslint.json | 1 + 5 files changed, 528 insertions(+) create mode 100644 types/moxios/index.d.ts create mode 100644 types/moxios/moxios-tests.ts create mode 100644 types/moxios/package.json create mode 100644 types/moxios/tsconfig.json create mode 100644 types/moxios/tslint.json diff --git a/types/moxios/index.d.ts b/types/moxios/index.d.ts new file mode 100644 index 0000000000..aa3b82e9f1 --- /dev/null +++ b/types/moxios/index.d.ts @@ -0,0 +1,192 @@ +// Type definitions for moxios v0.4.0 +// Project: https://github.com/mzabriskie/moxios +// Definitions by: Asuka Ito +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped + +import {AxiosInstance} from "axios"; + +interface Item { + response?: any; + responseText?: string; + status?: number; + statusText?: string; + headers?: any; +} + +declare class Tracker { + constructor(); + + /** + * Reset all the items being tracked + */ + reset(): void; + + /** + * Add an item to be tracked + * + * @param {Object} item An item to be tracked + */ + track(item: Item): void; + + /** + * The count of items being tracked + * + * @return {number} + */ + count(): number; + + /** + * Get an item being tracked at a given index + * + * @param {number} index The index for the item to retrieve + * @return {Object} + */ + at(index: number): Request; + + /** + * Get the first item being tracked + * + * @return {Object} + */ + first(): Request; + + /** + * Get the most recent (last) item being tracked + * + * @return {Object} + */ + mostRecent(): Request; + + /** + * Dump the items being tracked to the console. + */ + debug(): void; + + /** + * Find and return element given the HTTP method and the URL. + */ + get(method: string, url?: string): Request; + + /** + * Stop an element from being tracked by removing it. Finds and returns the element, + * given the HTTP method and the URL. + */ + remove(method: string, url: string): Request; +} + +declare class Request { + /** + * Create a new Request object + * + * @param {Function} resolve The function to call when Promise is resolved + * @param {Function} reject The function to call when Promise is rejected + * @param {Object} config The config object to be used for the request + */ + constructor(resolve: (arg: any) => void, reject: (arg: any) => void, config: any); + + /** + * Respond to this request with a timeout result + * + * @return {Promise} A Promise that rejects with a timeout result + */ + respondWithTimeout(): Promise; + + /** + * Respond to this request with a specified result + * + * @param {Object} res The data representing the result of the request + * @return {Promise} A Promise that resolves once the response is ready + */ + respondWith(res: Item): Promise; +} + +declare class Response { + /** + * Create a new Response object + * + * @param {Request} req The Request that this Response is associated with + * @param {Object} res The data representing the result of the request + */ + constructor(req: Request, res: any); + + config: any; + data?: any; + status?: number; + statusText?: string; + headers: any; + request: Request; +} + +declare let moxios: { + stubs: Tracker; + requests: Tracker; + delay: number; + timeoutException: Error; + + /** + * Install the mock adapter for axios + */ + install(instance?: AxiosInstance): void; + + /** + * Uninstall the mock adapter and reset state + */ + uninstall(instance?: AxiosInstance): void; + + /** + * Stub a response to be used to respond to a request matching a URL or RegExp + * + * @param {string|RegExp} urlOrRegExp A URL or RegExp to test against + * @param {Object} response The response to use when a match is made + */ + stubRequest(urlOrRegExp: string | RegExp, response: Item): void; + + /** + * Stub a response to be used one or more times to respond to a request matching a + * method and a URL or RegExp. + * + * @param {string} method An axios command + * @param {string|RegExp} urlOrRegExp A URL or RegExp to test against + * @param {Object} response The response to use when a match is made + */ + stubOnce(method: string, urlOrRegExp: string | RegExp, response: Item): Promise; + + /** + * Stub a timed response to a request matching a method and a URL or RegExp. If + * timer fires, reject with a TimeoutException for simple assertions. The goal is + * to show that a certain request was not made. + * + * @param {string} method An axios command + * @param {string|RegExp} urlOrRegExp A URL or RegExp to test against + * @param {Object} response The response to use when a match is made + */ + stubFailure(method: string, urlOrRegExp: string | RegExp, response: Item): Promise; + + /** + * Stub a timeout to be used to respond to a request matching a URL or RegExp + * + * @param {string|RegExp} urlOrRegExp A URL or RegExp to test against + */ + stubTimeout(urlOrRegExp: string | RegExp): string; + + /** + * Run a single test with mock adapter installed. + * This will install the mock adapter, execute the function provided, + * then uninstall the mock adapter once complete. + * + * @param {Function} fn The function to be executed + */ + withMock(fn: () => void): void; + + /** + * Wait for request to be made before proceding. + * This is naively using a `setTimeout`. + * May need to beef this up a bit in the future. + * + * @param {Function} fn The function to execute once waiting is over + * @param {number} delay How much time in milliseconds to wait + */ + wait(fn: () => void, delay?: number): void; +}; + +export default moxios; diff --git a/types/moxios/moxios-tests.ts b/types/moxios/moxios-tests.ts new file mode 100644 index 0000000000..82ceb8535b --- /dev/null +++ b/types/moxios/moxios-tests.ts @@ -0,0 +1,308 @@ +// from https://github.com/mzabriskie/moxios/blob/master/test.js +import {equal, notEqual, deepEqual} from 'power-assert'; // compatible with 'assert'; +import axios from 'axios'; +import moxios from 'moxios'; + +declare const sinon: any; +declare const describe: any; +declare function it(testName: string, test: (done: () => void) => void|Promise): void; +declare const beforeEach: any; +declare const afterEach: any; + +const USER_FRED = { + id: 12345, + firstName: 'Fred', + lastName: 'Flintstone' +}; + +describe('moxios', () => { + it('should install', () => { + let defaultAdapter = axios.defaults.adapter; + moxios.install(); + notEqual(axios.defaults.adapter, defaultAdapter); + moxios.uninstall(); + }); + + it('should uninstall', () => { + let defaultAdapter = axios.defaults.adapter; + moxios.install(); + moxios.uninstall(); + equal(axios.defaults.adapter, defaultAdapter); + }); + + describe('requests', () => { + let onFulfilled: any; + let onRejected: any; + + beforeEach(() => { + moxios.install(); + onFulfilled = sinon.spy(); + onRejected = sinon.spy(); + }); + + afterEach(() => { + moxios.uninstall(); + }); + + it('should intercept requests', (done) => { + axios.get('/users/12345'); + + moxios.wait(() => { + let request = moxios.requests.mostRecent(); + equal(moxios.requests.count(), 1); + done(); + }); + }); + + it('should mock responses', (done) => { + axios.get('/users/12345').then(onFulfilled); + + moxios.wait(() => { + let request = moxios.requests.mostRecent(); + request.respondWith({ + status: 200, + response: USER_FRED + }).then(() => { + let response = onFulfilled.getCall(0).args[0]; + equal(onFulfilled.called, true); + equal(response.status, 200); + deepEqual(response.data, USER_FRED); + done(); + }); + }); + }); + + it('should mock responses Error', (done) => { + axios.get('/users/12346').then(onFulfilled, onRejected); + + moxios.wait(() => { + let request = moxios.requests.mostRecent(); + request.respondWith({ + status: 404 + }).then(() => { + equal(onFulfilled.called, false); + equal(onRejected.called, true); + done(); + }); + }); + }); + + it('should mock one time', (done) => { + moxios.uninstall(); + + moxios.withMock(() => { + axios.get('/users/12345').then(onFulfilled); + + moxios.wait(() => { + let request = moxios.requests.mostRecent(); + request.respondWith({ + status: 200, + response: USER_FRED + }).then(() => { + equal(onFulfilled.called, true); + done(); + }); + }); + }); + }); + + it('should timeout requests one time', (done) => { + moxios.uninstall(); + + moxios.withMock(() => { + axios.get('/users/12345'); + + moxios.wait(() => { + let request = moxios.requests.mostRecent(); + request.respondWithTimeout().catch((err: any) => { + equal(err.code, 'ECONNABORTED'); + done(); + }); + }); + }); + }); + + it('should stub requests', (done) => { + moxios.stubRequest('/users/12345', { + status: 200, + response: USER_FRED + }); + + axios.get('/users/12345').then(onFulfilled); + + moxios.wait(() => { + let response = onFulfilled.getCall(0).args[0]; + deepEqual(response.data, USER_FRED); + done(); + }); + }); + + it('should stub timeout', (done) => { + moxios.stubTimeout('/users/12345'); + + axios.get('/users/12345').catch(onRejected); + + moxios.wait(() => { + let err = onRejected.getCall(0).args[0]; + deepEqual(err.code, 'ECONNABORTED'); + done(); + }); + }); + + it('should stub requests RegExp', (done) => { + moxios.stubRequest(/\/users\/\d*/, { + status: 200, + response: USER_FRED + }); + + axios.get('/users/12345').then(onFulfilled); + + moxios.wait(() => { + let response = onFulfilled.getCall(0).args[0]; + deepEqual(response.data, USER_FRED); + done(); + }); + }); + + describe('stubs', () => { + it('should track multiple stub requests', () => { + moxios.stubOnce('PUT', '/users/12345', { + status: 204 + }); + + moxios.stubOnce('GET', '/users/12346', { + status: 200, + response: USER_FRED + }); + + equal(moxios.stubs.count(), 2); + }); + + it('should find single stub by method', () => { + moxios.stubOnce('PUT', '/users/12345', { + status: 204 + }); + + moxios.stubOnce('GET', '/users/12346', { + status: 200, + response: USER_FRED + }); + + let request = moxios.stubs.get('PUT', '/users/12345'); + + notEqual(request, undefined); + }); + + it('should remove a single stub by method', () => { + moxios.stubOnce('PUT', '/users/12346', { + status: 204 + }); + + moxios.stubOnce('GET', '/users/12346', { + status: 200, + response: USER_FRED + }); + + moxios.stubOnce('PUT', '/users/12345', { + status: 204 + }); + + moxios.stubOnce('GET', '/users/12345', { + status: 200, + response: USER_FRED + }); + + moxios.stubs.remove('PUT', '/users/12345'); + equal(moxios.stubs.count(), 3); + }); + + it('should not find stub with invalid method', () => { + moxios.stubOnce('PUT', '/users/12345', { + status: 204 + }); + + moxios.stubOnce('GET', '/users/12346', { + status: 200, + response: USER_FRED + }); + + let request = moxios.stubs.get('GET', '/users/12345'); + + equal(request, undefined); + }); + + it('should not find request on invalid method', () => { + moxios.stubOnce('PUT', '/users/12345', { + status: 204 + }); + + moxios.stubOnce('GET', '/users/12346', { + status: 200, + response: USER_FRED + }); + + axios.put('/users/12346', USER_FRED); + let request = moxios.requests.get('TEST'); + + equal(request, undefined); + }); + + it('should find request after multiple stubs using same URI', (done) => { + moxios.stubOnce('POST', '/users/12345', { + status: 204 + }); + + moxios.stubOnce('PUT', '/users/12345', { + status: 204 + }); + + moxios.stubOnce('GET', '/users/12345', { + status: 200, + response: USER_FRED + }); + + axios.put('/users/12345', USER_FRED).then(onFulfilled); + + moxios.wait(() => { + let response = onFulfilled.getCall(0).args[0]; + equal(response.status, 204); + let request = moxios.requests.get('PUT', '/users/12345'); + notEqual(request, undefined); + done(); + }); + }); + + it('Should stub and find multiple requests by method', (done) => { + moxios.stubOnce('PUT', '/users/12345', { + status: 204 + }); + + moxios.stubOnce('GET', '/users/12346', { + status: 200, + response: USER_FRED + }); + + axios.put('/users/12345', USER_FRED).then(onFulfilled); + axios.get('/users/12346', {}).then(onFulfilled); + + moxios.wait(() => { + equal(onFulfilled.calledTwice, true); + + let response1 = onFulfilled.getCall(0).args[0]; + let response2 = onFulfilled.getCall(1).args[0]; + equal(response1.status, 204); + equal(response2.status, 200); + equal(response2.data.firstName, 'Fred'); + + let request = moxios.requests.get('PUT', '/users/12345'); + notEqual(request, undefined); + + request = moxios.requests.get('GET', '/users/12346'); + notEqual(request, undefined); + + done(); + }); + }); + }); + }); +}); diff --git a/types/moxios/package.json b/types/moxios/package.json new file mode 100644 index 0000000000..2886d8e5fc --- /dev/null +++ b/types/moxios/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "axios": "^0.16.1" + } +} diff --git a/types/moxios/tsconfig.json b/types/moxios/tsconfig.json new file mode 100644 index 0000000000..ae7c3788f9 --- /dev/null +++ b/types/moxios/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "moxios-tests.ts" + ] +} diff --git a/types/moxios/tslint.json b/types/moxios/tslint.json new file mode 100644 index 0000000000..377cc837d4 --- /dev/null +++ b/types/moxios/tslint.json @@ -0,0 +1 @@ +{ "extends": "../tslint.json" }