mocha-typescript
Advanced tools
Comparing version 1.1.12 to 1.1.14
@@ -51,8 +51,2 @@ /// <reference path="./index.d.ts" /> | ||
declare var suite: Mocha.IContextDefinition; | ||
declare var test: Mocha.ITestDefinition; | ||
declare var describe: Mocha.IContextDefinition; | ||
declare var it: Mocha.ITestDefinition; | ||
declare var skipOnError: MochaTypeScript.SuiteTrait; | ||
@@ -59,0 +53,0 @@ |
declare namespace Mocha { | ||
export interface IContextDefinition {} | ||
export interface ITestDefinition {} | ||
export interface ISuiteCallbackContext {} | ||
export interface ITestCallbackContext {} | ||
export interface ITest { | ||
@@ -15,6 +10,2 @@ <T>(target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>): TypedPropertyDescriptor<T> | void; | ||
interface MochaDone { | ||
(error?: any): any; | ||
} | ||
declare namespace MochaTypeScript { | ||
@@ -21,0 +12,0 @@ export interface Suite { |
86
index.js
@@ -33,8 +33,8 @@ "use strict"; | ||
const slowValue = method[slowSymbol]; | ||
if (typeof slowValue === "number") { | ||
mocha.slow(slowValue); | ||
if (mocha['slow'] && typeof slowValue === "number") { | ||
mocha['slow'](slowValue); | ||
} | ||
const retriesValue = method[retriesSymbol]; | ||
if (typeof retriesValue === "number") { | ||
mocha.retries(retriesValue); | ||
if (mocha['retries'] && typeof retriesValue === "number") { | ||
mocha['retries'](retriesValue); | ||
} | ||
@@ -150,40 +150,48 @@ const contextProperty = ctorOrProto[contextSymbol]; | ||
context.afterEach(afterEachFunction); | ||
Object.getOwnPropertyNames(prototype).forEach(key => { | ||
try { | ||
let method = prototype[key]; | ||
if (method === target) { | ||
return; | ||
} | ||
let testName = method[testNameSymbol]; | ||
let shouldSkip = method[skipSymbol]; | ||
let shouldOnly = method[onlySymbol]; | ||
let shouldPending = method[pendingSumbol]; | ||
let testFunc = (shouldSkip && context.it.skip) | ||
|| (shouldOnly && context.it.only) | ||
|| context.it; | ||
if (testName || shouldOnly || shouldPending || shouldSkip) { | ||
testName = testName || method.name; | ||
if (shouldPending && !shouldSkip && !shouldOnly) { | ||
context.it.skip(testName); | ||
function runTests(prototype) { | ||
Object.getOwnPropertyNames(prototype).forEach(key => { | ||
try { | ||
let method = prototype[key]; | ||
if (method === target) { | ||
return; | ||
} | ||
else if (method.length > 0) { | ||
testFunc(testName, noname(function (done) { | ||
applyDecorators(this, prototype, method, instance); | ||
applyTestTraits(this, instance, method); | ||
return method.call(instance, done); | ||
})); | ||
let testName = method[testNameSymbol]; | ||
let shouldSkip = method[skipSymbol]; | ||
let shouldOnly = method[onlySymbol]; | ||
let shouldPending = method[pendingSumbol]; | ||
let testFunc = (shouldSkip && context.it.skip) | ||
|| (shouldOnly && context.it.only) | ||
|| context.it; | ||
if (testName || shouldOnly || shouldPending || shouldSkip) { | ||
testName = testName || method.name; | ||
if (shouldPending && !shouldSkip && !shouldOnly) { | ||
context.it.skip(testName); | ||
} | ||
else if (method.length > 0) { | ||
testFunc(testName, noname(function (done) { | ||
applyDecorators(this, prototype, method, instance); | ||
applyTestTraits(this, instance, method); | ||
return method.call(instance, done); | ||
})); | ||
} | ||
else { | ||
testFunc(testName, noname(function () { | ||
applyDecorators(this, prototype, method, instance); | ||
applyTestTraits(this, instance, method); | ||
return method.call(instance); | ||
})); | ||
} | ||
} | ||
else { | ||
testFunc(testName, noname(function () { | ||
applyDecorators(this, prototype, method, instance); | ||
applyTestTraits(this, instance, method); | ||
return method.call(instance); | ||
})); | ||
} | ||
} | ||
} | ||
catch (e) { | ||
// console.log(e); | ||
} | ||
}); | ||
catch (e) { | ||
// console.log(e); | ||
} | ||
}); | ||
} | ||
// run all tests along the inheritance chain | ||
let currentPrototype = prototype; | ||
while (currentPrototype !== Object.prototype) { | ||
runTests(currentPrototype); | ||
currentPrototype = Object.getPrototypeOf(currentPrototype); | ||
} | ||
}; | ||
@@ -190,0 +198,0 @@ } |
89
index.ts
@@ -71,3 +71,3 @@ import * as Mocha from "mocha"; | ||
function applyDecorators(mocha: Mocha.IHookCallbackContext | Mocha.ISuiteCallbackContext, ctorOrProto, method, instance) { | ||
function applyDecorators(mocha: Mocha.IHookCallbackContext, ctorOrProto, method, instance) { | ||
const timeoutValue = method[timeoutSymbol]; | ||
@@ -78,8 +78,8 @@ if (typeof timeoutValue === "number") { | ||
const slowValue = method[slowSymbol]; | ||
if (typeof slowValue === "number") { | ||
mocha.slow(slowValue); | ||
if (mocha['slow'] && typeof slowValue === "number") { | ||
mocha['slow'](slowValue); | ||
} | ||
const retriesValue = method[retriesSymbol]; | ||
if (typeof retriesValue === "number") { | ||
mocha.retries(retriesValue); | ||
if (mocha['retries'] && typeof retriesValue === "number") { | ||
mocha['retries'](retriesValue); | ||
} | ||
@@ -190,40 +190,49 @@ const contextProperty = ctorOrProto[contextSymbol]; | ||
(<any>Object).getOwnPropertyNames(prototype).forEach(key => { | ||
try { | ||
let method = <Function>prototype[key]; | ||
if (method === target) { | ||
return; | ||
} | ||
function runTests(prototype: any) { | ||
(<any>Object).getOwnPropertyNames(prototype).forEach(key => { | ||
try { | ||
let method = <Function>prototype[key]; | ||
if (method === target) { | ||
return; | ||
} | ||
let testName = method[testNameSymbol]; | ||
let shouldSkip = method[skipSymbol]; | ||
let shouldOnly = method[onlySymbol]; | ||
let shouldPending = method[pendingSumbol]; | ||
let testName = method[testNameSymbol]; | ||
let shouldSkip = method[skipSymbol]; | ||
let shouldOnly = method[onlySymbol]; | ||
let shouldPending = method[pendingSumbol]; | ||
let testFunc = (shouldSkip && context.it.skip) | ||
|| (shouldOnly && context.it.only) | ||
|| context.it; | ||
let testFunc = (shouldSkip && context.it.skip) | ||
|| (shouldOnly && context.it.only) | ||
|| context.it; | ||
if (testName || shouldOnly || shouldPending || shouldSkip) { | ||
testName = testName || (<any>method).name; | ||
if (shouldPending && !shouldSkip && !shouldOnly) { | ||
context.it.skip(testName); | ||
} else if (method.length > 0) { | ||
testFunc(testName, noname(function (this: Mocha.ITestCallbackContext, done) { | ||
applyDecorators(this, prototype, method, instance); | ||
applyTestTraits(this, instance, method); | ||
return method.call(instance, done); | ||
})); | ||
} else { | ||
testFunc(testName, noname(function (this: Mocha.ITestCallbackContext) { | ||
applyDecorators(this, prototype, method, instance); | ||
applyTestTraits(this, instance, method); | ||
return method.call(instance); | ||
})); | ||
} | ||
} | ||
} catch (e) { | ||
// console.log(e); | ||
} | ||
}); | ||
if (testName || shouldOnly || shouldPending || shouldSkip) { | ||
testName = testName || (<any>method).name; | ||
if (shouldPending && !shouldSkip && !shouldOnly) { | ||
context.it.skip(testName); | ||
} else if (method.length > 0) { | ||
testFunc(testName, noname(function(this: Mocha.ITestCallbackContext, done) { | ||
applyDecorators(this, prototype, method, instance); | ||
applyTestTraits(this, instance, method); | ||
return method.call(instance, done); | ||
})); | ||
} else { | ||
testFunc(testName, noname(function(this: Mocha.ITestCallbackContext) { | ||
applyDecorators(this, prototype, method, instance); | ||
applyTestTraits(this, instance, method); | ||
return method.call(instance); | ||
})); | ||
} | ||
} | ||
} catch (e) { | ||
// console.log(e); | ||
} | ||
}); | ||
} | ||
// run all tests along the inheritance chain | ||
let currentPrototype = prototype; | ||
while (currentPrototype !== Object.prototype) { | ||
runTests(currentPrototype); | ||
currentPrototype = (<any>Object).getPrototypeOf(currentPrototype); | ||
} | ||
} | ||
@@ -230,0 +239,0 @@ } |
{ | ||
"name": "mocha-typescript", | ||
"version": "1.1.12", | ||
"version": "1.1.14", | ||
"description": "TypeScript decorators based wrapper over mocha's interface", | ||
@@ -22,2 +22,3 @@ "main": "index.js", | ||
"dependencies": { | ||
"@types/mocha": "*", | ||
"chalk": "^1.1.3", | ||
@@ -29,3 +30,4 @@ "cross-spawn": "^5.1.0", | ||
"@types/chai": "^3.4.35", | ||
"@types/node": "^7.0.12", | ||
"@types/mocha": "^5.0.0", | ||
"@types/node": "^7.0.60", | ||
"assert": "^1.3.0", | ||
@@ -32,0 +34,0 @@ "better-assert": "^1.0.2", |
127
README.md
@@ -29,2 +29,4 @@ Writing mocha tests with style - OOP style: | ||
- [Declarative Suites and Tests](#declarative-suites-and-tests) | ||
- [Test Inheritance](#test-inheritance) | ||
- [Inheritance and Both Synchronous and Asynchronous Before and After Actions](#inheritance-and-both-synchronous-and-asynchronous-before-and-after-actions) | ||
- [Generated Suites and Tests](#generated-suites-and-tests) | ||
@@ -79,3 +81,3 @@ - [Before and After Actions](#before-and-after-actions) | ||
@test.only method1() {} | ||
@test mothod2() {} | ||
@test method2() {} | ||
} | ||
@@ -211,3 +213,3 @@ ``` | ||
For complete list with check `./node_modules/.bin/mocha-typescript-watch --help`: | ||
For complete list with check `./node_modules/.bin/mocha-typescript-watch --help`: | ||
``` | ||
@@ -254,3 +256,3 @@ Options: | ||
At few occasions when misxing BDD and the mocha-typescript decorators based UI, trying to run a single BDD test would cause WebStorm to generate a mocha task that would run using BDD ui, instead of mocha-typescript. In these cases the tests may fail as there is no `suite` or `test` functions defined in the BDD UI. To fix this you may edit the default Mocha task, and configure it to use mocha-typescript UI explicitly. From that point on, when you try to run a single test, event BDD one, WebStorm will create Mocha tasks that will use the mocha-typescript UI. | ||
At few occasions when misxing BDD and the mocha-typescript decorators based UI, trying to run a single BDD test would cause WebStorm to generate a mocha task that would run using BDD ui, instead of mocha-typescript. In these cases the tests may fail as there is no `suite` or `test` functions defined in the BDD UI. To fix this you may edit the default Mocha task, and configure it to use mocha-typescript UI explicitly. From that point on, when you try to run a single test, event BDD one, WebStorm will create Mocha tasks that will use the mocha-typescript UI. | ||
@@ -281,2 +283,119 @@ # Test UI API | ||
## Test Inheritance | ||
One can declare abstract classes as bases for derived test classes. Tests methods declared in these base classes will be run in the context of | ||
the concrete test class, namely the one that has been decorated with the `@suite` decorator: | ||
``` TypeScript | ||
export abstract class AbstractTestBase { | ||
public static before() { | ||
// ... | ||
} | ||
public before() { | ||
// ... | ||
} | ||
@test aTestFromBase() { | ||
// ... | ||
} | ||
@test "another test from base"() { | ||
// ... | ||
} | ||
public after () { | ||
// ... | ||
} | ||
public static after () { | ||
// ... | ||
} | ||
} | ||
@suite class ConcreteTest extends AbstractTestBase { | ||
public static before() { | ||
// AbstractTestBase.before(); | ||
// ... | ||
} | ||
public before() { | ||
// super.before(); | ||
// ... | ||
} | ||
@test aTestFromConcrete() { | ||
// ... | ||
} | ||
public after() { | ||
// ... | ||
// super.after(); | ||
} | ||
public static after() { | ||
// ... | ||
// AbstractTestBase.after(); | ||
} | ||
} | ||
``` | ||
One can also inherit from another concrete test class or suite, but keep in mind that that the tests declared by that suite will | ||
be run multiple times and not just in the context of the concrete test classes, see the example provided in `tests/ts/suite.inheritance.suite.ts`. | ||
Important: One should not override test methods inherited from a base class and then call `super()` as this will run the tests from the base class twice. | ||
### Inheritance and Both Synchronous and Asynchronous Before and After Actions | ||
As for both static and instance `before()` and `after()` actions, one must make sure that the hooks from the parent class are called, see the | ||
above example on how. | ||
When using asynchronous actions, additional care must be taken, since one cannot simply pass the `done` callback to the parent | ||
classes' hooks and you will have to use something along the line of this in order to make it happen: | ||
``` TypeScript | ||
export abstract class AbstractTestBase { | ||
public static before(done) { | ||
// ... | ||
// done([err]); | ||
} | ||
public before(done) { | ||
// ... | ||
// done([err]); | ||
} | ||
} | ||
@suite class ConcreteTest extends AbstractTestBase { | ||
public static before(done) { | ||
AbstractTestBase.before((err) => { | ||
if (err) { | ||
done(err); | ||
return; | ||
} | ||
// ... | ||
// done([err]); | ||
}); | ||
} | ||
public before(done) { | ||
super.before((err) => { | ||
if (err) { | ||
done(err); | ||
return; | ||
} | ||
// ... | ||
// done([err]); | ||
}); | ||
} | ||
} | ||
``` | ||
With `after()` actions the patterns are similar yet a bit more involved. Note that similar patterns apply when using `Promise`s or `async` and `await`. | ||
Important: One must not mix chained calls to both asynchronous and synchronous before and after actions. If a base class defines either action to be asynchronous then | ||
you will have to make your action asynchronous as well. | ||
See [Before and After Actions](#before-and-after-actions) and [Async Tests, Before and After Actions](#async-tests-before-and-after-actions) for more information. | ||
## Generated Suites and Tests | ||
@@ -362,3 +481,3 @@ Mocha's simple interface is very flexible when tests have to be dynamically generated. | ||
## Retries | ||
I would not recomend retrying failed tests multiple times to ensure green light but I also wouldn't judge, here it goes mocha-typescript retries: | ||
I would not recommend retrying failed tests multiple times to ensure green light but I also wouldn't judge, here it goes mocha-typescript retries: | ||
``` TypeScript | ||
@@ -365,0 +484,0 @@ @suite(retries(2)) |
Sorry, the diff of this file is not supported yet
Floating dependency
QualityPackage has a dependency with a floating version range. This can cause issues if the dependency publishes a new major version.
Found 1 instance in 1 package
101747
1358
520
4
10
1
+ Added@types/mocha@*
+ Added@types/mocha@10.0.6(transitive)