UNPKG

microvium

Version:

A compact, embeddable scripting engine for microcontrollers for executing small scripts written in a subset of JavaScript.

155 lines 6.37 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.updateCoverageMarkers = exports.reconstructCoverageLine = exports.getCoveragePoints = void 0; const utils_1 = require("./utils"); const colors_1 = __importDefault(require("colors")); const fs_1 = __importDefault(require("fs")); const os_1 = __importDefault(require("os")); const path_1 = __importDefault(require("path")); function getCoveragePoints(sourceLines, filename) { const coveragePoints = []; for (const [lineI, line] of sourceLines.entries()) { let m = line.match(/^(\s*)CODE_COVERAGE(|_UNTESTED|_UNIMPLEMENTED|_ERROR_PATH)\((.*?)\);\s*(\/\/.*)?$/); if (m) { const info = { lineI, indent: m[1], type: m[2] === '' ? 'normal' : m[2] === '_UNTESTED' ? 'untested' : m[2] === '_UNIMPLEMENTED' ? 'unimplemented' : m[2] === '_ERROR_PATH' ? 'error-path' : (0, utils_1.unexpected)(), id: parseInt(m[3]), comment: m[4], }; coveragePoints.push(info); } else if (line.includes('CODE_COVERAGE') && !line.trim().startsWith('//')) { throw new Error(`Invalid CODE_COVERAGE marker\n at ${filename}:${lineI + 1}`); } m = line.match(/^(\s*)TABLE_COVERAGE\((.*?),(.*?)(?:,(.*?))?\);\s*(\/\/.*)?$/); if (m) { const info = { type: 'table', lineI, indent: m[1], indexInTable: m[2].trim(), tableSize: m[3].trim(), id: parseInt(m[4]), comment: m[5], }; coveragePoints.push(info); } else if (line.includes('TABLE_COVERAGE') && !line.trim().startsWith('//')) { throw new Error(`Invalid TABLE_COVERAGE marker\n at ${colors_1.default.red(`${filename}:${lineI + 1}`)}`); } } return coveragePoints; } exports.getCoveragePoints = getCoveragePoints; function reconstructCoverageLine(lineInfo, includeIndent) { let macroMain; switch (lineInfo.type) { case 'normal': macroMain = `CODE_COVERAGE(${lineInfo.id});`; break; case 'untested': macroMain = `CODE_COVERAGE_UNTESTED(${lineInfo.id});`; break; case 'unimplemented': macroMain = `CODE_COVERAGE_UNIMPLEMENTED(${lineInfo.id});`; break; case 'error-path': macroMain = `CODE_COVERAGE_ERROR_PATH(${lineInfo.id});`; break; case 'table': macroMain = `TABLE_COVERAGE(${lineInfo.indexInTable}, ${lineInfo.tableSize}, ${lineInfo.id});`; break; } return `${includeIndent ? lineInfo.indent : ''}${macroMain}${lineInfo.comment ? ' ' + lineInfo.comment : ''}`; } exports.reconstructCoverageLine = reconstructCoverageLine; /** * @param removeUntestedFlags Removes the `_UNTESTED` flag for paths that are hit. */ function updateCoverageMarkers(silent, removeUntestedFlags) { const hitInfoFilename = path_1.default.resolve('./test/end-to-end/artifacts/code-coverage-details.json'); const microviumCFilename = './native-vm/microvium.c'; const ids = new Set(); const toAssign = new Array(); const lines = fs_1.default.readFileSync(microviumCFilename, 'utf8') .split(/\r?\n/g); const log = (s) => !silent && console.log(s); const coveragePoints = getCoveragePoints(lines, microviumCFilename); for (const c of coveragePoints) { if (!isNaN(c.id)) { if (ids.has(c.id)) { console.error(` Warning: duplicate coverage ID ${c.id} at ` + colors_1.default.yellow(`${microviumCFilename}:${c.lineI + 1}`)); toAssign.push(c); } else { ids.add(c.id); } } else { toAssign.push(c); } } let changedCount = 0; let nextID = 1; for (const c of toAssign) { while (ids.has(nextID)) { nextID++; } const id = nextID++; c.id = id; } // If we have hit count information, then we calculate all lines based on hit information if (fs_1.default.existsSync(hitInfoFilename)) { const coverageHits = JSON.parse(fs_1.default.readFileSync(hitInfoFilename, 'utf8')); for (const c of coveragePoints) { const hitInfo = coverageHits[c.id]; if (hitInfo) { if (removeUntestedFlags && c.type === 'untested') c.type = 'normal'; if (hitInfo.tableSize !== undefined && hitInfo.hitCountByTableEntry !== undefined) { c.comment = `// Hit ${Object.keys(hitInfo.hitCountByTableEntry).length}/${hitInfo.tableSize}`; } else { c.comment = '// Hit'; } } else { c.comment = '// Not hit'; } const s = reconstructCoverageLine(c, false); const lineContent = `${c.indent}${s}`; if (lines[c.lineI] !== lineContent) { lines[c.lineI] = lineContent; log(` ${microviumCFilename}:${c.lineI + 1} ${s}`); changedCount++; } } } else { for (const c of toAssign) { const s = reconstructCoverageLine(c, false); lines[c.lineI] = `${c.indent}${s}`; log(`✓ ` + colors_1.default.green(`${microviumCFilename}:${c.lineI + 1} `) + s); changedCount++; } } if (!changedCount) { log(colors_1.default.cyan(`✓ All ${coveragePoints.length} coverage markers are up to date`)); } else { (0, utils_1.writeTextFile)(microviumCFilename, lines.join(os_1.default.EOL)); } } exports.updateCoverageMarkers = updateCoverageMarkers; //# sourceMappingURL=code-coverage-utils.js.map