UNPKG

grading

Version:

Grading of student submissions, in particular programming tests.

85 lines (69 loc) 2.63 kB
import { Submitter } from "../cli/submitter"; import { GRADING_SCHEMA_URL } from "../constants"; import { Grading, GradingSchema, Task } from "./gradingschema"; import { loadUnitReport } from "./reportLoader"; export async function generateGradingSchema(reportsDir: string, submitter: Submitter) { const unitCheck = await loadUnitReport(reportsDir, submitter.submissionId, "check"); if (!unitCheck) { program.error(`No unit check report with ID ${submitter.submissionId} found in ${reportsDir}, cannot generate schema`); } const gradingSchema: GradingSchema = { $schema: GRADING_SCHEMA_URL, course: "Generated", term: "WS/SS", exam: "Exam", points: 100, tasks: [] } gradingSchema.term = computeTerm(); const testSuites = unitCheck.testsuite instanceof Array ? unitCheck.testsuite : [unitCheck.testsuite]; const pointsPerTask = Math.round(100 / testSuites.length); let totalPoints = 0; for (let counter = 0; counter < testSuites.length; counter++) { const testSuite = testSuites[counter]; const task: Task = { name: computeNameFromSuite(testSuite.name, counter), suite: testSuite.name, points: counter < testSuites.length - 1 ? pointsPerTask : 100 - totalPoints, grading: [], manual: false } gradingSchema.tasks.push(task); totalPoints += task.points; const testCases = testSuite.testcase; const grading: Grading = { points: task.points, text: `Generated from test suite ${testSuite.name} with ${testCases.length} test cases.`, tests: testCases.map(testCase=>testCase.name) } task.grading.push(grading); } return gradingSchema; } function computeTerm() { const now = new Date(); const month = now.getMonth(); let year = now.getFullYear(); const term = month < 3 || month>9 ? "WS" : "SS"; if (term==='WS') { if (month < 3) year--; return term + " " + year + "/" + ((year+1)%2000); } else { return term + " " + year; } } function computeNameFromSuite(name: string, counter: number): string { if (!name) { return "Task " + (1 + counter); } const parts = name.split("."); for (let i = parts.length-1; i >= 0; i--) { if ( ["ts", "js", "test", "check", "spec", "jsx", "tsx"].includes(parts[i])) { parts.splice(i, 1); } } if (parts.length > 0) { return parts.join(" "); } return parts[0] ?? ("Task " + (1 + counter)); }