Skip to content

Commit 0eba51c

Browse files
docs(changeset): Updates to Radio Scoring to ensure non-specific multiselect questions are marked correctly. (#2518)
## Summary: This PR is part of the Radio Widget Upgrade Project. This work ensures that non-specific multi-select Radios don't trigger CHOOSE_CORRECT_NUM_ERRORs, and are instead marked as "incorrect". Issue: LEMS-2996 ## Test plan: - New scoring test - Previous tests pass (after making them specific) Author: SonicScrewdriver Reviewers: mark-fitzgerald, anakaren-rojas, ivyolamit, SonicScrewdriver Required Reviewers: Approved By: mark-fitzgerald, anakaren-rojas, ivyolamit Checks: ✅ 8 checks were successful Pull Request URL: #2518
1 parent b7c1be2 commit 0eba51c

File tree

5 files changed

+36
-3
lines changed

5 files changed

+36
-3
lines changed

.changeset/little-goats-prove.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"@khanacademy/perseus": minor
3+
"@khanacademy/perseus-core": minor
4+
"@khanacademy/perseus-score": minor
5+
---
6+
7+
Updates to Radio Scoring to ensure non-specific multiselect questions are marked correctly.

packages/perseus-core/src/validation.types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,8 @@ export type PerseusPlotterUserInput = number[];
256256
export type PerseusRadioRubric = {
257257
// The choices provided to the user.
258258
choices: PerseusRadioChoice[];
259+
// If true, the number of choices selected must match the number of correct choices.
260+
countChoices?: boolean;
259261
};
260262

261263
export type PerseusRadioUserInput = {

packages/perseus-score/src/widgets/radio/score-radio.test.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import type {
66
} from "@khanacademy/perseus-core";
77

88
describe("scoreRadio", () => {
9-
it("is invalid when number selected does not match number correct", () => {
9+
it("is invalid when number selected does not match number correct and countChoices is true", () => {
1010
const userInput: PerseusRadioUserInput = {
1111
choicesSelected: [true, false, false, false],
1212
};
@@ -18,13 +18,34 @@ describe("scoreRadio", () => {
1818
{content: "Choice 3", correct: false},
1919
{content: "Choice 4", correct: false},
2020
],
21+
countChoices: true,
2122
};
2223

2324
const score = scoreRadio(userInput, rubric);
2425

2526
expect(score).toHaveInvalidInput();
2627
});
2728

29+
it("is incorrect when number selected does not match number correct and countChoices is false", () => {
30+
const userInput: PerseusRadioUserInput = {
31+
choicesSelected: [true, false, false, false],
32+
};
33+
34+
const rubric: PerseusRadioRubric = {
35+
choices: [
36+
{content: "Choice 1", correct: true},
37+
{content: "Choice 2", correct: true},
38+
{content: "Choice 3", correct: false},
39+
{content: "Choice 4", correct: false},
40+
],
41+
countChoices: false,
42+
};
43+
44+
const score = scoreRadio(userInput, rubric);
45+
46+
expect(score).toHaveBeenAnsweredIncorrectly();
47+
});
48+
2849
it("is invalid when none of the above and an answer are both selected", () => {
2950
const userInput: PerseusRadioUserInput = {
3051
choicesSelected: [true, false, false, false, true],

packages/perseus-score/src/widgets/radio/score-radio.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,14 @@ function scoreRadio(
1919
return currentChoice.correct ? sum + 1 : sum;
2020
}, 0);
2121

22-
if (numCorrect > 1 && numSelected !== numCorrect) {
22+
// If the number of correct answers is greater than 1 and the number of
23+
// selected answers is not equal to the number of correct answers, and
24+
// the countChoices option is true, then return an invalid score.
25+
if (numCorrect > 1 && numSelected !== numCorrect && rubric.countChoices) {
2326
return {
2427
type: "invalid",
2528
message: ErrorCodes.CHOOSE_CORRECT_NUM_ERROR,
2629
};
27-
// If NOTA and some other answer are checked, ...
2830
}
2931

3032
const noneOfTheAboveSelected = rubric.choices.some(

packages/perseus/src/widgets/radio/__tests__/radio.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,7 @@ describe("Radio Widget", () => {
724724
correct: false,
725725
},
726726
],
727+
countChoices: true,
727728
},
728729
},
729730
},

0 commit comments

Comments
 (0)