mirror of
https://github.com/alexmickelson/canvasManagement.git
synced 2026-03-25 23:28:33 -06:00
added shorter syntax for multipel choice
This commit is contained in:
62
Management.Test/Markdown/Quiz/MatchingTests.cs
Normal file
62
Management.Test/Markdown/Quiz/MatchingTests.cs
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
using LocalModels;
|
||||||
|
|
||||||
|
public class MatchingTests
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void CanParseMatchingQuestion()
|
||||||
|
{
|
||||||
|
var 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:
|
||||||
|
---
|
||||||
|
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.)
|
||||||
|
";
|
||||||
|
|
||||||
|
var quiz = LocalQuiz.ParseMarkdown(rawMarkdownQuiz);
|
||||||
|
var firstQuestion = quiz.Questions.First();
|
||||||
|
firstQuestion.QuestionType.Should().Be(QuestionType.MATCHING);
|
||||||
|
firstQuestion.Text.Should().NotContain("statement");
|
||||||
|
firstQuestion.Answers.First().MatchedText.Should().Be("a single command to be executed");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void CanCreateMarkdownForMatchingQuesiton()
|
||||||
|
{
|
||||||
|
var 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:
|
||||||
|
---
|
||||||
|
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.)
|
||||||
|
";
|
||||||
|
|
||||||
|
var quiz = LocalQuiz.ParseMarkdown(rawMarkdownQuiz);
|
||||||
|
var questionMarkdown = quiz.Questions.First().ToMarkdown();
|
||||||
|
var 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.)";
|
||||||
|
questionMarkdown.Should().Contain(expectedMarkdown);
|
||||||
|
}
|
||||||
|
}
|
||||||
83
Management.Test/Markdown/Quiz/MultipleAnswersTests.cs
Normal file
83
Management.Test/Markdown/Quiz/MultipleAnswersTests.cs
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
using LocalModels;
|
||||||
|
|
||||||
|
public class MultipleAnswersTests
|
||||||
|
{
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void QuzMarkdownIncludesMultipleAnswerQuestion()
|
||||||
|
{
|
||||||
|
var quiz = new LocalQuiz()
|
||||||
|
{
|
||||||
|
Name = "Test Quiz",
|
||||||
|
Description = "desc",
|
||||||
|
LockAt = DateTime.MaxValue,
|
||||||
|
DueAt = DateTime.MaxValue,
|
||||||
|
ShuffleAnswers = true,
|
||||||
|
OneQuestionAtATime = false,
|
||||||
|
LocalAssignmentGroupName = "someId",
|
||||||
|
AllowedAttempts = -1,
|
||||||
|
Questions = new LocalQuizQuestion[]
|
||||||
|
{
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Text = "oneline question",
|
||||||
|
Points = 1,
|
||||||
|
QuestionType = QuestionType.MULTIPLE_ANSWERS,
|
||||||
|
Answers = new LocalQuizQuestionAnswer[]
|
||||||
|
{
|
||||||
|
new() { Correct = true, Text = "true" },
|
||||||
|
new() { Correct = true, Text = "false"},
|
||||||
|
new() { Correct = false, Text = "neither"},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var markdown = quiz.ToMarkdown();
|
||||||
|
var expectedQuestionString = @"
|
||||||
|
Points: 1
|
||||||
|
oneline question
|
||||||
|
[*] true
|
||||||
|
[*] false
|
||||||
|
[ ] neither
|
||||||
|
";
|
||||||
|
markdown.Should().Contain(expectedQuestionString);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void CanParseQuestionWithMultipleAnswers()
|
||||||
|
{
|
||||||
|
var 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
|
||||||
|
[*] focus
|
||||||
|
[*] mousedown
|
||||||
|
[] submit
|
||||||
|
[] change
|
||||||
|
[] mouseout
|
||||||
|
[] keydown
|
||||||
|
---
|
||||||
|
";
|
||||||
|
|
||||||
|
var quiz = LocalQuiz.ParseMarkdown(rawMarkdownQuiz);
|
||||||
|
var firstQuestion = quiz.Questions.First();
|
||||||
|
firstQuestion.Points.Should().Be(1);
|
||||||
|
firstQuestion.QuestionType.Should().Be(QuestionType.MULTIPLE_ANSWERS);
|
||||||
|
firstQuestion.Text.Should().Contain("Which events are triggered when the user clicks on an input field?");
|
||||||
|
firstQuestion.Answers.First().Text.Should().Be("click");
|
||||||
|
firstQuestion.Answers.First().Correct.Should().BeTrue();
|
||||||
|
firstQuestion.Answers.ElementAt(3).Correct.Should().BeFalse();
|
||||||
|
firstQuestion.Answers.ElementAt(3).Text.Should().Be("submit");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
73
Management.Test/Markdown/Quiz/MultipleChoiceTests.cs
Normal file
73
Management.Test/Markdown/Quiz/MultipleChoiceTests.cs
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
using LocalModels;
|
||||||
|
|
||||||
|
public class MultipleChoiceTests
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void QuzMarkdownIncludesMultipleChoiceQuestion()
|
||||||
|
{
|
||||||
|
var quiz = new LocalQuiz()
|
||||||
|
{
|
||||||
|
Name = "Test Quiz",
|
||||||
|
Description = "desc",
|
||||||
|
LockAt = DateTime.MaxValue,
|
||||||
|
DueAt = DateTime.MaxValue,
|
||||||
|
ShuffleAnswers = true,
|
||||||
|
OneQuestionAtATime = false,
|
||||||
|
LocalAssignmentGroupName = "someId",
|
||||||
|
AllowedAttempts = -1,
|
||||||
|
Questions = new LocalQuizQuestion[]
|
||||||
|
{
|
||||||
|
new LocalQuizQuestion()
|
||||||
|
{
|
||||||
|
Points = 2,
|
||||||
|
Text = @"`some type` of question
|
||||||
|
|
||||||
|
with many
|
||||||
|
|
||||||
|
```
|
||||||
|
lines
|
||||||
|
```
|
||||||
|
",
|
||||||
|
QuestionType = QuestionType.MULTIPLE_CHOICE,
|
||||||
|
Answers = new LocalQuizQuestionAnswer[]
|
||||||
|
{
|
||||||
|
new LocalQuizQuestionAnswer() { Correct = true, Text = "true" },
|
||||||
|
new LocalQuizQuestionAnswer() { Correct = false, Text = "false" + Environment.NewLine +Environment.NewLine + "endline" },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var markdown = quiz.ToMarkdown();
|
||||||
|
var expectedQuestionString = @"
|
||||||
|
Points: 2
|
||||||
|
`some type` of question
|
||||||
|
|
||||||
|
with many
|
||||||
|
|
||||||
|
```
|
||||||
|
lines
|
||||||
|
```
|
||||||
|
|
||||||
|
*a) true
|
||||||
|
b) false
|
||||||
|
|
||||||
|
endline
|
||||||
|
";
|
||||||
|
markdown.Should().Contain(expectedQuestionString);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void LetterOptionalForMultipleChoice()
|
||||||
|
{
|
||||||
|
|
||||||
|
var questionMarkdown = @"Points: 2
|
||||||
|
`some type` of question
|
||||||
|
*) true
|
||||||
|
) false
|
||||||
|
";
|
||||||
|
var question = LocalQuizQuestion.ParseMarkdown(questionMarkdown, 0);
|
||||||
|
question.Answers.Count().Should().Be(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
114
Management.Test/Markdown/Quiz/TextAnswerTests.cs
Normal file
114
Management.Test/Markdown/Quiz/TextAnswerTests.cs
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
using LocalModels;
|
||||||
|
|
||||||
|
public class TextAnswerTests
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void CanParseEssay()
|
||||||
|
{
|
||||||
|
var 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?
|
||||||
|
essay
|
||||||
|
";
|
||||||
|
|
||||||
|
var quiz = LocalQuiz.ParseMarkdown(rawMarkdownQuiz);
|
||||||
|
var firstQuestion = quiz.Questions.First();
|
||||||
|
firstQuestion.Points.Should().Be(1);
|
||||||
|
firstQuestion.QuestionType.Should().Be(QuestionType.ESSAY);
|
||||||
|
firstQuestion.Text.Should().NotContain("essay");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void CanParseShortAnswer()
|
||||||
|
{
|
||||||
|
var 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
|
||||||
|
";
|
||||||
|
|
||||||
|
var quiz = LocalQuiz.ParseMarkdown(rawMarkdownQuiz);
|
||||||
|
var firstQuestion = quiz.Questions.First();
|
||||||
|
firstQuestion.Points.Should().Be(1);
|
||||||
|
firstQuestion.QuestionType.Should().Be(QuestionType.SHORT_ANSWER);
|
||||||
|
firstQuestion.Text.Should().NotContain("short answer");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void ShortAnswerToMarkdown_IsCorrect()
|
||||||
|
{
|
||||||
|
var 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
|
||||||
|
";
|
||||||
|
|
||||||
|
var quiz = LocalQuiz.ParseMarkdown(rawMarkdownQuiz);
|
||||||
|
var firstQuestion = quiz.Questions.First();
|
||||||
|
|
||||||
|
var questionMarkdown = firstQuestion.ToMarkdown();
|
||||||
|
var expectedMarkdown = @"Points: 1
|
||||||
|
Which events are triggered when the user clicks on an input field?
|
||||||
|
short_answer";
|
||||||
|
questionMarkdown.Should().Contain(expectedMarkdown);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void EssayQuestionToMarkdown_IsCorrect()
|
||||||
|
{
|
||||||
|
var 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?
|
||||||
|
essay
|
||||||
|
";
|
||||||
|
|
||||||
|
var quiz = LocalQuiz.ParseMarkdown(rawMarkdownQuiz);
|
||||||
|
var firstQuestion = quiz.Questions.First();
|
||||||
|
|
||||||
|
var questionMarkdown = firstQuestion.ToMarkdown();
|
||||||
|
var expectedMarkdown = @"Points: 1
|
||||||
|
Which events are triggered when the user clicks on an input field?
|
||||||
|
essay";
|
||||||
|
questionMarkdown.Should().Contain(expectedMarkdown);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,302 +0,0 @@
|
|||||||
using LocalModels;
|
|
||||||
|
|
||||||
public class QuizQuestionMarkdownTests
|
|
||||||
{
|
|
||||||
[Test]
|
|
||||||
public void QuzMarkdownIncludesMultipleChoiceQuestion()
|
|
||||||
{
|
|
||||||
var quiz = new LocalQuiz()
|
|
||||||
{
|
|
||||||
Name = "Test Quiz",
|
|
||||||
Description = "desc",
|
|
||||||
LockAt = DateTime.MaxValue,
|
|
||||||
DueAt = DateTime.MaxValue,
|
|
||||||
ShuffleAnswers = true,
|
|
||||||
OneQuestionAtATime = false,
|
|
||||||
LocalAssignmentGroupName = "someId",
|
|
||||||
AllowedAttempts = -1,
|
|
||||||
Questions = new LocalQuizQuestion[]
|
|
||||||
{
|
|
||||||
new LocalQuizQuestion()
|
|
||||||
{
|
|
||||||
Points = 2,
|
|
||||||
Text = @"`some type` of question
|
|
||||||
|
|
||||||
with many
|
|
||||||
|
|
||||||
```
|
|
||||||
lines
|
|
||||||
```
|
|
||||||
",
|
|
||||||
QuestionType = QuestionType.MULTIPLE_CHOICE,
|
|
||||||
Answers = new LocalQuizQuestionAnswer[]
|
|
||||||
{
|
|
||||||
new LocalQuizQuestionAnswer() { Correct = true, Text = "true" },
|
|
||||||
new LocalQuizQuestionAnswer() { Correct = false, Text = "false" + Environment.NewLine +Environment.NewLine + "endline" },
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var markdown = quiz.ToMarkdown();
|
|
||||||
var expectedQuestionString = @"
|
|
||||||
Points: 2
|
|
||||||
`some type` of question
|
|
||||||
|
|
||||||
with many
|
|
||||||
|
|
||||||
```
|
|
||||||
lines
|
|
||||||
```
|
|
||||||
|
|
||||||
*a) true
|
|
||||||
b) false
|
|
||||||
|
|
||||||
endline
|
|
||||||
";
|
|
||||||
markdown.Should().Contain(expectedQuestionString);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void QuzMarkdownIncludesMultipleAnswerQuestion()
|
|
||||||
{
|
|
||||||
var quiz = new LocalQuiz()
|
|
||||||
{
|
|
||||||
Name = "Test Quiz",
|
|
||||||
Description = "desc",
|
|
||||||
LockAt = DateTime.MaxValue,
|
|
||||||
DueAt = DateTime.MaxValue,
|
|
||||||
ShuffleAnswers = true,
|
|
||||||
OneQuestionAtATime = false,
|
|
||||||
LocalAssignmentGroupName = "someId",
|
|
||||||
AllowedAttempts = -1,
|
|
||||||
Questions = new LocalQuizQuestion[]
|
|
||||||
{
|
|
||||||
new()
|
|
||||||
{
|
|
||||||
Text = "oneline question",
|
|
||||||
Points = 1,
|
|
||||||
QuestionType = QuestionType.MULTIPLE_ANSWERS,
|
|
||||||
Answers = new LocalQuizQuestionAnswer[]
|
|
||||||
{
|
|
||||||
new() { Correct = true, Text = "true" },
|
|
||||||
new() { Correct = true, Text = "false"},
|
|
||||||
new() { Correct = false, Text = "neither"},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
var markdown = quiz.ToMarkdown();
|
|
||||||
var expectedQuestionString = @"
|
|
||||||
Points: 1
|
|
||||||
oneline question
|
|
||||||
[*] true
|
|
||||||
[*] false
|
|
||||||
[ ] neither
|
|
||||||
";
|
|
||||||
markdown.Should().Contain(expectedQuestionString);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void CanParseQuestionWithMultipleAnswers()
|
|
||||||
{
|
|
||||||
var 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
|
|
||||||
[*] focus
|
|
||||||
[*] mousedown
|
|
||||||
[] submit
|
|
||||||
[] change
|
|
||||||
[] mouseout
|
|
||||||
[] keydown
|
|
||||||
---
|
|
||||||
";
|
|
||||||
|
|
||||||
var quiz = LocalQuiz.ParseMarkdown(rawMarkdownQuiz);
|
|
||||||
var firstQuestion = quiz.Questions.First();
|
|
||||||
firstQuestion.Points.Should().Be(1);
|
|
||||||
firstQuestion.QuestionType.Should().Be(QuestionType.MULTIPLE_ANSWERS);
|
|
||||||
firstQuestion.Text.Should().Contain("Which events are triggered when the user clicks on an input field?");
|
|
||||||
firstQuestion.Answers.First().Text.Should().Be("click");
|
|
||||||
firstQuestion.Answers.First().Correct.Should().BeTrue();
|
|
||||||
firstQuestion.Answers.ElementAt(3).Correct.Should().BeFalse();
|
|
||||||
firstQuestion.Answers.ElementAt(3).Text.Should().Be("submit");
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void CanParseEssay()
|
|
||||||
{
|
|
||||||
var 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?
|
|
||||||
essay
|
|
||||||
";
|
|
||||||
|
|
||||||
var quiz = LocalQuiz.ParseMarkdown(rawMarkdownQuiz);
|
|
||||||
var firstQuestion = quiz.Questions.First();
|
|
||||||
firstQuestion.Points.Should().Be(1);
|
|
||||||
firstQuestion.QuestionType.Should().Be(QuestionType.ESSAY);
|
|
||||||
firstQuestion.Text.Should().NotContain("essay");
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void CanParseShortAnswer()
|
|
||||||
{
|
|
||||||
var 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
|
|
||||||
";
|
|
||||||
|
|
||||||
var quiz = LocalQuiz.ParseMarkdown(rawMarkdownQuiz);
|
|
||||||
var firstQuestion = quiz.Questions.First();
|
|
||||||
firstQuestion.Points.Should().Be(1);
|
|
||||||
firstQuestion.QuestionType.Should().Be(QuestionType.SHORT_ANSWER);
|
|
||||||
firstQuestion.Text.Should().NotContain("short answer");
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void ShortAnswerToMarkdown_IsCorrect()
|
|
||||||
{
|
|
||||||
var 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
|
|
||||||
";
|
|
||||||
|
|
||||||
var quiz = LocalQuiz.ParseMarkdown(rawMarkdownQuiz);
|
|
||||||
var firstQuestion = quiz.Questions.First();
|
|
||||||
|
|
||||||
var questionMarkdown = firstQuestion.ToMarkdown();
|
|
||||||
var expectedMarkdown = @"Points: 1
|
|
||||||
Which events are triggered when the user clicks on an input field?
|
|
||||||
short_answer";
|
|
||||||
questionMarkdown.Should().Contain(expectedMarkdown);
|
|
||||||
}
|
|
||||||
[Test]
|
|
||||||
public void EssayQuestionToMarkdown_IsCorrect()
|
|
||||||
{
|
|
||||||
var 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?
|
|
||||||
essay
|
|
||||||
";
|
|
||||||
|
|
||||||
var quiz = LocalQuiz.ParseMarkdown(rawMarkdownQuiz);
|
|
||||||
var firstQuestion = quiz.Questions.First();
|
|
||||||
|
|
||||||
var questionMarkdown = firstQuestion.ToMarkdown();
|
|
||||||
var expectedMarkdown = @"Points: 1
|
|
||||||
Which events are triggered when the user clicks on an input field?
|
|
||||||
essay";
|
|
||||||
questionMarkdown.Should().Contain(expectedMarkdown);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void CanParseMatchingQuestion()
|
|
||||||
{
|
|
||||||
var 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:
|
|
||||||
---
|
|
||||||
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.)
|
|
||||||
";
|
|
||||||
|
|
||||||
var quiz = LocalQuiz.ParseMarkdown(rawMarkdownQuiz);
|
|
||||||
var firstQuestion = quiz.Questions.First();
|
|
||||||
firstQuestion.QuestionType.Should().Be(QuestionType.MATCHING);
|
|
||||||
firstQuestion.Text.Should().NotContain("statement");
|
|
||||||
firstQuestion.Answers.First().MatchedText.Should().Be("a single command to be executed");
|
|
||||||
}
|
|
||||||
[Test]
|
|
||||||
public void CanCreateMarkdownForMatchingQuesiton()
|
|
||||||
{
|
|
||||||
var 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:
|
|
||||||
---
|
|
||||||
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.)
|
|
||||||
";
|
|
||||||
|
|
||||||
var quiz = LocalQuiz.ParseMarkdown(rawMarkdownQuiz);
|
|
||||||
var questionMarkdown = quiz.Questions.First().ToMarkdown();
|
|
||||||
var 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.)";
|
|
||||||
questionMarkdown.Should().Contain(expectedMarkdown);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -138,7 +138,12 @@ short_answer
|
|||||||
---
|
---
|
||||||
points: 4
|
points: 4
|
||||||
the underscore is optional
|
the underscore is optional
|
||||||
short answer";
|
short answer
|
||||||
|
---
|
||||||
|
this is a matching question
|
||||||
|
^ left answer - right dropdown
|
||||||
|
^ other thing shown - another option
|
||||||
|
";
|
||||||
}
|
}
|
||||||
|
|
||||||
<div class="d-flex flex-column py-3" style="height: 100vh;">
|
<div class="d-flex flex-column py-3" style="height: 100vh;">
|
||||||
|
|||||||
@@ -1,88 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
@code {
|
|
||||||
[Parameter, EditorRequired]
|
|
||||||
public LocalQuizQuestionAnswer Answer { get; set; } = default!;
|
|
||||||
[Parameter, EditorRequired]
|
|
||||||
public int AnswerIndex { get; set; } = default!;
|
|
||||||
[Parameter, EditorRequired]
|
|
||||||
public int QuestionIndex { get; set; } = default!;
|
|
||||||
[Parameter, EditorRequired]
|
|
||||||
public LocalQuizQuestion Question { get; set; } = default!;
|
|
||||||
|
|
||||||
[Parameter, EditorRequired]
|
|
||||||
public Action<LocalQuizQuestionAnswer, int> SaveAnswer { get; set; } = (_, _) => {};
|
|
||||||
|
|
||||||
private string label => "question_" + QuestionIndex + "_answer_" + AnswerIndex;
|
|
||||||
private string _text { get; set; } = string.Empty;
|
|
||||||
private string text
|
|
||||||
{
|
|
||||||
get => _text;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_text = value;
|
|
||||||
SaveAnswer(Answer with { Text = _text }, AnswerIndex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnParametersSet()
|
|
||||||
{
|
|
||||||
if(_text == string.Empty)
|
|
||||||
_text = Answer.Text;
|
|
||||||
base.OnParametersSet();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleOneAnswerChange()
|
|
||||||
{
|
|
||||||
SaveAnswer(Answer with {Correct = !Answer.Correct}, AnswerIndex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-auto my-auto">
|
|
||||||
@if(Question.QuestionType == QuestionType.MULTIPLE_ANSWERS)
|
|
||||||
{
|
|
||||||
<div class="form-check form-switch">
|
|
||||||
<input
|
|
||||||
class="form-check-input"
|
|
||||||
type="checkbox"
|
|
||||||
role="switch"
|
|
||||||
id="@label"
|
|
||||||
checked="@Answer.Correct"
|
|
||||||
@onchange="@(() => handleOneAnswerChange())"
|
|
||||||
>
|
|
||||||
<label
|
|
||||||
class="form-check-label" for="@label">
|
|
||||||
Is Correct
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
@if(Question.QuestionType == QuestionType.MULTIPLE_CHOICE)
|
|
||||||
{
|
|
||||||
<div class="form-check">
|
|
||||||
<input
|
|
||||||
class="form-check-input"
|
|
||||||
type="radio"
|
|
||||||
id="@label"
|
|
||||||
checked="@Answer.Correct"
|
|
||||||
|
|
||||||
@onchange="@(() => handleOneAnswerChange())"
|
|
||||||
>
|
|
||||||
<label
|
|
||||||
class="form-check-label" for="@label">
|
|
||||||
Is Correct
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<div class="m-1">
|
|
||||||
<textarea
|
|
||||||
class="form-control"
|
|
||||||
@bind="text"
|
|
||||||
@bind:event="oninput"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@@ -18,6 +18,26 @@
|
|||||||
|
|
||||||
@((MarkupString)Question.HtmlText)
|
@((MarkupString)Question.HtmlText)
|
||||||
|
|
||||||
|
@if(Question.QuestionType == QuestionType.MATCHING)
|
||||||
|
{
|
||||||
|
@foreach(var answer in Question.Answers)
|
||||||
|
{
|
||||||
|
<div class="mx-3 mb-1 bg-dark px-2 rounded rounded-2 border row">
|
||||||
|
<div
|
||||||
|
class="col text-end my-auto p-1"
|
||||||
|
>
|
||||||
|
@answer.Text
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="col my-auto"
|
||||||
|
>
|
||||||
|
@answer.MatchedText
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
@foreach(var answer in Question.Answers)
|
@foreach(var answer in Question.Answers)
|
||||||
{
|
{
|
||||||
string answerPreview = answer.HtmlText.StartsWith("<p>")
|
string answerPreview = answer.HtmlText.StartsWith("<p>")
|
||||||
@@ -59,3 +79,4 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
}
|
||||||
@@ -49,7 +49,7 @@ public record LocalQuizQuestion
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly string[] _validFirstAnswerDelimiters = ["*a)", "a)", "[ ]", "[*]", "^"];
|
private static readonly string[] _validFirstAnswerDelimiters = ["*a)", "a)", "*)", ")", "[ ]", "[*]", "^"];
|
||||||
|
|
||||||
public static LocalQuizQuestion ParseMarkdown(string input, int questionIndex)
|
public static LocalQuizQuestion ParseMarkdown(string input, int questionIndex)
|
||||||
{
|
{
|
||||||
@@ -115,15 +115,18 @@ public record LocalQuizQuestion
|
|||||||
return "short_answer";
|
return "short_answer";
|
||||||
|
|
||||||
var answerLines = getAnswersGroupedByLines(linesWithoutPoints, questionIndex);
|
var answerLines = getAnswersGroupedByLines(linesWithoutPoints, questionIndex);
|
||||||
|
var firstAnswerLine = answerLines.First();
|
||||||
var isMultipleChoice =
|
var isMultipleChoice =
|
||||||
answerLines.First().StartsWith("a)")
|
firstAnswerLine.StartsWith("a)")
|
||||||
|| answerLines.First().StartsWith("*a)");
|
|| firstAnswerLine.StartsWith("*a)")
|
||||||
|
|| firstAnswerLine.StartsWith("*)")
|
||||||
|
|| firstAnswerLine.StartsWith(")");
|
||||||
if (isMultipleChoice)
|
if (isMultipleChoice)
|
||||||
return "multiple_choice";
|
return "multiple_choice";
|
||||||
|
|
||||||
var isMultipleAnswer =
|
var isMultipleAnswer =
|
||||||
answerLines.First().StartsWith("[ ]")
|
firstAnswerLine.StartsWith("[ ]")
|
||||||
|| answerLines.First().StartsWith("[*]");
|
|| firstAnswerLine.StartsWith("[*]");
|
||||||
|
|
||||||
if (isMultipleAnswer)
|
if (isMultipleAnswer)
|
||||||
return "multiple_answers";
|
return "multiple_answers";
|
||||||
@@ -150,7 +153,7 @@ public record LocalQuizQuestion
|
|||||||
|
|
||||||
var answerLinesRaw = linesWithoutPoints[indexOfAnswerStart..];
|
var answerLinesRaw = linesWithoutPoints[indexOfAnswerStart..];
|
||||||
|
|
||||||
var answerStartPattern = @"^(\*?[a-z]\))|\[\s*\]|\[\*\]|\^";
|
var answerStartPattern = @"^(\*?[a-z]?\))|\[\s*\]|\[\*\]|\^";
|
||||||
var answerLines = answerLinesRaw.Aggregate(new List<string>(), (acc, line) =>
|
var answerLines = answerLinesRaw.Aggregate(new List<string>(), (acc, line) =>
|
||||||
{
|
{
|
||||||
var isNewAnswer = Regex.IsMatch(line, answerStartPattern);
|
var isNewAnswer = Regex.IsMatch(line, answerStartPattern);
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ public record LocalQuizQuestionAnswer
|
|||||||
public static LocalQuizQuestionAnswer ParseMarkdown(string input, string questionType)
|
public static LocalQuizQuestionAnswer ParseMarkdown(string input, string questionType)
|
||||||
{
|
{
|
||||||
var isCorrect = input[0] == '*' || input[1] == '*';
|
var isCorrect = input[0] == '*' || input[1] == '*';
|
||||||
string startingQuestionPattern = @"^(\*?[a-z]\))|\[\s*\]|\[\*\]|\^ ";
|
string startingQuestionPattern = @"^(\*?[a-z]?\))|\[\s*\]|\[\*\]|\^ ";
|
||||||
var text = Regex.Replace(input, startingQuestionPattern, string.Empty).Trim();
|
var text = Regex.Replace(input, startingQuestionPattern, string.Empty).Trim();
|
||||||
|
|
||||||
if(questionType == QuestionType.MATCHING)
|
if(questionType == QuestionType.MATCHING)
|
||||||
@@ -23,7 +23,7 @@ public record LocalQuizQuestionAnswer
|
|||||||
{
|
{
|
||||||
Correct = true,
|
Correct = true,
|
||||||
Text = text.Split('-')[0].Trim(),
|
Text = text.Split('-')[0].Trim(),
|
||||||
MatchedText = string.Join("", text.Split('-')[1..]).Trim(),
|
MatchedText = string.Join("-", text.Split('-')[1..]).Trim(),
|
||||||
};
|
};
|
||||||
|
|
||||||
return new LocalQuizQuestionAnswer()
|
return new LocalQuizQuestionAnswer()
|
||||||
|
|||||||
Reference in New Issue
Block a user