escover 1.0.1 → 1.0.5

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.
Files changed (33) hide show
  1. package/ChangeLog +28 -0
  2. package/example/example.js +1 -1
  3. package/lib/c4.js +2 -2
  4. package/lib/escover.js +2 -2
  5. package/lib/instrument/index.js +3 -3
  6. package/lib/instrument/{plugin-mark-line → plugin-mark}/arrow.js +0 -0
  7. package/lib/instrument/{plugin-mark-line → plugin-mark}/fixture/arrow-fix.js +2 -2
  8. package/lib/instrument/{plugin-mark-line → plugin-mark}/fixture/arrow.js +0 -0
  9. package/lib/instrument/plugin-mark/fixture/assignment-fix.js +2 -0
  10. package/lib/instrument/plugin-mark/fixture/assignment.js +2 -0
  11. package/lib/instrument/plugin-mark/fixture/if-fix.js +6 -0
  12. package/lib/instrument/plugin-mark/fixture/if.js +6 -0
  13. package/lib/instrument/plugin-mark/fixture/logical-fix.js +3 -0
  14. package/lib/instrument/{plugin-mark-line → plugin-mark}/fixture/logical.js +0 -0
  15. package/lib/instrument/plugin-mark/fixture/mark-line-fix.js +30 -0
  16. package/lib/instrument/{plugin-mark-line → plugin-mark}/fixture/mark-line.js +0 -0
  17. package/lib/instrument/plugin-mark/fixture/new-fix.js +1 -0
  18. package/lib/instrument/{plugin-mark-line → plugin-mark}/fixture/new.js +0 -0
  19. package/lib/instrument/plugin-mark/fixture/no-loc-fix.js +8 -0
  20. package/lib/instrument/{plugin-mark-line → plugin-mark}/fixture/no-loc.js +0 -0
  21. package/lib/instrument/{plugin-mark-line → plugin-mark}/index.js +19 -9
  22. package/lib/instrument/{plugin-mark-line → plugin-mark}/return.js +0 -0
  23. package/lib/instrument/plugin-mark/throw.js +17 -0
  24. package/lib/merge.js +44 -0
  25. package/lib/parse.js +20 -0
  26. package/lib/report.js +21 -16
  27. package/lib/save.js +5 -17
  28. package/package.json +3 -1
  29. package/coverage.json +0 -9
  30. package/lib/instrument/plugin-mark-line/fixture/logical-fix.js +0 -3
  31. package/lib/instrument/plugin-mark-line/fixture/mark-line-fix.js +0 -30
  32. package/lib/instrument/plugin-mark-line/fixture/new-fix.js +0 -1
  33. package/lib/instrument/plugin-mark-line/fixture/no-loc-fix.js +0 -8
package/ChangeLog CHANGED
@@ -1,3 +1,31 @@
1
+ 2022.01.08, v1.0.5
2
+
3
+ feature:
4
+ - escover: report
5
+
6
+
7
+ 2022.01.08, v1.0.4
8
+
9
+ feature:
10
+ - escover: add support of AssignmentExpression
11
+
12
+
13
+ 2022.01.08, v1.0.3
14
+
15
+ feature:
16
+ - escover: plugin-mark: add support ot ThrowStatement
17
+ - escover: add merger
18
+
19
+
20
+ 2022.01.08, v1.0.2
21
+
22
+ fix:
23
+ - escover: impove support of AssignmentPattern
24
+
25
+ feature:
26
+ - escover: plugin-mark-line -> plugin-mark
27
+
28
+
1
29
  2022.01.08, v1.0.1
2
30
 
3
31
  fix:
@@ -1,4 +1,4 @@
1
1
  export const sum = (a, b) => a + b;
2
2
 
3
- export const mul = (a, b) => a * b;
3
+ // export const mul = (a, b) => a * b;
4
4
 
package/lib/c4.js CHANGED
@@ -5,10 +5,10 @@ export const createFileEntry = (url) => {
5
5
  files.set(url, lines);
6
6
 
7
7
  return {
8
- mark: (line, column) => {
8
+ '🧨': (line, column) => {
9
9
  lines.set(`${line}:${column}`, true);
10
10
  },
11
- init: (line, column) => {
11
+ 'init': (line, column) => {
12
12
  lines.set(`${line}:${column}`, false);
13
13
  },
14
14
  };
package/lib/escover.js CHANGED
@@ -8,6 +8,8 @@ import {createFileEntry} from './c4.js';
8
8
 
9
9
  global.__createC4 = createFileEntry;
10
10
 
11
+ process.once('exit', exit);
12
+
11
13
  export async function load(url, context, defaultLoad) {
12
14
  const {format, source: rawSource} = await defaultLoad(url, context, defaultLoad);
13
15
 
@@ -33,5 +35,3 @@ export async function load(url, context, defaultLoad) {
33
35
  };
34
36
  }
35
37
 
36
- process.once('exit', exit);
37
-
@@ -1,17 +1,17 @@
1
1
  import putout, {} from 'putout';
2
2
 
3
- import * as markLine from './plugin-mark-line/index.js';
3
+ import * as mark from './plugin-mark/index.js';
4
4
 
5
5
  export const instrument = (url, source) => {
6
6
  const __c4 = global.__createC4(url);
7
7
  const options = {
8
8
  rules: {
9
- 'mark-line': ['on', {
9
+ mark: ['on', {
10
10
  __c4,
11
11
  }],
12
12
  },
13
13
  plugins: [
14
- ['mark-line', markLine],
14
+ ['mark', mark],
15
15
  ],
16
16
  };
17
17
 
@@ -1,6 +1,6 @@
1
1
  export const nothing = (a, b) => {
2
- return __c4.mark(2, 4);
2
+ return __c4['🧨'](2, 4);
3
3
  };
4
4
  export const sum = (a, b) => {
5
- return __c4.mark(5, 4), a + b;
5
+ return __c4['🧨'](5, 4), a + b;
6
6
  };
@@ -0,0 +1,2 @@
1
+ const [error, {packageJson} = (__c4['🧨'](1, 14), {})] = (__c4['🧨'](1, 36), tryCatch(readPackageUpSync));
2
+ data += (__c4['🧨'](2, 0), 'fix:' + '\n');
@@ -0,0 +1,2 @@
1
+ const [error, {packageJson} = {}] = tryCatch(readPackageUpSync);
2
+ data += 'fix:' + '\n';
@@ -0,0 +1,6 @@
1
+ if (error) {
2
+ throw (__c4['🧨'](2, 4), `error reading package.json: ${error.message}`);
3
+ }
4
+
5
+ if (error)
6
+ throw (__c4['🧨'](6, 4), (__c4.mark(11, 8), `error reading package.json: ${error.message}`));
@@ -0,0 +1,6 @@
1
+ if (error) {
2
+ throw `error reading package.json: ${error.message}`;
3
+ }
4
+
5
+ if (error)
6
+ throw (__c4.mark(11, 8), `error reading package.json: ${error.message}`);
@@ -0,0 +1,3 @@
1
+ if ((__c4['🧨'](1, 4), a) || (__c4['🧨'](1, 9), b)) {
2
+ __c4['🧨'](1, 12);
3
+ }
@@ -0,0 +1,30 @@
1
+ const a = () => {
2
+ a = (__c4['🧨'](2, 4), 5);
3
+ __c4['🧨'](3, 4), console.log(5);
4
+ };
5
+
6
+
7
+ function x() {
8
+
9
+ if (a > 2) {
10
+ __c4['🧨'](9, 14), a();
11
+ } else {
12
+ __c4['🧨'](10, 9), b();
13
+ }
14
+ }
15
+
16
+ for (const x of y) {
17
+ __c4['🧨'](13, 19);
18
+ }
19
+
20
+ const ax = ((__c4['🧨'](16, 12), a()), (__c4['🧨'](16, 17), b()));
21
+ const bx = (c, (__c4['🧨'](17, 15), d()));
22
+
23
+ if ((__c4['🧨'](19, 4), a) || (__c4['🧨'](19, 9), b)) {
24
+ __c4['🧨'](19, 12);
25
+ }
26
+
27
+
28
+ function x1(a, b = (__c4['🧨'](23, 15), 5)) {
29
+ __c4['🧨'](23, 22);
30
+ }
@@ -0,0 +1 @@
1
+ const files = (__c4['🧨'](1, 14), new Map());
@@ -0,0 +1,8 @@
1
+ __c4['🧨'](1, 0), cli({
2
+ stdout,
3
+ stderr,
4
+ exit,
5
+ cwd: (__c4['🧨'](5, 9), process.cwd()),
6
+ argv: (__c4['🧨'](6, 10), process.argv.slice(2))
7
+ });
8
+
@@ -5,6 +5,7 @@ import {
5
5
  } from 'putout';
6
6
  import {addMarkToReturn} from './return.js';
7
7
  import {addMarkToArrowFunction} from './arrow.js';
8
+ import {addMarkToThrow} from './throw.js';
8
9
 
9
10
  const {
10
11
  NumericLiteral,
@@ -13,12 +14,11 @@ const {
13
14
  } = types;
14
15
 
15
16
  const {
16
- replaceWithMultiple,
17
17
  replaceWith,
18
18
  compareAny,
19
19
  } = operator;
20
20
 
21
- const LINE = '__c4.mark(__l, __c)';
21
+ const LINE = `__c4['🧨'](__l, __c)`;
22
22
  const buildLineNode = template(LINE, {
23
23
  placeholderPattern: /^__[a-z]$/,
24
24
  });
@@ -80,11 +80,11 @@ export const fix = (path, {options}) => {
80
80
  return;
81
81
  }
82
82
 
83
- if (path.isAssignmentPattern()) {
84
- replaceWithMultiple(path.get('right'), [
85
- lineNode,
86
- node.left,
87
- ]);
83
+ if (path.isAssignmentPattern() || path.isAssignmentExpression()) {
84
+ replaceWith(path.get('right'), SequenceExpression([
85
+ lineNode.expression,
86
+ node.right,
87
+ ]));
88
88
  return;
89
89
  }
90
90
 
@@ -102,6 +102,9 @@ export const fix = (path, {options}) => {
102
102
  if (path.isArrowFunctionExpression())
103
103
  return addMarkToArrowFunction(path, lineNode);
104
104
 
105
+ if (path.isThrowStatement())
106
+ return addMarkToThrow(path, lineNode);
107
+
105
108
  replaceWith(path, BlockStatement([
106
109
  node,
107
110
  ]));
@@ -112,18 +115,25 @@ const EXCLUDE = [
112
115
  `(${LINE}, __z)`,
113
116
  `return (${LINE}, __z)`,
114
117
  `return ${LINE}`,
118
+ `throw (${LINE}, __z)`,
115
119
  ];
116
120
 
117
121
  export const exclude = () => EXCLUDE;
118
122
 
119
123
  export const include = () => [
120
- 'AssignmentPattern',
121
124
  'CallExpression',
122
125
  'NewExpression',
123
126
  'ReturnStatement',
127
+ 'ThrowStatement',
124
128
  ];
125
129
 
126
130
  export const traverse = ({push}) => ({
131
+ 'AssignmentPattern|AssignmentExpression'(path) {
132
+ if (compareAny(path.get('right'), EXCLUDE))
133
+ return;
134
+
135
+ push(path);
136
+ },
127
137
  ArrowFunctionExpression(path) {
128
138
  if (path.get('body').isBlockStatement())
129
139
  return;
@@ -156,7 +166,7 @@ export const traverse = ({push}) => ({
156
166
  const consequentPath = path.get('consequent');
157
167
  const alternatePath = path.get('alternate');
158
168
 
159
- if (!consequentPath.isBlockStatement())
169
+ if (!consequentPath.isBlockStatement() && !compareAny(consequentPath, EXCLUDE))
160
170
  push(consequentPath);
161
171
 
162
172
  if (!alternatePath.node)
@@ -0,0 +1,17 @@
1
+ import {
2
+ types,
3
+ operator,
4
+ } from 'putout';
5
+ const {SequenceExpression} = types;
6
+
7
+ const {replaceWith} = operator;
8
+
9
+ export const addMarkToThrow = (path, lineNode) => {
10
+ const argumentPath = path.get('argument');
11
+
12
+ return replaceWith(argumentPath, SequenceExpression([
13
+ lineNode.expression,
14
+ argumentPath.node,
15
+ ]));
16
+ };
17
+
package/lib/merge.js ADDED
@@ -0,0 +1,44 @@
1
+ const {entries} = Object;
2
+
3
+ export const merge = (files) => {
4
+ const deduplicator = {};
5
+
6
+ for (const {rawName, rawLines} of files) {
7
+ const name = cutQuery(rawName);
8
+ const lines = applyCoverage({
9
+ name,
10
+ rawLines,
11
+ deduplicator,
12
+ });
13
+
14
+ deduplicator[name] = lines;
15
+ }
16
+
17
+ const list = [];
18
+ for (const [name, lines] of entries(deduplicator)) {
19
+ list.push({
20
+ name,
21
+ lines,
22
+ });
23
+ }
24
+
25
+ return list;
26
+ };
27
+
28
+ function applyCoverage({rawLines, name, deduplicator}) {
29
+ if (!deduplicator[name])
30
+ return rawLines;
31
+
32
+ const newLines = {};
33
+
34
+ for (const [line, value] of entries(rawLines))
35
+ newLines[line] = deduplicator[name][line] || value;
36
+
37
+ return newLines;
38
+ }
39
+
40
+ function cutQuery(name) {
41
+ return name
42
+ .replace('file://', '')
43
+ .replace(/\?.*/, '');
44
+ }
package/lib/parse.js ADDED
@@ -0,0 +1,20 @@
1
+ export const parse = (files) => {
2
+ const result = [];
3
+
4
+ for (const [rawName, places] of files.entries()) {
5
+ const rawLines = {};
6
+
7
+ for (const [place, covered] of places.entries()) {
8
+ const [line] = place.split(':');
9
+
10
+ rawLines[line] = covered;
11
+ }
12
+
13
+ result.push({
14
+ rawName,
15
+ rawLines,
16
+ });
17
+ }
18
+
19
+ return result;
20
+ };
package/lib/report.js CHANGED
@@ -2,24 +2,25 @@ import chalk from 'chalk';
2
2
  import {readFileSync} from 'fs';
3
3
 
4
4
  const {parse} = JSON;
5
+ const {entries} = Object;
5
6
 
6
7
  export const report = () => {
7
8
  const coverageFile = parse(readFileSync('./coverage.json', 'utf8'));
8
-
9
+
9
10
  const files = [];
10
11
  const coverage = {
11
12
  files,
12
13
  coveredCount: 0,
13
14
  uncoveredCount: 0,
14
15
  };
15
-
16
- console.log('# TAP version 13');
16
+
17
+ console.log('# CAP version 13');
17
18
  console.log('');
18
-
19
+
19
20
  for (const {name, lines} of coverageFile) {
20
21
  const uncoveredLines = [];
21
22
 
22
- for (const [line, covered] of Object.entries(lines)) {
23
+ for (const [line, covered] of entries(lines)) {
23
24
  if (covered)
24
25
  continue;
25
26
 
@@ -40,30 +41,34 @@ export const report = () => {
40
41
 
41
42
  files.push(file);
42
43
  }
43
-
44
+
44
45
  for (const {name, covered, uncoveredLines} of files) {
45
46
  if (!covered) {
46
47
  console.log(`# ${name}`);
47
- console.log(' should be covered');
48
+ console.log('🧨 should be covered');
48
49
  console.log('---');
49
- console.log(`lines: ${chalk.red(uncoveredLines.join(','))}`);
50
+ console.log(`lines:`);
51
+ for (const line of uncoveredLines) {
52
+ console.log(`️- ${chalk.red(line)} at file://${name}:${line}`);
53
+ }
54
+ console.log('');
50
55
  }
51
56
  }
52
-
53
- if (coverage.uncoveredCount)
54
- console.log('');
55
-
57
+
56
58
  console.log(`1..${files.length}`);
57
59
  console.log(`# files: ${files.length}`);
58
60
  console.log(`# covered: ${coverage.coveredCount}`);
59
-
61
+
62
+ console.log('');
63
+
60
64
  if (!coverage.uncoveredCount) {
61
- console.log('');
62
65
  console.log('# ☘️ ok');
63
66
  }
64
-
67
+
65
68
  if (coverage.uncoveredCount) {
66
69
  console.log(`# 🧨 fail: ${coverage.uncoveredCount}`);
67
70
  }
68
- }
71
+
72
+ console.log('');
73
+ };
69
74
 
package/lib/save.js CHANGED
@@ -1,26 +1,14 @@
1
1
  import {writeFileSync} from 'fs';
2
2
  import {getFiles} from './c4.js';
3
+ import {parse} from './parse.js';
4
+ import {merge} from './merge.js';
3
5
 
4
6
  const {stringify} = JSON;
5
7
 
6
8
  export const save = () => {
7
9
  const files = getFiles();
8
- const report = [];
9
- for (const [name, places] of files.entries()) {
10
- const lines = {};
11
- const current = {
12
- name,
13
- lines,
14
- };
15
- for (const [place, covered] of places.entries()) {
16
- const [line] = place.split(':');
17
-
18
- lines[line] = covered;
19
- }
20
-
21
- report.push(current);
22
- }
10
+ const parsed = parse(files);
11
+ const merged = merge(parsed);
23
12
 
24
- writeFileSync('./coverage.json', stringify(report, null, 4));
13
+ writeFileSync('./coverage.json', stringify(merged, null, 4));
25
14
  };
26
-
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "escover",
3
- "version": "1.0.1",
3
+ "version": "1.0.5",
4
4
  "author": "coderaiser <mnemonic.enemy@gmail.com> (https://github.com/coderaiser)",
5
5
  "description": "Coverage for EcmaScript Modules",
6
6
  "main": "lib/escover.js",
@@ -15,7 +15,9 @@
15
15
  "loader"
16
16
  ],
17
17
  "scripts": {
18
+ "loader": "madrun loader",
18
19
  "test": "madrun test",
20
+ "test:only": "madrun test:only",
19
21
  "coverage": "madrun coverage",
20
22
  "lint": "madrun lint",
21
23
  "fresh:lint": "madrun fresh:lint",
package/coverage.json DELETED
@@ -1,9 +0,0 @@
1
- [
2
- {
3
- "name": "file:///Users/coderaiser/escover/example/example.js",
4
- "lines": {
5
- "1": true,
6
- "3": false
7
- }
8
- }
9
- ]
@@ -1,3 +0,0 @@
1
- if ((__c4.mark(1, 4), a) || (__c4.mark(1, 9), b)) {
2
- __c4.mark(1, 12);
3
- }
@@ -1,30 +0,0 @@
1
- const a = () => {
2
- a = 5;
3
- __c4.mark(3, 4), console.log(5);
4
- };
5
-
6
-
7
- function x() {
8
-
9
- if (a > 2) {
10
- __c4.mark(9, 14), a();
11
- } else {
12
- __c4.mark(10, 9), b();
13
- }
14
- }
15
-
16
- for (const x of y) {
17
- __c4.mark(13, 19);
18
- }
19
-
20
- const ax = ((__c4.mark(16, 12), a()), (__c4.mark(16, 17), b()));
21
- const bx = (c, (__c4.mark(17, 15), d()));
22
-
23
- if ((__c4.mark(19, 4), a) || (__c4.mark(19, 9), b)) {
24
- __c4.mark(19, 12);
25
- }
26
-
27
-
28
- function x1(a, b = (__c4.mark(23, 15), b)) {
29
- __c4.mark(23, 22);
30
- }
@@ -1 +0,0 @@
1
- const files = (__c4.mark(1, 14), new Map());
@@ -1,8 +0,0 @@
1
- __c4.mark(1, 0), cli({
2
- stdout,
3
- stderr,
4
- exit,
5
- cwd: (__c4.mark(5, 9), process.cwd()),
6
- argv: (__c4.mark(6, 10), process.argv.slice(2))
7
- });
8
-