grading
Version:
Grading of student submissions, in particular programming tests.
78 lines (71 loc) • 3.03 kB
text/typescript
import { error, log, warn } from '../cli/cliUtil';
import fs from "fs";
import path from "path";
import xml2js from "xml2js";
import { parseNumbers } from "xml2js/lib/processors";
import { Coverage } from "./coverage";
import { Testsuites } from '../junit';
/**
* Loads JUnit-Report.
* It returns a Testuites object.
*/
export async function loadUnitReport(reportsDir: string, submissionID: string, type: "student" | "check") {
const reportFile = path.join(reportsDir, `_${submissionID}_junit.${type}.xml`);
try {
if (fs.existsSync(reportFile)) {
const xmlParser = new xml2js.Parser({
mergeAttrs: true, explicitArray: false, trim: true, charkey: "message",
attrValueProcessors: [parseNumbers]
});
const fileContent = await fs.promises.readFile(reportFile, "utf-8");
const unitReport = await xmlParser.parseStringPromise(fileContent);
const testsuites = unitReport.testsuites as Testsuites;
if (!Array.isArray(testsuites.testsuite)) { // enforce array
testsuites.testsuite = [testsuites.testsuite];
}
testsuites.testsuite.forEach(testsuite => {
if (typeof testsuite.name !== 'string') { // enforce string
testsuite.name = String(testsuite.name);
} else {
testsuite.name = testsuite.name.trim();
}
if (!Array.isArray(testsuite.testcase)) { // enforce array
testsuite.testcase = [testsuite.testcase];
}
testsuite.testcase.forEach(testcase => {
if (typeof testcase.name !== 'string') { // enforce string
testcase.name = String(testcase.name)
} else {
testcase.name = testcase.name.trim();
}
});
});
return testsuites;
} else {
warn(`Warning, unit report "${reportFile}" not found.`)
}
} catch (err) {
warn("Error loading " + reportFile + ": " + err);
}
return null;
}
/**
* Reads coverage report in clover format
*/
export async function loadCoverageReport(reportsDir: string, submissionid: string, type: "student" | "check") {
const coverageFile = path.join(reportsDir, `_${submissionid}_coverage.${type}.xml`);
try {
if (fs.existsSync(coverageFile)) {
const xmlParser = new xml2js.Parser({
mergeAttrs: true, explicitArray: false, trim: true, charkey: "message",
attrValueProcessors: [parseNumbers]
});
const fileContent = await fs.promises.readFile(coverageFile, "utf-8");
const coverageReport = await xmlParser.parseStringPromise(fileContent);
return coverageReport.coverage as Coverage;
}
} catch (err) {
warn("Error loading " + coverageFile + ": " + err);
}
return null;
}