Commit 38a3efe6 authored by Jakob Moser's avatar Jakob Moser
Browse files

Wrap pooltest exercises in test() function

parent 9a784041
Loading
Loading
Loading
Loading
+28 −6
Changes for static/js/exercises.api.mjs: 28 added lines, 6 removed lines.
Original line number Diff line number Diff line
@@ -12,8 +12,7 @@ import { arrayEquals } from "./util.mjs"
 * exercises.mjs.
 * 
 * Instances of this class are not created directly by the user, instead,
 * they are created using the `exercise` function which will also immediately
 * add them to the global list of exercises.
 * they are created using the `exercise` function.
 */
class Exercise {
    #execute = null
@@ -203,9 +202,26 @@ class ExerciseExecutionContext {
}

/**
 * List of all exercises created using the `exericse` function.
 * A test. It has a human-readable name and a list of exercises.
 */
export const exercises = []
class Test {
    constructor(name, exercises) {
        this.name = name
        this.exercises = exercises
    }
}

/**
 * Create a test. Returns the test object
 * 
 * @param {String} name A human-readable name of the test
 * @param {Function} exerciseCreationFunction A function that calls `exercise` to create exercise.
 * Note: This must be a function declared with the function keyword, arrow functions (()=>{...}) do not work.
 */
export function test(name, exerciseCreationFunction) {

    const exerciseCollector = {
        exercises: [],

        /**
         * Add an exercise.
@@ -214,7 +230,13 @@ export const exercises = []
         * @param {Function} execute A function that executes the exercise. 
         * Note: This must be a function declared with the function keyword, arrow functions (()=>{...}) do not work.
         */
export function exercise(name, execute) {
        exercise(name, execute) {
            const exerciseObj = new Exercise(name, execute)
    exercises.push(exerciseObj)
            this.exercises.push(exerciseObj)
        }
    }

    exerciseCreationFunction.bind(exerciseCollector)()

    return new Test(name, exerciseCollector.exercises)
}
+5 −4
Changes for static/js/exercises.mjs: 5 added lines, 4 removed lines.
Original line number Diff line number Diff line
/** Exercises that students must pass to pass the pool test **/
import { exercise } from "./exercises.api.mjs";
export { exercises } from "./exercises.api.mjs"
import { test } from "./exercises.api.mjs";

exercise("Datei anlegen", async function () {
export const pooltest = test("Pooltest Sommersemester 2022", function () {
    this.exercise("Datei anlegen", async function () {
        this.describe(`Erstelle eine Datei mit dem Namen "botschaft" und dem Inhalt
        "Der Junge sieht den Mann mit dem Fernglas." (jeweils ohne
        Anführungszeichen)`)
@@ -14,7 +14,7 @@ exercise("Datei anlegen", async function () {
        this.verify("cat botschaft").hasOutput("Der Junge sieht den Mann mit dem Fernglas.")
    })

exercise("Berechtigungen anpassen", async function () {
    this.exercise("Berechtigungen anpassen", async function () {
        this.describe(`Ändere die Berechtigungen der Datei "/resources/supergeheim" so, dass nur der Besitzer sie anzeigen kann
        (und sonst niemand).`)

@@ -31,3 +31,4 @@ exercise("Berechtigungen anpassen", async function () {

    // To add another exercise, simply copy and paste an exercise(...) block from above and adjust it.
    // Order is respected, so you can e.g. order the exercises by increasing difficulty.    
})
+5 −5
Changes for static/js/state.mjs: 5 added lines, 5 removed lines.
Original line number Diff line number Diff line
/** Read and modify the current state of the application. Allows saving to local storage. */

import { exercises } from "./exercises.mjs"
import { pooltest } from "./exercises.mjs"

export const currentState = {

@@ -46,8 +46,8 @@ export const currentState = {
            throw new Error("index must be a number")
        }

        if (index < 0 || index > exercises.length) {
            throw new Error(`Exercise index must be >= 0 and < exercises.length (${exercises.length})`)
        if (index < 0 || index > pooltest.exercises.length) {
            throw new Error(`Exercise index must be >= 0 and < exercises.length (${pooltest.exercises.length})`)
        }

        localStorage.setItem("exerciseIndex", index)
@@ -77,8 +77,8 @@ export const currentState = {
            throw new Error(`Can't solve the same exercise (${exerciseIndex}) twice`)
        }

        if (exerciseIndex < 0 || exerciseIndex > exercises.length) {
            throw new Error(`Exercise index must be >= 0 and < exercises.length (${exercises.length})`)
        if (exerciseIndex < 0 || exerciseIndex > pooltest.exercises.length) {
            throw new Error(`Exercise index must be >= 0 and < exercises.length (${pooltest.exercises.length})`)
        }

        const newIndices = this.solvedExercises
+6 −6
Changes for static/js/yalikejazz.mjs: 6 added lines, 6 removed lines.
Original line number Diff line number Diff line
import { currentState } from "./state.mjs"
import { exercises } from "./exercises.mjs"
import { pooltest } from "./exercises.mjs"
import { getHandInToken } from "./snakeoil.mjs"
import { createExerciseCard, displayAsSolved, displayAsNonCurrent, displayAsCurrent } from "./exercises.cards.mjs"

function findNextUnsolvedExerciseIndex(currentExerciseIndex) {
    if (currentState.solvedExercises.length === exercises.length) {
    if (currentState.solvedExercises.length === pooltest.exercises.length) {
        return null
    } else {
        let nextUnsolvedExerciseIndex = currentExerciseIndex
        while (currentState.solvedExercises.includes(nextUnsolvedExerciseIndex)) {
            nextUnsolvedExerciseIndex = (nextUnsolvedExerciseIndex + 1) % exercises.length
            nextUnsolvedExerciseIndex = (nextUnsolvedExerciseIndex + 1) % pooltest.exercises.length
        }

        return nextUnsolvedExerciseIndex
@@ -42,7 +42,7 @@ function createAndInitExerciseCard(exercise, exerciseIndex) {
 * meaning that description and action buttons are not visible).
 */
function initExerciseList() {
    document.querySelector("#exercises").append(...exercises.map(createAndInitExerciseCard))
    document.querySelector("#exercises").append(...pooltest.exercises.map(createAndInitExerciseCard))
}

/**
@@ -51,7 +51,7 @@ function initExerciseList() {
 */
function startExercise(exerciseIndex) {
    const cardEl = document.querySelector(`.exercise[data-exercise-index='${exerciseIndex}']`)
    const exercise = exercises[exerciseIndex]
    const exercise = pooltest.exercises[exerciseIndex]

    currentState.exerciseIndex = exerciseIndex
    exercise.onDescribed(description => cardEl.querySelector(".description").textContent = description)
@@ -108,7 +108,7 @@ function initActionLinks() {
}

export function main() {
    document.querySelector("#exerciseCnt").textContent = exercises.length
    document.querySelector("#exerciseCnt").textContent = pooltest.exercises.length
    if (currentState.firstStart) {
        // Show welcome message
        document.body.classList.add("overlay-shown")