From 7853b88b0ae57dde654f0cb6edc350ca873693e8 Mon Sep 17 00:00:00 2001 From: Alex Mickelson Date: Wed, 21 Aug 2024 21:19:30 -0600 Subject: [PATCH] tests --- .../local/quiz/utils/quizMarkdownUtils.ts | 1 - .../tests/markdown/quiz/quizMarkdown.test.ts | 254 ++++++++++++++++++ 2 files changed, 254 insertions(+), 1 deletion(-) create mode 100644 nextjs/src/models/local/tests/markdown/quiz/quizMarkdown.test.ts diff --git a/nextjs/src/models/local/quiz/utils/quizMarkdownUtils.ts b/nextjs/src/models/local/quiz/utils/quizMarkdownUtils.ts index 1aca211..1d0ac27 100644 --- a/nextjs/src/models/local/quiz/utils/quizMarkdownUtils.ts +++ b/nextjs/src/models/local/quiz/utils/quizMarkdownUtils.ts @@ -1,4 +1,3 @@ -import { LocalQuiz } from "../localQuiz"; import { quizQuestionMarkdownUtils } from "./quizQuestionMarkdownUtils"; const extractLabelValue = (input: string, label: string): string => { diff --git a/nextjs/src/models/local/tests/markdown/quiz/quizMarkdown.test.ts b/nextjs/src/models/local/tests/markdown/quiz/quizMarkdown.test.ts new file mode 100644 index 0000000..daf6a72 --- /dev/null +++ b/nextjs/src/models/local/tests/markdown/quiz/quizMarkdown.test.ts @@ -0,0 +1,254 @@ +import { describe, it, expect } from "vitest"; +import { LocalQuiz } from "../../../../../models/local/quiz/localQuiz"; +import { quizMarkdownUtils } from "../../../../../models/local/quiz/utils/quizMarkdownUtils"; + +// Test suite for QuizMarkdown +describe("QuizMarkdownTests", () => { + it("can serialize quiz to markdown", () => { + const quiz: LocalQuiz = { + name: "Test Quiz", + description: ` +# quiz description + +this is my description in markdown + +\`here is code\` +`, + lockAt: new Date(8640000000000000).toISOString(), // DateTime.MaxValue equivalent in TypeScript + dueAt: new Date(8640000000000000).toISOString(), + shuffleAnswers: true, + oneQuestionAtATime: false, + localAssignmentGroupName: "someId", + allowedAttempts: -1, + showCorrectAnswers: false, + questions: [], + }; + + const markdown = quizMarkdownUtils.toMarkdown(quiz); + + expect(markdown).toContain("Name: Test Quiz"); + expect(markdown).toContain(quiz.description); + expect(markdown).toContain("ShuffleAnswers: true"); + expect(markdown).toContain("OneQuestionAtATime: false"); + expect(markdown).toContain("AssignmentGroup: someId"); + expect(markdown).toContain("AllowedAttempts: -1"); + }); + + it("can parse markdown quiz with no questions", () => { + const rawMarkdownQuiz = ` +Name: Test Quiz +ShuffleAnswers: true +OneQuestionAtATime: false +DueAt: 2023-08-21T23:59:00 +LockAt: 2023-08-21T23:59:00 +AssignmentGroup: Assignments +AllowedAttempts: -1 +Description: this is the +multi line +description +--- +`; + + const quiz = LocalQuiz.parseMarkdown(rawMarkdownQuiz); + + const expectedDescription = ` +this is the +multi line +description`; + + expect(quiz.name).toBe("Test Quiz"); + expect(quiz.shuffleAnswers).toBe(true); + expect(quiz.oneQuestionAtATime).toBe(false); + expect(quiz.allowedAttempts).toBe(-1); + expect(quiz.description.trim()).toBe(expectedDescription.trim()); + }); + + it("can parse markdown quiz with password", () => { + const password = "this-is-the-password"; + const rawMarkdownQuiz = ` +Name: Test Quiz +Password: ${password} +ShuffleAnswers: true +OneQuestionAtATime: false +DueAt: 2023-08-21T23:59:00 +LockAt: 2023-08-21T23:59:00 +AssignmentGroup: Assignments +AllowedAttempts: -1 +Description: this is the +multi line +description +--- +`; + + const quiz = LocalQuiz.parseMarkdown(rawMarkdownQuiz); + + expect(quiz.password).toBe(password); + }); + + it("can parse markdown quiz and configure to show correct answers", () => { + const rawMarkdownQuiz = ` +Name: Test Quiz +ShuffleAnswers: true +OneQuestionAtATime: false +ShowCorrectAnswers: false +DueAt: 2023-08-21T23:59:00 +LockAt: 2023-08-21T23:59:00 +AssignmentGroup: Assignments +AllowedAttempts: -1 +Description: this is the +multi line +description +--- +`; + + const quiz = LocalQuiz.parseMarkdown(rawMarkdownQuiz); + + expect(quiz.showCorrectAnswers).toBe(false); + }); + + it("can parse quiz with questions", () => { + const rawMarkdownQuiz = ` +Name: Test Quiz +ShuffleAnswers: true +OneQuestionAtATime: false +DueAt: 2023-08-21T23:59:00 +LockAt: 2023-08-21T23:59:00 +AssignmentGroup: Assignments +AllowedAttempts: -1 +Description: this is the +multi line +description +--- +Points: 2 +\`some type\` of question + +with many + +\`\`\` +lines +\`\`\` + +*a) true +b) false + + endline`; + + const quiz = LocalQuiz.parseMarkdown(rawMarkdownQuiz); + const firstQuestion = quiz.questions[0]; + + expect(firstQuestion.questionType).toBe(QuestionType.MULTIPLE_CHOICE); + expect(firstQuestion.points).toBe(2); + expect(firstQuestion.text).toContain("```"); + expect(firstQuestion.text).toContain("`some type` of question"); + expect(firstQuestion.answers[0].text).toBe("true"); + expect(firstQuestion.answers[0].correct).toBe(true); + expect(firstQuestion.answers[1].correct).toBe(false); + expect(firstQuestion.answers[1].text).toContain("endline"); + }); + + it("can parse multiple questions", () => { + const rawMarkdownQuiz = ` +Name: Test Quiz +ShuffleAnswers: true +OneQuestionAtATime: false +DueAt: 2023-08-21T23:59:00 +LockAt: 2023-08-21T23:59:00 +AssignmentGroup: Assignments +AllowedAttempts: -1 +Description: this is the +multi line +description +--- +Which events are triggered when the user clicks on an input field? +[*] click +--- +Points: 2 +\`some type\` of question +*a) true +b) false +`; + + const quiz = LocalQuiz.parseMarkdown(rawMarkdownQuiz); + const firstQuestion = quiz.questions[0]; + expect(firstQuestion.points).toBe(1); + expect(firstQuestion.questionType).toBe(QuestionType.MULTIPLE_ANSWERS); + + const secondQuestion = quiz.questions[1]; + expect(secondQuestion.points).toBe(2); + expect(secondQuestion.questionType).toBe(QuestionType.MULTIPLE_CHOICE); + }); + + it("short answer to markdown is correct", () => { + const rawMarkdownQuiz = ` +Name: Test Quiz +ShuffleAnswers: true +OneQuestionAtATime: false +DueAt: 2023-08-21T23:59:00 +LockAt: 2023-08-21T23:59:00 +AssignmentGroup: Assignments +AllowedAttempts: -1 +Description: this is the +multi line +description +--- +Which events are triggered when the user clicks on an input field? +short answer +`; + + const quiz = LocalQuiz.parseMarkdown(rawMarkdownQuiz); + const firstQuestion = quiz.questions[0]; + + const questionMarkdown = firstQuestion.toMarkdown(); + const expectedMarkdown = ` +Points: 1 +Which events are triggered when the user clicks on an input field? +short_answer`; + expect(questionMarkdown).toContain(expectedMarkdown); + }); + + it("negative points is allowed", () => { + const rawMarkdownQuiz = ` +Name: Test Quiz +ShuffleAnswers: true +OneQuestionAtATime: false +DueAt: 2023-08-21T23:59:00 +LockAt: 2023-08-21T23:59:00 +AssignmentGroup: Assignments +AllowedAttempts: -1 +Description: this is the +multi line +description +--- +Points: -4 +Which events are triggered when the user clicks on an input field? +short answer +`; + + const quiz = LocalQuiz.parseMarkdown(rawMarkdownQuiz); + const firstQuestion = quiz.questions[0]; + expect(firstQuestion.points).toBe(-4); + }); + + it("floating point points is allowed", () => { + const rawMarkdownQuiz = ` +Name: Test Quiz +ShuffleAnswers: true +OneQuestionAtATime: false +DueAt: 2023-08-21T23:59:00 +LockAt: 2023-08-21T23:59:00 +AssignmentGroup: Assignments +AllowedAttempts: -1 +Description: this is the +multi line +description +--- +Points: 4.56 +Which events are triggered when the user clicks on an input field? +short answer +`; + + const quiz = LocalQuiz.parseMarkdown(rawMarkdownQuiz); + const firstQuestion = quiz.questions[0]; + expect(firstQuestion.points).toBe(4.56); + }); +});