diff --git a/types/mocha-each/index.d.ts b/types/mocha-each/index.d.ts new file mode 100644 index 0000000000..f368cdfc03 --- /dev/null +++ b/types/mocha-each/index.d.ts @@ -0,0 +1,50 @@ +// Type definitions for mocha-each 1.1 +// Project: https://github.com/ryym/mocha-each#readme +// Definitions by: Tom Harley +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.1 + +import { ITest, ITestDefinition, ITestCallbackContext } from 'mocha'; + +/** + * This function takes an array collections of parameters to be used in + * a series of mocha tests, defined using the `it` notation common to + * Mocha. + */ +declare function forEach( + parameters: ReadonlyArray, + defaultIt?: ITestDefinition +): { it: ForEachITestDefinition }; + +/** + * This interface describes the kind of `it` available from a `forEach` call. + * The result is very similar to Mocha's `ITestDefinition` interface. + */ +interface ForEachITestDefinition { + /* + * The callback functions in each of these properties take a variable + * number of arguments, based on how many values were passed in tuples + * in the call of forEach that generated this property. + * + * This problem is similar to `Function.prototype.apply`, which also + * does not have strong typing + * (see github.com/Microsoft/Typescript/issues/212). + * + * These callback functions can all accept an optional callback generated + * by mocha, which is used for asynchronous code testing. However, + * since rest parameters have to be the final parameter in a function + * declaration, this function cannot be explicitly mentioned here. + * + * A more accurate signature for the callback functions would be + * callback?: (this, ...args, done?: MochaDone) + * Additionally, Mocha does not export its MochaDone interface. + */ + (expectation: string, callback?: + (this: ITestCallbackContext, ...args: any[]) => any): ITest; + only(expectation: string, callback?: + (this: ITestCallbackContext, ...args: any[]) => any): ITest; + skip(expectation: string, callback?: + (this: ITestCallbackContext, ...args: any[]) => any): ITest; +} + +export = forEach; diff --git a/types/mocha-each/mocha-each-tests.ts b/types/mocha-each/mocha-each-tests.ts new file mode 100644 index 0000000000..1cf3e47c43 --- /dev/null +++ b/types/mocha-each/mocha-each-tests.ts @@ -0,0 +1,86 @@ +/* + * These tests are adapted from the use examples for the package from + * its host repository, [github.com/ryym/mocha-each#readme]. + * + * Adapting involved ensuring each set of test was wrapped in its own + * `describe` context; adding mock functions for use in the examples; + * and adding type declarations for most elements. + */ + +import forEach = require('mocha-each'); + +// Basic +declare function assert(...args: any[]): void; + +function add(a: any, b: any) { + return parseInt(a, 10) + parseInt(b, 10); +} + +describe('add()', () => { + forEach([ + [1, 1, 2], + [2, -2, 0], + [140, 48, 188] + ]) + .it('adds %d and %d then returns %d', (left: any, right: any, expected: any) => { + assert(add(left, right) === expected); + }); + + context('with invalid arguments', () => { + forEach([ + [1, 'foo'], + [null, 10], + [{}, []] + ]) + .it('adds %j and %j then returns NaN', (left: any, right: any) => { + const value = add(left, right); + assert(isNaN(value)); + }); + }); +}); + +// Asynchronous code +declare function fetchData(a: any): Promise; + +describe('Asynchronous Code Example', () => { + forEach([ + [0, 1], + [2, 3] + ]) + .it('does async operation', (arg: any, expected: any, done: (error: any) => any) => { + fetchData(arg) + .then((actual: any) => assert(actual === expected)) + .then(done); + }); +}); + +// Exclusive or inclusive tests +describe('Exclusive/Inclusive Test Example', () => { + forEach([ + 0, 1, 2, 3 + ]) + .it.only('works fine', (number: number) => { + assert(number); + }); + + forEach([ + 'foo', 'bar', 'baz' + ]) + .it.skip('also works fine', (word: string) => { + assert(word); + }); +}); + +// .timeout example +declare function use(...args: any[]): void; + +describe('.timeout Example', () => { + forEach([ + // ... + ]) + .it('is a slow test', function(p0: null, p1: null, p2: null/* , done */) { + this.timeout(3000); // Configure timeout. + use(p0, p1, p2); + // ... + }); +}); diff --git a/types/mocha-each/tsconfig.json b/types/mocha-each/tsconfig.json new file mode 100644 index 0000000000..51ac693789 --- /dev/null +++ b/types/mocha-each/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "mocha-each-tests.ts" + ] +} diff --git a/types/mocha-each/tslint.json b/types/mocha-each/tslint.json new file mode 100644 index 0000000000..3db14f85ea --- /dev/null +++ b/types/mocha-each/tslint.json @@ -0,0 +1 @@ +{ "extends": "dtslint/dt.json" }