Skip to content

Commit 46aed58

Browse files
lanceMylesBorins
authored andcommittedMar 30, 2018
test: make common.mustNotCall show file:linenumber
When a test fails via `common.mustNotCall` it is sometimes hard to determine exactly what was called. This modification stores the caller's file and line number by using the V8 Error API to capture a stack at the time `common.mustNotCall()` is called. In the event of failure, this information is printed. This change also exposes a new function in test/common, `getCallSite()` which accepts a `function` and returns a `String` with the file name and line number for the function. Backport-PR-URL: #19355 PR-URL: #17257 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Gibson Fahnestock <gibfahn@gmail.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Sakthipriyan Vairamani <thechargingvolcano@gmail.com> Reviewed-By: Khaidi Chu <i@2333.moe>
1 parent 969398d commit 46aed58

File tree

3 files changed

+75
-1
lines changed

3 files changed

+75
-1
lines changed
 

‎test/common/README.md

+6
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,12 @@ Path to the 'fixtures' directory.
9494

9595
Returns an instance of all possible `ArrayBufferView`s of the provided Buffer.
9696

97+
### getCallSite(func)
98+
* `func` [&lt;Function>]
99+
* return [&lt;String>]
100+
101+
Returns the file name and line number for the provided Function.
102+
97103
### globalCheck
98104
* [&lt;Boolean>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type)
99105

‎test/common/index.js

+43-1
Original file line numberDiff line numberDiff line change
@@ -480,9 +480,51 @@ exports.fileExists = function(pathname) {
480480
}
481481
};
482482

483+
exports.canCreateSymLink = function() {
484+
// On Windows, creating symlinks requires admin privileges.
485+
// We'll only try to run symlink test if we have enough privileges.
486+
// On other platforms, creating symlinks shouldn't need admin privileges
487+
if (exports.isWindows) {
488+
// whoami.exe needs to be the one from System32
489+
// If unix tools are in the path, they can shadow the one we want,
490+
// so use the full path while executing whoami
491+
const whoamiPath = path.join(process.env['SystemRoot'],
492+
'System32', 'whoami.exe');
493+
494+
let err = false;
495+
let output = '';
496+
497+
try {
498+
output = execSync(`${whoamiPath} /priv`, { timout: 1000 });
499+
} catch (e) {
500+
err = true;
501+
} finally {
502+
if (err || !output.includes('SeCreateSymbolicLinkPrivilege')) {
503+
return false;
504+
}
505+
}
506+
}
507+
508+
return true;
509+
};
510+
511+
exports.getCallSite = function getCallSite(top) {
512+
const originalStackFormatter = Error.prepareStackTrace;
513+
Error.prepareStackTrace = (err, stack) =>
514+
`${stack[0].getFileName()}:${stack[0].getLineNumber()}`;
515+
const err = new Error();
516+
Error.captureStackTrace(err, top);
517+
// with the V8 Error API, the stack is not formatted until it is accessed
518+
err.stack;
519+
Error.prepareStackTrace = originalStackFormatter;
520+
return err.stack;
521+
};
522+
483523
exports.mustNotCall = function(msg) {
524+
const callSite = exports.getCallSite(exports.mustNotCall);
484525
return function mustNotCall() {
485-
assert.fail(msg || 'function should not have been called');
526+
assert.fail(
527+
`${msg || 'function should not have been called'} at ${callSite}`);
486528
};
487529
};
488530

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const assert = require('assert');
5+
const path = require('path');
6+
7+
const message = 'message';
8+
const testFunction = common.mustNotCall(message);
9+
10+
const validateError = common.mustCall((e) => {
11+
const prefix = `${message} at `;
12+
assert.ok(e.message.startsWith(prefix));
13+
if (process.platform === 'win32') {
14+
e.message = e.message.substring(2); // remove 'C:'
15+
}
16+
const [ fileName, lineNumber ] = e.message
17+
.substring(prefix.length).split(':');
18+
assert.strictEqual(path.basename(fileName), 'test-common-must-not-call.js');
19+
assert.strictEqual(lineNumber, '8');
20+
});
21+
22+
try {
23+
testFunction();
24+
} catch (e) {
25+
validateError(e);
26+
}

0 commit comments

Comments
 (0)
Please sign in to comment.