ava 0.15.0 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/cli.js CHANGED
@@ -1,203 +1,28 @@
1
1
  #!/usr/bin/env node
2
2
  'use strict';
3
3
 
4
+ var path = require('path');
4
5
  var debug = require('debug')('ava');
5
6
 
6
7
  // Prefer the local installation of AVA.
7
8
  var resolveCwd = require('resolve-cwd');
8
9
  var localCLI = resolveCwd('ava/cli');
9
10
 
10
- if (localCLI && localCLI !== __filename) {
11
+ // Use path.relative() to detect local AVA installation,
12
+ // because __filename's case is inconsistent on Windows
13
+ // see https://github.com/nodejs/node/issues/6624
14
+ if (localCLI && path.relative(localCLI, __filename) !== '') {
11
15
  debug('Using local install of AVA');
12
- require(localCLI);
13
- return;
14
- }
15
-
16
- if (debug.enabled) {
17
- require('time-require');
18
- }
19
-
20
- var updateNotifier = require('update-notifier');
21
- var figures = require('figures');
22
- var arrify = require('arrify');
23
- var meow = require('meow');
24
- var Promise = require('bluebird');
25
- var pkgConf = require('pkg-conf');
26
- var chalk = require('chalk');
27
- var isCi = require('is-ci');
28
- var hasFlag = require('has-flag');
29
- var colors = require('./lib/colors');
30
- var verboseReporter = require('./lib/reporters/verbose');
31
- var miniReporter = require('./lib/reporters/mini');
32
- var tapReporter = require('./lib/reporters/tap');
33
- var Logger = require('./lib/logger');
34
- var Watcher = require('./lib/watcher');
35
- var Api = require('./api');
36
-
37
- // Bluebird specific
38
- Promise.longStackTraces();
39
-
40
- var conf = pkgConf.sync('ava', {
41
- defaults: {
42
- babel: 'default'
43
- }
44
- });
45
-
46
- // check for valid babel config shortcuts (can be either "default" or "inherit")
47
- var isValidShortcut = ['default', 'inherit'].indexOf(conf.babel) !== -1;
48
-
49
- if (!conf.babel || (typeof conf.babel === 'string' && !isValidShortcut)) {
50
- var message = '';
51
- message += 'Unexpected Babel configuration for AVA. ';
52
- message += 'See ' + chalk.underline('https://github.com/avajs/ava#es2015-support') + ' for allowed values.';
53
-
54
- console.log('\n ' + colors.error(figures.cross) + ' ' + message);
55
- process.exit(1);
56
- }
57
-
58
- var cli = meow([
59
- 'Usage',
60
- ' ava [<file|directory|glob> ...]',
61
- '',
62
- 'Options',
63
- ' --init Add AVA to your project',
64
- ' --fail-fast Stop after first test failure',
65
- ' --serial, -s Run tests serially',
66
- ' --require, -r Module to preload (Can be repeated)',
67
- ' --tap, -t Generate TAP output',
68
- ' --verbose, -v Enable verbose output',
69
- ' --no-cache Disable the transpiler cache',
70
- ' --match, -m Only run tests with matching title (Can be repeated)',
71
- ' --watch, -w Re-run tests when tests and source files change',
72
- ' --source, -S Pattern to match source files so tests can be re-run (Can be repeated)',
73
- ' --timeout, -T Set global timeout',
74
- ' --concurrency, -c Maximum number of test files running at the same time (EXPERIMENTAL)',
75
- '',
76
- 'Examples',
77
- ' ava',
78
- ' ava test.js test2.js',
79
- ' ava test-*.js',
80
- ' ava test',
81
- ' ava --init',
82
- ' ava --init foo.js',
83
- '',
84
- 'Default patterns when no arguments:',
85
- 'test.js test-*.js test/**/*.js **/__tests__/**/*.js **/*.test.js'
86
- ], {
87
- string: [
88
- '_',
89
- 'require',
90
- 'timeout',
91
- 'source',
92
- 'match',
93
- 'concurrency'
94
- ],
95
- boolean: [
96
- 'fail-fast',
97
- 'verbose',
98
- 'serial',
99
- 'tap',
100
- 'watch'
101
- ],
102
- default: conf,
103
- alias: {
104
- t: 'tap',
105
- v: 'verbose',
106
- r: 'require',
107
- s: 'serial',
108
- m: 'match',
109
- w: 'watch',
110
- S: 'source',
111
- T: 'timeout',
112
- c: 'concurrency'
113
- }
114
- });
115
-
116
- updateNotifier({pkg: cli.pkg}).notify();
117
-
118
- if (cli.flags.init) {
119
- require('ava-init')();
120
- return;
121
- }
122
-
123
- if (
124
- (hasFlag('--watch') || hasFlag('-w')) && (hasFlag('--tap') || hasFlag('-t')) ||
125
- conf.watch && conf.tap
126
- ) {
127
- console.error(' ' + colors.error(figures.cross) + ' The TAP reporter is not available when using watch mode.');
128
- process.exit(1);
129
- }
130
-
131
- var api = new Api({
132
- failFast: cli.flags.failFast,
133
- serial: cli.flags.serial,
134
- require: arrify(cli.flags.require),
135
- cacheEnabled: cli.flags.cache !== false,
136
- explicitTitles: cli.flags.watch,
137
- match: arrify(cli.flags.match),
138
- babelConfig: conf.babel,
139
- timeout: cli.flags.timeout,
140
- concurrency: cli.flags.concurrency ? parseInt(cli.flags.concurrency, 10) : 0
141
- });
142
-
143
- var reporter;
144
-
145
- if (cli.flags.tap && !cli.flags.watch) {
146
- reporter = tapReporter();
147
- } else if (cli.flags.verbose || isCi) {
148
- reporter = verboseReporter();
16
+ require(localCLI); // eslint-disable-line import/no-dynamic-require
149
17
  } else {
150
- reporter = miniReporter({watching: cli.flags.watch});
151
- }
152
-
153
- reporter.api = api;
154
- var logger = new Logger(reporter);
155
-
156
- logger.start();
157
-
158
- api.on('test-run', function (runStatus) {
159
- reporter.api = runStatus;
160
- runStatus.on('test', logger.test);
161
- runStatus.on('error', logger.unhandledError);
162
-
163
- runStatus.on('stdout', logger.stdout);
164
- runStatus.on('stderr', logger.stderr);
165
- });
166
-
167
- var files = cli.input.length ? cli.input : arrify(conf.files);
168
- if (files.length === 0) {
169
- files = [
170
- 'test.js',
171
- 'test-*.js',
172
- 'test'
173
- ];
174
- }
18
+ if (debug.enabled) {
19
+ require('time-require'); // eslint-disable-line import/no-unassigned-import
20
+ }
175
21
 
176
- if (cli.flags.watch) {
177
22
  try {
178
- var watcher = new Watcher(logger, api, files, arrify(cli.flags.source));
179
- watcher.observeStdin(process.stdin);
23
+ require('./lib/cli').run();
180
24
  } catch (err) {
181
- if (err.name === 'AvaError') {
182
- // An AvaError may be thrown if chokidar is not installed. Log it nicely.
183
- console.error(' ' + colors.error(figures.cross) + ' ' + err.message);
184
- logger.exit(1);
185
- } else {
186
- // Rethrow so it becomes an uncaught exception.
187
- throw err;
188
- }
25
+ console.error('\n ' + err.message);
26
+ process.exit(1);
189
27
  }
190
- } else {
191
- api.run(files)
192
- .then(function (runStatus) {
193
- logger.finish(runStatus);
194
- logger.exit(runStatus.failCount > 0 || runStatus.rejectionCount > 0 || runStatus.exceptionCount > 0 ? 1 : 0);
195
- })
196
- .catch(function (err) {
197
- // Don't swallow exceptions. Note that any expected error should already
198
- // have been logged.
199
- setImmediate(function () {
200
- throw err;
201
- });
202
- });
203
28
  }
package/index.js CHANGED
@@ -1,101 +1,8 @@
1
1
  'use strict';
2
- var path = require('path');
3
- var chalk = require('chalk');
4
- var serializeError = require('./lib/serialize-error');
5
- var globals = require('./lib/globals');
6
- var Runner = require('./lib/runner');
7
- var send = require('./lib/send');
8
2
 
9
- var opts = globals.options;
10
- var runner = new Runner({
11
- serial: opts.serial,
12
- bail: opts.failFast,
13
- match: opts.match
14
- });
15
-
16
- // check if the test is being run without AVA cli
17
- var isForked = typeof process.send === 'function';
18
-
19
- if (!isForked) {
20
- var fp = path.relative('.', process.argv[1]);
21
-
22
- console.log();
23
- console.error('Test files must be run with the AVA CLI:\n\n ' + chalk.grey.dim('$') + ' ' + chalk.cyan('ava ' + fp) + '\n');
24
-
25
- process.exit(1); // eslint-disable-line
3
+ // Ensure the same AVA install is loaded by the test file as by the test worker.
4
+ if (process.env.AVA_PATH && process.env.AVA_PATH !== __dirname) {
5
+ module.exports = require(process.env.AVA_PATH); // eslint-disable-line import/no-dynamic-require
6
+ } else {
7
+ module.exports = require('./lib/main');
26
8
  }
27
-
28
- // note that test files have require('ava')
29
- require('./lib/test-worker').avaRequired = true;
30
-
31
- // if fail-fast is enabled, use this variable to detect
32
- // that no more tests should be logged
33
- var isFailed = false;
34
-
35
- Error.stackTraceLimit = Infinity;
36
-
37
- function test(props) {
38
- if (isFailed) {
39
- return;
40
- }
41
-
42
- var hasError = typeof props.error !== 'undefined';
43
-
44
- // don't display anything if it's a passed hook
45
- if (!hasError && props.type !== 'test') {
46
- return;
47
- }
48
-
49
- if (hasError) {
50
- props.error = serializeError(props.error);
51
- } else {
52
- props.error = null;
53
- }
54
-
55
- send('test', props);
56
-
57
- if (hasError && opts.failFast) {
58
- isFailed = true;
59
- exit();
60
- }
61
- }
62
-
63
- function exit() {
64
- var stats = runner._buildStats();
65
-
66
- send('results', {
67
- stats: stats
68
- });
69
- }
70
-
71
- globals.setImmediate(function () {
72
- var hasExclusive = runner.tests.hasExclusive;
73
- var numberOfTests = runner.tests.tests.concurrent.length + runner.tests.tests.serial.length;
74
-
75
- if (numberOfTests === 0) {
76
- send('no-tests', {avaRequired: true});
77
- return;
78
- }
79
-
80
- send('stats', {
81
- testCount: numberOfTests,
82
- hasExclusive: hasExclusive
83
- });
84
-
85
- runner.on('test', test);
86
-
87
- process.on('ava-run', function (options) {
88
- runner.run(options).then(exit);
89
- });
90
-
91
- process.on('ava-init-exit', function () {
92
- exit();
93
- });
94
- });
95
-
96
- module.exports = runner.test;
97
-
98
- // TypeScript imports the `default` property for
99
- // an ES2015 default import (`import test from 'ava'`)
100
- // See: https://github.com/Microsoft/TypeScript/issues/2242#issuecomment-83694181
101
- module.exports.default = runner.test;
package/index.js.flow ADDED
@@ -0,0 +1,218 @@
1
+ /* @flow */
2
+
3
+ /**
4
+ * Misc Setup Types
5
+ */
6
+
7
+ type PromiseLike<R> = {
8
+ then<U>(
9
+ onFulfill?: (value: R) => Promise<U> | U,
10
+ onReject?: (error: any) => Promise<U> | U
11
+ ): Promise<U>;
12
+ }
13
+
14
+ type ObservableLike = {
15
+ subscribe(observer: (value: {}) => void): void;
16
+ };
17
+
18
+ type SpecialReturnTypes =
19
+ | PromiseLike<any>
20
+ | Iterator<any>
21
+ | ObservableLike;
22
+
23
+ type Constructor = Class<{
24
+ constructor(...args: Array<any>): any
25
+ }>;
26
+
27
+ type ErrorValidator =
28
+ | Constructor
29
+ | RegExp
30
+ | string
31
+ | ((error: any) => boolean);
32
+
33
+ /**
34
+ * Asertion Types
35
+ */
36
+
37
+ type AssertContext = {
38
+ // Passing assertion.
39
+ pass(message?: string): void;
40
+ // Failing assertion.
41
+ fail(message?: string): void;
42
+ // Assert that value is truthy.
43
+ truthy(value: mixed, message?: string): void;
44
+ // Assert that value is falsy.
45
+ falsy(value: mixed, message?: string): void;
46
+ // DEPRECATED, use `truthy`. Assert that value is truthy.
47
+ ok(value: mixed, message?: string): void;
48
+ // DEPRECATED, use `falsy`. Assert that value is falsy.
49
+ notOk(value: mixed, message?: string): void;
50
+ // Assert that value is true.
51
+ true(value: boolean, message?: string): void;
52
+ // Assert that value is false.
53
+ false(value: boolean, message?: string): void;
54
+ // Assert that value is equal to expected.
55
+ is<U>(value: U, expected: U, message?: string): void;
56
+ // Assert that value is not equal to expected.
57
+ not<U>(value: U, expected: U, message?: string): void;
58
+ // Assert that value is deep equal to expected.
59
+ deepEqual<U>(value: U, expected: U, message?: string): void;
60
+ // Assert that value is not deep equal to expected.
61
+ notDeepEqual<U>(value: U, expected: U, message?: string): void;
62
+ // Assert that function throws an error or promise rejects.
63
+ // DEPRECATED, use `deepEqual`. Assert that value is deep equal to expected.
64
+ // @param error Can be a constructor, regex, error message or validation function.
65
+ same<U>(value: U, expected: U, message?: string): void;
66
+ // DEPRECATED use `notDeepEqual`. Assert that value is not deep equal to expected.
67
+ notSame<U>(value: U, expected: U, message?: string): void;
68
+ // Assert that function throws an error or promise rejects.
69
+ // @param error Can be a constructor, regex, error message or validation function.
70
+ throws(value: PromiseLike<mixed>, error?: ErrorValidator, message?: string): Promise<mixed>;
71
+ throws(value: () => void, error?: ErrorValidator, message?: string): mixed;
72
+ // Assert that function doesn't throw an error or promise resolves.
73
+ notThrows<U>(value: PromiseLike<U>, message?: string): Promise<U>;
74
+ notThrows(value: () => void, message?: string): void;
75
+ // Assert that contents matches regex.
76
+ regex(contents: string, regex: RegExp, message?: string): void;
77
+ // Assert that contents does not match regex.
78
+ notRegex(contents: string, regex: RegExp, message?: string): void;
79
+ // Assert that error is falsy.
80
+ ifError(error: any, message?: string): void;
81
+ };
82
+
83
+ /**
84
+ * Context Types
85
+ */
86
+
87
+ type TestContext = AssertContext & {
88
+ plan(count: number): void;
89
+ skip: AssertContext;
90
+ };
91
+ type CallbackTestContext = TestContext & { end(): void; };
92
+ type ContextualTestContext = TestContext & { context: any; };
93
+ type ContextualCallbackTestContext = CallbackTestContext & { context: any; };
94
+
95
+ /**
96
+ * Test Types
97
+ */
98
+
99
+ type Test = (t: TestContext) => SpecialReturnTypes | void;
100
+ type CallbackTest = (t: CallbackTestContext) => void;
101
+ type ContextualTest = (t: ContextualTestContext) => SpecialReturnTypes | void;
102
+ type ContextualCallbackTest = (t: ContextualCallbackTestContext) => void;
103
+
104
+ /**
105
+ * Macro Types
106
+ */
107
+
108
+ type Macro<T> = {
109
+ (t: T, ...args: Array<any>): void;
110
+ title?: (providedTitle: string, ...args: Array<any>) => string;
111
+ };
112
+
113
+ type Macros<T> =
114
+ | Macro<T>
115
+ | Array<Macro<T>>;
116
+
117
+ /**
118
+ * Method Types
119
+ */
120
+
121
+ type TestMethod = {
122
+ ( implementation: Test): void;
123
+ (name: string, implementation: Test): void;
124
+ ( implementation: Macros<TestContext>, ...args: Array<any>): void;
125
+ (name: string, implementation: Macros<TestContext>, ...args: Array<any>): void;
126
+
127
+ serial : TestMethod;
128
+ before : TestMethod;
129
+ after : TestMethod;
130
+ skip : TestMethod;
131
+ todo : TestMethod;
132
+ failing : TestMethod;
133
+ only : TestMethod;
134
+ beforeEach : TestMethod;
135
+ afterEach : TestMethod;
136
+ cb : CallbackTestMethod;
137
+ always : TestMethod;
138
+ };
139
+
140
+ type CallbackTestMethod = {
141
+ ( implementation: CallbackTest): void;
142
+ (name: string, implementation: CallbackTest): void;
143
+ ( implementation: Macros<CallbackTestContext>, ...args: Array<any>): void;
144
+ (name: string, implementation: Macros<CallbackTestContext>, ...args: Array<any>): void;
145
+
146
+ serial : CallbackTestMethod;
147
+ before : CallbackTestMethod;
148
+ after : CallbackTestMethod;
149
+ skip : CallbackTestMethod;
150
+ todo : CallbackTestMethod;
151
+ failing : CallbackTestMethod;
152
+ only : CallbackTestMethod;
153
+ beforeEach : CallbackTestMethod;
154
+ afterEach : CallbackTestMethod;
155
+ cb : CallbackTestMethod;
156
+ always : CallbackTestMethod;
157
+ };
158
+
159
+ type ContextualTestMethod = {
160
+ ( implementation: ContextualTest): void;
161
+ (name: string, implementation: ContextualTest): void;
162
+ ( implementation: Macros<ContextualTestContext>, ...args: Array<any>): void;
163
+ (name: string, implementation: Macros<ContextualTestContext>, ...args: Array<any>): void;
164
+
165
+ serial : ContextualTestMethod;
166
+ before : ContextualTestMethod;
167
+ after : ContextualTestMethod;
168
+ skip : ContextualTestMethod;
169
+ todo : ContextualTestMethod;
170
+ failing : ContextualTestMethod;
171
+ only : ContextualTestMethod;
172
+ beforeEach : ContextualTestMethod;
173
+ afterEach : ContextualTestMethod;
174
+ cb : ContextualCallbackTestMethod;
175
+ always : ContextualTestMethod;
176
+ };
177
+
178
+ type ContextualCallbackTestMethod = {
179
+ ( implementation: ContextualCallbackTest): void;
180
+ (name: string, implementation: ContextualCallbackTest): void;
181
+ ( implementation: Macros<ContextualCallbackTestContext>, ...args: Array<any>): void;
182
+ (name: string, implementation: Macros<ContextualCallbackTestContext>, ...args: Array<any>): void;
183
+
184
+ serial : ContextualCallbackTestMethod;
185
+ before : ContextualCallbackTestMethod;
186
+ after : ContextualCallbackTestMethod;
187
+ skip : ContextualCallbackTestMethod;
188
+ todo : ContextualCallbackTestMethod;
189
+ failing : ContextualCallbackTestMethod;
190
+ only : ContextualCallbackTestMethod;
191
+ beforeEach : ContextualCallbackTestMethod;
192
+ afterEach : ContextualCallbackTestMethod;
193
+ cb : ContextualCallbackTestMethod;
194
+ always : ContextualCallbackTestMethod;
195
+ };
196
+
197
+ /**
198
+ * Public API
199
+ */
200
+
201
+ declare module.exports: {
202
+ ( run: ContextualTest): void;
203
+ (name: string, run: ContextualTest): void;
204
+ ( run: Macros<ContextualTestContext>, ...args: Array<any>): void;
205
+ (name: string, run: Macros<ContextualTestContext>, ...args: Array<any>): void;
206
+
207
+ beforeEach : TestMethod;
208
+ afterEach : TestMethod;
209
+ serial : ContextualTestMethod;
210
+ before : ContextualTestMethod;
211
+ after : ContextualTestMethod;
212
+ skip : ContextualTestMethod;
213
+ todo : ContextualTestMethod;
214
+ failing : ContextualTestMethod;
215
+ only : ContextualTestMethod;
216
+ cb : ContextualCallbackTestMethod;
217
+ always : ContextualTestMethod;
218
+ };
package/lib/assert.js CHANGED
@@ -1,10 +1,11 @@
1
1
  'use strict';
2
2
  var util = require('util');
3
3
  var assert = require('core-assert');
4
- var deepEqual = require('not-so-shallow');
4
+ var deepEqual = require('lodash.isequal');
5
5
  var observableToPromise = require('observable-to-promise');
6
6
  var isObservable = require('is-observable');
7
7
  var isPromise = require('is-promise');
8
+
8
9
  var x = module.exports;
9
10
 
10
11
  Object.defineProperty(x, 'AssertionError', {value: assert.AssertionError});
@@ -101,9 +102,9 @@ x.throws = function (fn, err, msg) {
101
102
  assert.throws(function () {
102
103
  try {
103
104
  fn();
104
- } catch (error) {
105
- result = error;
106
- throw error;
105
+ } catch (err) {
106
+ result = err;
107
+ throw err;
107
108
  }
108
109
  }, err, msg);
109
110
 
@@ -142,18 +143,22 @@ x.regex = function (contents, regex, msg) {
142
143
  test(regex.test(contents), create(regex, contents, '===', msg, x.regex));
143
144
  };
144
145
 
145
- x.ifError = x.error = function (err, msg) {
146
+ x.notRegex = function (contents, regex, msg) {
147
+ test(!regex.test(contents), create(regex, contents, '!==', msg, x.notRegex));
148
+ };
149
+
150
+ x.ifError = function (err, msg) {
146
151
  test(!err, create(err, 'Error', '!==', msg, x.ifError));
147
152
  };
148
153
 
149
154
  /*
150
155
  * deprecated APIs
151
156
  */
152
- x.doesNotThrow = util.deprecate(x.notThrows, getDeprecationNotice('doesNotThrow()', 'notThrows()'));
153
157
  x.ok = util.deprecate(x.truthy, getDeprecationNotice('ok()', 'truthy()'));
154
158
  x.notOk = util.deprecate(x.falsy, getDeprecationNotice('notOk()', 'falsy()'));
155
159
  x.same = util.deprecate(x.deepEqual, getDeprecationNotice('same()', 'deepEqual()'));
156
160
  x.notSame = util.deprecate(x.notDeepEqual, getDeprecationNotice('notSame()', 'notDeepEqual()'));
161
+ x.error = util.deprecate(x.ifError, getDeprecationNotice('error()', 'ifError()'));
157
162
 
158
163
  function getDeprecationNotice(oldApi, newApi) {
159
164
  return 'DEPRECATION NOTICE: ' + oldApi + ' has been renamed to ' + newApi + ' and will eventually be removed. See https://github.com/avajs/ava-codemods to help upgrade your codebase automatically.';