mirror of
https://github.com/alexmickelson/canvasManagement.git
synced 2026-03-25 23:28:33 -06:00
matched tests with distractors
This commit is contained in:
@@ -5,6 +5,7 @@ export interface LocalQuizQuestion {
|
||||
questionType: QuestionType;
|
||||
points: number;
|
||||
answers: LocalQuizQuestionAnswer[];
|
||||
matchDistractors: string[];
|
||||
}
|
||||
|
||||
export enum QuestionType {
|
||||
|
||||
@@ -126,6 +126,12 @@ export const quizQuestionMarkdownUtils = {
|
||||
const answerArray = question.answers.map((a, i) =>
|
||||
getAnswerMarkdown(question, a, i)
|
||||
);
|
||||
|
||||
const distractorText =
|
||||
question.questionType === QuestionType.MATCHING
|
||||
? question.matchDistractors?.map((d) => `\n^ - ${d}`).join("") ?? ""
|
||||
: "";
|
||||
|
||||
const answersText = answerArray.join("\n");
|
||||
const questionTypeIndicator =
|
||||
question.questionType === "essay" ||
|
||||
@@ -133,7 +139,7 @@ export const quizQuestionMarkdownUtils = {
|
||||
? question.questionType
|
||||
: "";
|
||||
|
||||
return `Points: ${question.points}\n${question.text}\n${answersText}${questionTypeIndicator}`;
|
||||
return `Points: ${question.points}\n${question.text}\n${answersText}${distractorText}${questionTypeIndicator}`;
|
||||
},
|
||||
|
||||
parseMarkdown(input: string, questionIndex: number): LocalQuizQuestion {
|
||||
@@ -153,13 +159,6 @@ export const quizQuestionMarkdownUtils = {
|
||||
|
||||
const linesWithoutPoints = firstLineIsPoints ? lines.slice(1) : lines;
|
||||
|
||||
// const linesWithoutAnswers = linesWithoutPoints.filter(
|
||||
// (line, index) =>
|
||||
// !_validFirstAnswerDelimiters.some((prefix) =>
|
||||
// line.trimStart().startsWith(prefix)
|
||||
// )
|
||||
// );
|
||||
|
||||
const { linesWithoutAnswers } = linesWithoutPoints.reduce(
|
||||
({ linesWithoutAnswers, taking }, currentLine) => {
|
||||
if (!taking)
|
||||
@@ -208,11 +207,22 @@ export const quizQuestionMarkdownUtils = {
|
||||
? getAnswers(linesWithoutPoints, questionIndex, questionType)
|
||||
: [];
|
||||
|
||||
const answersWithoutDistractors =
|
||||
questionType === QuestionType.MATCHING
|
||||
? answers.filter((a) => a.text)
|
||||
: answers;
|
||||
|
||||
const distractors =
|
||||
questionType === QuestionType.MATCHING
|
||||
? answers.filter((a) => !a.text).map((a) => a.matchedText ?? "")
|
||||
: [];
|
||||
|
||||
const question: LocalQuizQuestion = {
|
||||
text: description,
|
||||
questionType,
|
||||
points,
|
||||
answers,
|
||||
answers: answersWithoutDistractors,
|
||||
matchDistractors: distractors,
|
||||
};
|
||||
return question;
|
||||
},
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import { QuestionType } from "../../../../../models/local/quiz/localQuizQuestion";
|
||||
import { quizMarkdownUtils } from "@/models/local/quiz/utils/quizMarkdownUtils";
|
||||
import { quizQuestionMarkdownUtils } from "@/models/local/quiz/utils/quizQuestionMarkdownUtils";
|
||||
|
||||
describe("MatchingTests", () => {
|
||||
it("can parse matching question", () => {
|
||||
const rawMarkdownQuiz = `
|
||||
Name: Test Quiz
|
||||
ShuffleAnswers: true
|
||||
OneQuestionAtATime: false
|
||||
DueAt: 21/08/2023 23:59:00
|
||||
LockAt: 21/08/2023 23:59:00
|
||||
AssignmentGroup: Assignments
|
||||
AllowedAttempts: -1
|
||||
Description:
|
||||
---
|
||||
Match the following terms & definitions
|
||||
|
||||
^ statement - a single command to be executed
|
||||
^ identifier - name of a variable
|
||||
^ keyword - reserved word that has special meaning in a program (e.g. class, void, static, etc.)
|
||||
`;
|
||||
|
||||
const quiz = quizMarkdownUtils.parseMarkdown(rawMarkdownQuiz);
|
||||
const firstQuestion = quiz.questions[0];
|
||||
|
||||
expect(firstQuestion.questionType).toBe(QuestionType.MATCHING);
|
||||
expect(firstQuestion.text).not.toContain("statement");
|
||||
expect(firstQuestion.answers[0].matchedText).toBe(
|
||||
"a single command to be executed"
|
||||
);
|
||||
});
|
||||
|
||||
it("can create markdown for matching question", () => {
|
||||
const rawMarkdownQuiz = `
|
||||
Name: Test Quiz
|
||||
ShuffleAnswers: true
|
||||
OneQuestionAtATime: false
|
||||
DueAt: 21/08/2023 23:59:00
|
||||
LockAt: 21/08/2023 23:59:00
|
||||
AssignmentGroup: Assignments
|
||||
AllowedAttempts: -1
|
||||
Description:
|
||||
---
|
||||
Match the following terms & definitions
|
||||
|
||||
^ statement - a single command to be executed
|
||||
^ identifier - name of a variable
|
||||
^ keyword - reserved word that has special meaning in a program (e.g. class, void, static, etc.)
|
||||
`;
|
||||
|
||||
const quiz = quizMarkdownUtils.parseMarkdown(rawMarkdownQuiz);
|
||||
const questionMarkdown = quizQuestionMarkdownUtils.toMarkdown(
|
||||
quiz.questions[0]
|
||||
);
|
||||
const expectedMarkdown = `Points: 1
|
||||
Match the following terms & definitions
|
||||
|
||||
^ statement - a single command to be executed
|
||||
^ identifier - name of a variable
|
||||
^ keyword - reserved word that has special meaning in a program (e.g. class, void, static, etc.)`;
|
||||
|
||||
expect(questionMarkdown).toContain(expectedMarkdown);
|
||||
});
|
||||
|
||||
it("whitespace is optional", () => {
|
||||
const rawMarkdownQuiz = `
|
||||
Name: Test Quiz
|
||||
ShuffleAnswers: true
|
||||
OneQuestionAtATime: false
|
||||
DueAt: 21/08/2023 23:59:00
|
||||
LockAt: 21/08/2023 23:59:00
|
||||
AssignmentGroup: Assignments
|
||||
AllowedAttempts: -1
|
||||
Description:
|
||||
---
|
||||
Match the following terms & definitions
|
||||
|
||||
^statement - a single command to be executed
|
||||
`;
|
||||
|
||||
const quiz = quizMarkdownUtils.parseMarkdown(rawMarkdownQuiz);
|
||||
expect(quiz.questions[0].answers[0].text).toBe("statement");
|
||||
});
|
||||
|
||||
it("can have distractors", () => {
|
||||
const rawMarkdownQuiz = `
|
||||
Name: Test Quiz
|
||||
ShuffleAnswers: true
|
||||
OneQuestionAtATime: false
|
||||
DueAt: 21/08/2023 23:59:00
|
||||
LockAt: 21/08/2023 23:59:00
|
||||
AssignmentGroup: Assignments
|
||||
AllowedAttempts: -1
|
||||
Description:
|
||||
---
|
||||
Match the following terms & definitions
|
||||
|
||||
^ statement - a single command to be executed
|
||||
^ - this is the distractor
|
||||
`;
|
||||
|
||||
const quiz = quizMarkdownUtils.parseMarkdown(rawMarkdownQuiz);
|
||||
expect(quiz.questions[0].matchDistractors).toEqual([
|
||||
"this is the distractor",
|
||||
]);
|
||||
});
|
||||
|
||||
it("can have distractors and be persisted", () => {
|
||||
const rawMarkdownQuiz = `
|
||||
Name: Test Quiz
|
||||
ShuffleAnswers: true
|
||||
OneQuestionAtATime: false
|
||||
DueAt: 21/08/2023 23:59:00
|
||||
LockAt: 21/08/2023 23:59:00
|
||||
AssignmentGroup: Assignments
|
||||
AllowedAttempts: -1
|
||||
Description:
|
||||
---
|
||||
Match the following terms & definitions
|
||||
|
||||
^ statement - a single command to be executed
|
||||
^ - this is the distractor
|
||||
`;
|
||||
|
||||
const quiz = quizMarkdownUtils.parseMarkdown(rawMarkdownQuiz);
|
||||
const quizMarkdown = quizMarkdownUtils.toMarkdown(quiz);
|
||||
|
||||
expect(quizMarkdown).toContain(
|
||||
"^ statement - a single command to be executed\n^ - this is the distractor"
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -59,7 +59,8 @@ describe("QuizDeterministicChecks", () => {
|
||||
text: "test short answer",
|
||||
questionType: QuestionType.SHORT_ANSWER,
|
||||
points: 1,
|
||||
answers: []
|
||||
answers: [],
|
||||
matchDistractors: [],
|
||||
},
|
||||
],
|
||||
allowedAttempts: -1,
|
||||
@@ -86,6 +87,7 @@ describe("QuizDeterministicChecks", () => {
|
||||
text: "test essay",
|
||||
questionType: QuestionType.ESSAY,
|
||||
points: 1,
|
||||
matchDistractors: [],
|
||||
answers: []
|
||||
},
|
||||
],
|
||||
@@ -113,6 +115,7 @@ describe("QuizDeterministicChecks", () => {
|
||||
text: "test multiple answer",
|
||||
questionType: QuestionType.MULTIPLE_ANSWERS,
|
||||
points: 1,
|
||||
matchDistractors: [],
|
||||
answers: [
|
||||
{ text: "yes", correct: true },
|
||||
{ text: "no", correct: true },
|
||||
@@ -144,6 +147,7 @@ describe("QuizDeterministicChecks", () => {
|
||||
text: "test multiple choice",
|
||||
questionType: QuestionType.MULTIPLE_CHOICE,
|
||||
points: 1,
|
||||
matchDistractors: [],
|
||||
answers: [
|
||||
{ text: "yes", correct: true },
|
||||
{ text: "no", correct: false },
|
||||
@@ -175,6 +179,7 @@ describe("QuizDeterministicChecks", () => {
|
||||
text: "test matching",
|
||||
questionType: QuestionType.MATCHING,
|
||||
points: 1,
|
||||
matchDistractors: [],
|
||||
answers: [
|
||||
{ text: "yes", correct: true, matchedText: "testing yes" },
|
||||
{ text: "no", correct: true, matchedText: "testing no" },
|
||||
|
||||
Reference in New Issue
Block a user