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/api.js +243 -187
- package/cli.js +12 -187
- package/index.js +5 -98
- package/index.js.flow +218 -0
- package/lib/assert.js +11 -6
- package/lib/babel-config.js +152 -0
- package/lib/beautify-stack.js +23 -0
- package/lib/caching-precompiler.js +24 -115
- package/lib/cli.js +172 -0
- package/lib/colors.js +2 -0
- package/lib/concurrent.js +2 -3
- package/lib/enhance-assert.js +15 -6
- package/lib/fork.js +23 -15
- package/lib/logger.js +4 -5
- package/lib/main.js +89 -0
- package/lib/prefix-title.js +25 -0
- package/lib/process-adapter.js +107 -0
- package/lib/reporters/mini.js +32 -27
- package/lib/run-status.js +5 -36
- package/lib/runner.js +10 -0
- package/lib/sequence.js +2 -4
- package/lib/test-worker.js +13 -75
- package/lib/test.js +18 -5
- package/lib/throws-helper.js +6 -4
- package/lib/watcher.js +10 -18
- package/package.json +48 -29
- package/profile.js +15 -10
- package/readme.md +72 -43
- package/types/generated.d.ts +1667 -0
- package/types/make.js +166 -0
- package/index.d.ts +0 -206
- package/lib/ava-files.js +0 -262
- package/lib/send.js +0 -16
package/types/make.js
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// TypeScript definitions are generated here.
|
|
4
|
+
// AVA allows chaining of function names, like `test.after.cb.always`.
|
|
5
|
+
// The order of these names is not important.
|
|
6
|
+
// Writing these definitions by hand is hard. Because of chaining,
|
|
7
|
+
// the number of combinations grows fast (2^n). To reduce this number,
|
|
8
|
+
// illegal combinations are filtered out in `verify`.
|
|
9
|
+
// The order of the options is not important. We could generate full
|
|
10
|
+
// definitions for each possible order, but that would give a very big
|
|
11
|
+
// output. Instead, we write an alias for different orders. For instance,
|
|
12
|
+
// `after.cb` is fully written, and `cb.after` is emitted as an alias
|
|
13
|
+
// using `typeof after.cb`.
|
|
14
|
+
|
|
15
|
+
const path = require('path');
|
|
16
|
+
const fs = require('fs');
|
|
17
|
+
const runner = require('../lib/runner');
|
|
18
|
+
|
|
19
|
+
const arrayHas = parts => part => parts.includes(part);
|
|
20
|
+
|
|
21
|
+
const base = fs.readFileSync(path.join(__dirname, 'base.d.ts'), 'utf8');
|
|
22
|
+
|
|
23
|
+
// All suported function names
|
|
24
|
+
const allParts = Object.keys(runner._chainableMethods).filter(name => name !== 'test');
|
|
25
|
+
|
|
26
|
+
const output = base + generatePrefixed([]);
|
|
27
|
+
fs.writeFileSync(path.join(__dirname, 'generated.d.ts'), output);
|
|
28
|
+
|
|
29
|
+
// Generates type definitions, for the specified prefix
|
|
30
|
+
// The prefix is an array of function names
|
|
31
|
+
function generatePrefixed(prefix) {
|
|
32
|
+
let output = '';
|
|
33
|
+
let children = '';
|
|
34
|
+
|
|
35
|
+
for (const part of allParts) {
|
|
36
|
+
const parts = prefix.concat([part]);
|
|
37
|
+
|
|
38
|
+
if (prefix.includes(part) || !verify(parts, true)) {
|
|
39
|
+
// Function already in prefix or not allowed here
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// If `parts` is not sorted, we alias it to the sorted chain.
|
|
44
|
+
if (!isSorted(parts)) {
|
|
45
|
+
const chain = parts.sort().join('.');
|
|
46
|
+
if (exists(parts)) {
|
|
47
|
+
output += '\texport const ' + part + ': typeof test.' + chain + ';\n';
|
|
48
|
+
}
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Check that `part` is a valid function name.
|
|
53
|
+
// `always` is a valid prefix, for instance of `always.after`,
|
|
54
|
+
// but not a valid function name.
|
|
55
|
+
if (verify(parts, false)) {
|
|
56
|
+
if (prefix.includes(parts, 'todo')) {
|
|
57
|
+
output += '\t' + writeFunction(part, 'name: string', 'void');
|
|
58
|
+
} else {
|
|
59
|
+
const type = testType(parts);
|
|
60
|
+
output += '\t' + writeFunction(part, 'name: string, implementation: ' + type);
|
|
61
|
+
output += '\t' + writeFunction(part, 'implementation: ' + type);
|
|
62
|
+
output += '\t' + writeFunction(part, 'name: string, implementation: Macros<' + type + 'Context>, ...args: any[]');
|
|
63
|
+
output += '\t' + writeFunction(part, 'implementation: Macros<' + type + 'Context>, ...args: any[]');
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
children += generatePrefixed(parts);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (output === '') {
|
|
71
|
+
return children;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return 'export namespace ' + ['test'].concat(prefix).join('.') + ' {\n' + output + '}\n' + children;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function writeFunction(name, args) {
|
|
78
|
+
return 'export function ' + name + '(' + args + '): void;\n';
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Checks whether a chain is a valid function name (when `asPrefix === false`)
|
|
82
|
+
// or a valid prefix that could contain members.
|
|
83
|
+
// For instance, `test.always` is not a valid function name, but it is a valid
|
|
84
|
+
// prefix of `test.always.after`.
|
|
85
|
+
function verify(parts, asPrefix) {
|
|
86
|
+
const has = arrayHas(parts);
|
|
87
|
+
|
|
88
|
+
if (has('only') + has('skip') + has('todo') > 1) {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const beforeAfterCount = has('before') + has('beforeEach') + has('after') + has('afterEach');
|
|
93
|
+
|
|
94
|
+
if (beforeAfterCount > 1) {
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (beforeAfterCount === 1) {
|
|
99
|
+
if (has('only')) {
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (has('always')) {
|
|
105
|
+
// `always` can only be used with `after` or `afterEach`.
|
|
106
|
+
// Without it can still be a valid prefix
|
|
107
|
+
if (has('after') || has('afterEach')) {
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
if (!verify(parts.concat(['after']), false) && !verify(parts.concat(['afterEach']), false)) {
|
|
111
|
+
// If `after` nor `afterEach` cannot be added to this prefix,
|
|
112
|
+
// `always` is not allowed here.
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
// Only allowed as a prefix
|
|
116
|
+
return asPrefix;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Checks whether a chain is a valid function name or a valid prefix with some member
|
|
123
|
+
function exists(parts) {
|
|
124
|
+
if (verify(parts, false)) {
|
|
125
|
+
// valid function name
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
if (!verify(parts, true)) {
|
|
129
|
+
// not valid prefix
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
// valid prefix, check whether it has members
|
|
133
|
+
for (const prefix of allParts) {
|
|
134
|
+
if (!parts.includes(prefix) && exists(parts.concat([prefix]))) {
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Checks that an array is sorted
|
|
142
|
+
function isSorted(a) {
|
|
143
|
+
for (let i = 1; i < a.length; i++) {
|
|
144
|
+
if (a[i - 1] >= a[i]) {
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return true;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Returns the type name of for the test implementation
|
|
153
|
+
function testType(parts) {
|
|
154
|
+
const has = arrayHas(parts);
|
|
155
|
+
let type = 'Test';
|
|
156
|
+
|
|
157
|
+
if (has('cb')) {
|
|
158
|
+
type = 'Callback' + type;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (!has('before') && !has('after')) {
|
|
162
|
+
type = 'Contextual' + type;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return type;
|
|
166
|
+
}
|
package/index.d.ts
DELETED
|
@@ -1,206 +0,0 @@
|
|
|
1
|
-
export interface Observable {
|
|
2
|
-
subscribe(observer: (value: {}) => void): void;
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
export type Test = (t: TestContext) => Promise<void> | Iterator<any> | Observable | void;
|
|
6
|
-
export type ContextualTest = (t: ContextualTestContext) => Promise<void> | Iterator<any> | Observable | void;
|
|
7
|
-
export type SerialTest = (t: TestContext) => void;
|
|
8
|
-
export type ContextualSerialTest = (t: ContextualTestContext) => void;
|
|
9
|
-
export type CallbackTest = (t: CallbackTestContext) => void;
|
|
10
|
-
export type ContextualCallbackTest = (t: ContextualCallbackTestContext) => void;
|
|
11
|
-
|
|
12
|
-
export interface Runner {
|
|
13
|
-
(name: string, run: Test): void;
|
|
14
|
-
(run: Test): void;
|
|
15
|
-
skip: Runner;
|
|
16
|
-
cb: CallbackRunner;
|
|
17
|
-
}
|
|
18
|
-
export interface ContextualRunner {
|
|
19
|
-
(name: string, run: ContextualTest): void;
|
|
20
|
-
(run: ContextualTest): void;
|
|
21
|
-
skip: ContextualRunner;
|
|
22
|
-
cb: ContextualCallbackRunner;
|
|
23
|
-
}
|
|
24
|
-
export interface SerialRunner {
|
|
25
|
-
(name: string, run: SerialTest): void;
|
|
26
|
-
(run: SerialTest): void;
|
|
27
|
-
skip: SerialRunner;
|
|
28
|
-
}
|
|
29
|
-
export interface ContextualSerialRunner {
|
|
30
|
-
(name: string, run: ContextualSerialTest): void;
|
|
31
|
-
(run: ContextualSerialTest): void;
|
|
32
|
-
skip: ContextualSerialRunner;
|
|
33
|
-
}
|
|
34
|
-
export interface CallbackRunner {
|
|
35
|
-
(name: string, run: CallbackTest): void;
|
|
36
|
-
(run: CallbackTest): void;
|
|
37
|
-
skip: CallbackRunner;
|
|
38
|
-
}
|
|
39
|
-
export interface ContextualCallbackRunner {
|
|
40
|
-
(name: string, run: ContextualCallbackTest): void;
|
|
41
|
-
(run: ContextualCallbackTest): void;
|
|
42
|
-
skip: ContextualCallbackRunner;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export function test(name: string, run: ContextualTest): void;
|
|
46
|
-
export function test(run: ContextualTest): void;
|
|
47
|
-
export namespace test {
|
|
48
|
-
export const before: Runner;
|
|
49
|
-
export const after: Runner;
|
|
50
|
-
export const beforeEach: ContextualRunner;
|
|
51
|
-
export const afterEach: ContextualRunner;
|
|
52
|
-
|
|
53
|
-
export const skip: typeof test;
|
|
54
|
-
export const only: typeof test;
|
|
55
|
-
|
|
56
|
-
export function serial(name: string, run: ContextualSerialTest): void;
|
|
57
|
-
export function serial(run: ContextualSerialTest): void;
|
|
58
|
-
export function failing(name: string, run: ContextualCallbackTest): void;
|
|
59
|
-
export function failing(run: ContextualCallbackTest): void;
|
|
60
|
-
export function cb(name: string, run: ContextualCallbackTest): void;
|
|
61
|
-
export function cb(run: ContextualCallbackTest): void;
|
|
62
|
-
export function todo(name: string): void;
|
|
63
|
-
}
|
|
64
|
-
export namespace test.serial {
|
|
65
|
-
export const before: SerialRunner;
|
|
66
|
-
export const after: SerialRunner;
|
|
67
|
-
export const beforeEach: ContextualSerialRunner;
|
|
68
|
-
export const afterEach: ContextualSerialRunner;
|
|
69
|
-
|
|
70
|
-
export const skip: typeof test.serial;
|
|
71
|
-
export const only: typeof test.serial;
|
|
72
|
-
|
|
73
|
-
export function cb(name: string, run: ContextualCallbackTest): void;
|
|
74
|
-
export function cb(run: ContextualCallbackTest): void;
|
|
75
|
-
}
|
|
76
|
-
export namespace test.failing {
|
|
77
|
-
export const before: CallbackRunner;
|
|
78
|
-
export const after: CallbackRunner;
|
|
79
|
-
export const beforeEach: ContextualCallbackRunner;
|
|
80
|
-
export const afterEach: ContextualCallbackRunner;
|
|
81
|
-
|
|
82
|
-
export const skip: typeof test.cb;
|
|
83
|
-
export const only: typeof test.cb;
|
|
84
|
-
|
|
85
|
-
export function cb(name: string, run: ContextualCallbackTest): void;
|
|
86
|
-
export function cb(run: ContextualCallbackTest): void;
|
|
87
|
-
}
|
|
88
|
-
export namespace test.cb {
|
|
89
|
-
export const before: CallbackRunner;
|
|
90
|
-
export const after: CallbackRunner;
|
|
91
|
-
export const beforeEach: ContextualCallbackRunner;
|
|
92
|
-
export const afterEach: ContextualCallbackRunner;
|
|
93
|
-
|
|
94
|
-
export const skip: typeof test.cb;
|
|
95
|
-
export const only: typeof test.cb;
|
|
96
|
-
}
|
|
97
|
-
export default test;
|
|
98
|
-
|
|
99
|
-
export type ErrorValidator
|
|
100
|
-
= (new (...args: any[]) => any)
|
|
101
|
-
| RegExp
|
|
102
|
-
| string
|
|
103
|
-
| ((error: any) => boolean);
|
|
104
|
-
|
|
105
|
-
export interface AssertContext {
|
|
106
|
-
/**
|
|
107
|
-
* Passing assertion.
|
|
108
|
-
*/
|
|
109
|
-
pass(message?: string): void;
|
|
110
|
-
/**
|
|
111
|
-
* Failing assertion.
|
|
112
|
-
*/
|
|
113
|
-
fail(message?: string): void;
|
|
114
|
-
/**
|
|
115
|
-
* Assert that value is truthy.
|
|
116
|
-
*/
|
|
117
|
-
truthy(value: any, message?: string): void;
|
|
118
|
-
/**
|
|
119
|
-
* Assert that value is falsy.
|
|
120
|
-
*/
|
|
121
|
-
falsy(value: any, message?: string): void;
|
|
122
|
-
/**
|
|
123
|
-
* DEPRECATED, use `truthy`. Assert that value is truthy.
|
|
124
|
-
*/
|
|
125
|
-
ok(value: any, message?: string): void;
|
|
126
|
-
/**
|
|
127
|
-
* DEPRECATED, use `falsy`. Assert that value is falsy.
|
|
128
|
-
*/
|
|
129
|
-
notOk(value: any, message?: string): void;
|
|
130
|
-
/**
|
|
131
|
-
* Assert that value is true.
|
|
132
|
-
*/
|
|
133
|
-
true(value: boolean, message?: string): void;
|
|
134
|
-
/**
|
|
135
|
-
* Assert that value is false.
|
|
136
|
-
*/
|
|
137
|
-
false(value: boolean, message?: string): void;
|
|
138
|
-
/**
|
|
139
|
-
* Assert that value is equal to expected.
|
|
140
|
-
*/
|
|
141
|
-
is<U>(value: U, expected: U, message?: string): void;
|
|
142
|
-
/**
|
|
143
|
-
* Assert that value is not equal to expected.
|
|
144
|
-
*/
|
|
145
|
-
not<U>(value: U, expected: U, message?: string): void;
|
|
146
|
-
/**
|
|
147
|
-
* Assert that value is deep equal to expected.
|
|
148
|
-
*/
|
|
149
|
-
deepEqual<U>(value: U, expected: U, message?: string): void;
|
|
150
|
-
/**
|
|
151
|
-
* Assert that value is not deep equal to expected.
|
|
152
|
-
*/
|
|
153
|
-
notDeepEqual<U>(value: U, expected: U, message?: string): void;
|
|
154
|
-
/**
|
|
155
|
-
* Assert that function throws an error or promise rejects.
|
|
156
|
-
* @param error Can be a constructor, regex, error message or validation function.
|
|
157
|
-
*/
|
|
158
|
-
/**
|
|
159
|
-
* DEPRECATED, use `deepEqual`. Assert that value is deep equal to expected.
|
|
160
|
-
*/
|
|
161
|
-
same<U>(value: U, expected: U, message?: string): void;
|
|
162
|
-
/**
|
|
163
|
-
* DEPRECATED use `notDeepEqual`. Assert that value is not deep equal to expected.
|
|
164
|
-
*/
|
|
165
|
-
notSame<U>(value: U, expected: U, message?: string): void;
|
|
166
|
-
/**
|
|
167
|
-
* Assert that function throws an error or promise rejects.
|
|
168
|
-
* @param error Can be a constructor, regex, error message or validation function.
|
|
169
|
-
*/
|
|
170
|
-
throws(value: Promise<{}>, error?: ErrorValidator, message?: string): Promise<any>;
|
|
171
|
-
throws(value: () => void, error?: ErrorValidator, message?: string): any;
|
|
172
|
-
/**
|
|
173
|
-
* Assert that function doesn't throw an error or promise resolves.
|
|
174
|
-
*/
|
|
175
|
-
notThrows<U>(value: Promise<U>, message?: string): Promise<U>;
|
|
176
|
-
notThrows(value: () => void, message?: string): void;
|
|
177
|
-
/**
|
|
178
|
-
* Assert that contents matches regex.
|
|
179
|
-
*/
|
|
180
|
-
regex(contents: string, regex: RegExp, message?: string): void;
|
|
181
|
-
/**
|
|
182
|
-
* Assert that error is falsy.
|
|
183
|
-
*/
|
|
184
|
-
ifError(error: any, message?: string): void;
|
|
185
|
-
}
|
|
186
|
-
export interface TestContext extends AssertContext {
|
|
187
|
-
/**
|
|
188
|
-
* Plan how many assertion there are in the test.
|
|
189
|
-
* The test will fail if the actual assertion count doesn't match planned assertions.
|
|
190
|
-
*/
|
|
191
|
-
plan(count: number): void;
|
|
192
|
-
|
|
193
|
-
skip: AssertContext;
|
|
194
|
-
}
|
|
195
|
-
export interface CallbackTestContext extends TestContext {
|
|
196
|
-
/**
|
|
197
|
-
* End the test.
|
|
198
|
-
*/
|
|
199
|
-
end(): void;
|
|
200
|
-
}
|
|
201
|
-
export interface ContextualTestContext extends TestContext {
|
|
202
|
-
context: any;
|
|
203
|
-
}
|
|
204
|
-
export interface ContextualCallbackTestContext extends CallbackTestContext {
|
|
205
|
-
context: any;
|
|
206
|
-
}
|
package/lib/ava-files.js
DELETED
|
@@ -1,262 +0,0 @@
|
|
|
1
|
-
var fs = require('fs');
|
|
2
|
-
var path = require('path');
|
|
3
|
-
var Promise = require('bluebird');
|
|
4
|
-
var slash = require('slash');
|
|
5
|
-
var globby = require('globby');
|
|
6
|
-
var flatten = require('arr-flatten');
|
|
7
|
-
var defaultIgnore = require('ignore-by-default').directories();
|
|
8
|
-
var multimatch = require('multimatch');
|
|
9
|
-
|
|
10
|
-
function defaultExcludePatterns() {
|
|
11
|
-
return [
|
|
12
|
-
'!**/node_modules/**',
|
|
13
|
-
'!**/fixtures/**',
|
|
14
|
-
'!**/helpers/**'
|
|
15
|
-
];
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
function defaultIncludePatterns() {
|
|
19
|
-
return [
|
|
20
|
-
'test.js',
|
|
21
|
-
'test-*.js',
|
|
22
|
-
'test',
|
|
23
|
-
'**/__tests__',
|
|
24
|
-
'**/*.test.js'
|
|
25
|
-
];
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function AvaFiles(files, sources) {
|
|
29
|
-
if (!(this instanceof AvaFiles)) {
|
|
30
|
-
throw new TypeError('Class constructor AvaFiles cannot be invoked without \'new\'');
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
if (!files || !files.length) {
|
|
34
|
-
files = defaultIncludePatterns();
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
this.excludePatterns = defaultExcludePatterns();
|
|
38
|
-
|
|
39
|
-
this.files = files;
|
|
40
|
-
this.sources = sources || [];
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
AvaFiles.prototype.findTestFiles = function () {
|
|
44
|
-
return handlePaths(this.files, this.excludePatterns, {
|
|
45
|
-
cache: Object.create(null),
|
|
46
|
-
statCache: Object.create(null),
|
|
47
|
-
realpathCache: Object.create(null),
|
|
48
|
-
symlinks: Object.create(null)
|
|
49
|
-
});
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
function getDefaultIgnorePatterns() {
|
|
53
|
-
return defaultIgnore.map(function (dir) {
|
|
54
|
-
return dir + '/**/*';
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// Used on paths before they're passed to multimatch to harmonize matching
|
|
59
|
-
// across platforms.
|
|
60
|
-
var matchable = process.platform === 'win32' ? slash : function (path) {
|
|
61
|
-
return path;
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
AvaFiles.prototype.makeSourceMatcher = function () {
|
|
65
|
-
var mixedPatterns = [];
|
|
66
|
-
var defaultIgnorePatterns = getDefaultIgnorePatterns();
|
|
67
|
-
var overrideDefaultIgnorePatterns = [];
|
|
68
|
-
|
|
69
|
-
var hasPositivePattern = false;
|
|
70
|
-
this.sources.forEach(function (pattern) {
|
|
71
|
-
mixedPatterns.push(pattern);
|
|
72
|
-
// TODO: why not just pattern[0] !== '!'
|
|
73
|
-
if (!hasPositivePattern && pattern[0] !== '!') {
|
|
74
|
-
hasPositivePattern = true;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// Extract patterns that start with an ignored directory. These need to be
|
|
78
|
-
// rematched separately.
|
|
79
|
-
if (defaultIgnore.indexOf(pattern.split('/')[0]) >= 0) {
|
|
80
|
-
overrideDefaultIgnorePatterns.push(pattern);
|
|
81
|
-
}
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
// Same defaults as used for Chokidar.
|
|
85
|
-
if (!hasPositivePattern) {
|
|
86
|
-
mixedPatterns = ['package.json', '**/*.js'].concat(mixedPatterns);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
return function (path) {
|
|
90
|
-
path = matchable(path);
|
|
91
|
-
|
|
92
|
-
// Ignore paths outside the current working directory. They can't be matched
|
|
93
|
-
// to a pattern.
|
|
94
|
-
if (/^\.\.\//.test(path)) {
|
|
95
|
-
return false;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
var isSource = multimatch(path, mixedPatterns).length === 1;
|
|
99
|
-
if (!isSource) {
|
|
100
|
-
return false;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
var isIgnored = multimatch(path, defaultIgnorePatterns).length === 1;
|
|
104
|
-
if (!isIgnored) {
|
|
105
|
-
return true;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
var isErroneouslyIgnored = multimatch(path, overrideDefaultIgnorePatterns).length === 1;
|
|
109
|
-
if (isErroneouslyIgnored) {
|
|
110
|
-
return true;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
return false;
|
|
114
|
-
};
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
AvaFiles.prototype.makeTestMatcher = function () {
|
|
118
|
-
var excludePatterns = this.excludePatterns;
|
|
119
|
-
var initialPatterns = this.files.concat(excludePatterns);
|
|
120
|
-
|
|
121
|
-
return function (filepath) {
|
|
122
|
-
// Like in api.js, tests must be .js files and not start with _
|
|
123
|
-
if (path.extname(filepath) !== '.js' || path.basename(filepath)[0] === '_') {
|
|
124
|
-
return false;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// Check if the entire path matches a pattern.
|
|
128
|
-
if (multimatch(matchable(filepath), initialPatterns).length === 1) {
|
|
129
|
-
return true;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// Check if the path contains any directory components.
|
|
133
|
-
var dirname = path.dirname(filepath);
|
|
134
|
-
if (dirname === '.') {
|
|
135
|
-
return false;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
// Compute all possible subpaths. Note that the dirname is assumed to be
|
|
139
|
-
// relative to the working directory, without a leading `./`.
|
|
140
|
-
var subpaths = dirname.split(/[\\\/]/).reduce(function (subpaths, component) {
|
|
141
|
-
var parent = subpaths[subpaths.length - 1];
|
|
142
|
-
if (parent) {
|
|
143
|
-
// Always use / to makes multimatch consistent across platforms.
|
|
144
|
-
subpaths.push(parent + '/' + component);
|
|
145
|
-
} else {
|
|
146
|
-
subpaths.push(component);
|
|
147
|
-
}
|
|
148
|
-
return subpaths;
|
|
149
|
-
}, []);
|
|
150
|
-
|
|
151
|
-
// Check if any of the possible subpaths match a pattern. If so, generate a
|
|
152
|
-
// new pattern with **/*.js.
|
|
153
|
-
var recursivePatterns = subpaths.filter(function (subpath) {
|
|
154
|
-
return multimatch(subpath, initialPatterns).length === 1;
|
|
155
|
-
}).map(function (subpath) {
|
|
156
|
-
// Always use / to makes multimatch consistent across platforms.
|
|
157
|
-
return subpath + '/**/*.js';
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
// See if the entire path matches any of the subpaths patterns, taking the
|
|
161
|
-
// excludePatterns into account. This mimicks the behavior in api.js
|
|
162
|
-
return multimatch(matchable(filepath), recursivePatterns.concat(excludePatterns)).length === 1;
|
|
163
|
-
};
|
|
164
|
-
};
|
|
165
|
-
|
|
166
|
-
AvaFiles.prototype.getChokidarPatterns = function () {
|
|
167
|
-
var paths = [];
|
|
168
|
-
var ignored = [];
|
|
169
|
-
|
|
170
|
-
this.sources.forEach(function (pattern) {
|
|
171
|
-
if (pattern[0] === '!') {
|
|
172
|
-
ignored.push(pattern.slice(1));
|
|
173
|
-
} else {
|
|
174
|
-
paths.push(pattern);
|
|
175
|
-
}
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
// Allow source patterns to override the default ignore patterns. Chokidar
|
|
179
|
-
// ignores paths that match the list of ignored patterns. It uses anymatch
|
|
180
|
-
// under the hood, which supports negation patterns. For any source pattern
|
|
181
|
-
// that starts with an ignored directory, ensure the corresponding negation
|
|
182
|
-
// pattern is added to the ignored paths.
|
|
183
|
-
var overrideDefaultIgnorePatterns = paths.filter(function (pattern) {
|
|
184
|
-
return defaultIgnore.indexOf(pattern.split('/')[0]) >= 0;
|
|
185
|
-
}).map(function (pattern) {
|
|
186
|
-
return '!' + pattern;
|
|
187
|
-
});
|
|
188
|
-
ignored = getDefaultIgnorePatterns().concat(ignored, overrideDefaultIgnorePatterns);
|
|
189
|
-
|
|
190
|
-
if (paths.length === 0) {
|
|
191
|
-
paths = ['package.json', '**/*.js'];
|
|
192
|
-
}
|
|
193
|
-
paths = paths.concat(this.files);
|
|
194
|
-
|
|
195
|
-
return {
|
|
196
|
-
paths: paths,
|
|
197
|
-
ignored: ignored
|
|
198
|
-
};
|
|
199
|
-
};
|
|
200
|
-
|
|
201
|
-
function handlePaths(files, excludePatterns, globOptions) {
|
|
202
|
-
// convert pinkie-promise to Bluebird promise
|
|
203
|
-
files = Promise.resolve(globby(files.concat(excludePatterns), globOptions));
|
|
204
|
-
|
|
205
|
-
var searchedParents = Object.create(null);
|
|
206
|
-
var foundFiles = Object.create(null);
|
|
207
|
-
|
|
208
|
-
function alreadySearchingParent(dir) {
|
|
209
|
-
if (searchedParents[dir]) {
|
|
210
|
-
return true;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
var parentDir = path.dirname(dir);
|
|
214
|
-
|
|
215
|
-
if (parentDir === dir) {
|
|
216
|
-
// We have reached the root path.
|
|
217
|
-
return false;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
return alreadySearchingParent(parentDir);
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
return files
|
|
224
|
-
.map(function (file) {
|
|
225
|
-
if (fs.statSync(file).isDirectory()) {
|
|
226
|
-
if (alreadySearchingParent(file)) {
|
|
227
|
-
return null;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
searchedParents[file] = true;
|
|
231
|
-
|
|
232
|
-
var pattern = path.join(file, '**', '*.js');
|
|
233
|
-
|
|
234
|
-
if (process.platform === 'win32') {
|
|
235
|
-
// Always use / in patterns, harmonizing matching across platforms.
|
|
236
|
-
pattern = slash(pattern);
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
return handlePaths([pattern], excludePatterns, globOptions);
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
// globby returns slashes even on Windows. Normalize here so the file
|
|
243
|
-
// paths are consistently platform-accurate as tests are run.
|
|
244
|
-
return path.normalize(file);
|
|
245
|
-
})
|
|
246
|
-
.then(flatten)
|
|
247
|
-
.filter(function (file) {
|
|
248
|
-
return file && path.extname(file) === '.js' && path.basename(file)[0] !== '_';
|
|
249
|
-
})
|
|
250
|
-
.map(function (file) {
|
|
251
|
-
return path.resolve(file);
|
|
252
|
-
})
|
|
253
|
-
.filter(function (file) {
|
|
254
|
-
var alreadyFound = foundFiles[file];
|
|
255
|
-
foundFiles[file] = true;
|
|
256
|
-
return !alreadyFound;
|
|
257
|
-
});
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
module.exports = AvaFiles;
|
|
261
|
-
module.exports.defaultIncludePatterns = defaultIncludePatterns;
|
|
262
|
-
module.exports.defaultExcludePatterns = defaultExcludePatterns;
|
package/lib/send.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
// utility to send messages to processes
|
|
4
|
-
module.exports = function (ps, name, data) {
|
|
5
|
-
if (typeof ps === 'string') {
|
|
6
|
-
data = name || {};
|
|
7
|
-
name = ps;
|
|
8
|
-
ps = process;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
ps.send({
|
|
12
|
-
name: 'ava-' + name,
|
|
13
|
-
data: data,
|
|
14
|
-
ava: true
|
|
15
|
-
});
|
|
16
|
-
};
|