microvium
Version:
A compact, embeddable scripting engine for microcontrollers for executing small scripts written in a subset of JavaScript.
157 lines • 7.51 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const chai_1 = require("chai");
const fs_extra_1 = __importDefault(require("fs-extra"));
const microvium = __importStar(require("../../lib"));
const lodash_1 = __importDefault(require("lodash"));
const path_1 = __importDefault(require("path"));
const shelljs_1 = __importDefault(require("shelljs"));
const utils_1 = require("../../lib/utils");
const colors_1 = __importDefault(require("colors"));
const artifactDir = './test/getting-started/code';
const debugShellOutput = false;
suite('getting-started', function () {
// Extract the source texts from the getting-started guide
const host1Text = fs_extra_1.default.readFileSync('./doc/getting-started.md', 'utf8');
let matches = host1Text
.matchAll(/<!-- Script (.*?) -->\r?\n```\w+\r?\n(.*?)\r?\n```/gs);
matches = [...matches];
const gettingStartedMDScripts = lodash_1.default.fromPairs([...matches].map(([, id, scriptText]) => [id, scriptText]));
fs_extra_1.default.mkdirpSync(artifactDir);
for (const [id, scriptText] of Object.entries(gettingStartedMDScripts)) {
(0, utils_1.writeTextFile)(path_1.default.join(artifactDir, id), scriptText);
}
let logOutput = [];
let suiteFailed = false;
this.afterEach(function () {
if (this.currentTest && this.currentTest.isFailed()) {
suiteFailed = true;
}
});
// The guide has steps that depend on the previous, so we skip the remainder of the suite on the first failure
this.beforeEach(function () {
if (suiteFailed) {
this.skip();
}
});
const evalHostScript = (scriptText) => {
logOutput = [];
const dummyRequire = (specifier) => {
chai_1.assert.deepEqual(specifier, 'microvium');
return microvium;
};
const realConsoleLog = console.log;
const tempCwd = process.cwd();
console.log = (arg) => logOutput.push(arg);
process.chdir(artifactDir);
try {
eval(`(function (require) { ${scriptText}\n })`)(dummyRequire);
}
finally {
process.chdir(tempCwd);
console.log = realConsoleLog;
}
};
const runMicroviumCLI = (commandArgs) => {
const result = shelljs_1.default.exec(`node ../../../dist/cli.js ${commandArgs}`, {
async: false,
cwd: artifactDir,
silent: true,
});
if (result.code !== 0) {
throw new Error(`Microvium CLI failed with code ${result.code}\n${result.stderr}`);
}
return result;
};
test('1.hello-world.mvm.js', () => {
// The first example executes on the CLI. I'm suppressing the snapshot
// output here just because the filename clashes with the output in the 3rd
// test case.
const result = runMicroviumCLI('1.hello-world.mvm.js --no-snapshot');
chai_1.assert.deepEqual(result.stdout.trim(), 'Hello, World!');
chai_1.assert.deepEqual(result.stderr.trim(), '');
});
test('2.with-custom-host.js', () => {
evalHostScript(gettingStartedMDScripts['2.with-custom-host.js']);
chai_1.assert.deepEqual(logOutput, ['Hello, World!']);
});
test('3.script.mvm.js', () => {
const result = runMicroviumCLI('script.mvm.js');
chai_1.assert.deepEqual(result.stderr.trim(), 'Output generated: script.mvm-bc\n116 bytes');
chai_1.assert.deepEqual(result.stdout.trim(), '');
});
test('4.restoring-a-snapshot.js', () => {
logOutput = [];
evalHostScript(gettingStartedMDScripts['4.restoring-a-snapshot.js']);
chai_1.assert.deepEqual(logOutput, ['Hello, World!']);
});
test('5.restoring-a-snapshot-in-c.c', async function () {
// This test case actually compiles the C code in the getting-started.md
// guide, so it takes a while
this.timeout(20000);
const buildDir = path_1.default.resolve(artifactDir, 'build');
// The guide says to copy the source files into the project dir, so to be
// completely fair, I'll do that here as well, so the `code` dir becomes a
// self-contained example without any external dependencies. This also means
// that users can refer to the artifact directory as a self-contained
// example.
fs_extra_1.default.mkdirpSync(path_1.default.resolve(artifactDir, 'microvium'));
fs_extra_1.default.mkdirpSync(buildDir);
fs_extra_1.default.copyFileSync('./dist-c/microvium.c', path_1.default.resolve(artifactDir, 'microvium/microvium.c'));
fs_extra_1.default.copyFileSync('./dist-c/microvium.h', path_1.default.resolve(artifactDir, 'microvium/microvium.h'));
fs_extra_1.default.copyFileSync('./dist-c/microvium_port_example.h', path_1.default.resolve(artifactDir, 'microvium_port.h'));
fs_extra_1.default.copyFileSync('./test/getting-started/CMakeLists.txt', path_1.default.resolve(artifactDir, 'CMakeLists.txt'));
const originalDir = process.cwd();
process.chdir(buildDir);
try {
debugShellOutput && console.log('cwd', process.cwd());
exec(`cmake ..`);
exec(`cmake --build .`);
process.chdir("..");
let result = exec('"./build/Debug/restoring-a-snapshot-in-c.exe"');
chai_1.assert.deepEqual(result.stderr, '');
chai_1.assert.deepEqual(result.stdout.trim(), 'Hello, World!');
}
finally {
process.chdir(originalDir);
}
});
});
function exec(cmd, requireSuccess = true) {
debugShellOutput && console.log(colors_1.default.cyan(cmd));
const result = shelljs_1.default.exec(cmd, { silent: !debugShellOutput });
if (requireSuccess && result.code !== 0) {
throw new Error(`${result.stderr}\nShell command failed with code ${result.code}`);
}
else if (result.code !== 0 && debugShellOutput) {
console.log(colors_1.default.yellow(`${result.stderr}\nWARNING: Shell command failed with code ${result.code}`));
}
return result;
}
//# sourceMappingURL=getting-started.test.js.map