UNPKG

microvium

Version:

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

126 lines 5.96 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.anyGrepSelector = void 0; const code_coverage_utils_1 = require("../lib/code-coverage-utils"); const native_vm_1 = require("../lib/native-vm"); const utils_1 = require("../lib/utils"); const path_1 = __importDefault(require("path")); const fs_1 = __importDefault(require("fs")); const os_1 = __importDefault(require("os")); const colors_1 = __importDefault(require("colors")); const microviumCFilename = './native-vm/microvium.c'; const coverageHits = {}; let anyFailures = false; const rootArtifactDir = './test/end-to-end/artifacts'; const coveragePoints = (0, code_coverage_utils_1.getCoveragePoints)(fs_1.default.readFileSync(microviumCFilename, 'utf8').split(/\r?\n/g), microviumCFilename); exports.anyGrepSelector = process.argv.some(x => x === '-g' || x === '--grep'); const allTestsFilename = path_1.default.join(rootArtifactDir, 'all-tests.json'); const allTests = fs_1.default.existsSync(allTestsFilename) ? new Set(JSON.parse(fs_1.default.readFileSync(allTestsFilename, 'utf8'))) : new Set(); const remainingTests = new Set([...allTests]); let isFirstSetup = true; // Note: I couldn't figure out a builtin way of doing a global setup and // teardown across all tests, so I'm just keeping a list of tests and running // the global teardown when we've done all of them. This will have issues if we // delete or rename tests. If that happens, delete the `all-tests.json` output // file and it will recreate it on the next run. setup(function () { if (isFirstSetup) { globalSetup(); isFirstSetup = false; } }); teardown(function () { if (this.currentTest && this.currentTest.isFailed()) { anyFailures = true; } if (this.currentTest) { const titlePath = this.currentTest.titlePath().join(' '); allTests.add(titlePath); if (remainingTests.has(titlePath)) { remainingTests.delete(titlePath); if (remainingTests.size === 0) { globalTeardown(); } } else { // Otherwise, there's a change to the set of test cases (0, utils_1.writeTextFile)(allTestsFilename, JSON.stringify([...allTests], null, 4)); } } }); process.on('beforeExit', () => { // If there are remaining tests when the process is exiting, it means we haven't run the teardown if (remainingTests.size > 0) { globalTeardown(); } }); function globalSetup() { native_vm_1.NativeVM.setCoverageCallback((id, mode, indexInTable, tableSize, line) => { let hitInfo = coverageHits[id]; if (!hitInfo) { hitInfo = { lineHitCount: 0 }; if (mode === native_vm_1.CoverageCaseMode.TABLE) { hitInfo.hitCountByTableEntry = {}; hitInfo.tableSize = tableSize; } coverageHits[id] = hitInfo; } hitInfo.lineHitCount++; if (mode === native_vm_1.CoverageCaseMode.TABLE) { const tableHitCount = (0, utils_1.notUndefined)(hitInfo.hitCountByTableEntry); tableHitCount[indexInTable] = (tableHitCount[indexInTable] || 0) + 1; } }); } function globalTeardown() { native_vm_1.NativeVM.setCoverageCallback(undefined); const anySkips = remainingTests.size > 0; const summaryPath = path_1.default.resolve(rootArtifactDir, 'code-coverage-summary.txt'); let coverageHitLocations = 0; let coveragePossibleHitLocations = 0; for (const c of coveragePoints) { const hitInfo = coverageHits[c.id]; if (!hitInfo) { coveragePossibleHitLocations++; } else { if (hitInfo.tableSize !== undefined) { coveragePossibleHitLocations += hitInfo.tableSize; } else { coveragePossibleHitLocations++; } if (hitInfo.hitCountByTableEntry !== undefined) { const numberOfItemsInTableThatWereHit = Object.keys(hitInfo.hitCountByTableEntry).length; coverageHitLocations += numberOfItemsInTableThatWereHit; } else { // Else we just say that the line was hit coverageHitLocations++; } } } if (!exports.anyGrepSelector && !anySkips && !anyFailures) { const coverageOneLiner = `${coverageHitLocations} of ${coveragePossibleHitLocations} (${(coverageHitLocations / coveragePossibleHitLocations * 100).toFixed(1)}%)`; const microviumCFilenameRelative = path_1.default.relative(process.cwd(), microviumCFilename); (0, utils_1.writeTextFile)(path_1.default.resolve(rootArtifactDir, 'code-coverage-details.json'), JSON.stringify(coverageHits)); const summaryLines = [`microvium.c code coverage: ${coverageOneLiner}`]; (0, utils_1.writeTextFile)(summaryPath, summaryLines.join(os_1.default.EOL)); const expectedButNotHit = coveragePoints .filter(p => (p.type === 'normal') && !coverageHits[p.id]); (0, code_coverage_utils_1.updateCoverageMarkers)(true, !anySkips && !anyFailures && !exports.anyGrepSelector); if (expectedButNotHit.length) { throw new Error('The following coverage points were expected but not hit in the tests\n' + expectedButNotHit .map(p => ` at ${microviumCFilenameRelative}:${p.lineI + 1} ID(${p.id})`) .join('\n ')); } console.log(`\n ${colors_1.default.green('√')} ${colors_1.default.gray('microvium.c code coverage: ')}${coverageOneLiner}`); } } //# sourceMappingURL=code-coverage.test.js.map