001package edu.pdx.cs.joy.grader.gradebook;
002
003import org.junit.jupiter.api.Test;
004
005import static org.hamcrest.MatcherAssert.assertThat;
006import static org.hamcrest.Matchers.*;
007import static org.junit.jupiter.api.Assertions.assertThrows;
008
009public class GradeBookTest {
010
011  @Test
012  public void defaultLetterGradeRanges() {
013    GradeBook book = new GradeBook("test");
014    GradeBook.LetterGradeRanges undergrad = book.getLetterGradeRanges(Student.Section.UNDERGRADUATE);
015    assertDefaultLetterGradeRanges(undergrad);
016
017    GradeBook.LetterGradeRanges grad = book.getLetterGradeRanges(Student.Section.GRADUATE);
018    assertDefaultLetterGradeRanges(grad);
019  }
020
021  private void assertDefaultLetterGradeRanges(GradeBook.LetterGradeRanges ranges) {
022    assertLetterGradeRange(ranges, LetterGrade.A, 94, 100);
023    assertLetterGradeRange(ranges, LetterGrade.A_MINUS, 90, 93);
024    assertLetterGradeRange(ranges, LetterGrade.B_PLUS, 87, 89);
025    assertLetterGradeRange(ranges, LetterGrade.B, 83, 86);
026    assertLetterGradeRange(ranges, LetterGrade.B_MINUS, 80, 82);
027    assertLetterGradeRange(ranges, LetterGrade.C_PLUS, 77, 79);
028    assertLetterGradeRange(ranges, LetterGrade.C, 73, 76);
029    assertLetterGradeRange(ranges, LetterGrade.C_MINUS, 70, 72);
030    assertLetterGradeRange(ranges, LetterGrade.D_PLUS, 67, 69);
031    assertLetterGradeRange(ranges, LetterGrade.D, 63, 66);
032    assertLetterGradeRange(ranges, LetterGrade.D_MINUS, 60, 62);
033    assertLetterGradeRange(ranges, LetterGrade.F, 0, 59);
034  }
035
036  private void assertLetterGradeRange(GradeBook.LetterGradeRanges ranges, LetterGrade letterGrade, int minimum, int maximum) {
037    GradeBook.LetterGradeRanges.LetterGradeRange range = ranges.getRange(letterGrade);
038    assertThat("No range for " + letterGrade, range, not(nullValue()));
039    assertThat("Less than for " + letterGrade, range.maximum(), equalTo(maximum));
040    assertThat(range.minimum(), equalTo(minimum));
041  }
042
043  @Test
044  public void minimumValueGreaterThanMaximumValue() {
045    GradeBook book = new GradeBook("test");
046    GradeBook.LetterGradeRanges ranges = book.getLetterGradeRanges(Student.Section.UNDERGRADUATE);
047    GradeBook.LetterGradeRanges.LetterGradeRange range = ranges.getRange(LetterGrade.A);
048    assertThrows(GradeBook.LetterGradeRanges.LetterGradeRange.InvalidLetterGradeRange.class, () ->
049      range.setRange(100, 99)
050    );
051  }
052
053  @Test
054  public void minimumValueEqualsMaximumValue() {
055    GradeBook book = new GradeBook("test");
056    GradeBook.LetterGradeRanges ranges = book.getLetterGradeRanges(Student.Section.UNDERGRADUATE);
057    GradeBook.LetterGradeRanges.LetterGradeRange range = ranges.getRange(LetterGrade.A);
058    assertThrows(GradeBook.LetterGradeRanges.LetterGradeRange.InvalidLetterGradeRange.class, () ->
059      range.setRange(99, 99)
060    );
061  }
062
063  @Test
064  public void defaultLetterGradeRangesAreValid() {
065    GradeBook book = new GradeBook("test");
066    GradeBook.LetterGradeRanges ranges = book.getLetterGradeRanges(Student.Section.UNDERGRADUATE);
067    ranges.validate();
068  }
069
070  @Test
071  public void rangesDoNotStartAtZero() {
072    GradeBook book = new GradeBook("test");
073    GradeBook.LetterGradeRanges ranges = book.getLetterGradeRanges(Student.Section.UNDERGRADUATE);
074    GradeBook.LetterGradeRanges.LetterGradeRange range = ranges.getRange(LetterGrade.F);
075    range.setRange(2, range.maximum());
076    assertThrows(GradeBook.LetterGradeRanges.LetterGradeRange.InvalidLetterGradeRange.class, ranges::validate);
077  }
078
079  @Test
080  public void rangesDoNotContain100() {
081    GradeBook book = new GradeBook("test");
082    GradeBook.LetterGradeRanges ranges = book.getLetterGradeRanges(Student.Section.UNDERGRADUATE);
083    GradeBook.LetterGradeRanges.LetterGradeRange range = ranges.getRange(LetterGrade.A);
084    range.setRange(range.minimum(), 99);
085    assertThrows(GradeBook.LetterGradeRanges.LetterGradeRange.InvalidLetterGradeRange.class, ranges::validate);
086  }
087
088  @Test
089  public void rangesAreContiguous() {
090    GradeBook book = new GradeBook("test");
091    GradeBook.LetterGradeRanges ranges = book.getLetterGradeRanges(Student.Section.UNDERGRADUATE);
092    GradeBook.LetterGradeRanges.LetterGradeRange range = ranges.getRange(LetterGrade.A);
093    range.setRange(range.minimum() + 1, range.maximum());
094    assertThrows(GradeBook.LetterGradeRanges.LetterGradeRange.InvalidLetterGradeRange.class, ranges::validate);
095  }
096
097  @Test
098  public void rangesAreContiguousNotARange() {
099    GradeBook book = new GradeBook("test");
100    GradeBook.LetterGradeRanges ranges = book.getLetterGradeRanges(Student.Section.UNDERGRADUATE);
101    GradeBook.LetterGradeRanges.LetterGradeRange range = ranges.getRange(LetterGrade.C);
102    range.setRange(range.minimum(), range.maximum() - 1);
103    assertThrows(GradeBook.LetterGradeRanges.LetterGradeRange.InvalidLetterGradeRange.class, ranges::validate);
104  }
105
106  @Test
107  public void scoreIsInRange() {
108    GradeBook book = new GradeBook("test");
109    GradeBook.LetterGradeRanges ranges = book.getLetterGradeRanges(Student.Section.UNDERGRADUATE);
110    GradeBook.LetterGradeRanges.LetterGradeRange range = ranges.getRange(LetterGrade.A);
111    range.setRange(90, 100);
112
113    assertThat(range.isScoreInRange(90.0), is(true));
114    assertThat(range.isScoreInRange(100.0), is(true));
115    assertThat(range.isScoreInRange(95.0), is(true));
116    assertThat(range.isScoreInRange(89.5), is(true));
117    assertThat(range.isScoreInRange(101.0), is(false));
118    assertThat(range.isScoreInRange(89.0), is(false));
119    assertThat(range.isScoreInRange(89.4), is(false));
120
121  }
122
123  @Test
124  public void scoresAreCorrectlyMappedToLetterGrades() {
125    GradeBook book = new GradeBook("test");
126    assertThat(book.getLetterGradeForScore(Student.Section.UNDERGRADUATE, 99.0), equalTo(LetterGrade.A));
127    assertThat(book.getLetterGradeForScore(Student.Section.UNDERGRADUATE, 93.0), equalTo(LetterGrade.A_MINUS));
128  }
129
130}