Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

eshost

Package Overview
Dependencies
Maintainers
1
Versions
71
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

eshost - npm Package Compare versions

Comparing version 3.4.2 to 3.5.0

.travis.yml

3

lib/Agent.js

@@ -12,2 +12,3 @@ 'use strict';

this.args = options.hostArguments || [];
this.transform = options.transform || (x => x);

@@ -26,2 +27,4 @@ if (typeof this.args === 'string') {

code = this.transform(code);
if (options.async) {

@@ -28,0 +31,0 @@ return code;

11

lib/agents/BrowserAgent.js

@@ -7,4 +7,7 @@ 'use strict';

class BrowserAgent extends Agent {
constructor (hostPath) {
super(hostPath);
constructor (options) {
super(options);
this.webHost = options.webHost || 'localhost';
this.webPort = options.webPort || 1337;
this.id = agentId++;

@@ -15,4 +18,4 @@ }

return Server.start(this.id).then(_ => {
this._url = 'http://localhost:1337/?clientId=' + this.id +
'&shortName=' + this.shortName;
this._url = `http://${this.webHost}:${this.webPort}/` +
`?clientId=${this.id}&shortName=${this.shortName}`;
return this;

@@ -19,0 +22,0 @@ });

@@ -20,6 +20,18 @@ 'use strict';

// Because the input code may modify the global environment in ways that
// interfere with the normal operation of `eshost`, it must be run in a
// dedicated virtual machine.
//
// The "context" object for this virtual machine should be re-used if the
// input code invokes `$.evalScript`, but Node.js does not tolerate sharing
// context objects across virtual machines in this manner. Instead, define
// a new method for evaluating scripts in the context created here.
code = `
Function("return this;")().require = require;
var vm = require("vm");
vm.runInThisContext(${JSON.stringify(code)});
var eshostContext = vm.createContext({ require, console });
vm.runInESHostContext = function(code, options) {
return vm.runInContext(code, eshostContext, options);
};
vm.runInESHostContext(${JSON.stringify(code)});
`;

@@ -26,0 +38,0 @@

@@ -16,6 +16,4 @@ 'use strict';

createChildProcess(args) {
args = args || [];
args = args.concat(this.args);
return cp.spawn(this.hostPath, args);
createChildProcess(args = []) {
return cp.spawn(this.hostPath, this.args.concat(args));
}

@@ -22,0 +20,0 @@

@@ -56,3 +56,3 @@ 'use strict';

socket.on('print', str => this.gotStdout(str));
socket.on('print', ({value}) => this.gotStdout(value));
socket.on('execDone', _ => this.gotExecDone());

@@ -59,0 +59,0 @@ if (this._onGotSocket) this._onGotSocket(this);

@@ -66,3 +66,3 @@ 'use strict';

return baseP.then(_ => super.destroy()).then(_ => this._driver.quit());
return baseP.then(_ => this._driver.quit()).then(_ => super.destroy());
}

@@ -69,0 +69,0 @@ }

{
"name": "eshost",
"version": "3.4.2",
"version": "3.5.0",
"description": "Invoke ECMAScript scripts in any command line JS engine.",

@@ -5,0 +5,0 @@ "main": "lib/eshost.js",

@@ -58,2 +58,10 @@ ## eshost

* **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.
* **transform**: A function to map the source to some other source before running the result on the underlying host.
* **webHost**: for web browser hosts only; URL host name from which to serve browser assets; optional; defaults to `"localhost"`
* **webPort**: for web browser hosts only; URL port number from which to serve browser assets; optional; defaults to `1337`
* **capabilities**: for `remote` host only; the Selenium/WebDriver capabilities to request for the remote session; all specified attributes will be forwarded to the server; [a listing of available attributes is available in the Selenium project's wiki](https://github.com/SeleniumHQ/selenium/wiki/DesiredCapabilities); the following attributes are required:
* **capabilities.browserName**
* **capabilities.platform**
* **capabilities.version**
* **webdriverServer**: for `remote` host only; URL of the WebDriver server to which commands should be issued

@@ -145,1 +153,29 @@ ### Agent API

Sets a global property name to value.
### Running the tests
This project's tests can be executed with the following command:
npm test
The above command will cause tests to be run against all supported hosts.
Executables for each host must be available on the system's `PATH` environment
variable.
One or more hosts may be skipped from the test run by setting corresponding
environment variables whose name match the pattern `ESHOST_SKIP_*`, where `*`
is the capitalized name of the host. For example, in a Unix-like system, the
following command executes the project's tests but skips JavaScriptCore and D8
tests:
ESHOST_SKIP_JSC=1 ESHOST_SKIP_D8=1 npm test
Tests for the "remote" agent can be configured to run against any arbitrary
Selenium/WebDriver configuration through the specification of the following
environment variables: `ESHOST_REMOTE_BROWSERNAME`, `ESHOST_REMOTE_VERSION`,
`ESHOST_REMOTE_PLATFORM`. These values are used to define the host's
capabilities; see the above documentation of `eshost.createAgent` for more
details. For example, in a Unix-like system, the following command executes the
project's tests in a remote instance of the Firefox web browser:
ESHOST_REMOTE_BROWSERNAME=firefox npm test

@@ -23,2 +23,8 @@ (function() {

var fscript = fdoc.createElement('script');
// The following is a workaround for a bug in Chromium related to reporting
// errors produced from evaluating code using `eval`.
// https://bugs.chromium.org/p/chromium/issues/detail?id=746564
fdoc.write('<body>');
fscript.textContent = this.source;

@@ -86,4 +92,7 @@ fdoc.body.appendChild(fscript);

function print(str) {
$.socket.emit('print', str);
function print(value) {
// If the `undefined` value is emitted directly, Socket.io will transmit the
// `null` value in its place, invalidating the reported output. Emit the
// value as a property of an ordinary object to avoid this behavior.
$.socket.emit('print', {value: value});
}

@@ -90,0 +99,0 @@

@@ -33,3 +33,3 @@ var vm = require('vm');

} else {
vm.runInThisContext(code, {displayErrors: false});
vm.runInESHostContext(code, {displayErrors: false});
}

@@ -36,0 +36,0 @@

@@ -6,14 +6,24 @@ 'use strict';

const isWindows = process.platform === 'win32' ||
process.env.OSTYPE === 'cygwin' ||
process.env.OSTYPE === 'msys';
const remoteCapabilities = {
browserName: process.env.ESHOST_REMOTE_BROWSERNAME || 'firefox',
platform: process.env.ESHOST_REMOTE_PLATFORM || 'ANY',
version: process.env.ESHOST_REMOTE_VERSION || ''
};
const hosts = [
['./hosts/js.exe', 'jsshell'],
['./hosts/ch.exe', 'ch'],
['c:/program files/nodejs/node.exe', 'node'],
['../v8/build/Release/d8.exe', 'd8'],
['../webkit/build/bin64/jsc.exe', 'jsc'],
/*[undefined, 'chrome'],*/
//['C:/Program Files (x86)/Mozilla Firefox/firefox.exe', 'firefox'],
/*['C:/Program Files (x86)/Nightly/firefox.exe', 'firefox'],
['C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe', 'chrome'],
*/
['jsshell', { hostPath: 'js' }],
['ch', { hostPath: 'ch' }],
['node', { hostPath: 'node' }],
['d8', { hostPath: 'd8' }],
['jsc', { hostPath: 'jsc' }],
['chrome', { hostPath: 'chrome' }],
['firefox', { hostPath: 'firefox' }],
['remote', {
webdriverServer: 'http://localhost:4444/wd/hub',
capabilities: remoteCapabilities
}
],
];

@@ -28,320 +38,497 @@

hosts.forEach(function (record) {
const host = record[0];
const type = record[1];
const type = record[0];
const options = record[1];
const effectiveType = type === 'remote' ?
options.capabilities.browserName : type;
if (options.hostPath && isWindows) {
options.hostPath += '.exe';
}
describe(`${type} (${host})`, function () {
describe(`${type} (${options.hostPath || effectiveType})`, function () {
this.timeout(20000);
let agent;
before(function() {
return runify.createAgent(type, { hostPath: host }).then(a => agent = a);
});
if (process.env['ESHOST_SKIP_' + type.toUpperCase()]) {
this.skip();
return;
}
after(function() {
return agent.destroy();
if (type === 'remote') {
this.timeout(60 * 1000);
}
});
it('allows custom shortNames', function() {
return runify.createAgent(type, { hostPath: host, shortName: '$testing' }).then(agent => {
return agent.evalScript('$testing.evalScript("print(1)")').then(result => {
assert(result.error === null, 'no error');
assert.equal(result.stdout.indexOf('1'), 0);
});
describe('normal script evaluation', function() {
let agent;
before(function() {
return runify.createAgent(type, options)
.then(a => agent = a);
});
});
it('runs SyntaxErrors', function () {
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');
after(function() {
return agent.destroy();
});
});
it('runs thrown SyntaxErrors', function () {
return agent.evalScript('throw new SyntaxError("Custom Message");').then(function (result) {
assert(result.error, 'error is present');
assert.equal(result.stdout, '', 'stdout not present');
it('runs SyntaxErrors', function () {
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');
});
});
assert.equal(result.error.message, 'Custom Message');
assert.equal(result.error.name, 'SyntaxError');
assert.equal(result.error.stack[0].lineNumber, 1);
it('runs thrown SyntaxErrors', function () {
return agent.evalScript('throw new SyntaxError("Custom Message");').then(function (result) {
assert(result.error, 'error is present');
assert.equal(result.stdout, '', 'stdout not present');
assert.equal(result.error.message, 'Custom Message');
assert.equal(result.error.name, 'SyntaxError');
assert.equal(result.error.stack[0].lineNumber, 1);
});
});
});
it('runs thrown TypeErrors', function () {
return agent.evalScript('throw new TypeError("Custom Message");').then(function (result) {
assert(result.error, 'error is present');
assert.equal(result.stdout, '', 'stdout not present');
it('runs thrown TypeErrors', function () {
return agent.evalScript('throw new TypeError("Custom Message");').then(function (result) {
assert(result.error, 'error is present');
assert.equal(result.stdout, '', 'stdout not present');
assert.equal(result.error.message, 'Custom Message');
assert.equal(result.error.name, 'TypeError');
assert.equal(result.error.stack[0].lineNumber, 1);
assert.equal(result.error.message, 'Custom Message');
assert.equal(result.error.name, 'TypeError');
assert.equal(result.error.stack[0].lineNumber, 1);
});
});
});
it('runs thrown RangeErrors', function () {
return agent.evalScript('throw new RangeError("Custom Message");').then(function (result) {
assert(result.error, 'error is present');
assert.equal(result.stdout, '', 'stdout not present');
it('runs thrown RangeErrors', function () {
return agent.evalScript('throw new RangeError("Custom Message");').then(function (result) {
assert(result.error, 'error is present');
assert.equal(result.stdout, '', 'stdout not present');
assert.equal(result.error.message, 'Custom Message');
assert.equal(result.error.name, 'RangeError');
assert.equal(result.error.stack[0].lineNumber, 1);
assert.equal(result.error.message, 'Custom Message');
assert.equal(result.error.name, 'RangeError');
assert.equal(result.error.stack[0].lineNumber, 1);
});
});
});
it('runs thrown Errors', function () {
return agent.evalScript('throw new Error("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, 'Error');
it('runs thrown Errors', function () {
return agent.evalScript('throw new Error("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, 'Error');
});
});
});
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('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('runs thrown custom Errors that don\'t have Error.prototype', function () {
return agent.evalScript(`
function Foo2Error(msg) {
this.message = msg;
}
Foo2Error.prototype.name = 'Foo2Error';
Foo2Error.prototype.toString = function () {
return 'Foo2Error: ' + this.message;
}
it('runs thrown custom Errors that don\'t have Error.prototype', function () {
return agent.evalScript(`
function Foo2Error(msg) {
this.message = msg;
}
Foo2Error.prototype.name = 'Foo2Error';
Foo2Error.prototype.toString = function () {
return 'Foo2Error: ' + this.message;
}
throw new Foo2Error('FAIL!');
`).then(result => {
assert.equal(result.stdout, '', 'stdout not present');
assert(result.error, 'error is present');
assert.equal(result.error.message, 'FAIL!');
assert.equal(result.error.name, 'Foo2Error');
});
})
throw new Foo2Error('FAIL!');
`).then(result => {
assert.equal(result.stdout, '', 'stdout not present');
assert(result.error, 'error is present');
assert.equal(result.error.message, 'FAIL!');
assert.equal(result.error.name, 'Foo2Error');
});
})
it('runs thrown Errors without messages', function () {
return agent.evalScript('throw new Error();').then(function (result) {
assert.equal(result.stdout, '', 'stdout not present');
assert(result.error, 'error is present');
assert.equal(result.error.message, undefined);
assert.equal(result.error.name, 'Error');
it('runs thrown Errors without messages', function () {
return agent.evalScript('throw new Error();').then(function (result) {
assert.equal(result.stdout, '', 'stdout not present');
assert(result.error, 'error is present');
assert.equal(result.error.message, undefined);
assert.equal(result.error.name, 'Error');
});
});
});
it('runs thrown errors from eval', function () {
return agent.evalScript('eval("\'\\u000Astr\\u000Aing\\u000A\'") === "\\u000Astr\\u000Aing\\u000A"')
.then(function (result) {
assert.equal(result.stdout, '', 'stdout not present');
assert(result.error, 'error is present');
assert(result.error.message); // message should be present (but is implementation defined)
assert.equal(result.error.name, 'SyntaxError');
it('runs thrown errors from eval', function () {
return agent.evalScript('eval("\'\\u000Astr\\u000Aing\\u000A\'") === "\\u000Astr\\u000Aing\\u000A"')
.then(function (result) {
assert.equal(result.stdout, '', 'stdout not present');
assert(result.error, 'error is present');
assert(result.error.message); // message should be present (but is implementation defined)
assert.equal(result.error.name, 'SyntaxError');
});
});
});
it('gathers stdout', function () {
return agent.evalScript('print("foo")').then(function(result) {
assert(result.stdout.match(/^foo\r?\n/), 'Unexpected stdout: ' + result.stdout);
it('gathers stdout', function () {
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 agent.evalScript(`
var x = 2;
$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);
it('can eval in new realms', function () {
return agent.evalScript(`
var x = 2;
$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);
});
});
});
it('can create new realms', function() {
return agent.evalScript(`
var sub$ = $.createRealm({});
sub$.evalScript("var x = 1");
sub$.evalScript("print(x)");
subsub$ = sub$.createRealm({});
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);
it('can create new realms', function() {
return agent.evalScript(`
var sub$ = $.createRealm({});
sub$.evalScript("var x = 1");
sub$.evalScript("print(x)");
subsub$ = sub$.createRealm({});
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);
});
});
});
it('can set globals in new realms', function () {
return agent.evalScript(`
var x = 1;
$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);
it('can set globals in new realms', function () {
return agent.evalScript(`
var x = 1;
$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);
});
});
});
it('can eval in new scripts', function () {
return agent.evalScript(`
var x = 2;
$.evalScript("x = 3;");
print(x);
`).then(function(result) {
assert(result.stdout.match(/^3\r?\n/m), 'Unexpected stdout: ' + result.stdout + result.stderr);
it('can eval in new scripts', function () {
return agent.evalScript(`
var x = 2;
$.evalScript("x = 3;");
print(x);
`).then(function(result) {
assert(result.stdout.match(/^3\r?\n/m), 'Unexpected stdout: ' + result.stdout + result.stderr);
});
});
});
it('returns errors from evaling in new script', function () {
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);
it('returns errors from evaling in new script', function () {
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);
});
});
});
it('can eval lexical bindings in new scripts', function () {
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);
it('can eval lexical bindings in new scripts', function () {
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);
});
});
});
it('can set properties in new realms', function() {
return agent.evalScript(`
var sub$ = $.createRealm({});
sub$.evalScript("var x = 1");
sub$.evalScript("print(x)");
it('can set properties in new realms', function() {
return agent.evalScript(`
var sub$ = $.createRealm({});
sub$.evalScript("var x = 1");
sub$.evalScript("print(x)");
sub$.setGlobal("x", 2);
sub$.setGlobal("x", 2);
sub$.evalScript("print(x)");
`).then(function(result) {
assert(result.stdout.match(/^1\r?\n2\r?\n/m), 'Unexpected stdout: ' + result.stdout + result.stderr);
sub$.evalScript("print(x)");
`).then(function(result) {
assert(result.stdout.match(/^1\r?\n2\r?\n/m), 'Unexpected stdout: ' + result.stdout + result.stderr);
});
});
});
it('can access properties from new realms', function() {
return agent.evalScript(`
var sub$ = $.createRealm({});
sub$.evalScript("var x = 1");
it('can access properties from new realms', function() {
return agent.evalScript(`
var sub$ = $.createRealm({});
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);
print(sub$.getGlobal("x"));
`).then(function(result) {
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 () {
it('runs async code', function () {
return agent.evalScript(`
if ($.global.Promise === undefined) {
print('async result');
$.destroy()
});
}
`, { async: true }).then(result => {
assert(result.stdout.match(/async result/), 'Unexpected stdout: ' + result.stdout + result.stderr);
} 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('accepts destroy callbacks', function () {
return agent.evalScript(`
$child = $.createRealm({ destroy: function () { print("destroyed") }});
$child.destroy();
`)
.then(result => {
assert(result.stdout.match(/destroyed/), 'Unexpected stdout: ' + result.stdout + result.stderr);
it('accepts destroy callbacks', function () {
return agent.evalScript(`
$child = $.createRealm({ destroy: function () { print("destroyed") }});
$child.destroy();
`)
.then(result => {
assert(result.stdout.match(/destroyed/), 'Unexpected stdout: ' + result.stdout + result.stderr);
});
});
});
it('runs in the proper mode', function () {
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);
it('runs in the proper mode', function () {
return agent.evalScript(`
'use strict'
"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);
`)
.then(function(result) {
assert(result.stdout.match(/^true\r?\n/m), 'Unexpected stdout: ' + result.stdout + result.stderr);
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);
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);
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);
return agent.evalScript(`
/*---
---*/
" some other prolog "
"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);
return agent.evalScript(`
// normal comment
/*---
---*/
" some other prolog "
// another comment
"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);
});
});
it("prints values correctly", function () {
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);
print(undefined);
print(null);
print('string');
print(true);
print(false);
print(0);
print(1);
print(1.2);
print(-1);
`).then((result) => {
var values;
assert.equal(result.stderr, '');
values = result.stdout.split(/\r?\n/);
assert.equal(values[0], 'undefined')
assert.equal(values[1], 'null')
assert.equal(values[2], 'string')
assert.equal(values[3], 'true')
assert.equal(values[4], 'false')
assert.equal(values[5], '0')
assert.equal(values[6], '1')
assert.equal(values[7], '1.2')
assert.equal(values[8], '-1')
});
});
it('tolerates broken execution environments', function () {
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);
Object.defineProperty(Object.prototype, "length", {
get: function () {
return 1;
},
configurable: true
});
print('okay');
`).then((result) => {
assert.equal(result.stderr, '');
assert(result.stdout.match(/^okay\r?\n/m));
});
});
it('supports realm nesting', function () {
return agent.evalScript(`
/*---
---*/
" some other prolog "
"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);
x = 0;
$.createRealm().evalScript(\`
x = '';
$.createRealm().evalScript(\\\`
x = {};
print(typeof x);
\\\`);
print(typeof x);
\`);
print(typeof x);
`)
.then((result) => {
assert.equal(result.stderr, '');
assert(result.stdout.match(/^object\r?\nstring\r?\nnumber\r?\n/m));
});
});
it('observes correct cross-script interaction semantics', function () {
return agent.evalScript(`
// normal comment
/*---
---*/
" some other prolog "
// another comment
"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);
print($.evalScript('let eshost;').type);
print($.evalScript('let eshost;').type);
`)
.then((result) => {
assert.equal(result.stderr, '');
assert(result.stdout.match(/^normal\r?\nthrow/m));
});
});
// mostly this test shouldn't hang (if it hangs, it's a bug)
it('can kill infinite loops', function () {
// The GeckoDriver project cannot currently destroy browsing sessions
// whose main thread is blocked.
// https://github.com/mozilla/geckodriver/issues/825
if (effectiveType === 'firefox') {
this.skip();
return;
}
var resultP = agent.evalScript(`while (true) { }; print(2);`);
return timeout(100).then(_ => {
var stopP = agent.stop();
return Promise.all([resultP, stopP]);
}).then(record => {
const result = record[0];
assert(!result.stdout.match(/2/), 'Unexpected stdout: ' + result.stdout);
});
});
it('creates "optional" environments correctly (hostArgs)', function() {
// browsers are irrelevant to this test
if (['firefox', 'chrome', 'remote'].includes(type)) {
this.skip();
return;
}
let source = '';
let hostArguments = '';
// Setup special cases
if (type === 'ch') {
hostArguments = '-Intl-';
source = 'print(typeof Intl === "undefined");';
}
if (type === 'd8') {
hostArguments = '--expose_gc';
source = 'print(typeof gc === "function");';
}
if (type === 'jsc') {
hostArguments = '--useWebAssembly=true';
source = 'print(typeof WebAssembly === "function");';
}
if (type === 'jsshell') {
hostArguments = '--no-wasm';
source = 'print(typeof WebAssembly === "undefined");';
}
if (type === 'node') {
hostArguments = '--expose_gc';
source = 'print(typeof gc === "function");';
}
return runify.createAgent(type, Object.assign({ hostArguments }, options))
.then(a => {
agent = a;
return agent.evalScript(source)
.then(result => {
assert.equal(result.stdout.trim(), 'true');
});
});
});
});
// mostly this test shouldn't hang (if it hangs, it's a bug)
it('can kill infinite loops', function () {
var resultP = agent.evalScript(`while (true) { }; print(2);`);
return timeout(100).then(_ => {
var stopP = agent.stop();
describe('`shortName` option', function () {
it('allows custom shortNames', function() {
const withShortName = Object.assign({ shortName: '$testing' }, options);
return runify.createAgent(type, withShortName).then(agent => {
var p = agent.evalScript('$testing.evalScript("print(1)")').then(result => {
assert(result.error === null, 'no error');
assert.equal(result.stdout.indexOf('1'), 0);
});
return Promise.all([resultP, stopP]);
}).then(record => {
const result = record[0];
assert(!result.stdout.match(/2/), 'Unexpected stdout: ' + result.stdout);
})
})
p.catch(function() {}).then(() => agent.destroy());
return p;
});
});
});
describe('`transform` option', function () {
let agent;
function transform(x) { return `print("${x}")`; }
before(function() {
let withTransform = Object.assign({ transform }, options);
return runify.createAgent(type, withTransform).then(a => agent = a);
});
after(function() {
return agent.destroy();
});
it('runs transforms', function () {
return agent.evalScript('foo').then(function(result) {
assert(result.stdout.match(/^foo\r?\n/), 'Unexpected stdout: ' + result.stdout);
});
});
});
});
});

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc