supertape 6.6.0 → 6.7.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/ChangeLog +6 -0
- package/README.md +8 -0
- package/help.json +1 -0
- package/lib/cli.js +9 -1
- package/lib/run-tests.js +7 -7
- package/lib/supertape.js +10 -6
- package/lib/validator.js +117 -0
- package/package.json +3 -2
- package/lib/duplicator.js +0 -49
package/ChangeLog
CHANGED
package/README.md
CHANGED
|
@@ -53,6 +53,14 @@ Options
|
|
|
53
53
|
|
|
54
54
|
- `SUPERTAPE_TIMEOUT` - timeout for long running processes;
|
|
55
55
|
- `SUPERTAPE_CHECK_DUPLICATES` - toggle check duplicates;
|
|
56
|
+
- `SUPERTAPE_CHECK_SCOPES` - check that test message has a scope: `scope: subject`
|
|
57
|
+
|
|
58
|
+
```js
|
|
59
|
+
test('tape: error', (t) => {
|
|
60
|
+
t.equal(error.code, 'ENOENT');
|
|
61
|
+
t.end();
|
|
62
|
+
});
|
|
63
|
+
```
|
|
56
64
|
|
|
57
65
|
## Codemod
|
|
58
66
|
|
package/help.json
CHANGED
|
@@ -3,5 +3,6 @@
|
|
|
3
3
|
"-v, --version ": "output version information and exit",
|
|
4
4
|
"-f, --format ": "use a specific output format - default: progress-bar/tap on CI",
|
|
5
5
|
"-r, --require ": "require module",
|
|
6
|
+
"--check-scopes ": "check that messages contains scope: 'scope: message'",
|
|
6
7
|
"--no-check-duplicates ": "do not check messages for duplicates"
|
|
7
8
|
}
|
package/lib/cli.js
CHANGED
|
@@ -30,7 +30,10 @@ const maybeArray = (a) => isArray(a) ? a : [a];
|
|
|
30
30
|
const removeDuplicates = (a) => Array.from(new Set(a));
|
|
31
31
|
const filesCount = fullstore(0);
|
|
32
32
|
|
|
33
|
-
const {
|
|
33
|
+
const {
|
|
34
|
+
SUPERTAPE_CHECK_DUPLICATES = '1',
|
|
35
|
+
SUPERTAPE_CHECK_SCOPES = '0',
|
|
36
|
+
} = process.env;
|
|
34
37
|
|
|
35
38
|
module.exports = async ({argv, cwd, stdout, stderr, exit}) => {
|
|
36
39
|
const {isStop} = keypress();
|
|
@@ -85,6 +88,7 @@ const yargsOptions = {
|
|
|
85
88
|
'version',
|
|
86
89
|
'help',
|
|
87
90
|
'check-duplicates',
|
|
91
|
+
'check-scopes',
|
|
88
92
|
],
|
|
89
93
|
alias: {
|
|
90
94
|
version: 'v',
|
|
@@ -92,11 +96,13 @@ const yargsOptions = {
|
|
|
92
96
|
help: 'h',
|
|
93
97
|
require: 'r',
|
|
94
98
|
checkDuplicates: 'd',
|
|
99
|
+
checkScopes: 's',
|
|
95
100
|
},
|
|
96
101
|
default: {
|
|
97
102
|
format: 'progress-bar',
|
|
98
103
|
require: [],
|
|
99
104
|
checkDuplicates: SUPERTAPE_CHECK_DUPLICATES !== '0',
|
|
105
|
+
checkScopes: SUPERTAPE_CHECK_SCOPES === '1',
|
|
100
106
|
},
|
|
101
107
|
};
|
|
102
108
|
|
|
@@ -141,6 +147,7 @@ async function cli({argv, cwd, stdout, isStop}) {
|
|
|
141
147
|
const {
|
|
142
148
|
format,
|
|
143
149
|
checkDuplicates,
|
|
150
|
+
checkScopes,
|
|
144
151
|
} = args;
|
|
145
152
|
|
|
146
153
|
supertape.init({
|
|
@@ -149,6 +156,7 @@ async function cli({argv, cwd, stdout, isStop}) {
|
|
|
149
156
|
format,
|
|
150
157
|
isStop,
|
|
151
158
|
checkDuplicates,
|
|
159
|
+
checkScopes,
|
|
152
160
|
});
|
|
153
161
|
|
|
154
162
|
supertape.createStream().pipe(stdout);
|
package/lib/run-tests.js
CHANGED
|
@@ -6,7 +6,7 @@ const tryToCatch = require('try-to-catch');
|
|
|
6
6
|
const once = require('once');
|
|
7
7
|
|
|
8
8
|
const isDebug = require('./is-debug');
|
|
9
|
-
const
|
|
9
|
+
const {createValidator} = require('./validator');
|
|
10
10
|
|
|
11
11
|
const inc = wraptile((store) => store(store() + 1));
|
|
12
12
|
const isOnly = ({only}) => only;
|
|
@@ -76,7 +76,7 @@ async function runTests(tests, {formatter, operators, skiped, isStop}) {
|
|
|
76
76
|
});
|
|
77
77
|
|
|
78
78
|
const wasStop = fullstore();
|
|
79
|
-
const
|
|
79
|
+
const getValidationMessage = createValidator({
|
|
80
80
|
tests,
|
|
81
81
|
});
|
|
82
82
|
|
|
@@ -99,7 +99,7 @@ async function runTests(tests, {formatter, operators, skiped, isStop}) {
|
|
|
99
99
|
incCount,
|
|
100
100
|
incFailed,
|
|
101
101
|
incPassed,
|
|
102
|
-
|
|
102
|
+
getValidationMessage,
|
|
103
103
|
|
|
104
104
|
extensions: {
|
|
105
105
|
...operators,
|
|
@@ -123,7 +123,7 @@ async function runTests(tests, {formatter, operators, skiped, isStop}) {
|
|
|
123
123
|
};
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
-
async function runOneTest({message, fn, extensions, formatter, count, total, failed, incCount, incPassed, incFailed,
|
|
126
|
+
async function runOneTest({message, fn, extensions, formatter, count, total, failed, incCount, incPassed, incFailed, getValidationMessage}) {
|
|
127
127
|
formatter.emit('test', {
|
|
128
128
|
test: message,
|
|
129
129
|
});
|
|
@@ -159,10 +159,10 @@ async function runOneTest({message, fn, extensions, formatter, count, total, fai
|
|
|
159
159
|
failed: failed(),
|
|
160
160
|
});
|
|
161
161
|
|
|
162
|
-
const [
|
|
162
|
+
const [validationMessage, at] = getValidationMessage(message);
|
|
163
163
|
|
|
164
|
-
if (
|
|
165
|
-
t.fail(
|
|
164
|
+
if (at) {
|
|
165
|
+
t.fail(validationMessage, at);
|
|
166
166
|
t.end();
|
|
167
167
|
}
|
|
168
168
|
}
|
package/lib/supertape.js
CHANGED
|
@@ -6,7 +6,7 @@ const {createSimport} = require('simport');
|
|
|
6
6
|
|
|
7
7
|
const options = require('../supertape.json');
|
|
8
8
|
|
|
9
|
-
const {
|
|
9
|
+
const {getAt, setValidations} = require('./validator');
|
|
10
10
|
const runTests = require('./run-tests');
|
|
11
11
|
const createFormatter = once(require('./formatter').createFormatter);
|
|
12
12
|
|
|
@@ -35,20 +35,21 @@ const defaultOptions = {
|
|
|
35
35
|
getOperators,
|
|
36
36
|
isStop: () => false,
|
|
37
37
|
checkDuplicates: true,
|
|
38
|
+
checkScopes: false,
|
|
38
39
|
};
|
|
39
40
|
|
|
40
41
|
function _createEmitter({quiet, format, getOperators, isStop}) {
|
|
41
42
|
const tests = [];
|
|
42
43
|
const emitter = new EventEmitter();
|
|
43
44
|
|
|
44
|
-
emitter.on('test', (message, fn, {skip, only, extensions,
|
|
45
|
+
emitter.on('test', (message, fn, {skip, only, extensions, at}) => {
|
|
45
46
|
tests.push({
|
|
46
47
|
message,
|
|
47
48
|
fn,
|
|
48
49
|
skip,
|
|
49
50
|
only,
|
|
50
51
|
extensions,
|
|
51
|
-
|
|
52
|
+
at,
|
|
52
53
|
});
|
|
53
54
|
});
|
|
54
55
|
|
|
@@ -108,17 +109,20 @@ function test(message, fn, options = {}) {
|
|
|
108
109
|
getOperators,
|
|
109
110
|
isStop,
|
|
110
111
|
checkDuplicates,
|
|
112
|
+
checkScopes,
|
|
111
113
|
} = {
|
|
112
114
|
...defaultOptions,
|
|
113
115
|
...initedOptions,
|
|
114
116
|
...options,
|
|
115
117
|
};
|
|
116
118
|
|
|
117
|
-
|
|
118
|
-
message,
|
|
119
|
+
setValidations({
|
|
119
120
|
checkDuplicates,
|
|
121
|
+
checkScopes,
|
|
120
122
|
});
|
|
121
123
|
|
|
124
|
+
const at = getAt();
|
|
125
|
+
|
|
122
126
|
const emitter = createEmitter({
|
|
123
127
|
format,
|
|
124
128
|
quiet,
|
|
@@ -132,7 +136,7 @@ function test(message, fn, options = {}) {
|
|
|
132
136
|
skip,
|
|
133
137
|
only,
|
|
134
138
|
extensions,
|
|
135
|
-
|
|
139
|
+
at,
|
|
136
140
|
});
|
|
137
141
|
|
|
138
142
|
if (run)
|
package/lib/validator.js
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const once = require('once');
|
|
4
|
+
const StackTracey = require('stacktracey');
|
|
5
|
+
|
|
6
|
+
const getDuplicatesMessage = ([, a]) => a;
|
|
7
|
+
const getMessage = ({message, at}) => [message, at];
|
|
8
|
+
const getMessagesList = (tests) => tests.map(getMessage);
|
|
9
|
+
const compareMessage = (a) => ([b]) => a === b;
|
|
10
|
+
|
|
11
|
+
const SCOPE_DEFINED = /^\w+:/;
|
|
12
|
+
const processedList = new Set();
|
|
13
|
+
|
|
14
|
+
const validations = {
|
|
15
|
+
checkDuplicates: true,
|
|
16
|
+
checkScopes: false,
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const validators = {
|
|
20
|
+
checkDuplicates,
|
|
21
|
+
checkScopes,
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const {
|
|
25
|
+
assign,
|
|
26
|
+
values,
|
|
27
|
+
entries,
|
|
28
|
+
} = Object;
|
|
29
|
+
|
|
30
|
+
const findByMessage = (msg, tests) => {
|
|
31
|
+
const getMessages = once(getMessagesList);
|
|
32
|
+
const filtered = getMessages(tests).filter(compareMessage(msg));
|
|
33
|
+
|
|
34
|
+
return filtered;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
module.exports.setValidations = ({checkDuplicates, checkScopes}) => {
|
|
38
|
+
assign(validations, {
|
|
39
|
+
checkDuplicates,
|
|
40
|
+
checkScopes,
|
|
41
|
+
});
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const isValidationEnabled = (a) => values(a).filter(Boolean).length;
|
|
45
|
+
|
|
46
|
+
module.exports.createValidator = ({tests}) => (msg) => {
|
|
47
|
+
if (!isValidationEnabled(validations))
|
|
48
|
+
return [];
|
|
49
|
+
|
|
50
|
+
for (const [name, enabled] of entries(validations)) {
|
|
51
|
+
if (!enabled)
|
|
52
|
+
continue;
|
|
53
|
+
|
|
54
|
+
const filtered = findByMessage(msg, tests);
|
|
55
|
+
|
|
56
|
+
if (!filtered.length)
|
|
57
|
+
throw Error('☝️Looks like message cannot be fined in tests, this should never happen');
|
|
58
|
+
|
|
59
|
+
const [message, at] = validators[name](msg, filtered);
|
|
60
|
+
|
|
61
|
+
if (at)
|
|
62
|
+
return [message, at];
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return [];
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
module.exports.getAt = () => {
|
|
69
|
+
const {
|
|
70
|
+
checkDuplicates,
|
|
71
|
+
checkScopes,
|
|
72
|
+
} = validations;
|
|
73
|
+
|
|
74
|
+
if (!checkDuplicates && !checkScopes)
|
|
75
|
+
return '';
|
|
76
|
+
|
|
77
|
+
return getFileName();
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const CALLS_FROM_TEST = 3;
|
|
81
|
+
|
|
82
|
+
function getFileName() {
|
|
83
|
+
const {items} = new StackTracey(Error());
|
|
84
|
+
|
|
85
|
+
for (const {beforeParse, file} of items.slice(CALLS_FROM_TEST)) {
|
|
86
|
+
if (file.includes('node_modules'))
|
|
87
|
+
continue;
|
|
88
|
+
|
|
89
|
+
return beforeParse;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return '';
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function checkScopes(msg, filtered) {
|
|
96
|
+
const [message, at] = filtered[0];
|
|
97
|
+
|
|
98
|
+
if (!SCOPE_DEFINED.test(message))
|
|
99
|
+
return [`Scope should be defined before first colon: 'scope: subject', example: 'supertape: validator: enabled'`, at];
|
|
100
|
+
|
|
101
|
+
return [];
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function checkDuplicates(msg, filtered) {
|
|
105
|
+
if (filtered.length < 2)
|
|
106
|
+
return [];
|
|
107
|
+
|
|
108
|
+
const [first, second] = filtered.map(getDuplicatesMessage);
|
|
109
|
+
|
|
110
|
+
if (processedList.has(first))
|
|
111
|
+
return [];
|
|
112
|
+
|
|
113
|
+
processedList.add(first);
|
|
114
|
+
|
|
115
|
+
return [`Duplicate ${first}`, second];
|
|
116
|
+
}
|
|
117
|
+
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "supertape",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.7.0",
|
|
4
4
|
"author": "coderaiser <mnemonic.enemy@gmail.com> (https://github.com/coderaiser)",
|
|
5
5
|
"description": "tape compatible test runner with superpowers",
|
|
6
6
|
"homepage": "http://github.com/coderaiser/supertape",
|
|
@@ -87,7 +87,8 @@
|
|
|
87
87
|
"nodemon": "^2.0.2",
|
|
88
88
|
"pullout": "^4.0.0",
|
|
89
89
|
"putout": "^20.0.1",
|
|
90
|
-
"runsome": "^1.0.0"
|
|
90
|
+
"runsome": "^1.0.0",
|
|
91
|
+
"try-catch": "^3.0.0"
|
|
91
92
|
},
|
|
92
93
|
"license": "MIT",
|
|
93
94
|
"engines": {
|
package/lib/duplicator.js
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const once = require('once');
|
|
4
|
-
const StackTracey = require('stacktracey');
|
|
5
|
-
|
|
6
|
-
const getMessage = ({message, duplicatesMessage}) => [message, duplicatesMessage];
|
|
7
|
-
const getMessagesList = (tests) => tests.map(getMessage);
|
|
8
|
-
const compareMessage = (a) => ([b]) => a === b;
|
|
9
|
-
const getDuplicatesMessage = ([, a]) => a;
|
|
10
|
-
|
|
11
|
-
const processedList = new Set();
|
|
12
|
-
|
|
13
|
-
module.exports = ({tests}) => (msg) => {
|
|
14
|
-
const getMessages = once(getMessagesList);
|
|
15
|
-
const duplicates = getMessages(tests).filter(compareMessage(msg));
|
|
16
|
-
|
|
17
|
-
if (duplicates.length < 2)
|
|
18
|
-
return [];
|
|
19
|
-
|
|
20
|
-
const [duplicatesMessage, duplicateAt] = duplicates.map(getDuplicatesMessage);
|
|
21
|
-
|
|
22
|
-
if (processedList.has(duplicatesMessage))
|
|
23
|
-
return [];
|
|
24
|
-
|
|
25
|
-
processedList.add(duplicatesMessage);
|
|
26
|
-
return [`Duplicate ${duplicatesMessage}`, duplicateAt];
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
module.exports.getDuplicatesMessage = ({checkDuplicates}) => {
|
|
30
|
-
if (!checkDuplicates)
|
|
31
|
-
return '';
|
|
32
|
-
|
|
33
|
-
return getFileName();
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
const CALLS_FROM_TEST = 3;
|
|
37
|
-
|
|
38
|
-
function getFileName() {
|
|
39
|
-
const {items} = new StackTracey(Error());
|
|
40
|
-
|
|
41
|
-
for (const {beforeParse, file} of items.slice(CALLS_FROM_TEST)) {
|
|
42
|
-
if (file.includes('node_modules'))
|
|
43
|
-
continue;
|
|
44
|
-
|
|
45
|
-
return beforeParse;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return '';
|
|
49
|
-
}
|