Skip to content

Commit

Permalink
Expose a way to get user input from ServerItemRenderer (#1910)
Browse files Browse the repository at this point in the history
## Summary:
This is a repeat of PR #1753 (which was reverted in #1905)

While this PR is essentially the same as the previous one, I added prop upgrading to the scoring logic and the empty widget logic (along with some tests).

---

I'm trying to tread lightly, maybe being overly cautious at the expense of keeping too much old code around. I tried to make everything we can get rid of after the move with `@deprecated`.

Basically this should expose everything we need to move the actual scoring process out of ServerItemRenderer and the React tree. We now have `getUserInput` on `ServerItemRenderer` and `scorePerseusItem` which is a non-React, pure function that returns a score.

Next step is to replace uses of `scoreInput` in Webapp with `scorePerseusItem`; then we can come back and delete a lot of this legacy code 🤞

Issue: [LEMS-2665](https://khanacademy.atlassian.net/browse/LEMS-2665)

## Test plan:
After the swap in Webapp, we should be able to complete an exercise with `scorePerseusItem` and everything else will work the same.

[LEMS-2665]: https://khanacademy.atlassian.net/browse/LEMS-2665?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ

Author: handeyeco

Reviewers: jeremywiebe, handeyeco

Required Reviewers:

Approved By: jeremywiebe

Checks: ✅ Publish npm snapshot (ubuntu-latest, 20.x), ✅ Lint, Typecheck, Format, and Test (ubuntu-latest, 20.x), ✅ Cypress (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), ✅ Publish Storybook to Chromatic (ubuntu-latest, 20.x), ✅ gerald, ✅ .github/dependabot.yml

Pull Request URL: #1910
  • Loading branch information
handeyeco authored Dec 3, 2024
1 parent a0ff87e commit 0a44d46
Show file tree
Hide file tree
Showing 20 changed files with 571 additions and 146 deletions.
6 changes: 6 additions & 0 deletions .changeset/honest-tables-impress.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@khanacademy/perseus": major
"@khanacademy/perseus-dev-ui": patch
---

Change ServerItemRenderer scoring APIs to externalize scoring
11 changes: 10 additions & 1 deletion dev/flipbook.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {useEffect, useMemo, useReducer, useRef, useState} from "react";

import {Renderer} from "../packages/perseus/src";
import {SvgImage} from "../packages/perseus/src/components";
import {scorePerseusItem} from "../packages/perseus/src/renderer-util";
import {mockStrings} from "../packages/perseus/src/strings";
import {isCorrect} from "../packages/perseus/src/util";
import {trueForAllMafsSupportedGraphTypes} from "../packages/perseus/src/widgets/interactive-graphs/mafs-supported-graph-types";
Expand Down Expand Up @@ -319,7 +320,15 @@ function GradableRenderer(props: QuestionRendererProps) {
leftContent={
<Button
onClick={() => {
setScore(rendererRef.current?.score());
if (rendererRef.current) {
const score = scorePerseusItem(
question,
rendererRef.current.getUserInputMap(),
mockStrings,
"en",
);
setScore(score);
}
clearScoreTimeout.set();
}}
>
Expand Down
12 changes: 4 additions & 8 deletions packages/perseus/src/components/__tests__/sorter.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,15 +76,13 @@ describe("sorter widget", () => {
const {renderer} = renderQuestion(question1, apiOptions);
const sorter = renderer.findWidgets("sorter 1")[0];

// Act
// Put the options in the correct order

["$0.005$ kilograms", "$15$ grams", "$55$ grams"].forEach((option) => {
act(() => sorter.moveOptionToIndex(option, 3));
});
// Act
renderer.guessAndScore();

// assert
// Assert
expect(renderer).toHaveBeenAnsweredCorrectly();
});
it("can be answered incorrectly", () => {
Expand All @@ -95,17 +93,15 @@ describe("sorter widget", () => {
const {renderer} = renderQuestion(question1, apiOptions);
const sorter = renderer.findWidgets("sorter 1")[0];

// Act
// Put the options in the reverse order
["$0.005$ kilograms", "$15$ grams", "$55$ grams"].forEach(
(option, index) => {
act(() => sorter.moveOptionToIndex(option, 0));
},
);

// Act
renderer.guessAndScore();

// assert
// Assert
expect(renderer).toHaveBeenAnsweredIncorrectly();
});
});
2 changes: 2 additions & 0 deletions packages/perseus/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export {default as ServerItemRenderer} from "./server-item-renderer";
export {default as HintsRenderer} from "./hints-renderer";
export {default as HintRenderer} from "./hint-renderer";
export {default as Renderer} from "./renderer";
export {scorePerseusItem} from "./renderer-util";

/**
* Widgets
Expand Down Expand Up @@ -224,6 +225,7 @@ export type {
PerseusWidgetsMap,
MultiItem,
} from "./perseus-types";
export type {UserInputMap} from "./validation.types";
export type {Coord} from "./interactive2/types";
export type {MarkerType} from "./widgets/label-image/types";

Expand Down
4 changes: 2 additions & 2 deletions packages/perseus/src/interactive2/objective_.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ const mapObject = function <K extends string, V, U>(
lambda: (arg1: V, arg2: K) => U,
): Record<K, U> {
const result: Record<string, any> = {};
_.each(_.keys(obj), function (key) {
Object.keys(obj).forEach((key) => {
// @ts-expect-error - TS2345 - Argument of type 'string' is not assignable to parameter of type 'K'.
result[key] = lambda(obj[key], key);
});
Expand All @@ -66,7 +66,7 @@ const mapObjectFromArray = function <K extends string, V>(
lambda: (arg1: K) => V,
): Record<K, V> {
const result: Record<string, any> = {};
_.each(arr, function (elem) {
arr.forEach((elem) => {
result[elem] = lambda(elem);
});
return result;
Expand Down
Loading

0 comments on commit 0a44d46

Please sign in to comment.