Skip to content
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

Enable parsePerseusItem to handle all published Perseus content #2082

Open
wants to merge 16 commits into
base: main
Choose a base branch
from

Conversation

benchristel
Copy link
Member

@benchristel benchristel commented Jan 8, 2025

This PR fixes the remaining cases where the parser couldn't handle some data in
our content corpus -- notably, in articles and international content. After this
PR is merged, we will be able to use the parser in Webapp!

Note that running the exhaustive test tool still produces some failures.
However, I suspect the failing content isn't published, because it either
doesn't render (crashes the page) or can't be scored (throws an exception when
you click the "check answer" button). We'll find out when we start logging
parser errors in production whether I'm right about this.

The remaining errors are:

(root).question.widgets["grapher N"].options.correct.coords -- expected array of length 2; got []
(root).question.widgets["matcher N"].options -- expected object; got undefined
(root).question.widgets["graded-group N"].options.widgets["numeric-input N"].options.answers[N].answerForms[N] -- expected "integer", "mixed", "improper", "proper", "decimal", "percent", "pi"; got "number"
(root).question.widgets["example-graphie-widget N"] -- expected a valid widget type; got "example-graphie-widget"
(root).question.widgets["image N"]["(widget key)"][1] -- expected a string representing a positive integer; got "0"
(root).question.widgets["explanation N"]["(widget key)"][1] -- expected a string representing a positive integer; got "0"

Issue: LEMS-2582

Test plan:

yarn test

@benchristel benchristel self-assigned this Jan 8, 2025
Copy link
Contributor

github-actions bot commented Jan 8, 2025

npm Snapshot: NOT Published

Oh noes!! We couldn't publish an npm snapshot for you because
there is a release in progress. Please wait for the release to
finish, then retry this workflow.

View the workflow run

];
// If `coords` is null, the graph will not be gradable. All answers
// will be scored as invalid.
coords: null | [vertex: Coord, secondPoint: Coord];
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no way to default coords sensibly if it's missing, since it represents the correct answer. The widget renders fine with null coords, but scoring threw an exception. I've fixed the exception by returning a score of "invalid" if correct.coords is null (see score-grapher.ts below).

Copy link
Contributor

github-actions bot commented Jan 8, 2025

Size Change: +80 B (+0.01%)

Total Size: 1.27 MB

Filename Size Change
packages/perseus/dist/es/index.js 419 kB +80 B (+0.02%)
ℹ️ View Unchanged
Filename Size
packages/kas/dist/es/index.js 39 kB
packages/keypad-context/dist/es/index.js 760 B
packages/kmath/dist/es/index.js 4.27 kB
packages/math-input/dist/es/index.js 78 kB
packages/math-input/dist/es/strings.js 1.79 kB
packages/perseus-core/dist/es/index.js 1.48 kB
packages/perseus-editor/dist/es/index.js 688 kB
packages/perseus-linter/dist/es/index.js 22.2 kB
packages/perseus/dist/es/strings.js 4.64 kB
packages/pure-markdown/dist/es/index.js 3.66 kB
packages/simple-markdown/dist/es/index.js 12.5 kB

compressed-size-action

[-5, 5],
[5, 5],
] as [[number, number], [number, number]],
),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I previously thought we could default coords here, but thought better of it. This default isn't appropriate if the graph's X and Y ranges aren't the defaults ([-10, 10]).

@@ -17,7 +17,14 @@ import type {Parser} from "../parser-types";
export const parseMeasurerWidget: Parser<MeasurerWidget> = parseWidget(
constant("measurer"),
object({
image: parsePerseusImageBackground,
// The default value for image comes from measurer.tsx.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding these comments in! I think they'll be really helpful going forward.

@@ -34,6 +34,29 @@ describe("parseWidgetsMap", () => {
expect(result).toEqual(anyFailure);
});

it("rejects a key with ID 0", () => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We usually refer to this value as the widget Id and not the "key". I think it's a useful differentiation because it avoids being conflated with a React component key.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are the parts of a widget ID called, then? If the widget ID is something like radio 1, what is the radio part called and what is the 1 part called?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I'm just going to call it the "widget number".

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

radio is the widget type (in some places its referred to as the widget name).

radio 1 is the widget id and I've been working hard to avoid folks thinking of them as being "made up" of a type and number, but rather that we push for them to be opaque identifiers.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, well, they're definitely not treated as opaque currently, because if the number is 0 the entire page crashes. I've tried to avoid referring directly to the number in the tests and variable names.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, we do parse these widget ids in places, but I feel it's a thing we should avoid and remove when we can. Interpreting IDs as informative structures has bit me many times in the past when needs cause us to change the ID in some way. We hit this during Goliath when we assumed that KAIDs were of a specific format (legacy IDs weren't of that format).

@benchristel benchristel force-pushed the benc/regression-tests-6 branch from da0ce42 to 1fe6e42 Compare January 8, 2025 22:18
@benchristel benchristel changed the base branch from benc/article-parsing-regression-tests to main January 8, 2025 22:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants