UNPKG

grading

Version:

Grading of student submissions, in particular programming tests.

133 lines (122 loc) 3.4 kB
import { PathLike } from "fs"; import { parseJsonWithComments } from "../cli/cliUtil"; export async function readGradingSchema(schemaFile: PathLike) { const gradingSchema: GradingSchema = await parseJsonWithComments(schemaFile); // post processing gradingSchema.tasks.forEach(task => { if (!task.grading) { task.grading = []; } }); return gradingSchema; } export interface GradingSchema { /** Only for VSCode, * @see MANUAL_CORRECTIONS_SCHEMA_URL */ $schema: string course: string, term: string, exam: string; points: number; minCoverageStatements?: number; penaltiesCoverageMax?: number; extraCoverageMax?: number; /** * Optional, if tests of penalties fail points are subtracted (well, * actually added but the penalty points are expected to be negative). * * If the penalties have a precondition, the penalty is ignored if the precondition fails. * * Output is usually only generated if a penalty test fails. * Otherwise it is not visible in the report later on. */ penalties?: Grading[]; tasks: Task[]; } export interface Task { name: string; suite?: string; skipHint?: string; points: number; preconditions?: Precondition[]; grading: Grading[]; manual: boolean; /* Deprecated, use images instead */ image?: Image; images?: Image[]; /** * Optional, if tests of penalties fail points are subtracted (well, * actually added but the penalty points are expected to be negative). * * If the penalties have a precondition, the penalty is ignored if the precondition fails. * * Output is usually only generated if a penalty test fails. * Otherwise it is not visible in the report later on. */ penalties?: Grading[]; } export interface Image { src: string; text: string; missing?: string width?: string } /** * Bewertung (or Penalty) */ export interface Grading { suite?: string; tests: string[]; isBonus?: boolean; /** * Points, equally divided for each test. * If the Bewertung is a penalty, the points are expected to be negative. */ points: number; /** * If the precondition fails, no further tests are analyzed. * If the Bewertung is positive, 0 points are given. * If the Bewertung is a penalty, 0 points are subtracted as well. */ preconditions?: Precondition[]; /** * Do not access this property directly, instead * use {@link gradingText}. */ text?: string; /** * Deprecated, use images instead */ image?: Image; images?: Image[]; } /** * If not provided, text of first test is used. */ export function gradingText(grading: Grading) { if (grading.text) { return grading.text; } if (grading.tests.length > 0) { return grading.tests[0]; } throw new Error("Grading does not define any tests (and no text).") } export interface Precondition { test: string; /** * Use preconditionText instead */ failure?: string; suite?: string; } /** * If not provided, text of first test is used. */ export function preconditionText(precondition: Precondition) { if (precondition.failure) { return precondition.failure; } return precondition.test; }