[
{
"name": "a mark exactly on the top boundary earns the top grade",
"args": [
78,
100,
[
{
"grade": "9",
"minMark": 78
},
{
"grade": "8",
"minMark": 68
},
{
"grade": "7",
"minMark": 58
},
{
"grade": "6",
"minMark": 48
},
{
"grade": "5",
"minMark": 39
},
{
"grade": "4",
"minMark": 30
},
{
"grade": "3",
"minMark": 21
},
{
"grade": "2",
"minMark": 13
},
{
"grade": "1",
"minMark": 5
}
]
],
"expect": {
"grade": "9",
"minMark": 78,
"nextGrade": null,
"marksToNext": null
}
},
{
"name": "one mark below a boundary is the grade beneath it",
"args": [
77,
100,
[
{
"grade": "9",
"minMark": 78
},
{
"grade": "8",
"minMark": 68
},
{
"grade": "7",
"minMark": 58
},
{
"grade": "6",
"minMark": 48
},
{
"grade": "5",
"minMark": 39
},
{
"grade": "4",
"minMark": 30
},
{
"grade": "3",
"minMark": 21
},
{
"grade": "2",
"minMark": 13
},
{
"grade": "1",
"minMark": 5
}
]
],
"expect": {
"grade": "8",
"minMark": 68,
"nextGrade": "9",
"marksToNext": 1
}
},
{
"name": "full marks",
"args": [
100,
100,
[
{
"grade": "9",
"minMark": 78
},
{
"grade": "8",
"minMark": 68
},
{
"grade": "7",
"minMark": 58
},
{
"grade": "6",
"minMark": 48
},
{
"grade": "5",
"minMark": 39
},
{
"grade": "4",
"minMark": 30
},
{
"grade": "3",
"minMark": 21
},
{
"grade": "2",
"minMark": 13
},
{
"grade": "1",
"minMark": 5
}
]
],
"expect": {
"grade": "9",
"minMark": 78,
"nextGrade": null,
"marksToNext": null
}
},
{
"name": "a mid-table mark, and the marks to the next grade",
"args": [
30,
100,
[
{
"grade": "9",
"minMark": 78
},
{
"grade": "8",
"minMark": 68
},
{
"grade": "7",
"minMark": 58
},
{
"grade": "6",
"minMark": 48
},
{
"grade": "5",
"minMark": 39
},
{
"grade": "4",
"minMark": 30
},
{
"grade": "3",
"minMark": 21
},
{
"grade": "2",
"minMark": 13
},
{
"grade": "1",
"minMark": 5
}
]
],
"expect": {
"grade": "4",
"minMark": 30,
"nextGrade": "5",
"marksToNext": 9
}
},
{
"name": "one mark below the lowest boundary is ungraded",
"args": [
4,
100,
[
{
"grade": "9",
"minMark": 78
},
{
"grade": "8",
"minMark": 68
},
{
"grade": "7",
"minMark": 58
},
{
"grade": "6",
"minMark": 48
},
{
"grade": "5",
"minMark": 39
},
{
"grade": "4",
"minMark": 30
},
{
"grade": "3",
"minMark": 21
},
{
"grade": "2",
"minMark": 13
},
{
"grade": "1",
"minMark": 5
}
]
],
"expect": {
"grade": null,
"minMark": null,
"nextGrade": "1",
"marksToNext": 1
}
},
{
"name": "zero is ungraded and the whole lowest boundary away",
"args": [
0,
100,
[
{
"grade": "9",
"minMark": 78
},
{
"grade": "8",
"minMark": 68
},
{
"grade": "7",
"minMark": 58
},
{
"grade": "6",
"minMark": 48
},
{
"grade": "5",
"minMark": 39
},
{
"grade": "4",
"minMark": 30
},
{
"grade": "3",
"minMark": 21
},
{
"grade": "2",
"minMark": 13
},
{
"grade": "1",
"minMark": 5
}
]
],
"expect": {
"grade": null,
"minMark": null,
"nextGrade": "1",
"marksToNext": 5
}
},
{
"name": "a table in no particular order: 59 is a C, one short of a B, not the last row read",
"args": [
59,
100,
[
{
"grade": "C",
"minMark": 50
},
{
"grade": "A*",
"minMark": 80
},
{
"grade": "E",
"minMark": 30
},
{
"grade": "A",
"minMark": 70
},
{
"grade": "D",
"minMark": 40
},
{
"grade": "B",
"minMark": 60
}
]
],
"expect": {
"grade": "C",
"minMark": 50,
"nextGrade": "B",
"marksToNext": 1
}
},
{
"name": "A* at its boundary in a shuffled table",
"args": [
80,
100,
[
{
"grade": "C",
"minMark": 50
},
{
"grade": "A*",
"minMark": 80
},
{
"grade": "E",
"minMark": 30
},
{
"grade": "A",
"minMark": 70
},
{
"grade": "D",
"minMark": 40
},
{
"grade": "B",
"minMark": 60
}
]
],
"expect": {
"grade": "A*",
"minMark": 80,
"nextGrade": null,
"marksToNext": null
}
},
{
"name": "a lowest row at 0 means no mark is ungraded",
"args": [
0,
100,
[
{
"grade": "Distinction",
"minMark": 70
},
{
"grade": "Merit",
"minMark": 60
},
{
"grade": "Pass",
"minMark": 40
},
{
"grade": "Fail",
"minMark": 0
}
]
],
"expect": {
"grade": "Fail",
"minMark": 0,
"nextGrade": "Pass",
"marksToNext": 40
}
},
{
"name": "a single-row table: pass at the boundary",
"args": [
50,
50,
[
{
"grade": "Pass",
"minMark": 50
}
]
],
"expect": {
"grade": "Pass",
"minMark": 50,
"nextGrade": null,
"marksToNext": null
}
},
{
"name": "a single-row table: below it is ungraded",
"args": [
49,
50,
[
{
"grade": "Pass",
"minMark": 50
}
]
],
"expect": {
"grade": null,
"minMark": null,
"nextGrade": "Pass",
"marksToNext": 1
}
},
{
"name": "a mark above maxMark is an error",
"args": [
101,
100,
[
{
"grade": "9",
"minMark": 78
},
{
"grade": "8",
"minMark": 68
},
{
"grade": "7",
"minMark": 58
},
{
"grade": "6",
"minMark": 48
},
{
"grade": "5",
"minMark": 39
},
{
"grade": "4",
"minMark": 30
},
{
"grade": "3",
"minMark": 21
},
{
"grade": "2",
"minMark": 13
},
{
"grade": "1",
"minMark": 5
}
]
],
"expectError": "mark must be a whole number from 0 to maxMark (100)"
},
{
"name": "a negative mark is an error",
"args": [
-1,
100,
[
{
"grade": "9",
"minMark": 78
},
{
"grade": "8",
"minMark": 68
},
{
"grade": "7",
"minMark": 58
},
{
"grade": "6",
"minMark": 48
},
{
"grade": "5",
"minMark": 39
},
{
"grade": "4",
"minMark": 30
},
{
"grade": "3",
"minMark": 21
},
{
"grade": "2",
"minMark": 13
},
{
"grade": "1",
"minMark": 5
}
]
],
"expectError": "mark must be a whole number from 0 to maxMark (100)"
},
{
"name": "a half mark is an error",
"args": [
12.5,
100,
[
{
"grade": "9",
"minMark": 78
},
{
"grade": "8",
"minMark": 68
},
{
"grade": "7",
"minMark": 58
},
{
"grade": "6",
"minMark": 48
},
{
"grade": "5",
"minMark": 39
},
{
"grade": "4",
"minMark": 30
},
{
"grade": "3",
"minMark": 21
},
{
"grade": "2",
"minMark": 13
},
{
"grade": "1",
"minMark": 5
}
]
],
"expectError": "mark must be a whole number from 0 to maxMark (100)"
},
{
"name": "maxMark of zero is an error",
"args": [
0,
0,
[
{
"grade": "9",
"minMark": 78
},
{
"grade": "8",
"minMark": 68
},
{
"grade": "7",
"minMark": 58
},
{
"grade": "6",
"minMark": 48
},
{
"grade": "5",
"minMark": 39
},
{
"grade": "4",
"minMark": 30
},
{
"grade": "3",
"minMark": 21
},
{
"grade": "2",
"minMark": 13
},
{
"grade": "1",
"minMark": 5
}
]
],
"expectError": "maxMark must be a positive whole number"
},
{
"name": "an empty table is an error",
"args": [
10,
100,
[]
],
"expectError": "boundaries must not be empty"
},
{
"name": "a grade named twice is an error",
"args": [
10,
100,
[
{
"grade": "A",
"minMark": 70
},
{
"grade": "A",
"minMark": 60
}
]
],
"expectError": "grade A appears twice in boundaries"
},
{
"name": "two grades on one boundary is an error",
"args": [
10,
100,
[
{
"grade": "A",
"minMark": 70
},
{
"grade": "B",
"minMark": 70
}
]
],
"expectError": "grades A and B share the boundary 70"
},
{
"name": "a boundary above maxMark is an error",
"args": [
10,
60,
[
{
"grade": "9",
"minMark": 78
},
{
"grade": "8",
"minMark": 68
},
{
"grade": "7",
"minMark": 58
},
{
"grade": "6",
"minMark": 48
},
{
"grade": "5",
"minMark": 39
},
{
"grade": "4",
"minMark": 30
},
{
"grade": "3",
"minMark": 21
},
{
"grade": "2",
"minMark": 13
},
{
"grade": "1",
"minMark": 5
}
]
],
"expectError": "boundary minMark must be a whole number from 0 to maxMark (60), received 78 for grade 9"
},
{
"name": "an empty grade name is an error",
"args": [
10,
100,
[
{
"grade": "",
"minMark": 70
}
]
],
"expectError": "every boundary needs a non-empty grade"
}
]