@tapjs/processinfo 3.1.5 → 3.1.6

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.
@@ -0,0 +1,3 @@
1
+ export declare const canonicalSource: (s: string) => string;
2
+ export declare const canonicalPath: (s: string) => string;
3
+ //# sourceMappingURL=canonical-source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canonical-source.d.ts","sourceRoot":"","sources":["../../src/canonical-source.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,eAAe,MAAO,MAAM,KAAG,MAY3C,CAAA;AAED,eAAO,MAAM,aAAa,MAAO,MAAM,KAAG,MAUzC,CAAA"}
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ // The sources reported in sourcemaps can be fickle,
3
+ // and istanbul's reporting doesn't handle it so well.
4
+ // So, we canonicalize all entries in sources to a file://
5
+ // url with consistent capitalization.
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.canonicalPath = exports.canonicalSource = void 0;
8
+ const path_1 = require("path");
9
+ const url_1 = require("url");
10
+ const cwd = process.cwd();
11
+ const canonicalSource = (s) => {
12
+ // convert to a path
13
+ if (s.startsWith('file://')) {
14
+ const u = new URL(s);
15
+ const hash = u.hash;
16
+ const search = u.search;
17
+ return String((0, url_1.pathToFileURL)((0, exports.canonicalPath)((0, url_1.fileURLToPath)(s)))) +
18
+ hash + search;
19
+ }
20
+ // re-resolve it relative to the cwd
21
+ // back to a file: url
22
+ return String((0, url_1.pathToFileURL)((0, exports.canonicalPath)(s)));
23
+ };
24
+ exports.canonicalSource = canonicalSource;
25
+ const canonicalPath = (s) => {
26
+ const rel = (0, path_1.relative)(cwd, s);
27
+ s = (0, path_1.resolve)(cwd, rel);
28
+ // capitalize drive letters
29
+ if (/^[a-z]:/.test(s))
30
+ s = s.charAt(0).toUpperCase() + s.substring(1);
31
+ // capitalize UNC paths
32
+ if (s.startsWith('\\\\')) {
33
+ s = s.replace(/\\\\[^\\]+\\[^\\]+\\/, _0 => _0.toUpperCase());
34
+ }
35
+ return s;
36
+ };
37
+ exports.canonicalPath = canonicalPath;
38
+ //# sourceMappingURL=canonical-source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canonical-source.js","sourceRoot":"","sources":["../../src/canonical-source.ts"],"names":[],"mappings":";AAAA,oDAAoD;AACpD,sDAAsD;AACtD,0DAA0D;AAC1D,sCAAsC;;;AAEtC,+BAAwC;AACxC,6BAAkD;AAClD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAA;AAElB,MAAM,eAAe,GAAG,CAAC,CAAS,EAAU,EAAE;IACnD,oBAAoB;IACpB,IAAI,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE;QAC3B,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAA;QACpB,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAA;QACnB,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAA;QACvB,OAAO,MAAM,CAAC,IAAA,mBAAa,EAAC,IAAA,qBAAa,EAAC,IAAA,mBAAa,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC3D,IAAI,GAAG,MAAM,CAAA;KAChB;IACD,oCAAoC;IACpC,sBAAsB;IACtB,OAAO,MAAM,CAAC,IAAA,mBAAa,EAAC,IAAA,qBAAa,EAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AAChD,CAAC,CAAA;AAZY,QAAA,eAAe,mBAY3B;AAEM,MAAM,aAAa,GAAG,CAAC,CAAS,EAAU,EAAE;IACjD,MAAM,GAAG,GAAG,IAAA,eAAQ,EAAC,GAAG,EAAE,CAAC,CAAC,CAAA;IAC5B,CAAC,GAAG,IAAA,cAAO,EAAC,GAAG,EAAE,GAAG,CAAC,CAAA;IACrB,2BAA2B;IAC3B,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAA;IACrE,uBAAuB;IACvB,IAAI,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE;QACxB,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,sBAAsB,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,CAAA;KAC9D;IACD,OAAO,CAAC,CAAA;AACV,CAAC,CAAA;AAVY,QAAA,aAAa,iBAUzB","sourcesContent":["// The sources reported in sourcemaps can be fickle,\n// and istanbul's reporting doesn't handle it so well.\n// So, we canonicalize all entries in sources to a file://\n// url with consistent capitalization.\n\nimport { relative, resolve } from 'path'\nimport { fileURLToPath, pathToFileURL } from 'url'\nconst cwd = process.cwd()\n\nexport const canonicalSource = (s: string): string => {\n // convert to a path\n if (s.startsWith('file://')) {\n const u = new URL(s)\n const hash = u.hash\n const search = u.search\n return String(pathToFileURL(canonicalPath(fileURLToPath(s)))) +\n hash + search\n }\n // re-resolve it relative to the cwd\n // back to a file: url\n return String(pathToFileURL(canonicalPath(s)))\n}\n\nexport const canonicalPath = (s: string): string => {\n const rel = relative(cwd, s)\n s = resolve(cwd, rel)\n // capitalize drive letters\n if (/^[a-z]:/.test(s)) s = s.charAt(0).toUpperCase() + s.substring(1)\n // capitalize UNC paths\n if (s.startsWith('\\\\\\\\')) {\n s = s.replace(/\\\\\\\\[^\\\\]+\\\\[^\\\\]+\\\\/, _0 => _0.toUpperCase())\n }\n return s\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"register-coverage.d.ts","sourceRoot":"","sources":["../../src/register-coverage.ts"],"names":[],"mappings":";AAKA,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAA;AAQxC,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAA;AAE5D,eAAO,IAAI,OAAO,EAAE,OAAO,GAAG,SAAqB,CAAA;AA6DnD,eAAO,MAAM,QAAQ,YAYpB,CAAA;AAGD,eAAO,MAAM,oBAAoB,QAC1B,MAAM,eACE,mBAAmB,SAmEjC,CAAA"}
1
+ {"version":3,"file":"register-coverage.d.ts","sourceRoot":"","sources":["../../src/register-coverage.ts"],"names":[],"mappings":";AAKA,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAA;AASxC,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAA;AAE5D,eAAO,IAAI,OAAO,EAAE,OAAO,GAAG,SAAqB,CAAA;AA+DnD,eAAO,MAAM,QAAQ,YAYpB,CAAA;AAGD,eAAO,MAAM,oBAAoB,QAC1B,MAAM,eACE,mBAAmB,SAuEjC,CAAA"}
@@ -9,6 +9,7 @@ const node_fs_1 = require("node:fs");
9
9
  const node_inspector_1 = require("node:inspector");
10
10
  const node_path_1 = require("node:path");
11
11
  const node_url_1 = require("node:url");
12
+ const canonical_source_js_1 = require("./canonical-source.js");
12
13
  const find_source_map_safe_js_1 = require("./find-source-map-safe.js");
13
14
  const get_exclude_js_1 = require("./get-exclude.js");
14
15
  const line_lengths_js_1 = require("./line-lengths.js");
@@ -33,15 +34,16 @@ const uncoveredFiles = cxEnv
33
34
  .filter(f => !!f);
34
35
  const exclude = p.env._TAPJS_PROCESSINFO_COV_EXCLUDE_
35
36
  ? (0, get_exclude_js_1.getExclude)('_TAPJS_PROCESSINFO_COV_EXCLUDE_', false)
36
- : undefined;
37
+ : /[\\\/]node_modules[\\\/]/;
37
38
  const fileCovered = (f, sources = [], files = []) => {
38
39
  const testFiles = [f];
39
40
  for (const src of sources || []) {
40
41
  testFiles.push((0, node_path_1.resolve)(src.startsWith('file://') ? (0, node_url_1.fileURLToPath)(src) : src));
41
42
  }
42
43
  // never include coverage if the file is fully ignored.
43
- if (!testFiles.some(f => files.includes(f)))
44
+ if (!testFiles.some(f => files.includes(f))) {
44
45
  return false;
46
+ }
45
47
  // if at least one of them are explicitly covered, then include it,
46
48
  // otherwise omit if we explicitly listed
47
49
  if (coveredFiles.length) {
@@ -102,6 +104,7 @@ const coverageOnProcessEnd = (cwd, processInfo) => {
102
104
  if (!/^file:/.test(obj.url)) {
103
105
  return false;
104
106
  }
107
+ obj.url = (0, canonical_source_js_1.canonicalSource)(obj.url);
105
108
  const f = (0, node_url_1.fileURLToPath)(obj.url);
106
109
  // see if it has a source map
107
110
  // need to look up via the url, not the file path, because mocks
@@ -122,7 +125,10 @@ const coverageOnProcessEnd = (cwd, processInfo) => {
122
125
  //@ts-ignore
123
126
  lineLengths: s?.lineLengths || (0, line_lengths_js_1.getLineLengths)(f),
124
127
  /* c8 ignore stop */
125
- data: payload,
128
+ data: {
129
+ ...payload,
130
+ sources: payload.sources?.map(s => (0, canonical_source_js_1.canonicalSource)(s)),
131
+ },
126
132
  });
127
133
  }
128
134
  return true;
@@ -1 +1 @@
1
- {"version":3,"file":"register-coverage.js","sourceRoot":"","sources":["../../src/register-coverage.ts"],"names":[],"mappings":"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","sourcesContent":["// start tracking coverage, unless disabled explicltly\n// export so that we know to collect at the end of the process\nconst p = process\nconst enabled = p.env._TAPJS_PROCESSINFO_COVERAGE_ !== '0'\nimport { mkdirSync, writeFileSync } from 'node:fs'\nimport { Session } from 'node:inspector'\nimport { SourceMapPayload } from 'node:module'\nimport { resolve } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { findSourceMapSafe } from './find-source-map-safe.js'\nimport { getExclude } from './get-exclude.js'\nimport { getLineLengths } from './line-lengths.js'\nimport { lookupSources } from './lookup-sources.js'\nimport { ProcessInfoNodeData } from './process-info-node.js'\n\nexport let SESSION: Session | undefined = undefined\n\n// This is a \\n delimited list of files to show coverage for\n// If not set, or empty, then coverage is included for all files\n// that pass the exclusion RegExp filter. If included in this list,\n// then coverage will be recorded, even if it matches exclude.\nconst cfEnv = p.env._TAPJS_PROCESSINFO_COV_FILES_ || ''\nconst coveredFiles: string[] = cfEnv\n .trim()\n .split('\\n')\n .filter(f => !!f)\n\n// NB: coverage exclusion is in addition to processinfo\n// exclusion. Only show coverage for a file we care\n// about at least somewhat, but coverage is a subset.\nconst cxEnv = p.env._TAPJS_PROCESSINFO_COV_EXCLUDE_FILES_ || ''\nconst uncoveredFiles: string[] = cxEnv\n .trim()\n .split('\\n')\n .filter(f => !!f)\n\nconst exclude = p.env._TAPJS_PROCESSINFO_COV_EXCLUDE_\n ? getExclude('_TAPJS_PROCESSINFO_COV_EXCLUDE_', false)\n : undefined\n\nconst fileCovered = (\n f: string,\n sources: string[] = [],\n files: string[] = []\n) => {\n const testFiles = [f]\n for (const src of sources || []) {\n testFiles.push(\n resolve(src.startsWith('file://') ? fileURLToPath(src) : src)\n )\n }\n\n // never include coverage if the file is fully ignored.\n if (!testFiles.some(f => files.includes(f))) return false\n\n // if at least one of them are explicitly covered, then include it,\n // otherwise omit if we explicitly listed\n if (coveredFiles.length) {\n return testFiles.some(f => coveredFiles.includes(f))\n }\n\n // if any of the filenames are explicitly excluded, no coverage\n // otherwise, it is covered\n return !testFiles.some(\n f => uncoveredFiles.includes(f) || exclude?.test(f)\n )\n}\n\n// C8 can't see that this function runs, best theory is that it\n// collides with what it's doing with the coverage it's collecting\n// This ignore can possibly be removed once this is being tested\n// with a version of tap that uses this library, but it might just\n// be an unresolveable bootstrap problem.\n// The test does verify that it ran, because otherwise, there would\n// be no coverage, and it verifies that it gets the expected coverage.\n/* c8 ignore start */\nexport const register = () => {\n if (!enabled) return\n p.env._TAPJS_PROCESSINFO_COVERAGE_ = '1'\n\n SESSION = new Session()\n SESSION.connect()\n SESSION.post('Profiler.enable')\n SESSION.post('Runtime.enable')\n SESSION.post('Profiler.startPreciseCoverage', {\n callCount: true,\n detailed: true,\n })\n}\n/* c8 ignore stop */\n\nexport const coverageOnProcessEnd = (\n cwd: string,\n processInfo: ProcessInfoNodeData\n) => {\n // Similar to the coverage tracking bootstrap problem above, c8\n // doesn't see that this function runs, even though it DOES see\n // that the function defined below runs, which is weird.\n /* c8 ignore start */\n if (!SESSION) return\n const session = SESSION\n\n const f = `${cwd}/.tap/coverage/${processInfo.uuid}.json`\n mkdirSync(`${cwd}/.tap/coverage`, { recursive: true })\n\n session.post('Profiler.takePreciseCoverage', (er, cov) => {\n session.post('Profiler.stopPreciseCoverage')\n /* c8 ignore stop */\n\n // something very strange and bad happened\n /* c8 ignore start */\n if (er) {\n throw er\n }\n /* c8 ignore stop */\n\n // Create a source-map-cache that c8 uses in report generation\n const sourceMapCache: {\n [k: string]: {\n lineLengths: number[]\n data: SourceMapPayload\n }\n } = {}\n Object.assign(cov, {\n 'source-map-cache': sourceMapCache,\n })\n\n cov.result = cov.result.filter(obj => {\n if (!/^file:/.test(obj.url)) {\n return false\n }\n const f = fileURLToPath(obj.url)\n // see if it has a source map\n // need to look up via the url, not the file path, because mocks\n // attach a tapmock search param, which is in node's internal key.\n const sources = lookupSources(obj.url, true)\n if (!fileCovered(f, sources, processInfo.files)) {\n return false\n }\n // Most of the time this will be cached at the time of recording, but\n // if it's the last module loaded, or transpiled in-place by ts-node,\n // the sourcemap won't be pre-loaded and will have to be looked up.\n const s = findSourceMapSafe(obj.url)\n const { payload } = s || { payload: null }\n if (payload) {\n sourceMapCache[obj.url] = Object.assign(Object.create(null), {\n /* c8 ignore start */\n // node's SourceMap objects provide this as of 20.5.0\n //@ts-ignore\n lineLengths: s?.lineLengths || getLineLengths(f),\n /* c8 ignore stop */\n data: payload,\n })\n }\n return true\n })\n\n writeFileSync(f, JSON.stringify(cov, null, 2) + '\\n', 'utf8')\n /* c8 ignore start */\n })\n}\n/* c8 ignore stop */\n"]}
1
+ {"version":3,"file":"register-coverage.js","sourceRoot":"","sources":["../../src/register-coverage.ts"],"names":[],"mappings":"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","sourcesContent":["// start tracking coverage, unless disabled explicltly\n// export so that we know to collect at the end of the process\nconst p = process\nconst enabled = p.env._TAPJS_PROCESSINFO_COVERAGE_ !== '0'\nimport { mkdirSync, writeFileSync } from 'node:fs'\nimport { Session } from 'node:inspector'\nimport { SourceMapPayload } from 'node:module'\nimport { resolve } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { canonicalSource } from './canonical-source.js'\nimport { findSourceMapSafe } from './find-source-map-safe.js'\nimport { getExclude } from './get-exclude.js'\nimport { getLineLengths } from './line-lengths.js'\nimport { lookupSources } from './lookup-sources.js'\nimport { ProcessInfoNodeData } from './process-info-node.js'\n\nexport let SESSION: Session | undefined = undefined\n\n// This is a \\n delimited list of files to show coverage for\n// If not set, or empty, then coverage is included for all files\n// that pass the exclusion RegExp filter. If included in this list,\n// then coverage will be recorded, even if it matches exclude.\nconst cfEnv = p.env._TAPJS_PROCESSINFO_COV_FILES_ || ''\nconst coveredFiles: string[] = cfEnv\n .trim()\n .split('\\n')\n .filter(f => !!f)\n\n// NB: coverage exclusion is in addition to processinfo\n// exclusion. Only show coverage for a file we care\n// about at least somewhat, but coverage is a subset.\nconst cxEnv = p.env._TAPJS_PROCESSINFO_COV_EXCLUDE_FILES_ || ''\nconst uncoveredFiles: string[] = cxEnv\n .trim()\n .split('\\n')\n .filter(f => !!f)\n\nconst exclude = p.env._TAPJS_PROCESSINFO_COV_EXCLUDE_\n ? getExclude('_TAPJS_PROCESSINFO_COV_EXCLUDE_', false)\n : /[\\\\\\/]node_modules[\\\\\\/]/\n\nconst fileCovered = (\n f: string,\n sources: string[] = [],\n files: string[] = []\n) => {\n const testFiles = [f]\n for (const src of sources || []) {\n testFiles.push(\n resolve(src.startsWith('file://') ? fileURLToPath(src) : src)\n )\n }\n\n // never include coverage if the file is fully ignored.\n if (!testFiles.some(f => files.includes(f))) {\n return false\n }\n\n // if at least one of them are explicitly covered, then include it,\n // otherwise omit if we explicitly listed\n if (coveredFiles.length) {\n return testFiles.some(f => coveredFiles.includes(f))\n }\n\n // if any of the filenames are explicitly excluded, no coverage\n // otherwise, it is covered\n return !testFiles.some(\n f => uncoveredFiles.includes(f) || exclude?.test(f)\n )\n}\n\n// C8 can't see that this function runs, best theory is that it\n// collides with what it's doing with the coverage it's collecting\n// This ignore can possibly be removed once this is being tested\n// with a version of tap that uses this library, but it might just\n// be an unresolveable bootstrap problem.\n// The test does verify that it ran, because otherwise, there would\n// be no coverage, and it verifies that it gets the expected coverage.\n/* c8 ignore start */\nexport const register = () => {\n if (!enabled) return\n p.env._TAPJS_PROCESSINFO_COVERAGE_ = '1'\n\n SESSION = new Session()\n SESSION.connect()\n SESSION.post('Profiler.enable')\n SESSION.post('Runtime.enable')\n SESSION.post('Profiler.startPreciseCoverage', {\n callCount: true,\n detailed: true,\n })\n}\n/* c8 ignore stop */\n\nexport const coverageOnProcessEnd = (\n cwd: string,\n processInfo: ProcessInfoNodeData\n) => {\n // Similar to the coverage tracking bootstrap problem above, c8\n // doesn't see that this function runs, even though it DOES see\n // that the function defined below runs, which is weird.\n /* c8 ignore start */\n if (!SESSION) return\n const session = SESSION\n\n const f = `${cwd}/.tap/coverage/${processInfo.uuid}.json`\n mkdirSync(`${cwd}/.tap/coverage`, { recursive: true })\n\n session.post('Profiler.takePreciseCoverage', (er, cov) => {\n session.post('Profiler.stopPreciseCoverage')\n /* c8 ignore stop */\n\n // something very strange and bad happened\n /* c8 ignore start */\n if (er) {\n throw er\n }\n /* c8 ignore stop */\n\n // Create a source-map-cache that c8 uses in report generation\n const sourceMapCache: {\n [k: string]: {\n lineLengths: number[]\n data: SourceMapPayload\n }\n } = {}\n Object.assign(cov, {\n 'source-map-cache': sourceMapCache,\n })\n\n cov.result = cov.result.filter(obj => {\n if (!/^file:/.test(obj.url)) {\n return false\n }\n obj.url = canonicalSource(obj.url)\n const f = fileURLToPath(obj.url)\n // see if it has a source map\n // need to look up via the url, not the file path, because mocks\n // attach a tapmock search param, which is in node's internal key.\n const sources = lookupSources(obj.url, true)\n if (!fileCovered(f, sources, processInfo.files)) {\n return false\n }\n // Most of the time this will be cached at the time of recording, but\n // if it's the last module loaded, or transpiled in-place by ts-node,\n // the sourcemap won't be pre-loaded and will have to be looked up.\n const s = findSourceMapSafe(obj.url)\n const { payload } = s || { payload: null }\n if (payload) {\n sourceMapCache[obj.url] = Object.assign(Object.create(null), {\n /* c8 ignore start */\n // node's SourceMap objects provide this as of 20.5.0\n //@ts-ignore\n lineLengths: s?.lineLengths || getLineLengths(f),\n /* c8 ignore stop */\n data: {\n ...payload,\n sources: payload.sources?.map(s => canonicalSource(s)),\n },\n })\n }\n return true\n })\n\n writeFileSync(f, JSON.stringify(cov, null, 2) + '\\n', 'utf8')\n /* c8 ignore start */\n })\n}\n/* c8 ignore stop */\n"]}
@@ -0,0 +1,3 @@
1
+ export declare const canonicalSource: (s: string) => string;
2
+ export declare const canonicalPath: (s: string) => string;
3
+ //# sourceMappingURL=canonical-source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canonical-source.d.ts","sourceRoot":"","sources":["../../src/canonical-source.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,eAAe,MAAO,MAAM,KAAG,MAY3C,CAAA;AAED,eAAO,MAAM,aAAa,MAAO,MAAM,KAAG,MAUzC,CAAA"}
@@ -0,0 +1,33 @@
1
+ // The sources reported in sourcemaps can be fickle,
2
+ // and istanbul's reporting doesn't handle it so well.
3
+ // So, we canonicalize all entries in sources to a file://
4
+ // url with consistent capitalization.
5
+ import { relative, resolve } from 'path';
6
+ import { fileURLToPath, pathToFileURL } from 'url';
7
+ const cwd = process.cwd();
8
+ export const canonicalSource = (s) => {
9
+ // convert to a path
10
+ if (s.startsWith('file://')) {
11
+ const u = new URL(s);
12
+ const hash = u.hash;
13
+ const search = u.search;
14
+ return String(pathToFileURL(canonicalPath(fileURLToPath(s)))) +
15
+ hash + search;
16
+ }
17
+ // re-resolve it relative to the cwd
18
+ // back to a file: url
19
+ return String(pathToFileURL(canonicalPath(s)));
20
+ };
21
+ export const canonicalPath = (s) => {
22
+ const rel = relative(cwd, s);
23
+ s = resolve(cwd, rel);
24
+ // capitalize drive letters
25
+ if (/^[a-z]:/.test(s))
26
+ s = s.charAt(0).toUpperCase() + s.substring(1);
27
+ // capitalize UNC paths
28
+ if (s.startsWith('\\\\')) {
29
+ s = s.replace(/\\\\[^\\]+\\[^\\]+\\/, _0 => _0.toUpperCase());
30
+ }
31
+ return s;
32
+ };
33
+ //# sourceMappingURL=canonical-source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canonical-source.js","sourceRoot":"","sources":["../../src/canonical-source.ts"],"names":[],"mappings":"AAAA,oDAAoD;AACpD,sDAAsD;AACtD,0DAA0D;AAC1D,sCAAsC;AAEtC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AACxC,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,KAAK,CAAA;AAClD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAA;AAEzB,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAS,EAAU,EAAE;IACnD,oBAAoB;IACpB,IAAI,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE;QAC3B,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAA;QACpB,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAA;QACnB,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAA;QACvB,OAAO,MAAM,CAAC,aAAa,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC3D,IAAI,GAAG,MAAM,CAAA;KAChB;IACD,oCAAoC;IACpC,sBAAsB;IACtB,OAAO,MAAM,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AAChD,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAS,EAAU,EAAE;IACjD,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;IAC5B,CAAC,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;IACrB,2BAA2B;IAC3B,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAA;IACrE,uBAAuB;IACvB,IAAI,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE;QACxB,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,sBAAsB,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,CAAA;KAC9D;IACD,OAAO,CAAC,CAAA;AACV,CAAC,CAAA","sourcesContent":["// The sources reported in sourcemaps can be fickle,\n// and istanbul's reporting doesn't handle it so well.\n// So, we canonicalize all entries in sources to a file://\n// url with consistent capitalization.\n\nimport { relative, resolve } from 'path'\nimport { fileURLToPath, pathToFileURL } from 'url'\nconst cwd = process.cwd()\n\nexport const canonicalSource = (s: string): string => {\n // convert to a path\n if (s.startsWith('file://')) {\n const u = new URL(s)\n const hash = u.hash\n const search = u.search\n return String(pathToFileURL(canonicalPath(fileURLToPath(s)))) +\n hash + search\n }\n // re-resolve it relative to the cwd\n // back to a file: url\n return String(pathToFileURL(canonicalPath(s)))\n}\n\nexport const canonicalPath = (s: string): string => {\n const rel = relative(cwd, s)\n s = resolve(cwd, rel)\n // capitalize drive letters\n if (/^[a-z]:/.test(s)) s = s.charAt(0).toUpperCase() + s.substring(1)\n // capitalize UNC paths\n if (s.startsWith('\\\\\\\\')) {\n s = s.replace(/\\\\\\\\[^\\\\]+\\\\[^\\\\]+\\\\/, _0 => _0.toUpperCase())\n }\n return s\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"register-coverage.d.ts","sourceRoot":"","sources":["../../src/register-coverage.ts"],"names":[],"mappings":";AAKA,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAA;AAQxC,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAA;AAE5D,eAAO,IAAI,OAAO,EAAE,OAAO,GAAG,SAAqB,CAAA;AA6DnD,eAAO,MAAM,QAAQ,YAYpB,CAAA;AAGD,eAAO,MAAM,oBAAoB,QAC1B,MAAM,eACE,mBAAmB,SAmEjC,CAAA"}
1
+ {"version":3,"file":"register-coverage.d.ts","sourceRoot":"","sources":["../../src/register-coverage.ts"],"names":[],"mappings":";AAKA,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAA;AASxC,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAA;AAE5D,eAAO,IAAI,OAAO,EAAE,OAAO,GAAG,SAAqB,CAAA;AA+DnD,eAAO,MAAM,QAAQ,YAYpB,CAAA;AAGD,eAAO,MAAM,oBAAoB,QAC1B,MAAM,eACE,mBAAmB,SAuEjC,CAAA"}
@@ -6,6 +6,7 @@ import { mkdirSync, writeFileSync } from 'node:fs';
6
6
  import { Session } from 'node:inspector';
7
7
  import { resolve } from 'node:path';
8
8
  import { fileURLToPath } from 'node:url';
9
+ import { canonicalSource } from './canonical-source.js';
9
10
  import { findSourceMapSafe } from './find-source-map-safe.js';
10
11
  import { getExclude } from './get-exclude.js';
11
12
  import { getLineLengths } from './line-lengths.js';
@@ -30,15 +31,16 @@ const uncoveredFiles = cxEnv
30
31
  .filter(f => !!f);
31
32
  const exclude = p.env._TAPJS_PROCESSINFO_COV_EXCLUDE_
32
33
  ? getExclude('_TAPJS_PROCESSINFO_COV_EXCLUDE_', false)
33
- : undefined;
34
+ : /[\\\/]node_modules[\\\/]/;
34
35
  const fileCovered = (f, sources = [], files = []) => {
35
36
  const testFiles = [f];
36
37
  for (const src of sources || []) {
37
38
  testFiles.push(resolve(src.startsWith('file://') ? fileURLToPath(src) : src));
38
39
  }
39
40
  // never include coverage if the file is fully ignored.
40
- if (!testFiles.some(f => files.includes(f)))
41
+ if (!testFiles.some(f => files.includes(f))) {
41
42
  return false;
43
+ }
42
44
  // if at least one of them are explicitly covered, then include it,
43
45
  // otherwise omit if we explicitly listed
44
46
  if (coveredFiles.length) {
@@ -98,6 +100,7 @@ export const coverageOnProcessEnd = (cwd, processInfo) => {
98
100
  if (!/^file:/.test(obj.url)) {
99
101
  return false;
100
102
  }
103
+ obj.url = canonicalSource(obj.url);
101
104
  const f = fileURLToPath(obj.url);
102
105
  // see if it has a source map
103
106
  // need to look up via the url, not the file path, because mocks
@@ -118,7 +121,10 @@ export const coverageOnProcessEnd = (cwd, processInfo) => {
118
121
  //@ts-ignore
119
122
  lineLengths: s?.lineLengths || getLineLengths(f),
120
123
  /* c8 ignore stop */
121
- data: payload,
124
+ data: {
125
+ ...payload,
126
+ sources: payload.sources?.map(s => canonicalSource(s)),
127
+ },
122
128
  });
123
129
  }
124
130
  return true;
@@ -1 +1 @@
1
- {"version":3,"file":"register-coverage.js","sourceRoot":"","sources":["../../src/register-coverage.ts"],"names":[],"mappings":"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","sourcesContent":["// start tracking coverage, unless disabled explicltly\n// export so that we know to collect at the end of the process\nconst p = process\nconst enabled = p.env._TAPJS_PROCESSINFO_COVERAGE_ !== '0'\nimport { mkdirSync, writeFileSync } from 'node:fs'\nimport { Session } from 'node:inspector'\nimport { SourceMapPayload } from 'node:module'\nimport { resolve } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { findSourceMapSafe } from './find-source-map-safe.js'\nimport { getExclude } from './get-exclude.js'\nimport { getLineLengths } from './line-lengths.js'\nimport { lookupSources } from './lookup-sources.js'\nimport { ProcessInfoNodeData } from './process-info-node.js'\n\nexport let SESSION: Session | undefined = undefined\n\n// This is a \\n delimited list of files to show coverage for\n// If not set, or empty, then coverage is included for all files\n// that pass the exclusion RegExp filter. If included in this list,\n// then coverage will be recorded, even if it matches exclude.\nconst cfEnv = p.env._TAPJS_PROCESSINFO_COV_FILES_ || ''\nconst coveredFiles: string[] = cfEnv\n .trim()\n .split('\\n')\n .filter(f => !!f)\n\n// NB: coverage exclusion is in addition to processinfo\n// exclusion. Only show coverage for a file we care\n// about at least somewhat, but coverage is a subset.\nconst cxEnv = p.env._TAPJS_PROCESSINFO_COV_EXCLUDE_FILES_ || ''\nconst uncoveredFiles: string[] = cxEnv\n .trim()\n .split('\\n')\n .filter(f => !!f)\n\nconst exclude = p.env._TAPJS_PROCESSINFO_COV_EXCLUDE_\n ? getExclude('_TAPJS_PROCESSINFO_COV_EXCLUDE_', false)\n : undefined\n\nconst fileCovered = (\n f: string,\n sources: string[] = [],\n files: string[] = []\n) => {\n const testFiles = [f]\n for (const src of sources || []) {\n testFiles.push(\n resolve(src.startsWith('file://') ? fileURLToPath(src) : src)\n )\n }\n\n // never include coverage if the file is fully ignored.\n if (!testFiles.some(f => files.includes(f))) return false\n\n // if at least one of them are explicitly covered, then include it,\n // otherwise omit if we explicitly listed\n if (coveredFiles.length) {\n return testFiles.some(f => coveredFiles.includes(f))\n }\n\n // if any of the filenames are explicitly excluded, no coverage\n // otherwise, it is covered\n return !testFiles.some(\n f => uncoveredFiles.includes(f) || exclude?.test(f)\n )\n}\n\n// C8 can't see that this function runs, best theory is that it\n// collides with what it's doing with the coverage it's collecting\n// This ignore can possibly be removed once this is being tested\n// with a version of tap that uses this library, but it might just\n// be an unresolveable bootstrap problem.\n// The test does verify that it ran, because otherwise, there would\n// be no coverage, and it verifies that it gets the expected coverage.\n/* c8 ignore start */\nexport const register = () => {\n if (!enabled) return\n p.env._TAPJS_PROCESSINFO_COVERAGE_ = '1'\n\n SESSION = new Session()\n SESSION.connect()\n SESSION.post('Profiler.enable')\n SESSION.post('Runtime.enable')\n SESSION.post('Profiler.startPreciseCoverage', {\n callCount: true,\n detailed: true,\n })\n}\n/* c8 ignore stop */\n\nexport const coverageOnProcessEnd = (\n cwd: string,\n processInfo: ProcessInfoNodeData\n) => {\n // Similar to the coverage tracking bootstrap problem above, c8\n // doesn't see that this function runs, even though it DOES see\n // that the function defined below runs, which is weird.\n /* c8 ignore start */\n if (!SESSION) return\n const session = SESSION\n\n const f = `${cwd}/.tap/coverage/${processInfo.uuid}.json`\n mkdirSync(`${cwd}/.tap/coverage`, { recursive: true })\n\n session.post('Profiler.takePreciseCoverage', (er, cov) => {\n session.post('Profiler.stopPreciseCoverage')\n /* c8 ignore stop */\n\n // something very strange and bad happened\n /* c8 ignore start */\n if (er) {\n throw er\n }\n /* c8 ignore stop */\n\n // Create a source-map-cache that c8 uses in report generation\n const sourceMapCache: {\n [k: string]: {\n lineLengths: number[]\n data: SourceMapPayload\n }\n } = {}\n Object.assign(cov, {\n 'source-map-cache': sourceMapCache,\n })\n\n cov.result = cov.result.filter(obj => {\n if (!/^file:/.test(obj.url)) {\n return false\n }\n const f = fileURLToPath(obj.url)\n // see if it has a source map\n // need to look up via the url, not the file path, because mocks\n // attach a tapmock search param, which is in node's internal key.\n const sources = lookupSources(obj.url, true)\n if (!fileCovered(f, sources, processInfo.files)) {\n return false\n }\n // Most of the time this will be cached at the time of recording, but\n // if it's the last module loaded, or transpiled in-place by ts-node,\n // the sourcemap won't be pre-loaded and will have to be looked up.\n const s = findSourceMapSafe(obj.url)\n const { payload } = s || { payload: null }\n if (payload) {\n sourceMapCache[obj.url] = Object.assign(Object.create(null), {\n /* c8 ignore start */\n // node's SourceMap objects provide this as of 20.5.0\n //@ts-ignore\n lineLengths: s?.lineLengths || getLineLengths(f),\n /* c8 ignore stop */\n data: payload,\n })\n }\n return true\n })\n\n writeFileSync(f, JSON.stringify(cov, null, 2) + '\\n', 'utf8')\n /* c8 ignore start */\n })\n}\n/* c8 ignore stop */\n"]}
1
+ {"version":3,"file":"register-coverage.js","sourceRoot":"","sources":["../../src/register-coverage.ts"],"names":[],"mappings":"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","sourcesContent":["// start tracking coverage, unless disabled explicltly\n// export so that we know to collect at the end of the process\nconst p = process\nconst enabled = p.env._TAPJS_PROCESSINFO_COVERAGE_ !== '0'\nimport { mkdirSync, writeFileSync } from 'node:fs'\nimport { Session } from 'node:inspector'\nimport { SourceMapPayload } from 'node:module'\nimport { resolve } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { canonicalSource } from './canonical-source.js'\nimport { findSourceMapSafe } from './find-source-map-safe.js'\nimport { getExclude } from './get-exclude.js'\nimport { getLineLengths } from './line-lengths.js'\nimport { lookupSources } from './lookup-sources.js'\nimport { ProcessInfoNodeData } from './process-info-node.js'\n\nexport let SESSION: Session | undefined = undefined\n\n// This is a \\n delimited list of files to show coverage for\n// If not set, or empty, then coverage is included for all files\n// that pass the exclusion RegExp filter. If included in this list,\n// then coverage will be recorded, even if it matches exclude.\nconst cfEnv = p.env._TAPJS_PROCESSINFO_COV_FILES_ || ''\nconst coveredFiles: string[] = cfEnv\n .trim()\n .split('\\n')\n .filter(f => !!f)\n\n// NB: coverage exclusion is in addition to processinfo\n// exclusion. Only show coverage for a file we care\n// about at least somewhat, but coverage is a subset.\nconst cxEnv = p.env._TAPJS_PROCESSINFO_COV_EXCLUDE_FILES_ || ''\nconst uncoveredFiles: string[] = cxEnv\n .trim()\n .split('\\n')\n .filter(f => !!f)\n\nconst exclude = p.env._TAPJS_PROCESSINFO_COV_EXCLUDE_\n ? getExclude('_TAPJS_PROCESSINFO_COV_EXCLUDE_', false)\n : /[\\\\\\/]node_modules[\\\\\\/]/\n\nconst fileCovered = (\n f: string,\n sources: string[] = [],\n files: string[] = []\n) => {\n const testFiles = [f]\n for (const src of sources || []) {\n testFiles.push(\n resolve(src.startsWith('file://') ? fileURLToPath(src) : src)\n )\n }\n\n // never include coverage if the file is fully ignored.\n if (!testFiles.some(f => files.includes(f))) {\n return false\n }\n\n // if at least one of them are explicitly covered, then include it,\n // otherwise omit if we explicitly listed\n if (coveredFiles.length) {\n return testFiles.some(f => coveredFiles.includes(f))\n }\n\n // if any of the filenames are explicitly excluded, no coverage\n // otherwise, it is covered\n return !testFiles.some(\n f => uncoveredFiles.includes(f) || exclude?.test(f)\n )\n}\n\n// C8 can't see that this function runs, best theory is that it\n// collides with what it's doing with the coverage it's collecting\n// This ignore can possibly be removed once this is being tested\n// with a version of tap that uses this library, but it might just\n// be an unresolveable bootstrap problem.\n// The test does verify that it ran, because otherwise, there would\n// be no coverage, and it verifies that it gets the expected coverage.\n/* c8 ignore start */\nexport const register = () => {\n if (!enabled) return\n p.env._TAPJS_PROCESSINFO_COVERAGE_ = '1'\n\n SESSION = new Session()\n SESSION.connect()\n SESSION.post('Profiler.enable')\n SESSION.post('Runtime.enable')\n SESSION.post('Profiler.startPreciseCoverage', {\n callCount: true,\n detailed: true,\n })\n}\n/* c8 ignore stop */\n\nexport const coverageOnProcessEnd = (\n cwd: string,\n processInfo: ProcessInfoNodeData\n) => {\n // Similar to the coverage tracking bootstrap problem above, c8\n // doesn't see that this function runs, even though it DOES see\n // that the function defined below runs, which is weird.\n /* c8 ignore start */\n if (!SESSION) return\n const session = SESSION\n\n const f = `${cwd}/.tap/coverage/${processInfo.uuid}.json`\n mkdirSync(`${cwd}/.tap/coverage`, { recursive: true })\n\n session.post('Profiler.takePreciseCoverage', (er, cov) => {\n session.post('Profiler.stopPreciseCoverage')\n /* c8 ignore stop */\n\n // something very strange and bad happened\n /* c8 ignore start */\n if (er) {\n throw er\n }\n /* c8 ignore stop */\n\n // Create a source-map-cache that c8 uses in report generation\n const sourceMapCache: {\n [k: string]: {\n lineLengths: number[]\n data: SourceMapPayload\n }\n } = {}\n Object.assign(cov, {\n 'source-map-cache': sourceMapCache,\n })\n\n cov.result = cov.result.filter(obj => {\n if (!/^file:/.test(obj.url)) {\n return false\n }\n obj.url = canonicalSource(obj.url)\n const f = fileURLToPath(obj.url)\n // see if it has a source map\n // need to look up via the url, not the file path, because mocks\n // attach a tapmock search param, which is in node's internal key.\n const sources = lookupSources(obj.url, true)\n if (!fileCovered(f, sources, processInfo.files)) {\n return false\n }\n // Most of the time this will be cached at the time of recording, but\n // if it's the last module loaded, or transpiled in-place by ts-node,\n // the sourcemap won't be pre-loaded and will have to be looked up.\n const s = findSourceMapSafe(obj.url)\n const { payload } = s || { payload: null }\n if (payload) {\n sourceMapCache[obj.url] = Object.assign(Object.create(null), {\n /* c8 ignore start */\n // node's SourceMap objects provide this as of 20.5.0\n //@ts-ignore\n lineLengths: s?.lineLengths || getLineLengths(f),\n /* c8 ignore stop */\n data: {\n ...payload,\n sources: payload.sources?.map(s => canonicalSource(s)),\n },\n })\n }\n return true\n })\n\n writeFileSync(f, JSON.stringify(cov, null, 2) + '\\n', 'utf8')\n /* c8 ignore start */\n })\n}\n/* c8 ignore stop */\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tapjs/processinfo",
3
- "version": "3.1.5",
3
+ "version": "3.1.6",
4
4
  "files": [
5
5
  "dist"
6
6
  ],