@pie-element/multiple-choice 13.2.2 → 13.3.0-beta.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/CHANGELOG.md +13 -3
- package/configure/CHANGELOG.md +8 -5
- package/configure/lib/__tests__/root.test.js +279 -0
- package/configure/lib/index.js +1 -0
- package/configure/lib/index.js.map +1 -1
- package/configure/package.json +4 -4
- package/controller/CHANGELOG.md +5 -2
- package/controller/lib/__tests__/index.test.js +518 -0
- package/controller/lib/__tests__/utils.test.js +8 -0
- package/controller/lib/index.js +10 -0
- package/controller/lib/index.js.map +1 -1
- package/controller/package.json +2 -2
- package/docs/demo/pie.manifest.json +11 -0
- package/lib/__tests__/choice-input-test.js +49 -0
- package/lib/__tests__/index-test.js +206 -0
- package/lib/__tests__/key-events-test.js +95 -0
- package/lib/__tests__/multiple-choice-test.js +101 -0
- package/lib/__tests__/session-updater-test.js +70 -0
- package/lib/choice-input.js +15 -9
- package/lib/choice-input.js.map +1 -1
- package/lib/index.js +5 -2
- package/lib/index.js.map +1 -1
- package/lib/multiple-choice.js +3 -1
- package/lib/multiple-choice.js.map +1 -1
- package/lib/utils.js +14 -0
- package/lib/utils.js.map +1 -0
- package/module/configure.js +1 -1
- package/module/element.js +1 -1
- package/module/index.html +1 -1
- package/module/manifest.json +3 -3
- package/module/print.html +1 -1
- package/module/print.js +1 -1
- package/package.json +5 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["_lodashEs","require","_utils","_defaults","_interopRequireDefault","_controllerUtils","prepareChoice","model","env","defaultFeedback","choice","role","mode","out","label","value","rationale","rationaleEnabled","correct","feedbackEnabled","feedbackType","feedback","type","createDefaultModel","Promise","resolve","defaults","normalize","question","verticalMode","choicesLayout","questionProps","exports","session","updateSession","normalizedQuestion","Object","assign","incorrect","choices","map","lockChoiceOrder","lockChoices","getShuffledChoices","disabled","prompt","promptEnabled","gridColumns","choiceMode","keyMode","choicePrefix","responseCorrect","isResponseCorrect","undefined","language","extraCSSRules","fontSizeFactor","isSelectionButtonBelow","selectedAnswerBackgroundColor","selectedAnswerStrokeColor","selectedAnswerStrokeWidth","hoverAnswerBackgroundColor","hoverAnswerStrokeColor","hoverAnswerStrokeWidth","minSelections","maxSelections","keyboardEventsEnabled","autoplayAudioEnabled","completeAudioEnabled","customAudioButton","teacherInstructions","teacherInstructionsEnabled","getScore","config","isEmpty","selectedChoices","correctChoices","filter","ch","score","reduce","acc","selectedChoice","find","length","str","parseFloat","toFixed","getLogTrace","traceLog","selected","questionType","push","join","c","correctValues","correctSelected","v","includes","incorrectSelected","partialScoringEnabled","partialScoring","enabled","scoringMethod","outcome","empty","createCorrectResponseSession","id","getInnerText","html","replaceAll","getContent","replace","validate","minAnswerChoices","maxAnswerChoices","reversedChoices","reverse","choicesErrors","rationaleErrors","errors","forEach","field","required","hasCorrectResponse","index","identicalAnswer","slice","some","nbOfChoices","answerChoices","correctResponse"],"sources":["../src/index.js"],"sourcesContent":["/* eslint-disable no-console */\nimport { isEmpty } from 'lodash-es';\nimport { isResponseCorrect } from './utils';\nimport defaults from './defaults';\nimport { lockChoices, partialScoring, getShuffledChoices } from '@pie-lib/controller-utils';\n\nconst prepareChoice = (model, env, defaultFeedback) => (choice) => {\n const { role, mode } = env || {};\n const out = {\n label: choice.label,\n value: choice.value,\n };\n\n if (role === 'instructor' && (mode === 'view' || mode === 'evaluate')) {\n out.rationale = model.rationaleEnabled ? choice.rationale : null;\n } else {\n out.rationale = null;\n }\n\n if (mode === 'evaluate') {\n out.correct = !!choice.correct;\n\n if (model.feedbackEnabled) {\n const feedbackType = (choice.feedback && choice.feedback.type) || 'none';\n\n if (feedbackType === 'default') {\n out.feedback = defaultFeedback[choice.correct ? 'correct' : 'incorrect'];\n } else if (feedbackType === 'custom') {\n out.feedback = choice.feedback.value;\n }\n }\n }\n\n return out;\n};\n\nexport function createDefaultModel(model = {}) {\n return new Promise((resolve) => resolve({ ...defaults, ...model }));\n}\n\nexport const normalize = (question) => {\n const { verticalMode, choicesLayout, ...questionProps } = question || {};\n\n return {\n ...defaults,\n ...questionProps,\n // This is used for offering support for old models which have the property verticalMode\n // Same thing is set in authoring : packages/multiple-choice/configure/src/index.jsx - createDefaultModel\n choicesLayout: choicesLayout || (verticalMode === false && 'horizontal') || defaults.choicesLayout,\n };\n};\n\n/**\n *\n * @param {*} question\n * @param {*} session\n * @param {*} env\n * @param {*} updateSession - optional - a function that will set the properties passed into it on the session.\n */\nexport async function model(question, session, env, updateSession) {\n const normalizedQuestion = normalize(question);\n\n const defaultFeedback = Object.assign(\n { correct: 'Correct', incorrect: 'Incorrect' },\n normalizedQuestion.defaultFeedback,\n );\n\n let choices = (normalizedQuestion.choices || []).map(prepareChoice(normalizedQuestion, env, defaultFeedback));\n\n const lockChoiceOrder = lockChoices(normalizedQuestion, session, env);\n\n if (!lockChoiceOrder) {\n choices = await getShuffledChoices(choices, session, updateSession, 'value');\n }\n\n const out = {\n disabled: env.mode !== 'gather',\n mode: env.mode,\n prompt: normalizedQuestion.promptEnabled ? normalizedQuestion.prompt : null,\n choicesLayout: normalizedQuestion.choicesLayout,\n gridColumns: normalizedQuestion.gridColumns,\n choiceMode: normalizedQuestion.choiceMode,\n keyMode: normalizedQuestion.choicePrefix,\n choices,\n responseCorrect: env.mode === 'evaluate' ? isResponseCorrect(normalizedQuestion, session) : undefined,\n language: normalizedQuestion.language,\n extraCSSRules: normalizedQuestion.extraCSSRules,\n fontSizeFactor: normalizedQuestion.fontSizeFactor,\n isSelectionButtonBelow: normalizedQuestion.isSelectionButtonBelow,\n selectedAnswerBackgroundColor: normalizedQuestion.selectedAnswerBackgroundColor || 'initial',\n selectedAnswerStrokeColor: normalizedQuestion.selectedAnswerStrokeColor || 'initial',\n selectedAnswerStrokeWidth: normalizedQuestion.selectedAnswerStrokeWidth || 'initial',\n hoverAnswerBackgroundColor: normalizedQuestion.hoverAnswerBackgroundColor || 'initial',\n hoverAnswerStrokeColor: normalizedQuestion.hoverAnswerStrokeColor || 'initial',\n hoverAnswerStrokeWidth: normalizedQuestion.hoverAnswerStrokeWidth || 'initial',\n minSelections: normalizedQuestion.minSelections,\n maxSelections: normalizedQuestion.maxSelections,\n keyboardEventsEnabled: normalizedQuestion.keyboardEventsEnabled,\n autoplayAudioEnabled: normalizedQuestion.autoplayAudioEnabled,\n completeAudioEnabled: normalizedQuestion.completeAudioEnabled,\n customAudioButton: normalizedQuestion.customAudioButton,\n };\n\n const { role, mode } = env || {};\n\n if (role === 'instructor' && (mode === 'view' || mode === 'evaluate')) {\n out.teacherInstructions = normalizedQuestion.teacherInstructionsEnabled\n ? normalizedQuestion.teacherInstructions\n : null;\n } else {\n out.teacherInstructions = null;\n }\n\n return out;\n}\n\nexport const getScore = (config, session) => {\n if (!session || isEmpty(session)) {\n return 0;\n }\n\n const selectedChoices = session.value || [];\n const correctChoices = (config.choices || []).filter((ch) => ch.correct);\n\n let score = selectedChoices.reduce(\n (acc, selectedChoice) => acc + (correctChoices.find((ch) => ch.value === selectedChoice) ? 1 : 0),\n 0,\n );\n\n if (correctChoices.length < selectedChoices.length) {\n score -= selectedChoices.length - correctChoices.length;\n\n if (score < 0) {\n score = 0;\n }\n }\n\n const str = correctChoices.length ? score / correctChoices.length : 0;\n\n return parseFloat(str.toFixed(2));\n};\n\n/**\n * Generates detailed trace log for scoring evaluation\n * @param {Object} model - the question model\n * @param {Object} session - the student session\n * @param {Object} env - the environment\n * @returns {Array} traceLog - array of trace messages\n */\nexport const getLogTrace = (model, session, env) => {\n const traceLog = [];\n const selected = session?.value || [];\n \n const questionType = model.choiceMode === 'radio' ? 'multiple-choice (radio)' : 'multiple-select (checkbox)';\n traceLog.push(`Question type: ${questionType}.`);\n \n if (selected.length) {\n traceLog.push(`Student selected ${selected.length} answer(s): ${selected.join(', ')}.`);\n } else {\n traceLog.push('Student did not select any answers.');\n }\n\n const correctChoices = (model.choices || []).filter((c) => c.correct);\n const correctValues = correctChoices.map((c) => c.value);\n traceLog.push(`${correctChoices.length} correct answer(s) are defined for this question.`);\n \n if (selected.length) {\n const correctSelected = selected.filter((v) => correctValues.includes(v));\n const incorrectSelected = selected.filter((v) => !correctValues.includes(v));\n traceLog.push(\n `Student selected ${correctSelected.length} correct and ${incorrectSelected.length} incorrect answer(s).`\n );\n }\n\n const partialScoringEnabled = partialScoring.enabled(model, env) && model.choiceMode !== 'radio';\n const scoringMethod = partialScoringEnabled ? 'partial scoring' : 'all-or-nothing scoring';\n traceLog.push(`Score calculated using ${scoringMethod}.`);\n\n const score = getScore(model, session);\n traceLog.push(`Final score: ${score}.`);\n\n return traceLog;\n};\n\n/**\n *\n * The score is partial by default for checkbox mode, allOrNothing for radio mode.\n * To disable partial scoring for checkbox mode you either set model.partialScoring = false or env.partialScoring = false. the value in `env` will\n * override the value in `model`.\n * @param {Object} model - the main model\n * @param {*} session\n * @param {Object} env\n */\nexport function outcome(model, session, env) {\n return new Promise((resolve) => {\n if (!session || isEmpty(session)) {\n resolve({ score: 0, empty: true, traceLog: ['Student did not select any answers. Score is 0.'] });\n } else {\n const traceLog = getLogTrace(model, session, env);\n const score = getScore(model, session);\n const partialScoringEnabled = partialScoring.enabled(model, env) && model.choiceMode !== 'radio';\n\n resolve({ \n score: partialScoringEnabled ? score : score === 1 ? 1 : 0, \n empty: false, \n traceLog \n });\n }\n });\n}\n\nexport const createCorrectResponseSession = (question, env) => {\n return new Promise((resolve) => {\n if (env.mode !== 'evaluate' && env.role === 'instructor') {\n const { choices } = question || { choices: [] };\n\n resolve({\n id: '1',\n value: choices.filter((c) => c.correct).map((c) => c.value),\n });\n } else {\n resolve(null);\n }\n });\n};\n\n// remove all html tags\nconst getInnerText = (html) => (html || '').replaceAll(/<[^>]*>/g, '');\n\n// remove all html tags except img, iframe and source tag for audio\nconst getContent = (html) => (html || '').replace(/(<(?!img|iframe|source)([^>]+)>)/gi, '');\n\nexport const validate = (model = {}, config = {}) => {\n const { choices } = model;\n const { minAnswerChoices = 2, maxAnswerChoices } = config;\n const reversedChoices = [...(choices || [])].reverse();\n const choicesErrors = {};\n const rationaleErrors = {};\n const errors = {};\n\n ['teacherInstructions', 'prompt'].forEach((field) => {\n if (config[field]?.required && !getContent(model[field])) {\n errors[field] = 'This field is required.';\n }\n });\n\n let hasCorrectResponse = false;\n\n reversedChoices.forEach((choice, index) => {\n const { correct, value, label, rationale } = choice;\n\n if (correct) {\n hasCorrectResponse = true;\n }\n\n if (!getContent(label)) {\n choicesErrors[value] = 'Content should not be empty.';\n } else {\n const identicalAnswer = reversedChoices.slice(index + 1).some((c) => c.label === label);\n\n if (identicalAnswer) {\n choicesErrors[value] = 'Content should be unique.';\n }\n }\n\n if (config.rationale?.required && !getContent(rationale)) {\n rationaleErrors[value] = 'This field is required.';\n }\n });\n\n const nbOfChoices = (choices || []).length;\n\n if (nbOfChoices < minAnswerChoices) {\n errors.answerChoices = `There should be at least ${minAnswerChoices} choices defined.`;\n } else if (nbOfChoices > maxAnswerChoices) {\n errors.answerChoices = `No more than ${maxAnswerChoices} choices should be defined.`;\n }\n\n if (!hasCorrectResponse) {\n errors.correctResponse = 'No correct response defined.';\n }\n\n if (!isEmpty(choicesErrors)) {\n errors.choices = choicesErrors;\n }\n\n if (!isEmpty(rationaleErrors)) {\n errors.rationale = rationaleErrors;\n }\n\n return errors;\n};\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"index.js","names":["_lodashEs","require","_utils","_defaults","_interopRequireDefault","_controllerUtils","prepareChoice","model","env","defaultFeedback","choice","role","mode","out","label","value","rationale","rationaleEnabled","correct","feedbackEnabled","feedbackType","feedback","type","createDefaultModel","Promise","resolve","defaults","normalize","question","verticalMode","choicesLayout","questionProps","exports","session","updateSession","normalizedQuestion","Object","assign","incorrect","choices","map","lockChoiceOrder","lockChoices","getShuffledChoices","disabled","prompt","promptEnabled","gridColumns","choiceMode","keyMode","choicePrefix","responseCorrect","isResponseCorrect","undefined","language","extraCSSRules","fontSizeFactor","isSelectionButtonBelow","selectedAnswerBackgroundColor","selectedAnswerStrokeColor","selectedAnswerStrokeWidth","hoverAnswerBackgroundColor","hoverAnswerStrokeColor","hoverAnswerStrokeWidth","minSelections","maxSelections","keyboardEventsEnabled","autoplayAudioEnabled","completeAudioEnabled","customAudioButton","teacherInstructions","teacherInstructionsEnabled","getScore","config","isEmpty","selectedChoices","correctChoices","filter","ch","score","reduce","acc","selectedChoice","find","length","str","parseFloat","toFixed","getLogTrace","traceLog","selected","questionType","push","join","c","correctValues","correctSelected","v","includes","incorrectSelected","partialScoringEnabled","partialScoring","enabled","scoringMethod","outcome","empty","createCorrectResponseSession","id","getInnerText","html","replaceAll","getContent","replace","validate","minAnswerChoices","maxAnswerChoices","reversedChoices","reverse","choicesErrors","rationaleErrors","errors","forEach","field","required","hasCorrectResponse","correctCount","index","identicalAnswer","slice","some","nbOfChoices","answerChoices","correctResponse"],"sources":["../src/index.js"],"sourcesContent":["/* eslint-disable no-console */\nimport { isEmpty } from 'lodash-es';\nimport { isResponseCorrect } from './utils';\nimport defaults from './defaults';\nimport { lockChoices, partialScoring, getShuffledChoices } from '@pie-lib/controller-utils';\n\nconst prepareChoice = (model, env, defaultFeedback) => (choice) => {\n const { role, mode } = env || {};\n const out = {\n label: choice.label,\n value: choice.value,\n };\n\n if (role === 'instructor' && (mode === 'view' || mode === 'evaluate')) {\n out.rationale = model.rationaleEnabled ? choice.rationale : null;\n } else {\n out.rationale = null;\n }\n\n if (mode === 'evaluate') {\n out.correct = !!choice.correct;\n\n if (model.feedbackEnabled) {\n const feedbackType = (choice.feedback && choice.feedback.type) || 'none';\n\n if (feedbackType === 'default') {\n out.feedback = defaultFeedback[choice.correct ? 'correct' : 'incorrect'];\n } else if (feedbackType === 'custom') {\n out.feedback = choice.feedback.value;\n }\n }\n }\n\n return out;\n};\n\nexport function createDefaultModel(model = {}) {\n return new Promise((resolve) => resolve({ ...defaults, ...model }));\n}\n\nexport const normalize = (question) => {\n const { verticalMode, choicesLayout, ...questionProps } = question || {};\n\n return {\n ...defaults,\n ...questionProps,\n // This is used for offering support for old models which have the property verticalMode\n // Same thing is set in authoring : packages/multiple-choice/configure/src/index.jsx - createDefaultModel\n choicesLayout: choicesLayout || (verticalMode === false && 'horizontal') || defaults.choicesLayout,\n };\n};\n\n/**\n *\n * @param {*} question\n * @param {*} session\n * @param {*} env\n * @param {*} updateSession - optional - a function that will set the properties passed into it on the session.\n */\nexport async function model(question, session, env, updateSession) {\n const normalizedQuestion = normalize(question);\n\n const defaultFeedback = Object.assign(\n { correct: 'Correct', incorrect: 'Incorrect' },\n normalizedQuestion.defaultFeedback,\n );\n\n let choices = (normalizedQuestion.choices || []).map(prepareChoice(normalizedQuestion, env, defaultFeedback));\n\n const lockChoiceOrder = lockChoices(normalizedQuestion, session, env);\n\n if (!lockChoiceOrder) {\n choices = await getShuffledChoices(choices, session, updateSession, 'value');\n }\n\n const out = {\n disabled: env.mode !== 'gather',\n mode: env.mode,\n prompt: normalizedQuestion.promptEnabled ? normalizedQuestion.prompt : null,\n choicesLayout: normalizedQuestion.choicesLayout,\n gridColumns: normalizedQuestion.gridColumns,\n choiceMode: normalizedQuestion.choiceMode,\n keyMode: normalizedQuestion.choicePrefix,\n choices,\n responseCorrect: env.mode === 'evaluate' ? isResponseCorrect(normalizedQuestion, session) : undefined,\n language: normalizedQuestion.language,\n extraCSSRules: normalizedQuestion.extraCSSRules,\n fontSizeFactor: normalizedQuestion.fontSizeFactor,\n isSelectionButtonBelow: normalizedQuestion.isSelectionButtonBelow,\n selectedAnswerBackgroundColor: normalizedQuestion.selectedAnswerBackgroundColor || 'initial',\n selectedAnswerStrokeColor: normalizedQuestion.selectedAnswerStrokeColor || 'initial',\n selectedAnswerStrokeWidth: normalizedQuestion.selectedAnswerStrokeWidth || 'initial',\n hoverAnswerBackgroundColor: normalizedQuestion.hoverAnswerBackgroundColor || 'initial',\n hoverAnswerStrokeColor: normalizedQuestion.hoverAnswerStrokeColor || 'initial',\n hoverAnswerStrokeWidth: normalizedQuestion.hoverAnswerStrokeWidth || 'initial',\n minSelections: normalizedQuestion.minSelections,\n maxSelections: normalizedQuestion.maxSelections,\n keyboardEventsEnabled: normalizedQuestion.keyboardEventsEnabled,\n autoplayAudioEnabled: normalizedQuestion.autoplayAudioEnabled,\n completeAudioEnabled: normalizedQuestion.completeAudioEnabled,\n customAudioButton: normalizedQuestion.customAudioButton,\n };\n\n const { role, mode } = env || {};\n\n if (role === 'instructor' && (mode === 'view' || mode === 'evaluate')) {\n out.teacherInstructions = normalizedQuestion.teacherInstructionsEnabled\n ? normalizedQuestion.teacherInstructions\n : null;\n } else {\n out.teacherInstructions = null;\n }\n\n return out;\n}\n\nexport const getScore = (config, session) => {\n if (!session || isEmpty(session)) {\n return 0;\n }\n\n const selectedChoices = session.value || [];\n const correctChoices = (config.choices || []).filter((ch) => ch.correct);\n\n let score = selectedChoices.reduce(\n (acc, selectedChoice) => acc + (correctChoices.find((ch) => ch.value === selectedChoice) ? 1 : 0),\n 0,\n );\n\n if (correctChoices.length < selectedChoices.length) {\n score -= selectedChoices.length - correctChoices.length;\n\n if (score < 0) {\n score = 0;\n }\n }\n\n const str = correctChoices.length ? score / correctChoices.length : 0;\n\n return parseFloat(str.toFixed(2));\n};\n\n/**\n * Generates detailed trace log for scoring evaluation\n * @param {Object} model - the question model\n * @param {Object} session - the student session\n * @param {Object} env - the environment\n * @returns {Array} traceLog - array of trace messages\n */\nexport const getLogTrace = (model, session, env) => {\n const traceLog = [];\n const selected = session?.value || [];\n \n const questionType = model.choiceMode === 'radio' ? 'multiple-choice (radio)' : 'multiple-select (checkbox)';\n traceLog.push(`Question type: ${questionType}.`);\n \n if (selected.length) {\n traceLog.push(`Student selected ${selected.length} answer(s): ${selected.join(', ')}.`);\n } else {\n traceLog.push('Student did not select any answers.');\n }\n\n const correctChoices = (model.choices || []).filter((c) => c.correct);\n const correctValues = correctChoices.map((c) => c.value);\n traceLog.push(`${correctChoices.length} correct answer(s) are defined for this question.`);\n \n if (selected.length) {\n const correctSelected = selected.filter((v) => correctValues.includes(v));\n const incorrectSelected = selected.filter((v) => !correctValues.includes(v));\n traceLog.push(\n `Student selected ${correctSelected.length} correct and ${incorrectSelected.length} incorrect answer(s).`\n );\n }\n\n const partialScoringEnabled = partialScoring.enabled(model, env) && model.choiceMode !== 'radio';\n const scoringMethod = partialScoringEnabled ? 'partial scoring' : 'all-or-nothing scoring';\n traceLog.push(`Score calculated using ${scoringMethod}.`);\n\n const score = getScore(model, session);\n traceLog.push(`Final score: ${score}.`);\n\n return traceLog;\n};\n\n/**\n *\n * The score is partial by default for checkbox mode, allOrNothing for radio mode.\n * To disable partial scoring for checkbox mode you either set model.partialScoring = false or env.partialScoring = false. the value in `env` will\n * override the value in `model`.\n * @param {Object} model - the main model\n * @param {*} session\n * @param {Object} env\n */\nexport function outcome(model, session, env) {\n return new Promise((resolve) => {\n if (!session || isEmpty(session)) {\n resolve({ score: 0, empty: true, traceLog: ['Student did not select any answers. Score is 0.'] });\n } else {\n const traceLog = getLogTrace(model, session, env);\n const score = getScore(model, session);\n const partialScoringEnabled = partialScoring.enabled(model, env) && model.choiceMode !== 'radio';\n\n resolve({ \n score: partialScoringEnabled ? score : score === 1 ? 1 : 0, \n empty: false, \n traceLog \n });\n }\n });\n}\n\nexport const createCorrectResponseSession = (question, env) => {\n return new Promise((resolve) => {\n if (env.mode !== 'evaluate' && env.role === 'instructor') {\n const { choices } = question || { choices: [] };\n\n resolve({\n id: '1',\n value: choices.filter((c) => c.correct).map((c) => c.value),\n });\n } else {\n resolve(null);\n }\n });\n};\n\n// remove all html tags\nconst getInnerText = (html) => (html || '').replaceAll(/<[^>]*>/g, '');\n\n// remove all html tags except img, iframe and source tag for audio\nconst getContent = (html) => (html || '').replace(/(<(?!img|iframe|source)([^>]+)>)/gi, '');\n\nexport const validate = (model = {}, config = {}) => {\n const { choices } = model;\n const { minAnswerChoices = 2, maxAnswerChoices } = config;\n const reversedChoices = [...(choices || [])].reverse();\n const choicesErrors = {};\n const rationaleErrors = {};\n const errors = {};\n\n ['teacherInstructions', 'prompt'].forEach((field) => {\n if (config[field]?.required && !getContent(model[field])) {\n errors[field] = 'This field is required.';\n }\n });\n\n let hasCorrectResponse = false;\n let correctCount = 0;\n\n reversedChoices.forEach((choice, index) => {\n const { correct, value, label, rationale } = choice;\n\n if (correct) {\n hasCorrectResponse = true;\n correctCount++;\n }\n\n if (!getContent(label)) {\n choicesErrors[value] = 'Content should not be empty.';\n } else {\n const identicalAnswer = reversedChoices.slice(index + 1).some((c) => c.label === label);\n\n if (identicalAnswer) {\n choicesErrors[value] = 'Content should be unique.';\n }\n }\n\n if (config.rationale?.required && !getContent(rationale)) {\n rationaleErrors[value] = 'This field is required.';\n }\n });\n\n const nbOfChoices = (choices || []).length;\n\n if (nbOfChoices < minAnswerChoices) {\n errors.answerChoices = `There should be at least ${minAnswerChoices} choices defined.`;\n } else if (nbOfChoices > maxAnswerChoices) {\n errors.answerChoices = `No more than ${maxAnswerChoices} choices should be defined.`;\n }\n\n if (!hasCorrectResponse) {\n errors.correctResponse = 'No correct response defined.';\n } else {\n const { maxSelections, choiceMode } = model;\n\n if (choiceMode !== 'radio' && maxSelections != null && correctCount > maxSelections) {\n errors.correctResponse = `The number of correct answers (${correctCount}) exceeds max selections (${maxSelections}). Students won't be able to select all correct answers.`;\n }\n }\n\n if (!isEmpty(choicesErrors)) {\n errors.choices = choicesErrors;\n }\n\n if (!isEmpty(rationaleErrors)) {\n errors.rationale = rationaleErrors;\n }\n\n return errors;\n};\n"],"mappings":"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","ignoreList":[]}
|
package/controller/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pie-element/multiple-choice-controller",
|
|
3
3
|
"private": true,
|
|
4
|
-
"version": "8.
|
|
4
|
+
"version": "8.2.0-beta.0",
|
|
5
5
|
"description": "",
|
|
6
6
|
"main": "lib/index.js",
|
|
7
7
|
"module": "src/index.js",
|
|
8
8
|
"author": "",
|
|
9
9
|
"license": "ISC",
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"@pie-lib/controller-utils": "2.0.
|
|
11
|
+
"@pie-lib/controller-utils": "2.0.3",
|
|
12
12
|
"debug": "^4.1.1",
|
|
13
13
|
"lodash-es": "^4.17.23"
|
|
14
14
|
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
|
5
|
+
var _react = _interopRequireDefault(require("react"));
|
|
6
|
+
var _react2 = require("@testing-library/react");
|
|
7
|
+
var _choiceInput = require("../choice-input");
|
|
8
|
+
describe('ChoiceInput', () => {
|
|
9
|
+
let onChange;
|
|
10
|
+
const mkWrapper = (opts = {}) => {
|
|
11
|
+
const defaultOpts = {
|
|
12
|
+
checked: false,
|
|
13
|
+
disabled: false,
|
|
14
|
+
choiceMode: 'checkbox',
|
|
15
|
+
label: 'label',
|
|
16
|
+
displayKey: '1',
|
|
17
|
+
correctness: 'correct',
|
|
18
|
+
value: 'value',
|
|
19
|
+
classes: {
|
|
20
|
+
label: 'label'
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
const finalOpts = {
|
|
24
|
+
...defaultOpts,
|
|
25
|
+
...opts
|
|
26
|
+
};
|
|
27
|
+
return (0, _react2.render)(/*#__PURE__*/_react.default.createElement(_choiceInput.ChoiceInput, (0, _extends2.default)({}, finalOpts, {
|
|
28
|
+
onChange: onChange
|
|
29
|
+
})));
|
|
30
|
+
};
|
|
31
|
+
beforeEach(() => {
|
|
32
|
+
onChange = jest.fn();
|
|
33
|
+
});
|
|
34
|
+
describe('onToggleChoice', () => {
|
|
35
|
+
it('calls handler when checkbox is clicked', () => {
|
|
36
|
+
const {
|
|
37
|
+
container
|
|
38
|
+
} = mkWrapper({
|
|
39
|
+
disabled: false
|
|
40
|
+
});
|
|
41
|
+
const input = container.querySelector('input[type="checkbox"]');
|
|
42
|
+
if (input) {
|
|
43
|
+
_react2.fireEvent.click(input);
|
|
44
|
+
expect(onChange).toHaveBeenCalled();
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwicmVxdWlyZSIsIl9yZWFjdDIiLCJfY2hvaWNlSW5wdXQiLCJkZXNjcmliZSIsIm9uQ2hhbmdlIiwibWtXcmFwcGVyIiwib3B0cyIsImRlZmF1bHRPcHRzIiwiY2hlY2tlZCIsImRpc2FibGVkIiwiY2hvaWNlTW9kZSIsImxhYmVsIiwiZGlzcGxheUtleSIsImNvcnJlY3RuZXNzIiwidmFsdWUiLCJjbGFzc2VzIiwiZmluYWxPcHRzIiwicmVuZGVyIiwiZGVmYXVsdCIsImNyZWF0ZUVsZW1lbnQiLCJDaG9pY2VJbnB1dCIsIl9leHRlbmRzMiIsImJlZm9yZUVhY2giLCJqZXN0IiwiZm4iLCJpdCIsImNvbnRhaW5lciIsImlucHV0IiwicXVlcnlTZWxlY3RvciIsImZpcmVFdmVudCIsImNsaWNrIiwiZXhwZWN0IiwidG9IYXZlQmVlbkNhbGxlZCJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9fX3Rlc3RzX18vY2hvaWNlLWlucHV0LXRlc3QuanN4Il0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyByZW5kZXIsIGZpcmVFdmVudCB9IGZyb20gJ0B0ZXN0aW5nLWxpYnJhcnkvcmVhY3QnO1xuaW1wb3J0IHsgQ2hvaWNlSW5wdXQgfSBmcm9tICcuLi9jaG9pY2UtaW5wdXQnO1xuXG5kZXNjcmliZSgnQ2hvaWNlSW5wdXQnLCAoKSA9PiB7XG4gIGxldCBvbkNoYW5nZTtcblxuICBjb25zdCBta1dyYXBwZXIgPSAob3B0cyA9IHt9KSA9PiB7XG4gICAgY29uc3QgZGVmYXVsdE9wdHMgPSB7XG4gICAgICBjaGVja2VkOiBmYWxzZSxcbiAgICAgIGRpc2FibGVkOiBmYWxzZSxcbiAgICAgIGNob2ljZU1vZGU6ICdjaGVja2JveCcsXG4gICAgICBsYWJlbDogJ2xhYmVsJyxcbiAgICAgIGRpc3BsYXlLZXk6ICcxJyxcbiAgICAgIGNvcnJlY3RuZXNzOiAnY29ycmVjdCcsXG4gICAgICB2YWx1ZTogJ3ZhbHVlJyxcbiAgICAgIGNsYXNzZXM6IHtcbiAgICAgICAgbGFiZWw6ICdsYWJlbCcsXG4gICAgICB9LFxuICAgIH07XG5cbiAgICBjb25zdCBmaW5hbE9wdHMgPSB7IC4uLmRlZmF1bHRPcHRzLCAuLi5vcHRzIH07XG5cbiAgICByZXR1cm4gcmVuZGVyKDxDaG9pY2VJbnB1dCB7Li4uZmluYWxPcHRzfSBvbkNoYW5nZT17b25DaGFuZ2V9IC8+KTtcbiAgfTtcblxuICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICBvbkNoYW5nZSA9IGplc3QuZm4oKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ29uVG9nZ2xlQ2hvaWNlJywgKCkgPT4ge1xuICAgIGl0KCdjYWxscyBoYW5kbGVyIHdoZW4gY2hlY2tib3ggaXMgY2xpY2tlZCcsICgpID0+IHtcbiAgICAgIGNvbnN0IHsgY29udGFpbmVyIH0gPSBta1dyYXBwZXIoeyBkaXNhYmxlZDogZmFsc2UgfSk7XG4gICAgICBjb25zdCBpbnB1dCA9IGNvbnRhaW5lci5xdWVyeVNlbGVjdG9yKCdpbnB1dFt0eXBlPVwiY2hlY2tib3hcIl0nKTtcblxuICAgICAgaWYgKGlucHV0KSB7XG4gICAgICAgIGZpcmVFdmVudC5jbGljayhpbnB1dCk7XG4gICAgICAgIGV4cGVjdChvbkNoYW5nZSkudG9IYXZlQmVlbkNhbGxlZCgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcbn0pO1xuIl0sIm1hcHBpbmdzIjoiOzs7O0FBQUEsSUFBQUEsTUFBQSxHQUFBQyxzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQUMsT0FBQSxHQUFBRCxPQUFBO0FBQ0EsSUFBQUUsWUFBQSxHQUFBRixPQUFBO0FBRUFHLFFBQVEsQ0FBQyxhQUFhLEVBQUUsTUFBTTtFQUM1QixJQUFJQyxRQUFRO0VBRVosTUFBTUMsU0FBUyxHQUFHQSxDQUFDQyxJQUFJLEdBQUcsQ0FBQyxDQUFDLEtBQUs7SUFDL0IsTUFBTUMsV0FBVyxHQUFHO01BQ2xCQyxPQUFPLEVBQUUsS0FBSztNQUNkQyxRQUFRLEVBQUUsS0FBSztNQUNmQyxVQUFVLEVBQUUsVUFBVTtNQUN0QkMsS0FBSyxFQUFFLE9BQU87TUFDZEMsVUFBVSxFQUFFLEdBQUc7TUFDZkMsV0FBVyxFQUFFLFNBQVM7TUFDdEJDLEtBQUssRUFBRSxPQUFPO01BQ2RDLE9BQU8sRUFBRTtRQUNQSixLQUFLLEVBQUU7TUFDVDtJQUNGLENBQUM7SUFFRCxNQUFNSyxTQUFTLEdBQUc7TUFBRSxHQUFHVCxXQUFXO01BQUUsR0FBR0Q7SUFBSyxDQUFDO0lBRTdDLE9BQU8sSUFBQVcsY0FBTSxlQUFDbkIsTUFBQSxDQUFBb0IsT0FBQSxDQUFBQyxhQUFBLENBQUNqQixZQUFBLENBQUFrQixXQUFXLE1BQUFDLFNBQUEsQ0FBQUgsT0FBQSxNQUFLRixTQUFTO01BQUVaLFFBQVEsRUFBRUE7SUFBUyxFQUFFLENBQUMsQ0FBQztFQUNuRSxDQUFDO0VBRURrQixVQUFVLENBQUMsTUFBTTtJQUNmbEIsUUFBUSxHQUFHbUIsSUFBSSxDQUFDQyxFQUFFLENBQUMsQ0FBQztFQUN0QixDQUFDLENBQUM7RUFFRnJCLFFBQVEsQ0FBQyxnQkFBZ0IsRUFBRSxNQUFNO0lBQy9Cc0IsRUFBRSxDQUFDLHdDQUF3QyxFQUFFLE1BQU07TUFDakQsTUFBTTtRQUFFQztNQUFVLENBQUMsR0FBR3JCLFNBQVMsQ0FBQztRQUFFSSxRQUFRLEVBQUU7TUFBTSxDQUFDLENBQUM7TUFDcEQsTUFBTWtCLEtBQUssR0FBR0QsU0FBUyxDQUFDRSxhQUFhLENBQUMsd0JBQXdCLENBQUM7TUFFL0QsSUFBSUQsS0FBSyxFQUFFO1FBQ1RFLGlCQUFTLENBQUNDLEtBQUssQ0FBQ0gsS0FBSyxDQUFDO1FBQ3RCSSxNQUFNLENBQUMzQixRQUFRLENBQUMsQ0FBQzRCLGdCQUFnQixDQUFDLENBQUM7TUFDckM7SUFDRixDQUFDLENBQUM7RUFDSixDQUFDLENBQUM7QUFDSixDQUFDLENBQUMiLCJpZ25vcmVMaXN0IjpbXX0=
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
var _react = _interopRequireDefault(require("react"));
|
|
5
|
+
var _react2 = require("@testing-library/react");
|
|
6
|
+
var _piePlayerEvents = require("@pie-framework/pie-player-events");
|
|
7
|
+
var _main = _interopRequireDefault(require("../main"));
|
|
8
|
+
var _index = _interopRequireWildcard(require("../index"));
|
|
9
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
10
|
+
jest.useFakeTimers();
|
|
11
|
+
jest.mock('@pie-lib/math-rendering', () => ({
|
|
12
|
+
renderMath: jest.fn()
|
|
13
|
+
}));
|
|
14
|
+
jest.mock('lodash-es', () => {
|
|
15
|
+
const lodash = require('lodash');
|
|
16
|
+
return {
|
|
17
|
+
...lodash,
|
|
18
|
+
debounce: jest.fn(fn => fn)
|
|
19
|
+
};
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
// Mock the render-ui PreviewLayout
|
|
23
|
+
jest.mock('@pie-lib/render-ui', () => ({
|
|
24
|
+
PreviewLayout: ({
|
|
25
|
+
children
|
|
26
|
+
}) => /*#__PURE__*/_react.default.createElement("div", {
|
|
27
|
+
"data-testid": "preview-layout"
|
|
28
|
+
}, children),
|
|
29
|
+
Collapsible: ({
|
|
30
|
+
children,
|
|
31
|
+
labels
|
|
32
|
+
}) => /*#__PURE__*/_react.default.createElement("div", {
|
|
33
|
+
"data-testid": "collapsible"
|
|
34
|
+
}, /*#__PURE__*/_react.default.createElement("button", null, labels?.hidden || 'Show'), children),
|
|
35
|
+
PreviewPrompt: ({
|
|
36
|
+
prompt
|
|
37
|
+
}) => /*#__PURE__*/_react.default.createElement("div", {
|
|
38
|
+
"data-testid": "preview-prompt"
|
|
39
|
+
}, prompt),
|
|
40
|
+
color: {
|
|
41
|
+
text: () => '#000',
|
|
42
|
+
background: () => '#fff',
|
|
43
|
+
primary: () => '#1976d2',
|
|
44
|
+
correct: () => '#4caf50',
|
|
45
|
+
incorrect: () => '#f44336',
|
|
46
|
+
disabled: () => '#9e9e9e'
|
|
47
|
+
}
|
|
48
|
+
}));
|
|
49
|
+
describe('isComplete', () => {
|
|
50
|
+
it.each`
|
|
51
|
+
session | expected
|
|
52
|
+
${{
|
|
53
|
+
value: [1, 2, 3]
|
|
54
|
+
}} | ${true}
|
|
55
|
+
${{
|
|
56
|
+
value: []
|
|
57
|
+
}} | ${false}
|
|
58
|
+
${{}} | ${false}
|
|
59
|
+
${null} | ${false}
|
|
60
|
+
${undefined} | ${false}
|
|
61
|
+
`('session = $session is complete => $expected', ({
|
|
62
|
+
session,
|
|
63
|
+
expected
|
|
64
|
+
}) => {
|
|
65
|
+
expect((0, _index.isComplete)(session)).toEqual(expected);
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
describe('multiple-choice', () => {
|
|
69
|
+
describe('rendering', () => {
|
|
70
|
+
const renderComponent = (modelOverrides = {}) => {
|
|
71
|
+
const defaultProps = {
|
|
72
|
+
model: {
|
|
73
|
+
choices: [],
|
|
74
|
+
prompt: 'Select an answer',
|
|
75
|
+
...modelOverrides
|
|
76
|
+
},
|
|
77
|
+
session: {},
|
|
78
|
+
classes: {}
|
|
79
|
+
};
|
|
80
|
+
return (0, _react2.render)(/*#__PURE__*/_react.default.createElement(_main.default, defaultProps));
|
|
81
|
+
};
|
|
82
|
+
it('renders without crashing', () => {
|
|
83
|
+
const {
|
|
84
|
+
container
|
|
85
|
+
} = renderComponent();
|
|
86
|
+
expect(container).toBeInTheDocument();
|
|
87
|
+
});
|
|
88
|
+
it('renders the preview layout wrapper', () => {
|
|
89
|
+
renderComponent();
|
|
90
|
+
expect(_react2.screen.getByTestId('preview-layout')).toBeInTheDocument();
|
|
91
|
+
});
|
|
92
|
+
it('renders with rationale', () => {
|
|
93
|
+
renderComponent({
|
|
94
|
+
rationale: 'This is rationale'
|
|
95
|
+
});
|
|
96
|
+
expect(_react2.screen.getByText('This is rationale')).toBeInTheDocument();
|
|
97
|
+
});
|
|
98
|
+
it('renders with teacherInstructions', () => {
|
|
99
|
+
renderComponent({
|
|
100
|
+
teacherInstructions: 'These are teacher instructions'
|
|
101
|
+
});
|
|
102
|
+
expect(_react2.screen.getByText('These are teacher instructions')).toBeInTheDocument();
|
|
103
|
+
});
|
|
104
|
+
it('renders choices when provided', () => {
|
|
105
|
+
renderComponent({
|
|
106
|
+
choices: [{
|
|
107
|
+
value: 'a',
|
|
108
|
+
label: 'Option A'
|
|
109
|
+
}, {
|
|
110
|
+
value: 'b',
|
|
111
|
+
label: 'Option B'
|
|
112
|
+
}]
|
|
113
|
+
});
|
|
114
|
+
expect(_react2.screen.getByText('Option A')).toBeInTheDocument();
|
|
115
|
+
expect(_react2.screen.getByText('Option B')).toBeInTheDocument();
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
describe('events', () => {
|
|
119
|
+
describe('model', () => {
|
|
120
|
+
it('dispatches model set event', () => {
|
|
121
|
+
const el = new _index.default();
|
|
122
|
+
el.tagName = 'mc-el';
|
|
123
|
+
el.model = {};
|
|
124
|
+
expect(el.dispatchEvent).toBeCalledWith(new _piePlayerEvents.ModelSetEvent('mc-el', false, true));
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
describe('onChange', () => {
|
|
128
|
+
it('dispatches session changed event - add answer (checkbox)', () => {
|
|
129
|
+
const el = new _index.default();
|
|
130
|
+
el.tagName = 'mc-el';
|
|
131
|
+
el.model = {
|
|
132
|
+
choiceMode: 'checkbox'
|
|
133
|
+
};
|
|
134
|
+
el.session = {
|
|
135
|
+
value: []
|
|
136
|
+
};
|
|
137
|
+
el._onChange({
|
|
138
|
+
value: 'a',
|
|
139
|
+
selected: true
|
|
140
|
+
});
|
|
141
|
+
expect(el.dispatchEvent).toBeCalledWith(new _piePlayerEvents.SessionChangedEvent('mc-el', true));
|
|
142
|
+
});
|
|
143
|
+
it('dispatches session changed event - remove answer (checkbox)', () => {
|
|
144
|
+
const el = new _index.default();
|
|
145
|
+
el.tagName = 'mc-el';
|
|
146
|
+
el.model = {
|
|
147
|
+
choiceMode: 'checkbox'
|
|
148
|
+
};
|
|
149
|
+
el.session = {
|
|
150
|
+
value: ['a']
|
|
151
|
+
};
|
|
152
|
+
el._onChange({
|
|
153
|
+
value: 'a',
|
|
154
|
+
selected: false
|
|
155
|
+
});
|
|
156
|
+
expect(el.dispatchEvent).toBeCalledWith(new _piePlayerEvents.SessionChangedEvent('mc-el', false));
|
|
157
|
+
});
|
|
158
|
+
it('dispatches session changed event - add/remove answer (checkbox)', () => {
|
|
159
|
+
const el = new _index.default();
|
|
160
|
+
el.tagName = 'mc-el';
|
|
161
|
+
el.model = {
|
|
162
|
+
choiceMode: 'checkbox'
|
|
163
|
+
};
|
|
164
|
+
el.session = {
|
|
165
|
+
value: ['1']
|
|
166
|
+
};
|
|
167
|
+
el._onChange({
|
|
168
|
+
id: '2',
|
|
169
|
+
selected: true
|
|
170
|
+
});
|
|
171
|
+
expect(el.dispatchEvent).toBeCalledWith(new _piePlayerEvents.SessionChangedEvent('mc-el', true));
|
|
172
|
+
el._onChange({
|
|
173
|
+
id: '1',
|
|
174
|
+
selected: false
|
|
175
|
+
});
|
|
176
|
+
expect(el.dispatchEvent).toBeCalledWith(new _piePlayerEvents.SessionChangedEvent('mc-el', true));
|
|
177
|
+
el._onChange({
|
|
178
|
+
id: '2',
|
|
179
|
+
selected: false
|
|
180
|
+
});
|
|
181
|
+
expect(el.dispatchEvent).toBeCalledWith(new _piePlayerEvents.SessionChangedEvent('mc-el', false));
|
|
182
|
+
});
|
|
183
|
+
it('dispatches session changed event - add/change answer (radio)', () => {
|
|
184
|
+
const el = new _index.default();
|
|
185
|
+
el.tagName = 'mc-el';
|
|
186
|
+
el.model = {
|
|
187
|
+
choiceMode: 'radio'
|
|
188
|
+
};
|
|
189
|
+
el.session = {
|
|
190
|
+
value: []
|
|
191
|
+
};
|
|
192
|
+
el._onChange({
|
|
193
|
+
value: 'a',
|
|
194
|
+
selected: true
|
|
195
|
+
});
|
|
196
|
+
expect(el.dispatchEvent).toBeCalledWith(new _piePlayerEvents.SessionChangedEvent('mc-el', true));
|
|
197
|
+
el._onChange({
|
|
198
|
+
value: 'b',
|
|
199
|
+
selected: true
|
|
200
|
+
});
|
|
201
|
+
expect(el.dispatchEvent).toBeCalledWith(new _piePlayerEvents.SessionChangedEvent('mc-el', true));
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
});
|
|
205
|
+
});
|
|
206
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwicmVxdWlyZSIsIl9yZWFjdDIiLCJfcGllUGxheWVyRXZlbnRzIiwiX21haW4iLCJfaW5kZXgiLCJfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCIsImUiLCJ0IiwiV2Vha01hcCIsInIiLCJuIiwiX19lc01vZHVsZSIsIm8iLCJpIiwiZiIsIl9fcHJvdG9fXyIsImRlZmF1bHQiLCJoYXMiLCJnZXQiLCJzZXQiLCJoYXNPd25Qcm9wZXJ0eSIsImNhbGwiLCJPYmplY3QiLCJkZWZpbmVQcm9wZXJ0eSIsImdldE93blByb3BlcnR5RGVzY3JpcHRvciIsImplc3QiLCJ1c2VGYWtlVGltZXJzIiwibW9jayIsInJlbmRlck1hdGgiLCJmbiIsImxvZGFzaCIsImRlYm91bmNlIiwiUHJldmlld0xheW91dCIsImNoaWxkcmVuIiwiY3JlYXRlRWxlbWVudCIsIkNvbGxhcHNpYmxlIiwibGFiZWxzIiwiaGlkZGVuIiwiUHJldmlld1Byb21wdCIsInByb21wdCIsImNvbG9yIiwidGV4dCIsImJhY2tncm91bmQiLCJwcmltYXJ5IiwiY29ycmVjdCIsImluY29ycmVjdCIsImRpc2FibGVkIiwiZGVzY3JpYmUiLCJpdCIsImVhY2giLCJ2YWx1ZSIsInVuZGVmaW5lZCIsInNlc3Npb24iLCJleHBlY3RlZCIsImV4cGVjdCIsImlzQ29tcGxldGUiLCJ0b0VxdWFsIiwicmVuZGVyQ29tcG9uZW50IiwibW9kZWxPdmVycmlkZXMiLCJkZWZhdWx0UHJvcHMiLCJtb2RlbCIsImNob2ljZXMiLCJjbGFzc2VzIiwicmVuZGVyIiwiY29udGFpbmVyIiwidG9CZUluVGhlRG9jdW1lbnQiLCJzY3JlZW4iLCJnZXRCeVRlc3RJZCIsInJhdGlvbmFsZSIsImdldEJ5VGV4dCIsInRlYWNoZXJJbnN0cnVjdGlvbnMiLCJsYWJlbCIsImVsIiwiTXVsdGlwbGVDaG9pY2UiLCJ0YWdOYW1lIiwiZGlzcGF0Y2hFdmVudCIsInRvQmVDYWxsZWRXaXRoIiwiTW9kZWxTZXRFdmVudCIsImNob2ljZU1vZGUiLCJfb25DaGFuZ2UiLCJzZWxlY3RlZCIsIlNlc3Npb25DaGFuZ2VkRXZlbnQiLCJpZCJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9fX3Rlc3RzX18vaW5kZXgtdGVzdC5qc3giXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCB7IHJlbmRlciwgc2NyZWVuIH0gZnJvbSAnQHRlc3RpbmctbGlicmFyeS9yZWFjdCc7XG5pbXBvcnQgeyBNb2RlbFNldEV2ZW50LCBTZXNzaW9uQ2hhbmdlZEV2ZW50IH0gZnJvbSAnQHBpZS1mcmFtZXdvcmsvcGllLXBsYXllci1ldmVudHMnO1xuaW1wb3J0IE11bHRpcGxlQ2hvaWNlQ29tcG9uZW50IGZyb20gJy4uL21haW4nO1xuaW1wb3J0IE11bHRpcGxlQ2hvaWNlIGZyb20gJy4uL2luZGV4JztcbmltcG9ydCB7IGlzQ29tcGxldGUgfSBmcm9tICcuLi9pbmRleCc7XG5cbmplc3QudXNlRmFrZVRpbWVycygpO1xuamVzdC5tb2NrKCdAcGllLWxpYi9tYXRoLXJlbmRlcmluZycsICgpID0+ICh7IHJlbmRlck1hdGg6IGplc3QuZm4oKSB9KSk7XG5qZXN0Lm1vY2soJ2xvZGFzaC1lcycsICgpID0+IHtcbiAgY29uc3QgbG9kYXNoID0gcmVxdWlyZSgnbG9kYXNoJyk7XG4gIHJldHVybiB7XG4gICAgLi4ubG9kYXNoLFxuICAgIGRlYm91bmNlOiBqZXN0LmZuKChmbikgPT4gZm4pLFxuICB9O1xufSk7XG5cbi8vIE1vY2sgdGhlIHJlbmRlci11aSBQcmV2aWV3TGF5b3V0XG5qZXN0Lm1vY2soJ0BwaWUtbGliL3JlbmRlci11aScsICgpID0+ICh7XG4gIFByZXZpZXdMYXlvdXQ6ICh7IGNoaWxkcmVuIH0pID0+IDxkaXYgZGF0YS10ZXN0aWQ9XCJwcmV2aWV3LWxheW91dFwiPntjaGlsZHJlbn08L2Rpdj4sXG4gIENvbGxhcHNpYmxlOiAoeyBjaGlsZHJlbiwgbGFiZWxzIH0pID0+IChcbiAgICA8ZGl2IGRhdGEtdGVzdGlkPVwiY29sbGFwc2libGVcIj5cbiAgICAgIDxidXR0b24+e2xhYmVscz8uaGlkZGVuIHx8ICdTaG93J308L2J1dHRvbj5cbiAgICAgIHtjaGlsZHJlbn1cbiAgICA8L2Rpdj5cbiAgKSxcbiAgUHJldmlld1Byb21wdDogKHsgcHJvbXB0IH0pID0+IDxkaXYgZGF0YS10ZXN0aWQ9XCJwcmV2aWV3LXByb21wdFwiPntwcm9tcHR9PC9kaXY+LFxuICBjb2xvcjoge1xuICAgIHRleHQ6ICgpID0+ICcjMDAwJyxcbiAgICBiYWNrZ3JvdW5kOiAoKSA9PiAnI2ZmZicsXG4gICAgcHJpbWFyeTogKCkgPT4gJyMxOTc2ZDInLFxuICAgIGNvcnJlY3Q6ICgpID0+ICcjNGNhZjUwJyxcbiAgICBpbmNvcnJlY3Q6ICgpID0+ICcjZjQ0MzM2JyxcbiAgICBkaXNhYmxlZDogKCkgPT4gJyM5ZTllOWUnLFxuICB9LFxufSkpO1xuXG5kZXNjcmliZSgnaXNDb21wbGV0ZScsICgpID0+IHtcbiAgaXQuZWFjaGBcbiAgICBzZXNzaW9uICAgICAgICAgICAgICAgICB8IGV4cGVjdGVkXG4gICAgJHt7IHZhbHVlOiBbMSwgMiwgM10gfX0gfCAke3RydWV9XG4gICAgJHt7IHZhbHVlOiBbXSB9fSAgICAgICAgfCAke2ZhbHNlfVxuICAgICR7e319ICAgICAgICAgICAgICAgICAgIHwgJHtmYWxzZX1cbiAgICAke251bGx9ICAgICAgICAgICAgICAgICB8ICR7ZmFsc2V9XG4gICAgJHt1bmRlZmluZWR9ICAgICAgICAgICAgfCAke2ZhbHNlfVxuICBgKCdzZXNzaW9uID0gJHNlc3Npb24gaXMgY29tcGxldGUgPT4gJGV4cGVjdGVkJywgKHsgc2Vzc2lvbiwgZXhwZWN0ZWQgfSkgPT4ge1xuICAgIGV4cGVjdChpc0NvbXBsZXRlKHNlc3Npb24pKS50b0VxdWFsKGV4cGVjdGVkKTtcbiAgfSk7XG59KTtcblxuZGVzY3JpYmUoJ211bHRpcGxlLWNob2ljZScsICgpID0+IHtcbiAgZGVzY3JpYmUoJ3JlbmRlcmluZycsICgpID0+IHtcbiAgICBjb25zdCByZW5kZXJDb21wb25lbnQgPSAobW9kZWxPdmVycmlkZXMgPSB7fSkgPT4ge1xuICAgICAgY29uc3QgZGVmYXVsdFByb3BzID0ge1xuICAgICAgICBtb2RlbDoge1xuICAgICAgICAgIGNob2ljZXM6IFtdLFxuICAgICAgICAgIHByb21wdDogJ1NlbGVjdCBhbiBhbnN3ZXInLFxuICAgICAgICAgIC4uLm1vZGVsT3ZlcnJpZGVzLFxuICAgICAgICB9LFxuICAgICAgICBzZXNzaW9uOiB7fSxcbiAgICAgICAgY2xhc3Nlczoge30sXG4gICAgICB9O1xuXG4gICAgICByZXR1cm4gcmVuZGVyKDxNdWx0aXBsZUNob2ljZUNvbXBvbmVudCB7Li4uZGVmYXVsdFByb3BzfSAvPik7XG4gICAgfTtcblxuICAgIGl0KCdyZW5kZXJzIHdpdGhvdXQgY3Jhc2hpbmcnLCAoKSA9PiB7XG4gICAgICBjb25zdCB7IGNvbnRhaW5lciB9ID0gcmVuZGVyQ29tcG9uZW50KCk7XG4gICAgICBleHBlY3QoY29udGFpbmVyKS50b0JlSW5UaGVEb2N1bWVudCgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3JlbmRlcnMgdGhlIHByZXZpZXcgbGF5b3V0IHdyYXBwZXInLCAoKSA9PiB7XG4gICAgICByZW5kZXJDb21wb25lbnQoKTtcbiAgICAgIGV4cGVjdChzY3JlZW4uZ2V0QnlUZXN0SWQoJ3ByZXZpZXctbGF5b3V0JykpLnRvQmVJblRoZURvY3VtZW50KCk7XG4gICAgfSk7XG5cbiAgICBpdCgncmVuZGVycyB3aXRoIHJhdGlvbmFsZScsICgpID0+IHtcbiAgICAgIHJlbmRlckNvbXBvbmVudCh7IHJhdGlvbmFsZTogJ1RoaXMgaXMgcmF0aW9uYWxlJyB9KTtcbiAgICAgIGV4cGVjdChzY3JlZW4uZ2V0QnlUZXh0KCdUaGlzIGlzIHJhdGlvbmFsZScpKS50b0JlSW5UaGVEb2N1bWVudCgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3JlbmRlcnMgd2l0aCB0ZWFjaGVySW5zdHJ1Y3Rpb25zJywgKCkgPT4ge1xuICAgICAgcmVuZGVyQ29tcG9uZW50KHsgdGVhY2hlckluc3RydWN0aW9uczogJ1RoZXNlIGFyZSB0ZWFjaGVyIGluc3RydWN0aW9ucycgfSk7XG4gICAgICBleHBlY3Qoc2NyZWVuLmdldEJ5VGV4dCgnVGhlc2UgYXJlIHRlYWNoZXIgaW5zdHJ1Y3Rpb25zJykpLnRvQmVJblRoZURvY3VtZW50KCk7XG4gICAgfSk7XG5cbiAgICBpdCgncmVuZGVycyBjaG9pY2VzIHdoZW4gcHJvdmlkZWQnLCAoKSA9PiB7XG4gICAgICByZW5kZXJDb21wb25lbnQoe1xuICAgICAgICBjaG9pY2VzOiBbXG4gICAgICAgICAgeyB2YWx1ZTogJ2EnLCBsYWJlbDogJ09wdGlvbiBBJyB9LFxuICAgICAgICAgIHsgdmFsdWU6ICdiJywgbGFiZWw6ICdPcHRpb24gQicgfSxcbiAgICAgICAgXSxcbiAgICAgIH0pO1xuICAgICAgZXhwZWN0KHNjcmVlbi5nZXRCeVRleHQoJ09wdGlvbiBBJykpLnRvQmVJblRoZURvY3VtZW50KCk7XG4gICAgICBleHBlY3Qoc2NyZWVuLmdldEJ5VGV4dCgnT3B0aW9uIEInKSkudG9CZUluVGhlRG9jdW1lbnQoKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2V2ZW50cycsICgpID0+IHtcbiAgICBkZXNjcmliZSgnbW9kZWwnLCAoKSA9PiB7XG4gICAgICBpdCgnZGlzcGF0Y2hlcyBtb2RlbCBzZXQgZXZlbnQnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGVsID0gbmV3IE11bHRpcGxlQ2hvaWNlKCk7XG4gICAgICAgIGVsLnRhZ05hbWUgPSAnbWMtZWwnO1xuICAgICAgICBlbC5tb2RlbCA9IHt9O1xuICAgICAgICBleHBlY3QoZWwuZGlzcGF0Y2hFdmVudCkudG9CZUNhbGxlZFdpdGgobmV3IE1vZGVsU2V0RXZlbnQoJ21jLWVsJywgZmFsc2UsIHRydWUpKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ29uQ2hhbmdlJywgKCkgPT4ge1xuICAgICAgaXQoJ2Rpc3BhdGNoZXMgc2Vzc2lvbiBjaGFuZ2VkIGV2ZW50IC0gYWRkIGFuc3dlciAoY2hlY2tib3gpJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBlbCA9IG5ldyBNdWx0aXBsZUNob2ljZSgpO1xuICAgICAgICBlbC50YWdOYW1lID0gJ21jLWVsJztcbiAgICAgICAgZWwubW9kZWwgPSB7IGNob2ljZU1vZGU6ICdjaGVja2JveCcgfTtcbiAgICAgICAgZWwuc2Vzc2lvbiA9IHsgdmFsdWU6IFtdIH07XG4gICAgICAgIGVsLl9vbkNoYW5nZSh7IHZhbHVlOiAnYScsIHNlbGVjdGVkOiB0cnVlIH0pO1xuICAgICAgICBleHBlY3QoZWwuZGlzcGF0Y2hFdmVudCkudG9CZUNhbGxlZFdpdGgobmV3IFNlc3Npb25DaGFuZ2VkRXZlbnQoJ21jLWVsJywgdHJ1ZSkpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdkaXNwYXRjaGVzIHNlc3Npb24gY2hhbmdlZCBldmVudCAtIHJlbW92ZSBhbnN3ZXIgKGNoZWNrYm94KScsICgpID0+IHtcbiAgICAgICAgY29uc3QgZWwgPSBuZXcgTXVsdGlwbGVDaG9pY2UoKTtcbiAgICAgICAgZWwudGFnTmFtZSA9ICdtYy1lbCc7XG4gICAgICAgIGVsLm1vZGVsID0geyBjaG9pY2VNb2RlOiAnY2hlY2tib3gnIH07XG4gICAgICAgIGVsLnNlc3Npb24gPSB7IHZhbHVlOiBbJ2EnXSB9O1xuICAgICAgICBlbC5fb25DaGFuZ2UoeyB2YWx1ZTogJ2EnLCBzZWxlY3RlZDogZmFsc2UgfSk7XG4gICAgICAgIGV4cGVjdChlbC5kaXNwYXRjaEV2ZW50KS50b0JlQ2FsbGVkV2l0aChuZXcgU2Vzc2lvbkNoYW5nZWRFdmVudCgnbWMtZWwnLCBmYWxzZSkpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdkaXNwYXRjaGVzIHNlc3Npb24gY2hhbmdlZCBldmVudCAtIGFkZC9yZW1vdmUgYW5zd2VyIChjaGVja2JveCknLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGVsID0gbmV3IE11bHRpcGxlQ2hvaWNlKCk7XG4gICAgICAgIGVsLnRhZ05hbWUgPSAnbWMtZWwnO1xuICAgICAgICBlbC5tb2RlbCA9IHsgY2hvaWNlTW9kZTogJ2NoZWNrYm94JyB9O1xuICAgICAgICBlbC5zZXNzaW9uID0geyB2YWx1ZTogWycxJ10gfTtcbiAgICAgICAgZWwuX29uQ2hhbmdlKHsgaWQ6ICcyJywgc2VsZWN0ZWQ6IHRydWUgfSk7XG4gICAgICAgIGV4cGVjdChlbC5kaXNwYXRjaEV2ZW50KS50b0JlQ2FsbGVkV2l0aChuZXcgU2Vzc2lvbkNoYW5nZWRFdmVudCgnbWMtZWwnLCB0cnVlKSk7XG5cbiAgICAgICAgZWwuX29uQ2hhbmdlKHsgaWQ6ICcxJywgc2VsZWN0ZWQ6IGZhbHNlIH0pO1xuICAgICAgICBleHBlY3QoZWwuZGlzcGF0Y2hFdmVudCkudG9CZUNhbGxlZFdpdGgobmV3IFNlc3Npb25DaGFuZ2VkRXZlbnQoJ21jLWVsJywgdHJ1ZSkpO1xuXG4gICAgICAgIGVsLl9vbkNoYW5nZSh7IGlkOiAnMicsIHNlbGVjdGVkOiBmYWxzZSB9KTtcbiAgICAgICAgZXhwZWN0KGVsLmRpc3BhdGNoRXZlbnQpLnRvQmVDYWxsZWRXaXRoKG5ldyBTZXNzaW9uQ2hhbmdlZEV2ZW50KCdtYy1lbCcsIGZhbHNlKSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ2Rpc3BhdGNoZXMgc2Vzc2lvbiBjaGFuZ2VkIGV2ZW50IC0gYWRkL2NoYW5nZSBhbnN3ZXIgKHJhZGlvKScsICgpID0+IHtcbiAgICAgICAgY29uc3QgZWwgPSBuZXcgTXVsdGlwbGVDaG9pY2UoKTtcbiAgICAgICAgZWwudGFnTmFtZSA9ICdtYy1lbCc7XG4gICAgICAgIGVsLm1vZGVsID0geyBjaG9pY2VNb2RlOiAncmFkaW8nIH07XG4gICAgICAgIGVsLnNlc3Npb24gPSB7IHZhbHVlOiBbXSB9O1xuICAgICAgICBlbC5fb25DaGFuZ2UoeyB2YWx1ZTogJ2EnLCBzZWxlY3RlZDogdHJ1ZSB9KTtcbiAgICAgICAgZXhwZWN0KGVsLmRpc3BhdGNoRXZlbnQpLnRvQmVDYWxsZWRXaXRoKG5ldyBTZXNzaW9uQ2hhbmdlZEV2ZW50KCdtYy1lbCcsIHRydWUpKTtcbiAgICAgICAgZWwuX29uQ2hhbmdlKHsgdmFsdWU6ICdiJywgc2VsZWN0ZWQ6IHRydWUgfSk7XG4gICAgICAgIGV4cGVjdChlbC5kaXNwYXRjaEV2ZW50KS50b0JlQ2FsbGVkV2l0aChuZXcgU2Vzc2lvbkNoYW5nZWRFdmVudCgnbWMtZWwnLCB0cnVlKSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsSUFBQUEsTUFBQSxHQUFBQyxzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQUMsT0FBQSxHQUFBRCxPQUFBO0FBQ0EsSUFBQUUsZ0JBQUEsR0FBQUYsT0FBQTtBQUNBLElBQUFHLEtBQUEsR0FBQUosc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFJLE1BQUEsR0FBQUMsdUJBQUEsQ0FBQUwsT0FBQTtBQUFzQyxTQUFBSyx3QkFBQUMsQ0FBQSxFQUFBQyxDQUFBLDZCQUFBQyxPQUFBLE1BQUFDLENBQUEsT0FBQUQsT0FBQSxJQUFBRSxDQUFBLE9BQUFGLE9BQUEsWUFBQUgsdUJBQUEsWUFBQUEsQ0FBQUMsQ0FBQSxFQUFBQyxDQUFBLFNBQUFBLENBQUEsSUFBQUQsQ0FBQSxJQUFBQSxDQUFBLENBQUFLLFVBQUEsU0FBQUwsQ0FBQSxNQUFBTSxDQUFBLEVBQUFDLENBQUEsRUFBQUMsQ0FBQSxLQUFBQyxTQUFBLFFBQUFDLE9BQUEsRUFBQVYsQ0FBQSxpQkFBQUEsQ0FBQSx1QkFBQUEsQ0FBQSx5QkFBQUEsQ0FBQSxTQUFBUSxDQUFBLE1BQUFGLENBQUEsR0FBQUwsQ0FBQSxHQUFBRyxDQUFBLEdBQUFELENBQUEsUUFBQUcsQ0FBQSxDQUFBSyxHQUFBLENBQUFYLENBQUEsVUFBQU0sQ0FBQSxDQUFBTSxHQUFBLENBQUFaLENBQUEsR0FBQU0sQ0FBQSxDQUFBTyxHQUFBLENBQUFiLENBQUEsRUFB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
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
var _multipleChoice = _interopRequireDefault(require("../multiple-choice"));
|
|
5
|
+
describe('MultipleChoice', () => {
|
|
6
|
+
let instance;
|
|
7
|
+
beforeEach(() => {
|
|
8
|
+
instance = new _multipleChoice.default();
|
|
9
|
+
instance._model = {
|
|
10
|
+
choices: [{
|
|
11
|
+
value: '1'
|
|
12
|
+
}, {
|
|
13
|
+
value: '2'
|
|
14
|
+
}, {
|
|
15
|
+
value: '3'
|
|
16
|
+
}],
|
|
17
|
+
choiceMode: 'checkbox'
|
|
18
|
+
};
|
|
19
|
+
instance._session = {
|
|
20
|
+
value: []
|
|
21
|
+
};
|
|
22
|
+
instance._onChange = jest.fn();
|
|
23
|
+
});
|
|
24
|
+
describe('handleKeyDown', () => {
|
|
25
|
+
const simulateKeyDown = key => {
|
|
26
|
+
const event = new KeyboardEvent('keydown', {
|
|
27
|
+
key
|
|
28
|
+
});
|
|
29
|
+
instance.handleKeyDown(event);
|
|
30
|
+
};
|
|
31
|
+
it('selects a choice on valid numeric key (checkbox)', () => {
|
|
32
|
+
simulateKeyDown('1');
|
|
33
|
+
expect(instance._onChange).toHaveBeenCalledWith({
|
|
34
|
+
value: '1',
|
|
35
|
+
selected: true
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
it('toggles a choice on valid numeric key (checkbox)', () => {
|
|
39
|
+
instance._session.value = ['1'];
|
|
40
|
+
simulateKeyDown('1');
|
|
41
|
+
expect(instance._onChange).toHaveBeenCalledWith({
|
|
42
|
+
value: '1',
|
|
43
|
+
selected: false
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
it('selects a choice on valid alphabetic key (checkbox)', () => {
|
|
47
|
+
simulateKeyDown('a');
|
|
48
|
+
expect(instance._onChange).toHaveBeenCalledWith({
|
|
49
|
+
value: '1',
|
|
50
|
+
selected: true
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
it('does nothing on invalid key', () => {
|
|
54
|
+
simulateKeyDown('z');
|
|
55
|
+
expect(instance._onChange).not.toHaveBeenCalled();
|
|
56
|
+
});
|
|
57
|
+
it('selects a choice in radio mode', () => {
|
|
58
|
+
instance._model.choiceMode = 'radio';
|
|
59
|
+
simulateKeyDown('2');
|
|
60
|
+
expect(instance._onChange).toHaveBeenCalledWith({
|
|
61
|
+
value: '2',
|
|
62
|
+
selected: true
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
it('replaces the selected choice in radio mode', () => {
|
|
66
|
+
instance._model.choiceMode = 'radio';
|
|
67
|
+
instance._session.value = ['1'];
|
|
68
|
+
simulateKeyDown('3');
|
|
69
|
+
expect(instance._onChange).toHaveBeenCalledWith({
|
|
70
|
+
value: '3',
|
|
71
|
+
selected: true
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
it('does not toggle the same choice in radio mode', () => {
|
|
75
|
+
instance._model.choiceMode = 'radio';
|
|
76
|
+
instance._session.value = ['1'];
|
|
77
|
+
simulateKeyDown('1');
|
|
78
|
+
expect(instance._onChange).toHaveBeenCalledWith({
|
|
79
|
+
value: '1',
|
|
80
|
+
selected: true
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
it('does nothing if model is missing', () => {
|
|
84
|
+
instance._model = null;
|
|
85
|
+
simulateKeyDown('1');
|
|
86
|
+
expect(instance._onChange).not.toHaveBeenCalled();
|
|
87
|
+
});
|
|
88
|
+
it('does nothing if session is missing', () => {
|
|
89
|
+
instance._session = null;
|
|
90
|
+
simulateKeyDown('1');
|
|
91
|
+
expect(instance._onChange).not.toHaveBeenCalled();
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfbXVsdGlwbGVDaG9pY2UiLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwicmVxdWlyZSIsImRlc2NyaWJlIiwiaW5zdGFuY2UiLCJiZWZvcmVFYWNoIiwiTXVsdGlwbGVDaG9pY2UiLCJfbW9kZWwiLCJjaG9pY2VzIiwidmFsdWUiLCJjaG9pY2VNb2RlIiwiX3Nlc3Npb24iLCJfb25DaGFuZ2UiLCJqZXN0IiwiZm4iLCJzaW11bGF0ZUtleURvd24iLCJrZXkiLCJldmVudCIsIktleWJvYXJkRXZlbnQiLCJoYW5kbGVLZXlEb3duIiwiaXQiLCJleHBlY3QiLCJ0b0hhdmVCZWVuQ2FsbGVkV2l0aCIsInNlbGVjdGVkIiwibm90IiwidG9IYXZlQmVlbkNhbGxlZCJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9fX3Rlc3RzX18va2V5LWV2ZW50cy10ZXN0LmpzeCJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgTXVsdGlwbGVDaG9pY2UgZnJvbSAnLi4vbXVsdGlwbGUtY2hvaWNlJztcblxuZGVzY3JpYmUoJ011bHRpcGxlQ2hvaWNlJywgKCkgPT4ge1xuICBsZXQgaW5zdGFuY2U7XG5cbiAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgaW5zdGFuY2UgPSBuZXcgTXVsdGlwbGVDaG9pY2UoKTtcbiAgICBpbnN0YW5jZS5fbW9kZWwgPSB7XG4gICAgICBjaG9pY2VzOiBbXG4gICAgICAgIHsgdmFsdWU6ICcxJyB9LFxuICAgICAgICB7IHZhbHVlOiAnMicgfSxcbiAgICAgICAgeyB2YWx1ZTogJzMnIH0sXG4gICAgICBdLFxuICAgICAgY2hvaWNlTW9kZTogJ2NoZWNrYm94JyxcbiAgICB9O1xuICAgIGluc3RhbmNlLl9zZXNzaW9uID0geyB2YWx1ZTogW10gfTtcbiAgICBpbnN0YW5jZS5fb25DaGFuZ2UgPSBqZXN0LmZuKCk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdoYW5kbGVLZXlEb3duJywgKCkgPT4ge1xuICAgIGNvbnN0IHNpbXVsYXRlS2V5RG93biA9IChrZXkpID0+IHtcbiAgICAgIGNvbnN0IGV2ZW50ID0gbmV3IEtleWJvYXJkRXZlbnQoJ2tleWRvd24nLCB7IGtleSB9KTtcbiAgICAgIGluc3RhbmNlLmhhbmRsZUtleURvd24oZXZlbnQpO1xuICAgIH07XG5cbiAgICBpdCgnc2VsZWN0cyBhIGNob2ljZSBvbiB2YWxpZCBudW1lcmljIGtleSAoY2hlY2tib3gpJywgKCkgPT4ge1xuICAgICAgc2ltdWxhdGVLZXlEb3duKCcxJyk7XG4gICAgICBleHBlY3QoaW5zdGFuY2UuX29uQ2hhbmdlKS50b0hhdmVCZWVuQ2FsbGVkV2l0aCh7XG4gICAgICAgIHZhbHVlOiAnMScsXG4gICAgICAgIHNlbGVjdGVkOiB0cnVlLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgndG9nZ2xlcyBhIGNob2ljZSBvbiB2YWxpZCBudW1lcmljIGtleSAoY2hlY2tib3gpJywgKCkgPT4ge1xuICAgICAgaW5zdGFuY2UuX3Nlc3Npb24udmFsdWUgPSBbJzEnXTtcbiAgICAgIHNpbXVsYXRlS2V5RG93bignMScpO1xuICAgICAgZXhwZWN0KGluc3RhbmNlLl9vbkNoYW5nZSkudG9IYXZlQmVlbkNhbGxlZFdpdGgoe1xuICAgICAgICB2YWx1ZTogJzEnLFxuICAgICAgICBzZWxlY3RlZDogZmFsc2UsXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzZWxlY3RzIGEgY2hvaWNlIG9uIHZhbGlkIGFscGhhYmV0aWMga2V5IChjaGVja2JveCknLCAoKSA9PiB7XG4gICAgICBzaW11bGF0ZUtleURvd24oJ2EnKTtcbiAgICAgIGV4cGVjdChpbnN0YW5jZS5fb25DaGFuZ2UpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKHtcbiAgICAgICAgdmFsdWU6ICcxJyxcbiAgICAgICAgc2VsZWN0ZWQ6IHRydWUsXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdkb2VzIG5vdGhpbmcgb24gaW52YWxpZCBrZXknLCAoKSA9PiB7XG4gICAgICBzaW11bGF0ZUtleURvd24oJ3onKTtcbiAgICAgIGV4cGVjdChpbnN0YW5jZS5fb25DaGFuZ2UpLm5vdC50b0hhdmVCZWVuQ2FsbGVkKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2VsZWN0cyBhIGNob2ljZSBpbiByYWRpbyBtb2RlJywgKCkgPT4ge1xuICAgICAgaW5zdGFuY2UuX21vZGVsLmNob2ljZU1vZGUgPSAncmFkaW8nO1xuICAgICAgc2ltdWxhdGVLZXlEb3duKCcyJyk7XG4gICAgICBleHBlY3QoaW5zdGFuY2UuX29uQ2hhbmdlKS50b0hhdmVCZWVuQ2FsbGVkV2l0aCh7XG4gICAgICAgIHZhbHVlOiAnMicsXG4gICAgICAgIHNlbGVjdGVkOiB0cnVlLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgncmVwbGFjZXMgdGhlIHNlbGVjdGVkIGNob2ljZSBpbiByYWRpbyBtb2RlJywgKCkgPT4ge1xuICAgICAgaW5zdGFuY2UuX21vZGVsLmNob2ljZU1vZGUgPSAncmFkaW8nO1xuICAgICAgaW5zdGFuY2UuX3Nlc3Npb24udmFsdWUgPSBbJzEnXTtcbiAgICAgIHNpbXVsYXRlS2V5RG93bignMycpO1xuICAgICAgZXhwZWN0KGluc3RhbmNlLl9vbkNoYW5nZSkudG9IYXZlQmVlbkNhbGxlZFdpdGgoe1xuICAgICAgICB2YWx1ZTogJzMnLFxuICAgICAgICBzZWxlY3RlZDogdHJ1ZSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ2RvZXMgbm90IHRvZ2dsZSB0aGUgc2FtZSBjaG9pY2UgaW4gcmFkaW8gbW9kZScsICgpID0+IHtcbiAgICAgIGluc3RhbmNlLl9tb2RlbC5jaG9pY2VNb2RlID0gJ3JhZGlvJztcbiAgICAgIGluc3RhbmNlLl9zZXNzaW9uLnZhbHVlID0gWycxJ107XG4gICAgICBzaW11bGF0ZUtleURvd24oJzEnKTtcbiAgICAgIGV4cGVjdChpbnN0YW5jZS5fb25DaGFuZ2UpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKHtcbiAgICAgICAgdmFsdWU6ICcxJyxcbiAgICAgICAgc2VsZWN0ZWQ6IHRydWUsXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdkb2VzIG5vdGhpbmcgaWYgbW9kZWwgaXMgbWlzc2luZycsICgpID0+IHtcbiAgICAgIGluc3RhbmNlLl9tb2RlbCA9IG51bGw7XG4gICAgICBzaW11bGF0ZUtleURvd24oJzEnKTtcbiAgICAgIGV4cGVjdChpbnN0YW5jZS5fb25DaGFuZ2UpLm5vdC50b0hhdmVCZWVuQ2FsbGVkKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnZG9lcyBub3RoaW5nIGlmIHNlc3Npb24gaXMgbWlzc2luZycsICgpID0+IHtcbiAgICAgIGluc3RhbmNlLl9zZXNzaW9uID0gbnVsbDtcbiAgICAgIHNpbXVsYXRlS2V5RG93bignMScpO1xuICAgICAgZXhwZWN0KGluc3RhbmNlLl9vbkNoYW5nZSkubm90LnRvSGF2ZUJlZW5DYWxsZWQoKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsSUFBQUEsZUFBQSxHQUFBQyxzQkFBQSxDQUFBQyxPQUFBO0FBRUFDLFFBQVEsQ0FBQyxnQkFBZ0IsRUFBRSxNQUFNO0VBQy9CLElBQUlDLFFBQVE7RUFFWkMsVUFBVSxDQUFDLE1BQU07SUFDZkQsUUFBUSxHQUFHLElBQUlFLHVCQUFjLENBQUMsQ0FBQztJQUMvQkYsUUFBUSxDQUFDRyxNQUFNLEdBQUc7TUFDaEJDLE9BQU8sRUFBRSxDQUNQO1FBQUVDLEtBQUssRUFBRTtNQUFJLENBQUMsRUFDZDtRQUFFQSxLQUFLLEVBQUU7TUFBSSxDQUFDLEVBQ2Q7UUFBRUEsS0FBSyxFQUFFO01BQUksQ0FBQyxDQUNmO01BQ0RDLFVBQVUsRUFBRTtJQUNkLENBQUM7SUFDRE4sUUFBUSxDQUFDTyxRQUFRLEdBQUc7TUFBRUYsS0FBSyxFQUFFO0lBQUcsQ0FBQztJQUNqQ0wsUUFBUSxDQUFDUSxTQUFTLEdBQUdDLElBQUksQ0FBQ0MsRUFBRSxDQUFDLENBQUM7RUFDaEMsQ0FBQyxDQUFDO0VBRUZYLFFBQVEsQ0FBQyxlQUFlLEVBQUUsTUFBTTtJQUM5QixN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
|