wrote rubric parsing tests

This commit is contained in:
2023-10-25 10:03:06 -06:00
parent cd2591d76b
commit 1d58166a5c
5 changed files with 208 additions and 16 deletions

View File

@@ -0,0 +1,67 @@
using LocalModels;
public class RubricMarkdownTests
{
[Test]
public void TestCanParseOneItem()
{
var rawRubric = @"
- 2pts: this is the task
";
var rubric = LocalAssignment.ParseRubricMarkdown(rawRubric);
rubric.Count().Should().Be(1);
rubric.First().IsExtraCredit.Should().BeFalse();
rubric.First().Label.Should().Be("this is the task");
rubric.First().Points.Should().Be(2);
}
[Test]
public void TestCanParseMultipleItems()
{
var rawRubric = @"
- 2pts: this is the task
- 3pts: this is the other task
";
var rubric = LocalAssignment.ParseRubricMarkdown(rawRubric);
rubric.Count().Should().Be(2);
rubric.ElementAt(1).IsExtraCredit.Should().BeFalse();
rubric.ElementAt(1).Label.Should().Be("this is the other task");
rubric.ElementAt(1).Points.Should().Be(3);
}
[Test]
public void TestCanParseSinglePoint()
{
var rawRubric = @"
- 1pt: this is the task
";
var rubric = LocalAssignment.ParseRubricMarkdown(rawRubric);
rubric.First().IsExtraCredit.Should().BeFalse();
rubric.First().Label.Should().Be("this is the task");
rubric.First().Points.Should().Be(1);
}
[Test]
public void TestCanParseSingleExtraCredit_LowerCase()
{
var rawRubric = @"
- 1pt: (extra credit) this is the task
";
var rubric = LocalAssignment.ParseRubricMarkdown(rawRubric);
rubric.First().IsExtraCredit.Should().BeTrue();
rubric.First().Label.Should().Be("(extra credit) this is the task");
}
[Test]
public void TestCanParseSingleExtraCredit_UpperCase()
{
var rawRubric = @"
- 1pt: (Extra Credit) this is the task
";
var rubric = LocalAssignment.ParseRubricMarkdown(rawRubric);
rubric.First().IsExtraCredit.Should().BeTrue();
rubric.First().Label.Should().Be("(Extra Credit) this is the task");
}
}

View File

@@ -195,7 +195,7 @@
</label> </label>
</div> </div>
<div class="container"> <div class="container">
<RubricEditor /> <RubricMarkdownEditor />
<hr> <hr>
<div class="mx-5 px-5"> <div class="mx-5 px-5">
<SubmissionTypeSelector /> <SubmissionTypeSelector />

View File

@@ -0,0 +1,95 @@
@using Management.Web.Shared.Components
@inject CoursePlanner planner
@inject AssignmentEditorContext assignmentContext
@code
{
private IEnumerable<RubricItem> rubric { get; set; } = Array.Empty<RubricItem>();
private string rubricText = "";
private int rubricReloadKey = 0;
protected override void OnInitialized()
{
assignmentContext.StateHasChanged += reload;
reload();
}
private void reload()
{
if (assignmentContext.Assignment != null)
{
rubric = assignmentContext.Assignment.Rubric;
}
this.InvokeAsync(this.StateHasChanged);
}
public void Dispose()
{
assignmentContext.StateHasChanged -= reload;
}
private void save()
{
if (assignmentContext.Assignment != null)
{
var newAssignment = assignmentContext.Assignment with
{
Rubric = rubric,
};
assignmentContext.SaveAssignment(newAssignment);
StateHasChanged();
}
}
private void handleNewRubricText()
{
}
private int requiredPoints => rubric.Where(r => !r.IsExtraCredit).Select(r => r.Points).Sum();
private int extraCreditPoints => rubric.Where(r => r.IsExtraCredit).Select(r => r.Points).Sum();
}
<br>
<div class="row">
<div class="col offset-3">
<h4 class="text-center">Rubric</h4>
</div>
</div>
<div class="row">
<div class="col">
<label for="description" class="form-label">
Rubric
</label>
</div>
<div class="col">
HTML Preview
</div>
</div>
<div class="row">
<div class="col-6">
<textarea
id="description"
class="form-control h-100"
rows=12
@bind="rubricText"
@oninput="handleNewRubricText"
/>
</div>
<div class="col-6">
preview here
</div>
</div>
<div class="row">
<div class="col">
<div>
Requred Points: @requiredPoints
</div>
<div>
Extra Credit Points @extraCreditPoints
</div>
</div>
</div>

View File

@@ -1,3 +1,5 @@
using System.Collections;
using System.Text.RegularExpressions;
using YamlDotNet.Serialization; using YamlDotNet.Serialization;
namespace LocalModels; namespace LocalModels;
@@ -5,8 +7,8 @@ namespace LocalModels;
public record RubricItem public record RubricItem
{ {
public static readonly string extraCredit = "(Extra Credit) "; public static readonly string extraCredit = "(Extra Credit) ";
public string Label { get; set; } = ""; public required string Label { get; set; }
public int Points { get; set; } = 0; public required int Points { get; set; }
public bool IsExtraCredit => Label.Contains(extraCredit.ToLower(), StringComparison.CurrentCultureIgnoreCase); public bool IsExtraCredit => Label.Contains(extraCredit.ToLower(), StringComparison.CurrentCultureIgnoreCase);
} }
@@ -94,4 +96,32 @@ public record LocalAssignment
return assignmentMarkdown; return assignmentMarkdown;
} }
public static IEnumerable<RubricItem> ParseRubricMarkdown(string rawMarkdown)
{
var lines = rawMarkdown.Trim().Split(Environment.NewLine);
var items = lines.Select(l =>
{
var pointsPattern = @"\s*-\s*(\d+)\s*pt(s)?:";
var match = Regex.Match(l, pointsPattern);
if (!match.Success)
throw new RubricMarkdownParseException($"points not found: {l}");
var points = int.Parse(match.Groups[1].Value);
var label = string.Join(": ", l.Split(": ").Skip(1));
return new RubricItem()
{
Points = points,
Label = label
};
}).ToArray();
return items;
}
}
public class RubricMarkdownParseException : Exception
{
public RubricMarkdownParseException(string message) : base(message) { }
} }