muttley
Version:
Monitor Unit Test Tool
151 lines • 7.42 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs_1 = __importDefault(require("fs"));
const os_1 = __importDefault(require("os"));
const fast_xml_parser_1 = __importDefault(require("fast-xml-parser"));
const child_process_1 = require("child_process");
const test_runner_1 = require("./test-runner");
const logger_1 = require("./logger");
const command_line_1 = require("./command-line");
test_runner_1.FakeTestRunner; // add a reference so the dependency remains in the js file because test depends on it
class MochaTestRunner {
// eslint-disable-next-line class-methods-use-this
findTestsP(filePath) {
return new Promise((resolve, reject) => {
fs_1.default.readFile(filePath, (error, content) => {
if (error) {
reject(error);
}
else {
let suite = '';
const testcases = [];
content
.toString()
.split(os_1.default.EOL)
.forEach((line) => {
const matchDescribe = line.match(/[^a-zA-Z0-9]describe\(['"](.*)['"]/);
const matchIt = line.match(/[^a-zA-Z0-9]it\(['"](.*)['"]/);
if (matchDescribe) {
[, suite] = matchDescribe;
}
else if (matchIt) {
const [, name] = matchIt;
if (suite && name) {
testcases.push({ suite, name });
}
}
});
logger_1.logger.debug(`findTestsP ${filePath} => ${testcases}`);
resolve(testcases);
}
});
});
}
// eslint-disable-next-line class-methods-use-this
runFileP(filePath, onStart, onPass, onFail, onEnd) {
return new Promise(resolve => {
let passed = 0, failed = 0;
const cmd = command_line_1.config.testCmd;
const args = [...command_line_1.config.testArgs, filePath];
logger_1.logger.debug('exec @', process.cwd(), cmd, args);
child_process_1.exec([cmd, ...args].join(' '), (error, stdout, stderr) => {
onStart();
if (error) {
// Note - if mocha has failing tests, error is set like this :
// {"killed":false,"code":3,"signal":null,"cmd":"mocha /usr/src/app/demo/player.t.js
// --reporter=xunit --require source-map-support/register"}
// code=3 for 3 failing tests
// in this case stderr is blank
logger_1.logger.error(`mocha exe returned : ${error}`);
if (stderr) {
process.stdout.write(`error ${error.toString()}`);
process.stdout.write(JSON.stringify(error));
process.stdout.write(`stderr: ${stderr}`);
process.abort();
}
}
logger_1.logger.debug(`stdout: ${stdout}`);
logger_1.logger.debug(`stderr: ${stderr}`);
if (stderr) {
logger_1.logger.error('stderr output. You crashed mocha!');
onFail({
suite: 'mutt',
name: 'mutt',
fullMessage: `stderr output. You crashed mocha! ' ${stderr}`,
message: 'stderr output. You crashed mocha!',
stack: extractStack(stderr),
});
}
else {
// if there were errors in the runner avoid bad XML parse
const json = fast_xml_parser_1.default.parse(stdout, { ignoreAttributes: false, attributeNamePrefix: '' });
const suite = json.testsuite;
logger_1.logger.debug(suite);
// sometimes there is no testcase property on the suite.
// This is usually because the function tested is async
if (suite && suite.testcase) {
// if there is only a single case the testcase is *not* an array! Arrrrgg!
const cases = suite
.testcase.length
? suite.testcase
: [suite.testcase];
cases.forEach((testcase) => {
if (testcase.failure) {
logger_1.logger.debug(`failed: [${testcase.classname}] [${testcase.name}] [${testcase.time}]`);
logger_1.logger.debug('error message:\n', testcase.failure.replace(/\n+/g, '\n'));
failed++;
onFail({
suite: testcase.classname,
name: testcase.name,
fullMessage: testcase.failure,
message: extractError(testcase.failure),
stack: extractStack(testcase.failure),
});
}
else {
logger_1.logger.debug(`passed: [${testcase.classname}] [${testcase.name}] [${testcase.time}]`);
passed++;
const msPerSeconds = 1000;
onPass(testcase.classname, testcase.name, msPerSeconds * Number.parseFloat(testcase.time));
}
});
}
else {
logger_1.logger.error('No testcase output. Are you calling an async function without await?', suite);
onFail({
suite: 'mutt',
name: 'mutt',
fullMessage: 'No testcase output. Are you calling an async function without await?',
message: 'No testcase output. Are you calling an async function without await?',
stack: [],
});
}
}
onEnd(passed, failed);
resolve();
});
});
}
}
exports.MochaTestRunner = MochaTestRunner;
function extractError(message) {
return message.replace(/\n+/g, ' ');
}
function extractStack(stack) {
const ret = [];
stack.split(os_1.default.EOL).forEach((frame) => {
const start = frame.indexOf('(');
const end = frame.indexOf(':', start);
if (start > 0 && end > 0) {
const filepath = frame.substr(start + 1, end - start - 1);
const [line] = frame.substr(end + 1).split(':');
ret.push({ file: filepath, lineno: Number.parseInt(line, 10) });
}
});
logger_1.logger.debug('extractStack returns', ret);
return ret;
}
//# sourceMappingURL=mocha-runner.js.map