UNPKG

2.82 kBJavaScriptView Raw
1var path = require('path');
2var yaml = require('js-yaml');
3
4module.exports.getDiag = function (body) {
5 var yamlStart = body.indexOf(' ---');
6 var yamlEnd = body.indexOf(' ...\n');
7 var diag = body.slice(yamlStart, yamlEnd).split('\n').map(function (line) {
8 return line.slice(2);
9 }).join('\n');
10
11 // The stack trace and at variable will vary depending on where the code
12 // is run, so just strip it out.
13 var withStack = yaml.safeLoad(diag);
14 delete withStack.stack;
15 delete withStack.at;
16 return withStack;
17};
18
19// There are three challenges associated with checking the stack traces included
20// in errors:
21// 1) The base checkout directory of tape might change. Because stack traces
22// include absolute paths, the stack traces will change depending on the
23// checkout path. We handle this by replacing the base test directory with a
24// placeholder $TEST variable and the package root with a placehodler
25// $TAPE variable.
26// 2) Line positions within the file might change. We handle this by replacing
27// line and column markers with placeholder $LINE and $COL "variables"
28// a) node 0.8 does not provide nested eval line numbers, so we remove them
29// 3) Stacks themselves change frequently with refactoring. We've even run into
30// issues with node library refactorings "breaking" stack traces. Most of
31// these changes are irrelevant to the tests themselves. To counter this, we
32// strip out all stack frames that aren't directly under our test directory,
33// and replace them with placeholders.
34
35var stripChangingData = function (line) {
36 var withoutTestDir = line.replace(__dirname, '$TEST');
37 var withoutPackageDir = withoutTestDir.replace(path.dirname(__dirname), '$TAPE');
38 var withoutPathSep = withoutPackageDir.replace(new RegExp('\\' + path.sep, 'g'), '/');
39 var withoutLineNumbers = withoutPathSep.replace(/:\d+:\d+/g, ':$LINE:$COL');
40 var withoutNestedLineNumbers = withoutLineNumbers.replace(/, \<anonymous\>:\$LINE:\$COL\)$/, ')');
41 return withoutNestedLineNumbers;
42};
43
44module.exports.stripFullStack = function (output) {
45 var stripped = ' [... stack stripped ...]';
46 var withDuplicates = output.split('\n').map(stripChangingData).map(function (line) {
47 var m = line.match(/[ ]{8}at .*\((.*)\)/);
48
49 if (m && m[1].slice(0, 5) !== '$TEST') {
50 return stripped;
51 }
52 return line;
53 });
54
55 var deduped = withDuplicates.filter(function (line, ix) {
56 var hasPrior = line === stripped && withDuplicates[ix - 1] === stripped;
57 return !hasPrior;
58 });
59
60 return deduped.join('\n').replace(
61 // Handle stack trace variation in Node v0.8
62 /at(:?) Test\.(?:module\.exports|tap\.test\.err\.code)/g,
63 'at$1 Test.<anonymous>'
64 );
65};