-
Notifications
You must be signed in to change notification settings - Fork 351
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[LEMS-2851] Answerless NumericInput #2249
[LEMS-2851] Answerless NumericInput #2249
Conversation
npm Snapshot: PublishedGood news!! We've packaged up the latest commit from this PR (d60dfba) and published it to npm. You Example: yarn add @khanacademy/perseus@PR2249 If you are working in Khan Academy's webapp, you can run: ./dev/tools/bump_perseus_version.sh -t PR2249 |
Size Change: +471 B (+0.03%) Total Size: 1.48 MB
ℹ️ View Unchanged
|
@@ -1205,6 +1205,7 @@ export type PerseusNumericInputWidgetOptions = { | |||
// Used by examples, maybe not used and should be removed in the future | |||
// see TODO in numeric-input | |||
answerForms?: ReadonlyArray<PerseusNumericInputAnswerForm>; | |||
fullAnswerForms?: ReadonlyArray<PerseusNumericInputAnswerForm>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm expecting that this will change (or something will need to change). Here's what I think happened:
- Originally NumericInput used
PerseusNumericInputWidgetOptions.answerForms
- Then NumericInput was updated to use
PerseusNumericInputAnswer.answerForms
andPerseusNumericInputWidgetOptions.answerForms
was deprecated (see: "maybe not used and should be removed in the future")
Now PerseusNumericInputWidgetOptions.answers
is being removed and I think we need something like PerseusNumericInputWidgetOptions.answerForms
again but PerseusNumericInputWidgetOptions.answerForms
might exist on old data so I called the new thing fullAnswerForms
pending more research.
}; | ||
} | ||
|
||
export const parseNumericInputWidget: Parser<NumericInputWidget> = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Upgrader in Ben's parser
|
||
export const currentVersion = {major: 1, minor: 0}; | ||
|
||
export const widgetOptionsUpgrades = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Upgrader using the widgetOptionsUpgrades
API (which will likely be replaced by Ben's parser)
return rendererProps; | ||
return { | ||
...rendererProps, | ||
answerForms: fullAnswerForms, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Like I said, we might not keep it named fullAnswerForms
so for now I'm just renaming it to answerForms
so I don't have to update the widget code which I'd be fine doing once we have an established name.
}); | ||
}); | ||
|
||
it("only uses answer forms from correct answers", () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This got moved to tests for deriveAnswerForms
@@ -42,8 +46,16 @@ export const generateExamples = ( | |||
// Generate a list of the unique answer forms. | |||
const uniqueForms = getUniqueAnswerForms(answerForms); | |||
|
|||
// Sort them by the order they appear in the `formExamples` list. | |||
const formExampleKeys = Object.keys(NumericExampleStrings); | |||
const sortedForms = uniqueForms.sort((a, b) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So originally we were sorting answerForms
when deriving the data, but:
- I think that's a UI concern, not a data concern
- I didn't want to have to move
NumericExampleStrings
intoperseus-core
So I moved the sorting logic and added a test.
* answer forms. This is useful for ensuring that we don't show duplicate examples | ||
* to the user. | ||
*/ | ||
const getUniqueAnswerForms = function ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These were moved to perseus-core
because I needed them for deriving answer forms.
expect(score).toHaveBeenAnsweredCorrectly(); | ||
}); | ||
|
||
it("is interactive with answerless widget options", async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's the important test. We:
- Render the widget with the stripped data
- Assert that UI that previously required
answers
still renders - Answer and score the widget
} | ||
// Otherwise, add it to the set and return true. | ||
foundForms.add(form.name); | ||
return true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it correct to not take simplify
into account when de-duplicating answer forms? E.g. if we have
const answerForms = [
{name: "proper", simplify: "required"},
{name: "proper", simplify: "optional"},
];
Only {name: "proper", simplify: "required"}
will be present in the output. Whether simplify
is "required"
or "optional"
in the output depends on the order in which the answers were originally listed, which is awkward, since I don't think the order is otherwise important.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I noticed there's a very similar function, unionAnswerForms
, in numeric-input.tsx
. I think yours is better (better-typed, easier to read, possibly faster) but the two functions should probably be combined if they represent the same concept.
// so that we can generate the examples for the widget. | ||
(options.answers || []) | ||
.filter((answer) => answer.status === "correct") | ||
.map((answer) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we used flatMap
here I don't think we'd need the call to flat()
in unionAnswerForms
. unionAnswerForms
would then be a trivial wrapper around getUniqueAnswerForms
, so it could be removed.
.map((answer) => { | |
.flatMap((answer) => { |
|
||
import {parseNumericInputWidget} from "./numeric-input-widget"; | ||
|
||
describe("parseExpressionWidget", () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copy pasta mistake
## Summary: Alternative to #2249 Instead of doing a widget upgrade (the old PR), just split `answers` more selectively so that the data we need for rendering pre-scoring is still available. Issue: LEMS-2851 ## Test plan: - Go to a NumericInput widget that is known to show the tooltip that starts with "Your answer should be..." - That tooltip should continue to be visible - NumericInput should be renderable, interactive, and answerable. Author: handeyeco Reviewers: benchristel, Myranae, handeyeco, jeremywiebe Required Reviewers: Approved By: benchristel Checks: ✅ Publish npm snapshot (ubuntu-latest, 20.x), ✅ Check builds for changes in size (ubuntu-latest, 20.x), ✅ Check for .changeset entries for all changed files (ubuntu-latest, 20.x), ✅ Cypress (ubuntu-latest, 20.x), ✅ Lint, Typecheck, Format, and Test (ubuntu-latest, 20.x), ✅ Publish Storybook to Chromatic (ubuntu-latest, 20.x) Pull Request URL: #2261
Summary:
🚨🚨🚨 Will likely be closed in favor of: #2261
NumericInput needed to be adjusted for answerless rendering because it was using
answers.answerforms
to generate a set of answer forms it could use when generating text for a tooltip that's displayed pre-scoring (see the ticket for more information).This PR adds
PerseusNumericInputWidgetOptions.fullAnswerForms
(PerseusNumericInputWidgetOptions.answerForms
was already taken although it's deprecated), a new NumericInput widget version, and upgrade functionality to derivefullAnswerForms
fromanswers.answerforms
. I am totally willing to renamefullAnswerForms
, it's just a placeholder as I work. In case you're confused:PerseusNumericInputWidgetOptions.answerForms
: deprecated but might still exist for old data (though I don't think it's used)PerseusNumericInputAnswer.answerForms
: current way we deriveanswerForms
dataPerseusNumericInputWidgetOptions.fullAnswerForms
: what I add in this PR so we can getanswerForms
without answersIf you're still confused, I'm happy to do a tour.
Issue: LEMS-2851
Test plan: