@khanacademy/perseus-score 7.6.2 → 7.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -76,9 +76,9 @@ function scorePlotter(userInput,rubric){return {type:"points",earned:perseusCore
76
76
 
77
77
  function validatePlotter(userInput,validationData){if(userInput==null||perseusCore.approximateDeepEqual(userInput,validationData.starting)){return {type:"invalid",message:null}}return null}
78
78
 
79
- function scoreRadio(userInput,rubric){if(userInput==null){return {type:"invalid",message:null}}const numSelected=userInput.choicesSelected.reduce((sum,selected)=>{return sum+(selected?1:0)},0);const numCorrect=rubric.choices.reduce((sum,currentChoice)=>{return currentChoice.correct?sum+1:sum},0);if(numCorrect>1&&numSelected!==numCorrect&&rubric.countChoices){return {type:"invalid",message:ErrorCodes.CHOOSE_CORRECT_NUM_ERROR}}const noneOfTheAboveSelected=rubric.choices.some((choice,index)=>choice.isNoneOfTheAbove&&userInput.choicesSelected[index]);if(noneOfTheAboveSelected&&numSelected>1){return {type:"invalid",message:ErrorCodes.NOT_NONE_ABOVE_ERROR}}const correct=userInput.choicesSelected.every((selected,i)=>{let isCorrect;if(rubric.choices[i].isNoneOfTheAbove){isCorrect=rubric.choices.every((choice,j)=>{return i===j||!choice.correct});}else {isCorrect=!!rubric.choices[i].correct;}return isCorrect===selected});return {type:"points",earned:correct?1:0,total:1,message:null}}
79
+ function scoreRadio(userInput,rubric){if(userInput==null){return {type:"invalid",message:null}}const invalidIds=userInput.selectedChoiceIds.filter(id=>!rubric.choices.some(choice=>choice.id===id));if(invalidIds.length>0){return {type:"invalid",message:"Invalid choice selection"}}const numSelected=userInput.selectedChoiceIds.length;const numCorrect=rubric.choices.reduce((sum,currentChoice)=>{return currentChoice.correct?sum+1:sum},0);if(numCorrect>1&&numSelected!==numCorrect&&rubric.countChoices){return {type:"invalid",message:ErrorCodes.CHOOSE_CORRECT_NUM_ERROR}}const noneOfTheAboveSelected=rubric.choices.some(choice=>choice.isNoneOfTheAbove&&userInput.selectedChoiceIds.includes(choice.id));if(noneOfTheAboveSelected&&numSelected>1){return {type:"invalid",message:ErrorCodes.NOT_NONE_ABOVE_ERROR}}const correct=rubric.choices.every(choice=>{const isSelected=userInput.selectedChoiceIds.includes(choice.id);const isCorrect=!!choice.correct;return isCorrect===isSelected});return {type:"points",earned:correct?1:0,total:1,message:null}}
80
80
 
81
- function validateRadio(userInput){if(userInput==null||!userInput.choicesSelected.includes(true)){return {type:"invalid",message:null}}return null}
81
+ function validateRadio(userInput){if(userInput==null||userInput.selectedChoiceIds.length===0){return {type:"invalid",message:null}}return null}
82
82
 
83
83
  function scoreSorter(userInput,rubric){const correct=perseusCore.approximateDeepEqual(userInput.options,rubric.correct);return {type:"points",earned:correct?1:0,total:1,message:null}}
84
84
 
@@ -114,7 +114,7 @@ const widgets=new perseusCore.Registry("Score widget registry");function registe
114
114
 
115
115
  const noScore={type:"points",earned:0,total:0,message:null};function scoreIsEmpty(score){return score.type==="invalid"&&(!score.message||score.message.length===0)}function combineScores(scoreA,scoreB){let message;if(scoreA.type==="points"&&scoreB.type==="points"){if(scoreA.message&&scoreB.message&&scoreA.message!==scoreB.message){message=null;}else {message=scoreA.message||scoreB.message;}return {type:"points",earned:scoreA.earned+scoreB.earned,total:scoreA.total+scoreB.total,message:message}}if(scoreA.type==="points"&&scoreB.type==="invalid"){return scoreB}if(scoreA.type==="invalid"&&scoreB.type==="points"){return scoreA}if(scoreA.type==="invalid"&&scoreB.type==="invalid"){if(scoreA.message&&scoreB.message&&scoreA.message!==scoreB.message){message=null;}else {message=scoreA.message||scoreB.message;}return {type:"invalid",message:message}}throw new perseusCore.PerseusError("PerseusScore with unknown type encountered",perseusCore.Errors.InvalidInput,{metadata:{scoreA:JSON.stringify(scoreA),scoreB:JSON.stringify(scoreB)}})}function flattenScores(widgetScoreMap){return Object.values(widgetScoreMap).reduce(combineScores,noScore)}function scorePerseusItem(perseusRenderData,userInputMap,locale){const usedWidgetIds=perseusCore.getWidgetIdsFromContent(perseusRenderData.content);const scores=scoreWidgetsFunctional(perseusRenderData.widgets,usedWidgetIds,userInputMap,locale);return flattenScores(scores)}function scoreWidgetsFunctional(widgets,widgetIds,userInputMap,locale){const upgradedWidgets=perseusCore.applyDefaultsToWidgets(widgets);const gradedWidgetIds=widgetIds.filter(id=>{const props=upgradedWidgets[id];const widgetIsGraded=props?.graded==null||props.graded;const widgetIsStatic=!!props?.static;return widgetIsGraded&&!widgetIsStatic});const widgetScores={};gradedWidgetIds.forEach(id=>{const widget=upgradedWidgets[id];if(!widget){return}const userInput=userInputMap[id];const validator=getWidgetValidator(widget.type);const scorer=getWidgetScorer(widget.type);const score=validator?.(userInput,widget.options,locale)??scorer?.(userInput,widget.options,locale);if(score!=null){widgetScores[id]=score;}});return widgetScores}
116
116
 
117
- function hasEmptyDINERWidgets(itemData,userInputMap){const usedWidgetIds=perseusCore.getWidgetIdsFromContent(itemData.question.content);const widgets=itemData.question.widgets;for(const widgetId of usedWidgetIds){const widget=widgets[widgetId];const input=userInputMap[widgetId];switch(widget.type){case "dropdown":{if(input.value===0){return true}break}case "interactive-graph":{break}case "numeric-input":{if(!input.currentValue&&!widget.options.coefficient){return true}break}case "expression":{if(!input){return true}break}case "radio":{if(!input.choicesSelected.includes(true)){return true}break}}}return false}
117
+ function hasEmptyDINERWidgets(itemData,userInputMap){const usedWidgetIds=perseusCore.getWidgetIdsFromContent(itemData.question.content);const widgets=itemData.question.widgets;for(const widgetId of usedWidgetIds){const widget=widgets[widgetId];const input=userInputMap[widgetId];switch(widget.type){case "dropdown":{if(input.value===0){return true}break}case "interactive-graph":{break}case "numeric-input":{if(!input.currentValue&&!widget.options.coefficient){return true}break}case "expression":{if(!input){return true}break}case "radio":{if(input.selectedChoiceIds.length===0){return true}break}}}return false}
118
118
 
119
119
  exports.ErrorCodes = ErrorCodes;
120
120
  exports.KhanAnswerTypes = KhanAnswerTypes;