UNPKG

incubed

Version:

Typescript-version of the incubed client

148 lines 7.33 kB
"use strict"; /*********************************************************** * This file is part of the Slock.it IoT Layer. * * The Slock.it IoT Layer contains: * * - USN (Universal Sharing Network) * * - INCUBED (Trustless INcentivized remote Node Network) * ************************************************************ * Copyright (C) 2016 - 2018 Slock.it GmbH * * All Rights Reserved. * ************************************************************ * You may use, distribute and modify this code under the * * terms of the license contract you have concluded with * * Slock.it GmbH. * * For information about liability, maintenance etc. also * * refer to the contract concluded with Slock.it GmbH. * ************************************************************ * For more information, please refer to https://slock.it * * For questions, please contact info@slock.it * ***********************************************************/ Object.defineProperty(exports, "__esModule", { value: true }); const mocha = require("mocha"); // tslint:disable-next-line:no-submodule-imports const mu = require("mocha/lib/utils"); const fs = require("fs"); const memoryLogger_1 = require("./memoryLogger"); function color(colorName, content) { return `<span style="color:${colorName}">${content}</span>`; } /** * * reporter writing html including logs * * @export * @class USNReporter */ class TestReporter extends mocha.reporters.Spec { constructor(runner) { super(runner); this.root = 'test/report/'; this.results = []; runner.on('pass', (test) => this.reportTest(test, null, false)); runner.on('fail', (test, error) => this.reportTest(test, error, false)); runner.on('pending', (test) => this.reportTest(test, null, true)); runner.on('end', () => this.createIndex()); runner.on('test', () => this.lastStart = Date.now()); if (!fs.existsSync(this.root)) fs.mkdirSync(this.root); } writeHtml(fileName, title, body) { fs.writeFileSync(this.root + fileName, '<html><head><style>' + 'body, td { background-color: black; color:white; font-family: sans-serif; vertical-align:top; padding-right:10px;padding-bottom:10px }' + '</style><title>' + title + '</title></head><body>' + body + '</body></html>', 'utf-8'); } createIndex() { this.writeHtml('index.html', 'Test Result', '<h2>Test Results</h2>' + '<div style="padding-bottom:10px"><a style="color:yellow" href="coverage/index.html">Code Coverage</a></div>' + '<table border=0 cellspacing=0 cellpadding=0>' + this.results.map(r => '<tr><td colspan=2>' + r.title + '</td></tr>' + r.tests.map(t => `<tr><td>&nbsp;&nbsp;- </td><td><a style='color:${t.status === 'pass' ? 'green' : (t.status === 'fail' ? 'red' : 'white')}' href="${t.details}">${t.title}</a></td><td style='text-align:end'>${t.time} ms</td><td>${t.error || ''}</td></tr>`).join('')).join('') + '</table>'); } createError(test) { if (!test.err) return { message: '', stack: '' }; let message = test.err.toString(); let stackString; // <=IE7 stringifies to [Object Error]. Since it can be overloaded, we // check for the result of the stringifying. if (message === '[object Error]') message = test.err.message; if (test.err.stack) { const indexOfMessage = test.err.stack.indexOf(test.err.message); stackString = (indexOfMessage === -1) ? test.err.stack : test.err.stack.substr(test.err.message.length + indexOfMessage); } else if (test.err.sourceURL && test.err.line !== undefined) { // Safari doesn't give you a stack. Let's at least provide a source line. stackString = '\n(' + test.err.sourceURL + ':' + test.err.line + ')'; } stackString = stackString || ''; return { message, stack: stackString, err: test.err }; } reportTest(test, error, pending) { const err = this.createError(test); const logs = memoryLogger_1.getLogsAndClear(); const title = test.fullTitle(); const simpleTitle = test.title; const parentTitle = test.parent.title; const now = Date.now(); const fName = title.replace(/\W/g, '_') + '.html'; const eq = (error && error.expected !== undefined && '<span style="font-family:monospace; color:green">' + mu.stringify(error.expected) + '</span> != <br/><span style="font-family:monospace; color:red">' + mu.stringify(error.actual) + '</span>') || ''; let suite = this.results.find(_ => _.title === parentTitle); if (!suite) this.results.push(suite = { title: parentTitle, tests: [] }); this.createIndex(); const res = { title: simpleTitle, status: pending ? 'pending' : (error ? 'fail' : 'pass'), time: now - this.lastStart, error: error && err.message + '<br/>' + eq + ' <pre style="color:grey">npm test -- --grep \"' + simpleTitle + '\" </pre>', details: fName }; suite.tests.push(res); setTimeout(() => { const log = toHTML(logs); this.writeHtml(fName, simpleTitle, '<h2>' + parentTitle + ' / ' + simpleTitle + '</h2>' + ' <ul><li>Time : ' + res.time + '</li>' + '<li>Result: ' + (pending ? color('gray', 'skipped') : (error ? color('red', 'failed') : color('green', 'passed'))) + '</li>' + (error ? '<li>Error: ' + err.message + '<br>' + eq + getFileContent(err.stack) + ' <pre>' + err.stack + '</pre></li>' : '') + '</ul>' + '<h3>Log:</h3>' + log); }, 0); } } function toHTML(logs) { return '<div style="font-family: monospace;white-space:pre">' + logs.map((log, i) => { let l = '<div style="color:'; if (log.level === 'info') l += 'white'; if (log.level === 'error') l += 'red'; if (log.level === 'tx') l += 'green'; if (log.level === 'debug') l += 'gray'; l += '">' + (i + 1) + ' | ' + log.level.toUpperCase() + ' ' + log.message; if (log.data) { l += log.data.map(d => '<div style="padding-left:30px;color:gray">' + JSON.stringify(d, null, 2) + '</div>').join(''); } return l + '</div>'; }).join('') + '</div>'; } function getFileContent(stack) { const reg = /at.*?\((js\/test\/.*?\.js):(\d+)/; const found = stack.match(reg); if (!found) return ''; const file = found[1]; const line = parseInt(found[2]); let r = '<pre style="color:grey">'; const content = fs.readFileSync(file, 'utf-8').split('\n'); for (let i = Math.max(0, line - 4); i < Math.min(content.length - 1, line + 3); i++) r += '' + (i + 1) + ' <span ' + (i === line - 1 ? ' style="color:red"' : '') + '>' + content[i] + '</span>\n'; return r + '</pre>'; } module.exports = TestReporter; //# sourceMappingURL=mochaReporter.js.map