-
Notifications
You must be signed in to change notification settings - Fork 75
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
241 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
/* global lockdown */ | ||
import test from 'tape'; | ||
import '../src/main.js'; | ||
|
||
// TODO test Error API in | ||
// * non - start compartments | ||
// * with { errorTaming: 'safe' } | ||
// * on non-v8 | ||
lockdown({ errorTaming: 'unsafe' }); | ||
|
||
// depd (https://github.com/dougwilson/nodejs-depd) uses a stack trace to | ||
// determine the call site of a deprecated function | ||
|
||
function simulateDepd() { | ||
function prepareObjectStackTrace(obj, stack) { | ||
return stack; | ||
} | ||
|
||
function callSiteLocation(callSite) { | ||
let file = callSite.getFileName() || '<anonymous>'; | ||
const line = callSite.getLineNumber(); | ||
const colm = callSite.getColumnNumber(); | ||
if (callSite.isEval()) { | ||
file = `${callSite.getEvalOrigin()}, ${file}`; | ||
} | ||
const site = [file, line, colm]; | ||
site.callSite = callSite; | ||
site.name = callSite.getFunctionName(); | ||
return site; | ||
} | ||
|
||
function getStack() { | ||
const limit = Error.stackTraceLimit; | ||
const obj = {}; | ||
const prep = Error.prepareStackTrace; | ||
Error.prepareStackTrace = prepareObjectStackTrace; | ||
Error.stackTraceLimit = Math.max(10, limit); | ||
// capture the stack | ||
Error.captureStackTrace(obj); | ||
// slice this function off the top | ||
const stack = obj.stack.slice(1); | ||
Error.prepareStackTrace = prep; | ||
Error.stackTraceLimit = limit; | ||
return stack; | ||
} | ||
|
||
function middle() { | ||
return getStack(); | ||
} | ||
|
||
const site = callSiteLocation(middle()[0]); | ||
return site.name; | ||
} | ||
|
||
test('Error compatibility - depd', t => { | ||
// the Start Compartment should support this sort of manipulation | ||
const name = simulateDepd(); | ||
t.equal(name, 'middle'); | ||
|
||
// however a new Compartment should not | ||
// const c = new Compartment({ console }); | ||
// const sim = c.evaluate(`(${simulateDepd})`); | ||
// t.throws(() => sim(), /Cannot add property prepareStackTrace, object is not extensible/); | ||
|
||
t.end(); | ||
}); | ||
|
||
// callstack (https://github.com/nailgun/node-callstack#readme) returns a | ||
// stack as a list of strings, by reading Error().stack | ||
function simulateCallstack() { | ||
function callstack() { | ||
return new Error().stack.split('\n').splice(2); | ||
} | ||
function middle() { | ||
return callstack(); | ||
} | ||
return middle(); | ||
} | ||
|
||
test('Error compatibility - callstack', t => { | ||
const stack = simulateCallstack(); | ||
// TODO: upgrade to tape 5.x for t.match | ||
// t.match(stack[0], /at middle/, '"middle" found in callstack() output'); | ||
t.notEqual( | ||
stack[0].search(/at middle/), | ||
-1, | ||
'"middle" found in callstack() output', | ||
); | ||
|
||
t.end(); | ||
}); | ||
|
||
// callsite (https://www.npmjs.com/package/callsite) returns a list of stack | ||
// frames, obtained by replacing Error.prepareStackTrace . | ||
function simulateCallsite() { | ||
function callsite() { | ||
const orig = Error.prepareStackTrace; | ||
Error.prepareStackTrace = (_, stack) => stack; | ||
const err = new Error(); | ||
Error.captureStackTrace(err, callsite); | ||
const { stack } = err; | ||
Error.prepareStackTrace = orig; | ||
return stack; | ||
} | ||
|
||
function middle() { | ||
return callsite(); | ||
} | ||
|
||
return middle()[0].getFunctionName(); | ||
} | ||
|
||
test('Error compatibility - callsite', t => { | ||
const name = simulateCallsite(); | ||
t.equal(name, 'middle'); | ||
|
||
t.end(); | ||
}); | ||
|
||
// callsites from | ||
// https://github.com/sindresorhus/callsites/blob/master/index.js | ||
// triggers prepareStackTrace by accessing the `.stack` property | ||
// of an error, rather than calling `captureStackTrace`. | ||
function simulateCallsites() { | ||
function callsites() { | ||
const orig = Error.prepareStackTrace; | ||
Error.prepareStackTrace = (_, stack) => stack; | ||
const stack = new Error().stack.slice(1); | ||
Error.prepareStackTrace = orig; | ||
return stack; | ||
} | ||
|
||
function middle() { | ||
return callsites(); | ||
} | ||
|
||
return middle()[0].getFunctionName(); | ||
} | ||
|
||
test('Error compatibility - callsites', t => { | ||
const name = simulateCallsites(); | ||
t.equal(name, 'middle'); | ||
|
||
t.end(); | ||
}); |