This package makes it easy to use Mocha inside Node.js, allowing you to run untrusted Mocha code with Chai – securely!
IMPORTANT: Requires Node.js 6 or newer.
Using npm:
npm i mocha-vm
Using yarn:
yarn add mocha-vm
In Node.js:
const run = require('mocha-vm').run;
const toHTML = require('mocha-vm').toHTML;
// Or using ES6+ destructuring assignment syntax
const { run, toHTML } = require('mocha-vm');
const { run } = require('mocha-vm');
const code = `
describe('addOne', function () {
it('should return 3 when the value is 2', function () {
assert.equal(addOne(2), 3);
});
it('should return 0 when the value is -1', function () {
assert.equal(addOne(-1), 0);
});
it('return a number', function () {
assert.isNumber(addOne(-1));
});
});
function addOne(x) {
return x + 1;
};`;
run(code).then(obj => console.log(obj));
code
String | Arrayoptions
String | Objectlibrary
String | Object (Default:'chai'
)
The code
argument can be a String
(containing a code snippet or a file path) or an Array
.
The options
argument allows you to use Node.js's built-in 'assert'
library, rather than 'chai'
(the default). To do this, use:
run(code, { library: 'assert' });
Or simply:
run(code, 'assert');
result
Object
The toHTML
function is a utility, allowing you to tranform the result of run
into an HTML string, which can easily be displayed on the client-side.
run(code).then(result => {
let html = toHTML(result);
return html;
});
If using vanilla JavaScript, you can insert the HTML code like follows:
let node = document.createElement("section");
node.className = "mocha-result";
node.innerHTML = html;
document.querySelector("body").appendChild(node);
If using React, you can safely pass it into the dangerouslySetInnerHTML
property:
<section className="mocha-result" dangerouslySetInnerHTML={{ __html: html }} />
By default, the code inside the string(s) can make use of:
- Chai's
assert
,expect
and/orshould
libraries. - Mocha's BDD methods, including
describe
,context
,it
,specify
,before
,after
,beforeEach
andafterEach
.
To find out more about using these methods, visit the Mocha and Chai websites.
IMPORTANT: The methods and libraries above are imported in advance. Your code will not run if you try to re-import them.
To pass a file path, it's recommended to use Node.js's built-in 'path'
module, as below:
const { run } = require('mocha-vm');
const { join } = require('path');
run(join(__dirname, 'tests.js')).then(obj => console.log(obj));
You can pass an Array
containing:
- only code snippets,
- only file paths,
- a mixture of the two.
For example:
const { run } = require('mocha-vm');
const { join } = require('path');
const test = `
describe('addOne', function () {
it('should return 3 when the value is 2', function () {
assert.equal(addOne(2), 3);
});
});`;
const functionToTest = `
function addOne(x) {
return x + 1;
};`;
run([test, functionToTest, join(__dirname, 'tests.js')]).then(obj =>
console.log(obj)
);
Aside from just running the tests, the run
function returns a Promise
containing the results of the tests. Using the tests from the Quick Example (above), we would get an object like this:
{
"summary": {
"passed": 3,
"failed": 0,
"tests": 3,
"suites": 1,
"depth": 0,
"duration": "32ms"
},
"data": [
{
"depth": 0,
"suite": "addOne",
"tests": [
{
"description": "should return 3 when the value is 2",
"passed": true
},
{
"description": "should return 0 when the value is -1",
"passed": true
},
{ "description": "should return a number", "passed": true }
],
"duration": "18ms"
}
]
}
If we were to use the toHTML
function and pass the object above as an argument, we would get the following HTML string:
<div class="mocha-item">
<p class="mocha-suite">addOne</p>
<p class="mocha-test passed"> ✓ should return 3 when the value is 2</p>
<p class="mocha-test passed"> ✓ should return 0 when the value is -1</p>
<p class="mocha-test passed"> ✓ should return a number</p>
</div>
<br>
<div class="mocha-summary">
<p class="mocha-passing">3 passing <span class="mocha-duration">(32ms)</span></p>
<p class="mocha-failing">0 failing</p>
</div>
This package depends on Mocha and Chai for testing, and vm2 for sandboxing.
This project is licensed under the MIT License.