Browse Source

Convert some classes to ES2015 classes

replace-snapshot
Sindre Sorhus 8 years ago
parent
commit
fa82a24a31
  1. 13
      lib/ava-error.js
  2. 122
      lib/concurrent.js
  3. 221
      lib/run-status.js
  4. 266
      lib/runner.js
  5. 141
      lib/sequence.js
  6. 8
      test/api.js
  7. 11
      test/ava-error.js
  8. 8
      test/caching-precompiler.js
  9. 8
      test/concurrent.js
  10. 8
      test/logger.js
  11. 8
      test/run-status.js
  12. 8
      test/runner.js
  13. 8
      test/sequence.js
  14. 8
      test/test-collection.js
  15. 8
      test/test.js

13
lib/ava-error.js

@ -1,14 +1,11 @@
'use strict';
function AvaError(message) {
if (!(this instanceof AvaError)) {
throw new TypeError('Class constructor AvaError cannot be invoked without \'new\'');
class AvaError extends Error {
constructor(message) {
super(message);
this.name = 'AvaError';
this.message = message;
}
this.message = message;
this.name = 'AvaError';
}
AvaError.prototype = Object.create(Error.prototype);
module.exports = AvaError;

122
lib/concurrent.js

@ -4,88 +4,80 @@ const isPromise = require('is-promise');
const autoBind = require('auto-bind');
const AvaError = require('./ava-error');
function noop() {}
class Concurrent {
constructor(tests, bail) {
if (!Array.isArray(tests)) {
throw new TypeError('Expected an array of tests');
}
module.exports = Concurrent;
this.results = [];
this.passed = true;
this.reason = null;
this.tests = tests;
this.bail = bail || false;
function Concurrent(tests, bail) {
if (!(this instanceof Concurrent)) {
throw new TypeError('Class constructor Concurrent cannot be invoked without \'new\'');
autoBind(this);
}
run() {
let results;
if (!Array.isArray(tests)) {
throw new TypeError('Expected an array of tests');
}
this.results = [];
this.passed = true;
this.reason = null;
this.tests = tests;
this.bail = bail || false;
autoBind(this);
}
Concurrent.prototype.run = function () {
let results;
try {
results = this.tests.map(this._runTest);
} catch (err) {
if (err instanceof AvaError) {
return this._results();
}
try {
results = this.tests.map(this._runTest);
} catch (err) {
if (err instanceof AvaError) {
return this._results();
throw err;
}
throw err;
}
const isAsync = results.some(isPromise);
const isAsync = results.some(isPromise);
if (isAsync) {
return Promise.all(results)
.catch(AvaError, () => {})
.then(this._results);
}
if (isAsync) {
return Promise.all(results)
.catch(AvaError, noop)
.then(this._results);
return this._results();
}
_runTest(test, index) {
const result = test.run();
return this._results();
};
Concurrent.prototype._runTest = function (test, index) {
const result = test.run();
if (isPromise(result)) {
return result.then(result => this._addResult(result, index));
}
if (isPromise(result)) {
return result.then(result => this._addResult(result, index));
return this._addResult(result, index);
}
_addResult(result, index) {
// always save result when not in bail mode or all previous tests pass
if ((this.bail && this.passed) || !this.bail) {
this.results[index] = result;
}
return this._addResult(result, index);
};
if (result.passed === false) {
this.passed = false;
Concurrent.prototype._addResult = function (result, index) {
// always save result when not in bail mode or all previous tests pass
if ((this.bail && this.passed) || !this.bail) {
this.results[index] = result;
}
// only set reason once
if (!this.reason) {
this.reason = result.reason;
}
if (result.passed === false) {
this.passed = false;
// only set reason once
if (!this.reason) {
this.reason = result.reason;
if (this.bail) {
throw new AvaError('Error in Concurrent while in bail mode');
}
}
if (this.bail) {
throw new AvaError('Error in Concurrent while in bail mode');
}
return result;
}
_results() {
return {
passed: this.passed,
reason: this.reason,
result: this.results
};
}
}
return result;
};
Concurrent.prototype._results = function () {
return {
passed: this.passed,
reason: this.reason,
result: this.results
};
};
module.exports = Concurrent;

221
lib/run-status.js

@ -1,6 +1,5 @@
'use strict';
const EventEmitter = require('events').EventEmitter;
const util = require('util');
const EventEmitter = require('events');
const chalk = require('chalk');
const isObj = require('is-obj');
const flatten = require('arr-flatten');
@ -8,48 +7,15 @@ const figures = require('figures');
const autoBind = require('auto-bind');
const prefixTitle = require('./prefix-title');
function RunStatus(opts) {
if (!(this instanceof RunStatus)) {
throw new TypeError('Class constructor RunStatus cannot be invoked without \'new\'');
}
EventEmitter.call(this);
opts = opts || {};
this.prefixTitles = opts.prefixTitles !== false;
this.hasExclusive = Boolean(opts.runOnlyExclusive);
this.base = opts.base || '';
this.rejectionCount = 0;
this.exceptionCount = 0;
this.passCount = 0;
this.knownFailureCount = 0;
this.skipCount = 0;
this.todoCount = 0;
this.failCount = 0;
this.fileCount = 0;
this.testCount = 0;
this.previousFailCount = 0;
this.knownFailures = [];
this.errors = [];
this.stats = [];
this.tests = [];
autoBind(this);
}
function sum(arr, key) {
let result = 0;
util.inherits(RunStatus, EventEmitter);
module.exports = RunStatus;
arr.forEach(item => {
result += item[key];
});
RunStatus.prototype.observeFork = function (emitter) {
emitter
.on('teardown', this.handleTeardown)
.on('stats', this.handleStats)
.on('test', this.handleTest)
.on('unhandledRejections', this.handleRejections)
.on('uncaughtException', this.handleExceptions)
.on('stdout', this.handleOutput.bind(this, 'stdout'))
.on('stderr', this.handleOutput.bind(this, 'stderr'));
};
return result;
}
function normalizeError(err) {
if (!isObj(err)) {
@ -62,96 +28,117 @@ function normalizeError(err) {
return err;
}
RunStatus.prototype.handleRejections = function (data) {
this.rejectionCount += data.rejections.length;
class RunStatus extends EventEmitter {
constructor(opts) {
super();
opts = opts || {};
this.prefixTitles = opts.prefixTitles !== false;
this.hasExclusive = Boolean(opts.runOnlyExclusive);
this.base = opts.base || '';
this.rejectionCount = 0;
this.exceptionCount = 0;
this.passCount = 0;
this.knownFailureCount = 0;
this.skipCount = 0;
this.todoCount = 0;
this.failCount = 0;
this.fileCount = 0;
this.testCount = 0;
this.previousFailCount = 0;
this.knownFailures = [];
this.errors = [];
this.stats = [];
this.tests = [];
data.rejections.forEach(err => {
err = normalizeError(err);
err.type = 'rejection';
autoBind(this);
}
observeFork(emitter) {
emitter
.on('teardown', this.handleTeardown)
.on('stats', this.handleStats)
.on('test', this.handleTest)
.on('unhandledRejections', this.handleRejections)
.on('uncaughtException', this.handleExceptions)
.on('stdout', this.handleOutput.bind(this, 'stdout'))
.on('stderr', this.handleOutput.bind(this, 'stderr'));
}
handleRejections(data) {
this.rejectionCount += data.rejections.length;
data.rejections.forEach(err => {
err = normalizeError(err);
err.type = 'rejection';
err.file = data.file;
this.emit('error', err, this);
this.errors.push(err);
});
}
handleExceptions(data) {
this.exceptionCount++;
const err = normalizeError(data.exception);
err.type = 'exception';
err.file = data.file;
this.emit('error', err, this);
this.errors.push(err);
});
};
RunStatus.prototype.handleExceptions = function (data) {
this.exceptionCount++;
const err = normalizeError(data.exception);
err.type = 'exception';
err.file = data.file;
this.emit('error', err, this);
this.errors.push(err);
};
RunStatus.prototype.handleTeardown = function (data) {
this.emit('dependencies', data.file, data.dependencies, this);
};
RunStatus.prototype.handleStats = function (stats) {
this.emit('stats', stats, this);
if (this.hasExclusive && !stats.hasExclusive) {
return;
}
if (!this.hasExclusive && stats.hasExclusive) {
this.hasExclusive = true;
this.testCount = 0;
handleTeardown(data) {
this.emit('dependencies', data.file, data.dependencies, this);
}
handleStats(stats) {
this.emit('stats', stats, this);
this.testCount += stats.testCount;
};
RunStatus.prototype.handleTest = function (test) {
test.title = this.prefixTitle(test.file) + test.title;
if (test.error) {
if (test.error.name !== 'AssertionError') {
test.error.message = `Error: ${test.error.message}`;
if (this.hasExclusive && !stats.hasExclusive) {
return;
}
this.errors.push(test);
}
if (test.failing && !test.error) {
this.knownFailures.push(test);
}
this.emit('test', test, this);
};
if (!this.hasExclusive && stats.hasExclusive) {
this.hasExclusive = true;
this.testCount = 0;
}
RunStatus.prototype.prefixTitle = function (file) {
if (!this.prefixTitles) {
return '';
this.testCount += stats.testCount;
}
handleTest(test) {
test.title = this.prefixTitle(test.file) + test.title;
const separator = ' ' + chalk.gray.dim(figures.pointerSmall) + ' ';
return prefixTitle(file, this.base, separator);
};
if (test.error) {
if (test.error.name !== 'AssertionError') {
test.error.message = `Error: ${test.error.message}`;
}
RunStatus.prototype.handleOutput = function (channel, data) {
this.emit(channel, data, this);
};
this.errors.push(test);
}
RunStatus.prototype.processResults = function (results) {
// assemble stats from all tests
this.stats = results.map(result => result.stats);
this.tests = results.map(result => result.tests);
this.tests = flatten(this.tests);
this.passCount = sum(this.stats, 'passCount');
this.knownFailureCount = sum(this.stats, 'knownFailureCount');
this.skipCount = sum(this.stats, 'skipCount');
this.todoCount = sum(this.stats, 'todoCount');
this.failCount = sum(this.stats, 'failCount');
};
if (test.failing && !test.error) {
this.knownFailures.push(test);
}
function sum(arr, key) {
let result = 0;
this.emit('test', test, this);
}
prefixTitle(file) {
if (!this.prefixTitles) {
return '';
}
arr.forEach(item => {
result += item[key];
});
const separator = ' ' + chalk.gray.dim(figures.pointerSmall) + ' ';
return result;
return prefixTitle(file, this.base, separator);
}
handleOutput(channel, data) {
this.emit(channel, data, this);
}
processResults(results) {
// assemble stats from all tests
this.stats = results.map(result => result.stats);
this.tests = results.map(result => result.tests);
this.tests = flatten(this.tests);
this.passCount = sum(this.stats, 'passCount');
this.knownFailureCount = sum(this.stats, 'knownFailureCount');
this.skipCount = sum(this.stats, 'skipCount');
this.todoCount = sum(this.stats, 'todoCount');
this.failCount = sum(this.stats, 'failCount');
}
}
module.exports = RunStatus;

266
lib/runner.js

@ -1,14 +1,13 @@
'use strict';
var EventEmitter = require('events').EventEmitter;
var util = require('util');
var Promise = require('bluebird');
var optionChain = require('option-chain');
var matcher = require('matcher');
var TestCollection = require('./test-collection');
const EventEmitter = require('events');
const Promise = require('bluebird');
const optionChain = require('option-chain');
const matcher = require('matcher');
const TestCollection = require('./test-collection');
function noop() {}
var chainableMethods = {
const chainableMethods = {
defaults: {
type: 'test',
serial: false,
@ -35,32 +34,134 @@ var chainableMethods = {
}
};
function Runner(options) {
if (!(this instanceof Runner)) {
throw new TypeError('Class constructor Runner cannot be invoked without \'new\'');
function wrapFunction(fn, args) {
return function (t) {
return fn.apply(this, [t].concat(args));
};
}
class Runner extends EventEmitter {
constructor(options) {
super();
options = options || {};
this.results = [];
this.tests = new TestCollection();
this.hasStarted = false;
this._bail = options.bail;
this._serial = options.serial;
this._match = options.match || [];
this._addTestResult = this._addTestResult.bind(this);
this._buildStats = this._buildStats.bind(this);
}
_addTest(title, opts, fn, args) {
if (args) {
if (fn.title) {
title = fn.title.apply(fn, [title || ''].concat(args));
}
EventEmitter.call(this);
fn = wrapFunction(fn, args);
}
options = options || {};
if (opts.type === 'test' && this._match.length > 0) {
opts.exclusive = title !== null && matcher([title], this._match).length === 1;
}
this.results = [];
this.tests = new TestCollection();
this.hasStarted = false;
this._bail = options.bail;
this._serial = options.serial;
this._match = options.match || [];
this._addTestResult = this._addTestResult.bind(this);
this._buildStats = this._buildStats.bind(this);
}
if (opts.todo) {
if (typeof fn === 'function') {
throw new TypeError('`todo` tests are not allowed to have an implementation. Use `test.skip()` for tests with an implementation.');
}
util.inherits(Runner, EventEmitter);
module.exports = Runner;
fn = noop;
if (typeof title !== 'string') {
throw new TypeError('`todo` tests require a title');
}
} else if (typeof fn !== 'function') {
throw new TypeError('Expected an implementation. Use `test.todo()` for tests without an implementation.');
}
this.tests.add({
metadata: opts,
fn,
title
});
}
_addTestResult(result) {
const test = result.result;
const props = {
duration: test.duration,
title: test.title,
error: result.reason,
type: test.metadata.type,
skip: test.metadata.skipped,
todo: test.metadata.todo,
failing: test.metadata.failing
};
this.results.push(result);
this.emit('test', props);
}
_buildStats() {
const stats = {
testCount: 0,
skipCount: 0,
todoCount: 0
};
this.results
.map(result => {
return result.result;
})
.filter(test => {
return test.metadata.type === 'test';
})
.forEach(test => {
stats.testCount++;
if (test.metadata.skipped) {
stats.skipCount++;
}
if (test.metadata.todo) {
stats.todoCount++;
}
});
stats.failCount = this.results
.filter(result => {
return result.passed === false;
})
.length;
stats.knownFailureCount = this.results
.filter(result => {
return result.passed === true && result.result.metadata.failing;
})
.length;
stats.passCount = stats.testCount - stats.failCount - stats.skipCount - stats.todoCount;
return stats;
}
run(options) {
if (options.runOnlyExclusive && !this.tests.hasExclusive) {
return Promise.resolve(null);
}
this.tests.on('test', this._addTestResult);
this.hasStarted = true;
return Promise.resolve(this.tests.build(this._bail).run()).then(this._buildStats);
}
}
optionChain(chainableMethods, function (opts, args) {
var title;
var fn;
var macroArgIndex;
let title;
let fn;
let macroArgIndex;
if (this.hasStarted) {
throw new Error('All tests and hooks must be declared synchronously in your ' +
@ -96,115 +197,6 @@ optionChain(chainableMethods, function (opts, args) {
}
}, Runner.prototype);
function wrapFunction(fn, args) {
return function (t) {
return fn.apply(this, [t].concat(args));
};
}
Runner.prototype._addTest = function (title, opts, fn, args) {
if (args) {
if (fn.title) {
title = fn.title.apply(fn, [title || ''].concat(args));
}
fn = wrapFunction(fn, args);
}
if (opts.type === 'test' && this._match.length > 0) {
opts.exclusive = title !== null && matcher([title], this._match).length === 1;
}
if (opts.todo) {
if (typeof fn === 'function') {
throw new TypeError('`todo` tests are not allowed to have an implementation. Use `test.skip()` for tests with an implementation.');
}
fn = noop;
if (typeof title !== 'string') {
throw new TypeError('`todo` tests require a title');
}
} else if (typeof fn !== 'function') {
throw new TypeError('Expected an implementation. Use `test.todo()` for tests without an implementation.');
}
this.tests.add({
metadata: opts,
fn: fn,
title: title
});
};
Runner.prototype._addTestResult = function (result) {
var test = result.result;
var props = {
duration: test.duration,
title: test.title,
error: result.reason,
type: test.metadata.type,
skip: test.metadata.skipped,
todo: test.metadata.todo,
failing: test.metadata.failing
};
this.results.push(result);
this.emit('test', props);
};
Runner.prototype._buildStats = function () {
var stats = {
testCount: 0,
skipCount: 0,
todoCount: 0
};
this.results
.map(function (result) {
return result.result;
})
.filter(function (test) {
return test.metadata.type === 'test';
})
.forEach(function (test) {
stats.testCount++;
if (test.metadata.skipped) {
stats.skipCount++;
}
if (test.metadata.todo) {
stats.todoCount++;
}
});
stats.failCount = this.results
.filter(function (result) {
return result.passed === false;
})
.length;
stats.knownFailureCount = this.results
.filter(function (result) {
return result.passed === true && result.result.metadata.failing;
})
.length;
stats.passCount = stats.testCount - stats.failCount - stats.skipCount - stats.todoCount;
return stats;
};
Runner.prototype.run = function (options) {
if (options.runOnlyExclusive && !this.tests.hasExclusive) {
return Promise.resolve(null);
}
this.tests.on('test', this._addTestResult);
this.hasStarted = true;
return Promise.resolve(this.tests.build(this._bail).run()).then(this._buildStats);
};
Runner._chainableMethods = chainableMethods.chainableMethods;
module.exports = Runner;

141
lib/sequence.js

@ -3,98 +3,85 @@ const isPromise = require('is-promise');
const autoBind = require('auto-bind');
const AvaError = require('./ava-error');
function noop() {}
module.exports = Sequence;
function Sequence(tests, bail) {
if (!(this instanceof Sequence)) {
throw new TypeError('Class constructor Sequence cannot be invoked without \'new\'');
}
if (!tests) {
throw new Error('Sequence items can\'t be undefined');
}
this.results = [];
this.passed = true;
this.reason = null;
this.tests = tests;
this.bail = bail || false;
autoBind(this);
}
Sequence.prototype.run = function () {
const length = this.tests.length;
for (let i = 0; i < length; i++) {
// if last item failed and we should bail, return results and stop
if (this.bail && !this.passed) {
return this._results();
class Sequence {
constructor(tests, bail) {
if (!tests) {
throw new Error('Sequence items can\'t be undefined');
}
const result = this.tests[i].run();
this.results = [];
this.passed = true;
this.reason = null;
this.tests = tests;
this.bail = bail || false;
// if a Promise returned, we don't need to check for Promises after this test
// so we can just use Promise.each() on the rest of the tests
if (isPromise(result)) {
return result
.then(this._addResult)
.return(this.tests.slice(i + 1))
.each(this._runTest)
.catch(AvaError, noop)
.then(this._results);
}
autoBind(this);
}
run() {
const length = this.tests.length;
try {
this._addResult(result);
} catch (err) {
// in bail mode, don't execute the next tests
if (err instanceof AvaError) {
for (let i = 0; i < length; i++) {
// if last item failed and we should bail, return results and stop
if (this.bail && !this.passed) {
return this._results();
}
throw err;
}
}
const result = this.tests[i].run();
// if a Promise returned, we don't need to check for Promises after this test
// so we can just use Promise.each() on the rest of the tests
if (isPromise(result)) {
return result
.then(this._addResult)
.return(this.tests.slice(i + 1))
.each(this._runTest)
.catch(AvaError, () => {})
.then(this._results);
}
return this._results();
};
try {
this._addResult(result);
} catch (err) {
// in bail mode, don't execute the next tests
if (err instanceof AvaError) {
return this._results();
}
Sequence.prototype._runTest = function (test) {
const result = test.run();
throw err;
}
}
if (isPromise(result)) {
return result.then(this._addResult);
return this._results();
}
_runTest(test) {
const result = test.run();
return isPromise(result) ? result.then(this._addResult) : this._addResult(result);
}
_addResult(result) {
this.results.push(result);
return this._addResult(result);
};
Sequence.prototype._addResult = function (result) {
this.results.push(result);
if (result.passed === false) {
this.passed = false;
if (result.passed === false) {
this.passed = false;
// only set reason once
if (!this.reason) {
this.reason = result.reason;
}
// only set reason once
if (!this.reason) {
this.reason = result.reason;
if (this.bail) {
throw new AvaError('Error in Sequence while in bail mode');
}
}
if (this.bail) {
throw new AvaError('Error in Sequence while in bail mode');
}
return result;
}
_results() {
return {
passed: this.passed,
reason: this.reason,
result: this.results
};
}
}
return result;
};
Sequence.prototype._results = function () {
return {
passed: this.passed,
reason: this.reason,
result: this.results
};
};
module.exports = Sequence;

8
test/api.js

@ -11,14 +11,6 @@ var testCapitalizerPlugin = require('./fixture/babel-plugin-test-capitalizer');
var conf = pkgConf.sync('ava');
var pkgDir = path.dirname(pkgConf.filepath(conf));
test('must be called with new', function (t) {
t.throws(function () {
var api = Api;
api([path.join(__dirname, 'fixture/es2015.js')]);
}, {message: 'Class constructor Api cannot be invoked without \'new\''});
t.end();
});
generateTests('Without Pool: ', function (options) {
options = options || {};
options.powerAssert = true;

11
test/ava-error.js

@ -1,11 +0,0 @@
'use strict';
const test = require('tap').test;
const AvaError = require('../lib/ava-error');
test('must be called with new', t => {
t.throws(() => {
const avaError = AvaError;
avaError('test message');
}, {message: 'Class constructor AvaError cannot be invoked without \'new\''});
t.end();
});

8
test/caching-precompiler.js

@ -21,14 +21,6 @@ test('creation with new', t => {
t.end();
});
test('must be called with new', t => {
t.throws(() => {
const cachingPrecompiler = CachingPrecompiler;
cachingPrecompiler({path: uniqueTempDir()});
}, {message: 'Class constructor CachingPrecompiler cannot be invoked without \'new\''});
t.end();
});
test('adds files and source maps to the cache directory as needed', t => {
const tempDir = uniqueTempDir();
const precompiler = new CachingPrecompiler({path: tempDir});

8
test/concurrent.js

@ -794,14 +794,6 @@ test('rejections are just passed through - bail', t => {
});
});
test('must be called with new', t => {
t.throws(() => {
const concurrent = Concurrent;
concurrent([pass('a')]);
}, {message: 'Class constructor Concurrent cannot be invoked without \'new\''});
t.end();
});
test('sequences of sequences', t => {
const result = new Concurrent([
new Concurrent([pass('a'), pass('b')]),

8
test/logger.js

@ -3,14 +3,6 @@ var test = require('tap').test;
var Logger = require('../lib/logger');
var tap = require('../lib/reporters/tap');
test('must be called with new', function (t) {
t.throws(function () {
var logger = Logger;
logger();
}, {message: 'Class constructor Logger cannot be invoked without \'new\''});
t.end();
});
test('only call start if supported by reporter', function (t) {
var tapReporter = tap();
var logger = new Logger(tapReporter);

8
test/run-status.js

@ -7,14 +7,6 @@ const RunStatus = require('../lib/run-status');
const sep = ' ' + chalk.gray.dim(figures.pointerSmall) + ' ';
test('requires new', t => {
const runStatus = RunStatus;
t.throws(() => {
runStatus({});
}, 'Class constructor RunStatus cannot be invoked without \'new\'');
t.end();
});
test('prefixTitle returns empty if prefixTitles == false', t => {
const runStatus = new RunStatus({prefixTitles: false});
t.is(runStatus.prefixTitle('test/run-status.js'), '');

8
test/runner.js

@ -5,14 +5,6 @@ const Runner = require('../lib/runner');
const slice = Array.prototype.slice;
const noop = () => {};
test('must be called with new', t => {
t.throws(() => {
const runner = Runner;
runner();
}, {message: 'Class constructor Runner cannot be invoked without \'new\''});
t.end();
});
test('nested tests and hooks aren\'t allowed', t => {
t.plan(1);

8
test/sequence.js

@ -802,14 +802,6 @@ test('rejections are just passed through - bail', t => {
});
});
test('must be called with new', t => {
t.throws(() => {
const sequence = Sequence;
sequence([pass('a')]);
}, {message: 'Class constructor Sequence cannot be invoked without \'new\''});
t.end();
});
test('needs at least one sequence item', t => {
t.throws(() => {
new Sequence().run();

8
test/test-collection.js

@ -78,14 +78,6 @@ function serialize(collection) {
return removeEmptyProps(serialized);
}
test('must be called with new', t => {
const testCollection = TestCollection;
t.throws(() => {
testCollection();
}, {message: 'Class constructor TestCollection cannot be invoked without \'new\''});
t.end();
});
test('throws if no type is supplied', t => {
const collection = new TestCollection();
t.throws(() => {

8
test/test.js

@ -47,14 +47,6 @@ ava.cb.failing = function (title, fn, contextRef, report) {
return t;
};
test('must be called with new', t => {
t.throws(() => {
const test = Test;
test();
}, {message: 'Class constructor Test cannot be invoked without \'new\''});
t.end();
});
test('run test', t => {
const result = ava('foo', a => {
a.fail();

Loading…
Cancel
Save