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 CHANGED
@@ -1,3 +1,9 @@
1
+ 2021.09.18, v6.7.0
2
+
3
+ feature:
4
+ - (supertape) add --check-scopes flag that checks that test message contains scope
5
+
6
+
1
7
  2021.09.16, v6.6.0
2
8
 
3
9
  feature:
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 {SUPERTAPE_CHECK_DUPLICATES} = process.env;
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 duplicator = require('./duplicator');
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 getDuplicatesMessage = duplicator({
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
- getDuplicatesMessage,
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, getDuplicatesMessage}) {
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 [duplicateMessage, duplicateAt] = getDuplicatesMessage(message);
162
+ const [validationMessage, at] = getValidationMessage(message);
163
163
 
164
- if (duplicateAt) {
165
- t.fail(duplicateMessage, duplicateAt);
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 {getDuplicatesMessage} = require('./duplicator');
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, duplicatesMessage}) => {
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
- duplicatesMessage,
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
- const duplicatesMessage = getDuplicatesMessage({
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
- duplicatesMessage,
139
+ at,
136
140
  });
137
141
 
138
142
  if (run)
@@ -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.6.0",
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
- }