Comparing version 2.2.1 to 3.0.0
@@ -1,2 +0,2 @@ | ||
"use strict"; | ||
'use strict'; | ||
@@ -3,0 +3,0 @@ const fs = require('fs'); |
'use strict'; | ||
const ConsoleRunner = require('./ConsoleRunner.js'); | ||
const ChakraRunner = require('./ChakraRunner.js'); | ||
const SMRunner = require('./SMRunner.js'); | ||
const D8Runner = require('./D8Runner.js'); | ||
const NodeRunner = require('./NodeRunner.js'); | ||
const BrowserRunner = require('./BrowserRunner.js'); | ||
const JSCRunner = require('./JSCRunner.js'); | ||
const NashornRunner = require('./NashornRunner.js'); | ||
const fs = require('fs'); | ||
const path = require('path'); | ||
const files = fs.readdirSync(path.join(__dirname, 'agents')); | ||
const hosts = files.map(name => name.replace('.js', '')); | ||
exports.getRunner = function (path, type, args) { | ||
if (type === 'ch') { | ||
return new ChakraRunner(path, args); | ||
} else if (type === 'jsshell') { | ||
return new SMRunner(path, args); | ||
} else if (type === 'node') { | ||
return new NodeRunner(path, args); | ||
} else if (type === 'd8') { | ||
return new D8Runner(path, args); | ||
} else if (type === 'browser') { | ||
return new BrowserRunner(path, args); | ||
} else if (type === 'jsc') { | ||
return new JSCRunner(path, args); | ||
} else if (type === 'nashorn') { | ||
return new NashornRunner(path, args); | ||
} else { | ||
throw new Error("Unknown runner type: " + type); | ||
exports.createAgent = function (type, options) { | ||
const reqPath = './agents/' + type + '.js'; | ||
try { | ||
const Agent = new require(reqPath); | ||
const a = new Agent(options); | ||
return a.initialize(); | ||
} catch (e) { | ||
if (e.message.indexOf('Cannot find module \'' + reqPath + '\'') > -1) { | ||
throw new Error('Agent ' + type + ' not supported. Supported hosts are ' + hosts.join(', ')); | ||
} else { | ||
throw e; | ||
} | ||
} | ||
} | ||
exports.supportedHosts = [ | ||
'ch', | ||
'jsshell', | ||
'node', | ||
'd8', | ||
'browser', | ||
'jsc', | ||
'nashorn' | ||
] | ||
}; | ||
exports.supportedHosts = hosts; |
@@ -0,4 +1,6 @@ | ||
'use strict'; | ||
module.exports = function (runtimeStr) { | ||
const runtimeInception = runtimeStr.replace('$SOURCE', '""'); | ||
return runtimeStr.replace('$SOURCE', JSON.stringify(runtimeInception)); | ||
} | ||
}; |
'use strict'; | ||
const errorRe = /^\w+(:.*)?\r?\n(\s+at.*\r?\n)+/m; | ||
const errorRe = /^[\w\d]+(:.*)?\r?\n(\s+at.*\r?\n)*/m; | ||
const errorPropsRe = /^(\w+)(: (.*))?\r?\n/; | ||
@@ -5,0 +5,0 @@ const frameRe = /^\s+at(.*)\(?(.*):(\d+):(\d+)\)?/; |
@@ -1,2 +0,2 @@ | ||
"use strict"; | ||
'use strict'; | ||
const EventEmitter = require('events'); | ||
@@ -17,2 +17,6 @@ const http = require('http'); | ||
const runtimeJs = fs.readFileSync(Path.join(__dirname, '../runtimes/browser.js'), 'utf8'); | ||
const stackParserPath = Path.join(Path.dirname(require.resolve('error-stack-parser')), 'dist/error-stack-parser.js'); | ||
const stackframePath = Path.join(Path.dirname(require.resolve('stackframe')), 'dist/stackframe.js') | ||
const stackJs = fs.readFileSync(stackframePath, 'utf8') + fs.readFileSync(stackParserPath, 'utf8'); | ||
const server = http.createServer(httpHandler); | ||
@@ -27,17 +31,17 @@ enableDestroy(server); | ||
switch (url.pathname) { | ||
case '/': sendInit(req, res); break; | ||
case '/runtime.js': sendRuntime(req, res); break; | ||
case '/error-stack-parser.js': sendStackParser(req, res); break; | ||
default: | ||
res.writeHead(404); | ||
res.end(); | ||
case '/': sendInit(req, res); break; | ||
case '/runtime.js': sendRuntime(req, res); break; | ||
case '/error-stack-parser.js': sendStackParser(req, res); break; | ||
default: | ||
res.writeHead(404); | ||
res.end(); | ||
} | ||
} | ||
let currentError = null; | ||
let currentStdout = ''; | ||
let lastResult = null; | ||
function socketHandler (socket) { | ||
var clientId; | ||
let clientId; | ||
let currentError = null; | ||
let currentStdout = ''; | ||
let lastResult = null; | ||
socket.on('clientId', function (id) { | ||
@@ -64,3 +68,3 @@ clientId = Number(id); | ||
socket.on('execDone', function () { | ||
lastResult = { stdout: currentStdout, stderr: '', error: currentError } | ||
lastResult = { stdout: currentStdout, stderr: '', error: currentError }; | ||
currentStdout = ''; | ||
@@ -80,3 +84,3 @@ currentError = null; | ||
res.writeHead(200, { 'Content-type': 'text/html' }); | ||
res.end(runtimeHtml) | ||
res.end(runtimeHtml); | ||
} | ||
@@ -91,6 +95,3 @@ | ||
res.writeHead(200, { 'Content-type': 'application/javascript' }); | ||
res.end( | ||
fs.readFileSync('node_modules/error-stack-parser/node_modules/stackframe/dist/stackframe.js') + | ||
fs.readFileSync('node_modules/error-stack-parser/dist/error-stack-parser.js') | ||
); | ||
res.end(stackJs); | ||
} | ||
@@ -112,3 +113,3 @@ | ||
} | ||
} | ||
}; | ||
@@ -118,9 +119,5 @@ exports.stop = function stopServer(id) { | ||
if (activeClients.size === 0) { | ||
try { | ||
server.destroy(); | ||
} catch(e) { | ||
console.log("Failed", e); | ||
} | ||
} | ||
} | ||
}; | ||
@@ -131,3 +128,3 @@ exports.waitForClientId = function (id) { | ||
if (existing) { | ||
res(existing) | ||
res(existing); | ||
} | ||
@@ -137,3 +134,3 @@ | ||
}); | ||
} | ||
}; | ||
@@ -144,2 +141,2 @@ exports.waitForResult = function (id) { | ||
}); | ||
} | ||
}; |
{ | ||
"name": "eshost", | ||
"version": "2.2.1", | ||
"version": "3.0.0", | ||
"description": "Invoke ECMAScript scripts in any command line JS engine.", | ||
@@ -22,2 +22,3 @@ "main": "lib/eshost.js", | ||
"error-stack-parser": "^1.3.3", | ||
"selenium-webdriver": "^2.53.2", | ||
"server-destroy": "^1.0.1", | ||
@@ -24,0 +25,0 @@ "socket.io": "^1.3.7", |
## eshost | ||
eshost is a library for executing ECMAScript code uniformly across any ECMAScript host environment. eshost consists of a wrapper around the various ways of executing a host and processing its output (called a Runner) and a runtime library for host-agnostic scripts to use. | ||
Execute ECMAScript code uniformly across any ECMAScript host environment. See also [eshost-cli](https://github.com/bterlson/eshost-cli) for an easy way to use this library from the command line. | ||
For a CLI tool that uses this library to make comparing ECMAScript hosts super easy, see [eshost-cli](https://github.com/bterlson/eshost-cli). | ||
Using eshost, you can create an agent (eg. a web browser or a command-line ECMAScript host) and evaluate scripts within that agent. Code running within the agent has access to the eshost runtime API which enables code to evaluate scripts, create new realms, handle errors, and so forth all without worrying about the host-specific mechanisms for these capabilities are. | ||
eshost consists of a wrapper around the various ways of executing a host and processing its output (called a Runner) and a runtime library for host-agnostic scripts to use. | ||
### Installation | ||
@@ -17,3 +19,2 @@ | ||
|------|---------------------|----------|-------| | ||
| browser | Any | | Errors reported from Microsoft Edge are all of type Error. | | ||
| node | Any | https://nodejs.org | | | ||
@@ -25,2 +26,6 @@ | ch | Windows | Built [from source](https://github.com/microsoft/chakracore)| Chakra console host. | | ||
| nashorn | Any | Built [from source](https://wiki.openjdk.java.net/display/Nashorn/Building+Nashorn) | | | ||
| edge | Windows | | Errors reported from Microsoft Edge are all of type Error. | | ||
| chrome | Any | | | | ||
| firefox | Any | | Firefox Nightly on Windows doesn't appear to work at this time. | | ||
| safari | Mac | | | | ||
@@ -33,5 +38,7 @@ 1: Also available on your Mac system at `/System/Library/Frameworks/JavaScriptCore.framework/Versions/A/Resources/jsc`. | ||
const runner = js.getRunner('path/to/d8.exe', 'd8'); | ||
runner.exec(` | ||
await runner.initialize(); | ||
const result = await runner.exec(` | ||
print(1+1); | ||
`).then(result => console.log(result.stdout)); | ||
`); | ||
console.log(result.stdout); | ||
``` | ||
@@ -46,20 +53,26 @@ | ||
#### getRunner(path, type, arguments) | ||
Gets an instance of a runner for a particular host type. Supported host types: | ||
#### createAgent(type: string, options = {}): Runner | ||
Gets an instance of a runner for a particular host type. See the table above for supported host types. | ||
* browser | ||
* node | ||
* d8 | ||
* jsshell | ||
* ch | ||
##### Options | ||
Creating a runner may start the host (eg. for the browser, creating the host executes the browser process). | ||
* **hostPath**: Path to host to execute. For console hosts, this argument is required. For the specific browser runners, hostPath is optional and if omitted, the location for that browser will be detected automatically. | ||
* **hostArguments**: Command line arguments used when invoking your host. Not supported for browser hosts. **hostArguments** is an array of strings as you might pass to Node's spawn API. | ||
You can pass command line arguments to the host process using the arguments option. It is an array of strings as you might pass to Node's spawn API. | ||
### Agent API | ||
Runner | ||
#### initialize(): Promise<void> | ||
Initializes the host and returns a promise that is resolved once the host is initialized. Command line hosts have no initialization as a new process is started for each execution. | ||
### Runner API | ||
This is called for you if you use the createAgent factory. | ||
#### exec(code) | ||
Executes `code` in the host. Returns a result object. | ||
#### evalScript(code, options = {}): Promise<Result> | ||
Executes `code` in the host using the _Script_ goal symbol. Returns a promise for a result object. | ||
By default, a script will run in Eshost until the realm is destroyed. For most command-line hosts, this is done automatically when the script execution queues are empty. However, browsers will remain open waiting for more code to become available. Therefore, eshost will automatically append `$.destroy()` to the end of your scripts. This behavior is not correct if you are attempting to execute asynchronous code. In such cases, add `async: true` to the options. | ||
Options: | ||
* async: True if the test is expected to call `$.destroy()` on the root realm when it's finished. When false, $.destroy() is added for you. | ||
##### Result Object | ||
@@ -78,2 +91,5 @@ An object with the following keys: | ||
#### destroy(): Promise<void> | ||
Tears down the agent. For browsers, this will close the browser window. | ||
### Runtime Library | ||
@@ -97,6 +113,3 @@ | ||
#### $.evalInNewRealm(code, onError) | ||
Creates a new realm and evals `code` in that realm. If an error is thrown, it will be passed to the onError callback. | ||
#### $.evalInNewScript(code, onError) | ||
#### $.evalScript(code) | ||
Creates a new script and evals `code` in that realm. If an error is thrown, it will be passed to the onError callback. | ||
@@ -103,0 +116,0 @@ |
var $ = { | ||
global: this, | ||
createRealm: function (globals) { | ||
globals = globals || {}; | ||
createRealm: function (options) { | ||
options = options || {}; | ||
const globals = options.globals || {}; | ||
@@ -20,20 +21,39 @@ var frame = document.createElement('iframe'); | ||
fwin.$.destroy = function () { | ||
document.body.removeChild(frame); | ||
if (options.destroy) { | ||
options.destroy(); | ||
} | ||
} | ||
return fwin.$; | ||
}, | ||
evalInNewRealm: function (code, globals, errorCb) { | ||
if (typeof globals === 'function') { | ||
errorCb = globals; | ||
globals = {}; | ||
} | ||
evalScript: function (code, options) { | ||
options = options || {}; | ||
var $child = this.createRealm(globals); | ||
$child.evalInNewScript(code, errorCb); | ||
}, | ||
evalInNewScript: function (code, errorCb) { | ||
this.onNextError = errorCb; | ||
var s = document.createElement('script'); | ||
s.textContent = code; | ||
var error = null; | ||
window.onerror = function (msg, file, row, col, err) { | ||
if (!err) { | ||
// make up some error for Edge. | ||
err = { | ||
name: 'Error', | ||
message: msg | ||
}; | ||
} | ||
error = err; | ||
} | ||
document.body.appendChild(s); | ||
this.onNextError = null; | ||
if (window) { | ||
window.onerror = null; | ||
} | ||
if (error) { | ||
return { type: 'throw', value: error }; | ||
} else { | ||
return { type: 'normal', value: undefined }; | ||
} | ||
}, | ||
@@ -46,23 +66,10 @@ getGlobal: function (name) { | ||
}, | ||
_onError: function (err) { | ||
if (this.onNextError) { | ||
this.onNextError(err); | ||
this.onNextError = null; | ||
} | ||
destroy: function() { | ||
$.socket.emit('destroy') | ||
}, | ||
source: $SOURCE | ||
}; | ||
this.window.onerror = function (msg, file, row, col, err) { | ||
if (!err) { | ||
// make up some error for Edge. | ||
err = { | ||
name: 'Error', | ||
message: msg | ||
}; | ||
} | ||
$._onError(err) | ||
} | ||
function print(str) { | ||
$.socket.emit('print', str); | ||
} |
var $ = { | ||
global: this, | ||
createRealm(globals) { | ||
globals = globals || {}; | ||
createRealm(options) { | ||
options = options || {}; | ||
options.globals = options.globals || {}; | ||
@@ -9,4 +10,4 @@ var realm = WScript.LoadScript(this.source, 'samethread'); | ||
for(var glob in globals) { | ||
realm.$.global[glob] = globals[glob]; | ||
for(var glob in options.globals) { | ||
realm.$.global[glob] = options.globals[glob]; | ||
} | ||
@@ -16,16 +17,8 @@ | ||
}, | ||
evalInNewRealm(code, globals, errorCb) { | ||
if (typeof globals === 'function') { | ||
errorCb = globals; | ||
globals = {}; | ||
} | ||
var $child = this.createRealm(globals); | ||
$child.evalInNewScript(code, errorCb); | ||
}, | ||
evalInNewScript(code, errorCb) { | ||
evalScript(code) { | ||
try { | ||
WScript.LoadScript(code); | ||
return { type: 'normal', value: undefined }; | ||
} catch (e) { | ||
if (errorCb) errorCb(e); | ||
return { type: 'throw', value: e }; | ||
} | ||
@@ -39,3 +32,4 @@ }, | ||
}, | ||
destroy() { /* noop */ }, | ||
source: $SOURCE | ||
}; |
var $ = { | ||
global: this, | ||
createRealm: function (globals) { | ||
globals = globals || {}; | ||
createRealm: function (options) { | ||
options = options || {}; | ||
options.globals = options.globals || {}; | ||
@@ -13,4 +14,4 @@ var realm = Realm.create(); | ||
for(var glob in globals) { | ||
$child.setGlobal(glob, globals[glob]); | ||
for(var glob in options.globals) { | ||
$child.setGlobal(glob, options.globals[glob]); | ||
} | ||
@@ -20,16 +21,8 @@ | ||
}, | ||
evalInNewRealm: function (code, globals, errorCb) { | ||
if (typeof globals === 'function') { | ||
errorCb = globals; | ||
globals = {}; | ||
} | ||
var $child = this.createRealm(globals); | ||
$child.evalInNewScript(code, errorCb); | ||
}, | ||
evalInNewScript: function (code, errorCb) { | ||
evalScript: function (code) { | ||
try { | ||
Realm.eval(this.realm ? this.realm : Realm.current(), code); | ||
return { type: 'normal', value: undefined } | ||
} catch (e) { | ||
if (errorCb) errorCb(e); | ||
return { type: 'throw', value: e } | ||
} | ||
@@ -43,4 +36,5 @@ }, | ||
}, | ||
destroy: function() { /* noop */ }, | ||
source: $SOURCE | ||
}; | ||
Realm.shared = $; |
var $ = { | ||
global: this, | ||
createRealm(globals) { | ||
globals = globals || {}; | ||
createRealm(options) { | ||
options = options || {}; | ||
options.globals = options.globals || {}; | ||
@@ -13,4 +14,4 @@ var realm; | ||
for(var glob in globals) { | ||
realm.$.global[glob] = globals[glob]; | ||
for(var glob in options.globals) { | ||
realm.$.global[glob] = options.globals[glob]; | ||
} | ||
@@ -20,12 +21,3 @@ | ||
}, | ||
evalInNewRealm(code, globals, errorCb) { | ||
if (typeof globals === 'function') { | ||
errorCb = globals; | ||
globals = {}; | ||
} | ||
var $child = this.createRealm(globals); | ||
$child.evalInNewScript(code, errorCb); | ||
}, | ||
evalInNewScript(code, errorCb) { | ||
evalScript(code, errorCb) { | ||
try { | ||
@@ -40,4 +32,5 @@ print(this.scriptStartMarker); | ||
load(this.scriptFile); | ||
return { type: 'normal', value: undefined }; | ||
} catch (e) { | ||
if (errorCb) errorCb(e); | ||
return { type: 'throw', value: e } | ||
} | ||
@@ -51,2 +44,3 @@ }, | ||
}, | ||
destroy: function() { /* noop */ }, | ||
source: $SOURCE, | ||
@@ -53,0 +47,0 @@ file: $FILE, |
var $ = { | ||
global: this, | ||
createRealm: function(globals) { | ||
globals = globals || {}; | ||
createRealm: function(options) { | ||
options = options || {}; | ||
options.globals = options.globals || {}; | ||
@@ -10,4 +11,4 @@ var realm = loadWithNewGlobal({script: 'this', name: 'createRealm'}); | ||
for(var glob in globals) { | ||
realm.$.global[glob] = globals[glob]; | ||
for(var glob in options.globals) { | ||
realm.$.global[glob] = options.globals[glob]; | ||
} | ||
@@ -17,16 +18,8 @@ | ||
}, | ||
evalInNewRealm: function(code, globals, errorCb) { | ||
if (typeof globals === 'function') { | ||
errorCb = globals; | ||
globals = {}; | ||
} | ||
var $child = this.createRealm(globals); | ||
$child.evalInNewScript(code, errorCb); | ||
}, | ||
evalInNewScript: function(code, errorCb) { | ||
evalScript: function(code) { | ||
try { | ||
load({script: code, name: 'evalInNewScript'}); | ||
load({script: code, name: 'evalScript'}); | ||
return { type: 'normal', value: undefined } | ||
} catch (e) { | ||
if (errorCb) errorCb(e); | ||
return { type: 'throw', value: e } | ||
} | ||
@@ -40,3 +33,4 @@ }, | ||
}, | ||
destroy: function() { /* noop */ }, | ||
source: $SOURCE | ||
}; |
var vm = require('vm'); | ||
var $ = { | ||
global: this, | ||
createRealm: function (globals) { | ||
globals = globals || {}; | ||
createRealm: function (options) { | ||
options = options || {}; | ||
options.globals = options.globals || {}; | ||
@@ -12,4 +13,4 @@ context = { | ||
for(var glob in globals) { | ||
context[glob] = globals[glob]; | ||
for(var glob in options.globals) { | ||
context[glob] = options.globals[glob]; | ||
} | ||
@@ -23,14 +24,3 @@ | ||
}, | ||
evalInNewRealm: function (code, globals, errorCb) { | ||
if (typeof globals === 'function') { | ||
errorCb = globals; | ||
globals = {}; | ||
} | ||
$child = this.createRealm(globals); | ||
$child.evalInNewScript(code, errorCb); | ||
return $child; | ||
}, | ||
evalInNewScript: function (code, errorCb) { | ||
evalScript: function (code) { | ||
try { | ||
@@ -42,4 +32,6 @@ if (this.context) { | ||
} | ||
return { type: 'normal', value: undefined }; | ||
} catch (e) { | ||
if(errorCb) errorCb(e); | ||
return { type: 'throw', value: e }; | ||
} | ||
@@ -53,4 +45,5 @@ }, | ||
}, | ||
destroy: function() { /* noop */ }, | ||
source: $SOURCE | ||
}; | ||
function print() { console.log.apply(console, arguments) } |
var $ = { | ||
global: this, | ||
createRealm(globals) { | ||
globals = globals || {}; | ||
createRealm(options) { | ||
options = options || {}; | ||
options.globals = options.globals || {}; | ||
@@ -10,4 +11,4 @@ var realm = newGlobal(); | ||
for(var glob in globals) { | ||
realm.$.global[glob] = globals[glob]; | ||
for(var glob in options.globals) { | ||
realm.$.global[glob] = options.globals[glob]; | ||
} | ||
@@ -17,16 +18,8 @@ | ||
}, | ||
evalInNewRealm(code, globals, errorCb) { | ||
if (typeof globals === 'function') { | ||
errorCb = globals; | ||
globals = {}; | ||
} | ||
var $child = this.createRealm(globals); | ||
$child.evalInNewScript(code, errorCb); | ||
}, | ||
evalInNewScript(code, errorCb) { | ||
evalScript(code) { | ||
try { | ||
evaluate(code); | ||
return { completion: 'normal', value: undefined }; | ||
} catch (e) { | ||
if (errorCb) errorCb(e); | ||
return { completion: 'throw', value: e }; | ||
} | ||
@@ -40,4 +33,5 @@ }, | ||
}, | ||
destroy: function() { /* noop */ }, | ||
source: $SOURCE | ||
}; | ||
27
test.js
var fs = require('fs'); | ||
var esh = require('./'); | ||
var runner = esh.getRunner('c:/users/brterlso/projects/v8/build/Release/d8.exe', 'd8'); | ||
runner.exec(fs.readFileSync('./proxy-test.js', 'utf8')).then(function(result) { | ||
console.log(result); | ||
}); | ||
var payload = fs.readFileSync('./inproc.js', 'utf8'); | ||
//var agent = esh.createAgent('ch', { hostPath: 'c:/users/brterlso/projects/chakracore/build/vcbuild/bin/x64_test/ch.exe'}); | ||
//esh.createAgent('firefox').then(agent => { | ||
var agent; | ||
//esh.createAgent('chrome', { hostPath: undefined }).then(a => { | ||
esh.createAgent('ch', { hostPath: 'c:/users/brterlso/projects/chakracore/build/vcbuild/bin/x64_test/ch.exe'}).then(a => { | ||
agent = a; | ||
return agent.evalScript('function Foo1Error(msg) { this.message = msg } throw new Foo1Error("FAIL");'); | ||
}).then(result => { | ||
console.log('result', result); | ||
}) | ||
.catch(err => console.log(err)) | ||
function check() { | ||
var res = process._getActiveHandles().map(p => p.fd); | ||
console.log(res); | ||
if (res.length > 3) { | ||
setTimeout(check, 1000); | ||
} | ||
} |
@@ -11,5 +11,7 @@ 'use strict'; | ||
['../v8/build/Release/d8.exe', 'd8'], | ||
['C:/Users/brterlso/AppData/Local/Google/Chrome SxS/Application/chrome.exe', 'browser'], | ||
//['./hosts/MicrosoftEdgeLauncher.exe', 'browser'] | ||
] | ||
['C:/Users/brterlso/AppData/Local/Google/Chrome SxS/Application/chrome.exe', 'chrome'], | ||
[undefined, 'chrome'], | ||
['C:/Program Files (x86)/Mozilla Firefox/firefox.exe', 'firefox'], | ||
['C:/Program Files (x86)/Nightly/firefox.exe', 'firefox'], | ||
]; | ||
@@ -21,20 +23,18 @@ hosts.forEach(function (record) { | ||
describe(`${type} (${host})`, function () { | ||
this.timeout(5000); | ||
var runner; | ||
this.timeout(10000); | ||
let agent; | ||
before(function() { | ||
runner = runify.getRunner(host, type); | ||
return runify.createAgent(type, { hostPath: host }).then(a => agent = a); | ||
}); | ||
after(function() { | ||
return agent.destroy(); | ||
}); | ||
it('runs SyntaxErrors', function () { | ||
return runner.exec('foo x++').then(function (result) { | ||
return agent.evalScript('foo x++').then(function (result) { | ||
assert(result.error, 'error is present'); | ||
assert.equal(result.error.name, 'SyntaxError'); | ||
assert.equal(result.stdout, '', 'stdout not present'); | ||
if (type !== 'node' && type !== 'browser') { | ||
// node doesn't report any useful stack information for syntax errors at global scope | ||
// chrome seems to get confused with dynamically injected scripts | ||
assert.equal(result.error.stack[0].lineNumber, 1); | ||
} | ||
}); | ||
@@ -44,3 +44,3 @@ }); | ||
it('runs thrown SyntaxErrors', function () { | ||
return runner.exec('throw new SyntaxError("Custom Message");').then(function (result) { | ||
return agent.evalScript('throw new SyntaxError("Custom Message");').then(function (result) { | ||
assert(result.error, 'error is present'); | ||
@@ -56,3 +56,3 @@ assert.equal(result.stdout, '', 'stdout not present'); | ||
it('runs thrown TypeErrors', function () { | ||
return runner.exec('throw new TypeError("Custom Message");').then(function (result) { | ||
return agent.evalScript('throw new TypeError("Custom Message");').then(function (result) { | ||
assert(result.error, 'error is present'); | ||
@@ -68,3 +68,3 @@ assert.equal(result.stdout, '', 'stdout not present'); | ||
it('runs thrown RangeErrors', function () { | ||
return runner.exec('throw new RangeError("Custom Message");').then(function (result) { | ||
return agent.evalScript('throw new RangeError("Custom Message");').then(function (result) { | ||
assert(result.error, 'error is present'); | ||
@@ -80,3 +80,3 @@ assert.equal(result.stdout, '', 'stdout not present'); | ||
it('runs thrown Errors', function () { | ||
return runner.exec('throw new Error("Custom Message");').then(function (result) { | ||
return agent.evalScript('throw new Error("Custom Message");').then(function (result) { | ||
assert.equal(result.stdout, '', 'stdout not present'); | ||
@@ -89,103 +89,90 @@ assert(result.error, 'error is present'); | ||
it('runs thrown custom Errors', function () { | ||
return agent.evalScript('function Foo1Error(msg) { this.name = "Foo1Error"; this.message = msg }; Foo1Error.prototype = Error.prototype; throw new Foo1Error("Custom Message");').then(function (result) { | ||
assert.equal(result.stdout, '', 'stdout not present'); | ||
assert(result.error, 'error is present'); | ||
assert.equal(result.error.message, 'Custom Message'); | ||
assert.equal(result.error.name, 'Foo1Error'); | ||
}); | ||
}); | ||
it('gathers stdout', function () { | ||
return runner.exec('print("foo")').then(function(result) { | ||
assert(result.stdout.match(/^foo\r?\n/), "Unexpected stdout: " + result.stdout); | ||
}) | ||
return agent.evalScript('print("foo")').then(function(result) { | ||
assert(result.stdout.match(/^foo\r?\n/), 'Unexpected stdout: ' + result.stdout); | ||
}); | ||
}); | ||
it('can eval in new realms', function () { | ||
return runner.exec(` | ||
return agent.evalScript(` | ||
var x = 2; | ||
$.evalInNewRealm("var x = 1; print(x);"); | ||
$child = $.createRealm(); | ||
$child.evalScript("var x = 1; print(x);"); | ||
print(x); | ||
`).then(function(result) { | ||
assert(result.stdout.match(/^1\r?\n2\r?\n/m), "Unexpected stdout: " + result.stdout + result.stderr); | ||
}) | ||
assert(result.stdout.match(/^1\r?\n2\r?\n/m), 'Unexpected stdout: ' + result.stdout + result.stderr); | ||
}); | ||
}); | ||
it('returns errors from evaling in new realms', function () { | ||
return runner.exec(` | ||
$.evalInNewRealm("x+++", function (error) { print(error.name) }); | ||
`).then(function(result) { | ||
assert(result.stdout.match(/^SyntaxError\r?\n/m), "Unexpected stdout: " + result.stdout + result.stderr); | ||
}) | ||
}); | ||
it('can create new realms', function() { | ||
return runner.exec(` | ||
return agent.evalScript(` | ||
var sub$ = $.createRealm({}); | ||
sub$.evalInNewScript("var x = 1"); | ||
sub$.evalInNewScript("print(x)"); | ||
sub$.evalScript("var x = 1"); | ||
sub$.evalScript("print(x)"); | ||
subsub$ = sub$.createRealm({}); | ||
subsub$.evalInNewScript("var x = 2"); | ||
subsub$.evalInNewScript("print(2)"); | ||
subsub$.evalScript("var x = 2"); | ||
subsub$.evalScript("print(2)"); | ||
`).then(function(result) { | ||
assert(result.stdout.match(/^1\r?\n2\r?\n/m), "Unexpected stdout: " + result.stdout + result.stderr); | ||
assert(result.stdout.match(/^1\r?\n2\r?\n/m), 'Unexpected stdout: ' + result.stdout + result.stderr); | ||
}); | ||
}); | ||
it('can eval in new realms in new realms', function () { | ||
return runner.exec(` | ||
$.evalInNewRealm("$.evalInNewRealm(\\"var x = 1; print(x)\\")"); | ||
`).then(function(result) { | ||
assert(result.stdout.match(/^1\r?\n/m), "Unexpected stdout: " + result.stdout + result.stderr); | ||
}); | ||
}); | ||
it('can eval in new realms in new realms that throw', function () { | ||
var innerRealm = `$.evalInNewRealm("x+++++++;", function (err) { reportError(err); })`; | ||
var outerRealm = `$.evalInNewRealm("${innerRealm.replace(/"/g, '\\"')}", { reportError: function (err) { print(err.name) } })`; | ||
return runner.exec(outerRealm).then(function(result) { | ||
assert(result.stdout.match(/SyntaxError\r?\n/m), "Unexpected stdout: " + result.stdout + result.stderr); | ||
}); | ||
}); | ||
it('can set globals in new realms', function () { | ||
return runner.exec(` | ||
return agent.evalScript(` | ||
var x = 1; | ||
$.evalInNewRealm("print(x);", {x: 2}); | ||
$child = $.createRealm({globals: {x: 2}}); | ||
$child.evalScript("print(x);"); | ||
`).then(function(result) { | ||
assert(result.stdout.match(/^2\r?\n/m), "Unexpected stdout: " + result.stdout + result.stderr); | ||
}) | ||
assert(result.stdout.match(/^2\r?\n/m), 'Unexpected stdout: ' + result.stdout + result.stderr); | ||
}); | ||
}); | ||
it('can eval in new scripts', function () { | ||
return runner.exec(` | ||
return agent.evalScript(` | ||
var x = 2; | ||
$.evalInNewScript("x = 3;"); | ||
$.evalScript("x = 3;"); | ||
print(x); | ||
`).then(function(result) { | ||
assert(result.stdout.match(/^3\r?\n/m), "Unexpected stdout: " + result.stdout + result.stderr); | ||
}) | ||
assert(result.stdout.match(/^3\r?\n/m), 'Unexpected stdout: ' + result.stdout + result.stderr); | ||
}); | ||
}); | ||
it('returns errors from evaling in new script', function () { | ||
return runner.exec(` | ||
$.evalInNewScript("x+++", function (error) { print(error.name) }); | ||
return agent.evalScript(` | ||
var completion = $.evalScript("x+++"); | ||
print(completion.value.name); | ||
`).then(function(result) { | ||
assert(result.stdout.match(/^SyntaxError\r?\n/m), "Unexpected stdout: " + result.stdout + result.stderr); | ||
}) | ||
assert(result.stdout.match(/^SyntaxError\r?\n/m), 'Unexpected stdout: ' + result.stdout + result.stderr); | ||
}); | ||
}); | ||
it('can eval lexical bindings in new scripts', function () { | ||
return runner.exec(` | ||
$.evalInNewScript("'use strict'; let x = 3;"); | ||
return agent.evalScript(` | ||
$.evalScript("'use strict'; let x = 3;"); | ||
print(x); | ||
`).then(function(result) { | ||
assert(result.stdout.match(/^3\r?\n/m), "Unexpected stdout: " + result.stdout + result.stderr); | ||
}) | ||
assert(result.stdout.match(/^3\r?\n/m), 'Unexpected stdout: ' + result.stdout + result.stderr); | ||
}); | ||
}); | ||
it('can set properties in new realms', function() { | ||
return runner.exec(` | ||
return agent.evalScript(` | ||
var sub$ = $.createRealm({}); | ||
sub$.evalInNewScript("var x = 1"); | ||
sub$.evalInNewScript("print(x)"); | ||
sub$.evalScript("var x = 1"); | ||
sub$.evalScript("print(x)"); | ||
sub$.setGlobal("x", 2); | ||
sub$.evalInNewScript("print(x)"); | ||
sub$.evalScript("print(x)"); | ||
`).then(function(result) { | ||
assert(result.stdout.match(/^1\r?\n2\r?\n/m), "Unexpected stdout: " + result.stdout + result.stderr); | ||
assert(result.stdout.match(/^1\r?\n2\r?\n/m), 'Unexpected stdout: ' + result.stdout + result.stderr); | ||
}); | ||
@@ -195,14 +182,30 @@ }); | ||
it('can access properties from new realms', function() { | ||
return runner.exec(` | ||
return agent.evalScript(` | ||
var sub$ = $.createRealm({}); | ||
sub$.evalInNewScript("var x = 1"); | ||
sub$.evalScript("var x = 1"); | ||
print(sub$.getGlobal("x")); | ||
`).then(function(result) { | ||
assert(result.stdout.match(/^1\r?\n/m), "Unexpected stdout: " + result.stdout + result.stderr); | ||
assert(result.stdout.match(/^1\r?\n/m), 'Unexpected stdout: ' + result.stdout + result.stderr); | ||
}); | ||
}); | ||
it('runs async code', function () { | ||
return agent.evalScript(` | ||
if ($.global.Promise === undefined) { | ||
print('async result'); | ||
$.destroy() | ||
} else { | ||
Promise.resolve().then(function () { | ||
print('async result'); | ||
$.destroy() | ||
}); | ||
} | ||
`, { async: true }).then(result => { | ||
assert(result.stdout.match(/async result/), 'Unexpected stdout: ' + result.stdout + result.stderr); | ||
}); | ||
}); | ||
it('runs in the proper mode', function () { | ||
return runner.exec(` | ||
return agent.evalScript(` | ||
"use strict" | ||
@@ -213,22 +216,22 @@ function foo() { print(this === undefined) } | ||
.then(function(result) { | ||
assert(result.stdout.match(/^true\r?\n/m), "Unexpected stdout: " + result.stdout + result.stderr); | ||
assert(result.stdout.match(/^true\r?\n/m), 'Unexpected stdout: ' + result.stdout + result.stderr); | ||
return runner.exec(` | ||
return agent.evalScript(` | ||
'use strict' | ||
function foo() { print(this === undefined) } | ||
foo(); | ||
`) | ||
`); | ||
}) | ||
.then(function(result) { | ||
assert(result.stdout.match(/^true\r?\n/m), "Unexpected stdout: " + result.stdout + result.stderr); | ||
assert(result.stdout.match(/^true\r?\n/m), 'Unexpected stdout: ' + result.stdout + result.stderr); | ||
return runner.exec(` | ||
return agent.evalScript(` | ||
function foo() { print(this === Function('return this;')()) } | ||
foo(); | ||
`) | ||
`); | ||
}) | ||
.then(function(result) { | ||
assert(result.stdout.match(/^true\r?\n/m), "Unexpected stdout: " + result.stdout + result.stderr); | ||
assert(result.stdout.match(/^true\r?\n/m), 'Unexpected stdout: ' + result.stdout + result.stderr); | ||
return runner.exec(` | ||
return agent.evalScript(` | ||
/*--- | ||
@@ -239,8 +242,8 @@ ---*/ | ||
foo(); | ||
`) | ||
`); | ||
}) | ||
.then(function(result) { | ||
assert(result.stdout.match(/^true\r?\n/m), "Unexpected stdout: " + result.stdout + result.stderr); | ||
assert(result.stdout.match(/^true\r?\n/m), 'Unexpected stdout: ' + result.stdout + result.stderr); | ||
return runner.exec(` | ||
return agent.evalScript(` | ||
/*--- | ||
@@ -252,8 +255,8 @@ ---*/ | ||
foo(); | ||
`) | ||
`); | ||
}) | ||
.then(function(result) { | ||
assert(result.stdout.match(/^true\r?\n/m), "Unexpected stdout: " + result.stdout + result.stderr); | ||
assert(result.stdout.match(/^true\r?\n/m), 'Unexpected stdout: ' + result.stdout + result.stderr); | ||
return runner.exec(` | ||
return agent.evalScript(` | ||
// normal comment | ||
@@ -267,6 +270,6 @@ /*--- | ||
foo(); | ||
`) | ||
`); | ||
}) | ||
.then(function(result) { | ||
assert(result.stdout.match(/^true\r?\n/m), "Unexpected stdout: " + result.stdout + result.stderr); | ||
assert(result.stdout.match(/^true\r?\n/m), 'Unexpected stdout: ' + result.stdout + result.stderr); | ||
}); | ||
@@ -273,0 +276,0 @@ }); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
64466753
112
1395
118
5
18
66
+ Addedselenium-webdriver@^2.53.2
+ Addedadm-zip@0.4.4(transitive)
+ Addedrimraf@2.7.1(transitive)
+ Addedsax@0.6.1(transitive)
+ Addedselenium-webdriver@2.53.3(transitive)
+ Addedtmp@0.0.24(transitive)
+ Addedxml2js@0.4.4(transitive)
+ Addedxmlbuilder@15.1.1(transitive)