@khanacademy/perseus 11.5.0 → 11.6.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.
@@ -15,6 +15,7 @@ import type {
15
15
  PerseusNumericInputAnswer,
16
16
  PerseusNumericInputWidgetOptions,
17
17
  PerseusNumericInputAnswerForm,
18
+ MathFormat,
18
19
  } from "../perseus-types";
19
20
  import type {
20
21
  FocusPath,
@@ -25,7 +26,11 @@ import type {
25
26
 
26
27
  const ParseTex = TexWrangler.parseTex;
27
28
 
28
- const answerFormButtons = [
29
+ const answerFormButtons: ReadonlyArray<{
30
+ title: string;
31
+ value: MathFormat;
32
+ content: string;
33
+ }> = [
29
34
  {title: "Integers", value: "integer", content: "6"},
30
35
  {title: "Decimals", value: "decimal", content: "0.75"},
31
36
  {title: "Proper fractions", value: "proper", content: "\u2157"},
@@ -149,8 +154,8 @@ export class NumericInput extends React.Component<Props, State> {
149
154
  return answerStrings[0];
150
155
  }
151
156
 
152
- static validate(useInput: UserInput, rubric: Rubric): PerseusScore {
153
- const allAnswerForms = answerFormButtons
157
+ static validate(userInput: UserInput, rubric: Rubric): PerseusScore {
158
+ const defaultAnswerForms = answerFormButtons
154
159
  .map((e) => e["value"])
155
160
  // Don't default to validating the answer as a pi answer
156
161
  // if answerForm isn't set on the answer
@@ -159,6 +164,18 @@ export class NumericInput extends React.Component<Props, State> {
159
164
 
160
165
  const createValidator = (answer: PerseusNumericInputAnswer) => {
161
166
  const stringAnswer = `${answer.value}`;
167
+
168
+ // Always validate against the provided answer forms (pi, decimal, etc.)
169
+ const validatorForms = [...(answer.answerForms ?? [])];
170
+
171
+ // When an answer is set to strict, we validate using ONLY
172
+ // the provided answerForms. If strict is false, or if there
173
+ // were no provided answer forms, we will include all
174
+ // of the default answer forms in our validator.
175
+ if (!answer.strict || validatorForms.length === 0) {
176
+ validatorForms.push(...defaultAnswerForms);
177
+ }
178
+
162
179
  return KhanAnswerTypes.number.createValidatorFunctional(
163
180
  stringAnswer,
164
181
  {
@@ -169,19 +186,14 @@ export class NumericInput extends React.Component<Props, State> {
169
186
  : "optional",
170
187
  inexact: true, // TODO(merlob) backfill / delete
171
188
  maxError: answer.maxError,
172
- forms:
173
- answer.strict &&
174
- answer.answerForms &&
175
- answer.answerForms.length !== 0
176
- ? answer.answerForms
177
- : allAnswerForms,
189
+ forms: validatorForms,
178
190
  },
179
191
  );
180
192
  };
181
193
 
182
194
  // We may have received TeX; try to parse it before grading.
183
195
  // If `currentValue` is not TeX, this should be a no-op.
184
- const currentValue = ParseTex(useInput.currentValue);
196
+ const currentValue = ParseTex(userInput.currentValue);
185
197
  const correctAnswers = rubric.answers.filter(
186
198
  (answer) => answer.status === "correct",
187
199
  );