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

Handle all legacy English content in the Perseus parser #2073

Merged
merged 38 commits into from
Jan 7, 2025

Conversation

benchristel
Copy link
Member

@benchristel benchristel commented Jan 6, 2025

This PR adds regression tests for English-language exercises that were
previously not accepted by the Perseus JSON parser. It also updates the parser
to accept those exercises and convert them to the latest format.

As of this commit, all English exercises can now be parsed!

Issue: LEMS-2582

Test plan:

yarn test

@benchristel benchristel self-assigned this Jan 6, 2025
@benchristel
Copy link
Member Author

Note to reviewers: this PR will be easiest to review one commit at a time.

@@ -1215,7 +1218,7 @@ export type PerseusNumberLineWidgetOptions = {
// The correct relative value. default: "eq". options: "eq", "lt", "gt", "le", "ge"
correctRel: string | null | undefined;
// This is the correct answer. The answer is validated (as right or wrong) by using only the end position of the point and the relation (=, <, >, ≤, ≥).
correctX: number;
correctX: number | null;
Copy link
Member Author

Choose a reason for hiding this comment

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

The measurer widget component handles null values.

Copy link
Collaborator

Choose a reason for hiding this comment

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

<rant target='nobody-in-particular'>
I understand the difference between undefined and null, but so often we use these two values in the same way. IMHO it's a paper cut I wish we could remove eventually.
</rant>

Copy link
Contributor

github-actions bot commented Jan 6, 2025

npm Snapshot: Published

Good news!! We've packaged up the latest commit from this PR (14f0079) and published it to npm. You
can install it using the tag PR2073.

Example:

yarn add @khanacademy/perseus@PR2073

If you are working in Khan Academy's webapp, you can run:

./dev/tools/bump_perseus_version.sh -t PR2073

Copy link
Contributor

github-actions bot commented Jan 6, 2025

Size Change: +175 B (+0.01%)

Total Size: 1.28 MB

Filename Size Change
packages/perseus/dist/es/index.js 419 kB +175 B (+0.04%)
ℹ️ 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 5.03 kB
packages/pure-markdown/dist/es/index.js 3.67 kB
packages/simple-markdown/dist/es/index.js 12.5 kB

compressed-size-action

Base automatically changed from benc/discriminated-union to main January 7, 2025 00:02
@benchristel benchristel force-pushed the benc/regression-tests-5 branch from 3c712cb to f6b707b Compare January 7, 2025 00:05
@@ -1131,6 +1131,7 @@ export type PerseusMeasurerWidgetOptions = {
rulerLength: number;
// Containing area [width, height]
box: [number, number];
// TODO(benchristel): static is not used. Remove it?
Copy link
Collaborator

Choose a reason for hiding this comment

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

I suspect we can. These types were originally generated by iterating over our en content and deriving TypeScript types from them. I suspect static shows up in these widget options due to bugs that existed for some amount of time in our editors but have since been fixed (or not).

@@ -57,7 +57,7 @@ export const parseNumericInputWidget: Parser<NumericInputWidget> = parseWidget(
),
labelText: optional(string),
size: string,
coefficient: boolean,
coefficient: defaulted(boolean, () => false),
Copy link
Collaborator

Choose a reason for hiding this comment

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

Going through these regression tests has started me thinking. The widget React components often provide default props which fill in these missing values (eg. coefficient is defaulted to false here).

Sorry, I have post-vacation brain, but have we discussed this before?

Copy link
Member Author

Choose a reason for hiding this comment

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

My thoughts on where to put defaults are described in the parse-perseus-json/README.md. I think we want them in both the parser and the component's default props, because those defaults serve different purposes.

@@ -1215,7 +1218,7 @@ export type PerseusNumberLineWidgetOptions = {
// The correct relative value. default: "eq". options: "eq", "lt", "gt", "le", "ge"
correctRel: string | null | undefined;
// This is the correct answer. The answer is validated (as right or wrong) by using only the end position of the point and the relation (=, &lt;, &gt;, ≤, ≥).
correctX: number;
correctX: number | null;
Copy link
Collaborator

Choose a reason for hiding this comment

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

<rant target='nobody-in-particular'>
I understand the difference between undefined and null, but so often we use these two values in the same way. IMHO it's a paper cut I wish we could remove eventually.
</rant>

@@ -333,7 +333,7 @@ export type RefTargetWidget = WidgetOptions<'passage-ref-target', PerseusPassage
// prettier-ignore
export type VideoWidget = WidgetOptions<'video', PerseusVideoWidgetOptions>;
//prettier-ignore
export type AutoCorrectWidget = WidgetOptions<'deprecated-standin', object>;
export type DeprecatedStandinWidget = WidgetOptions<'deprecated-standin', object>;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Thank-you!! 😁

@@ -199,7 +199,7 @@ const parseWidgetsMapEntry: (
}
};

const parseDeprecatedWidget: Parser<AutoCorrectWidget> = parseWidget(
Copy link
Collaborator

Choose a reason for hiding this comment

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

This line makes much more sense now. :)

Comment on lines 25 to +27
width: number,
height: number,
static: boolean,
static: defaulted(boolean, () => false),
Copy link
Collaborator

Choose a reason for hiding this comment

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

Fun fact: it seems like width and static are never used by the widget. 🤔

Comment on lines +121 to +123
const parser = versionedWidgetOptions(2, parseOptionsV2)
.withMigrationFrom(1, parseOptionsV1, migrateV1ToV2)
.withMigrationFrom(0, parseOptionsV0, migrateV0ToV1).parser;
Copy link
Collaborator

Choose a reason for hiding this comment

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

This reads more clearly. Thanks! I like that the major version is mentioned explicitly here.

Copy link
Member Author

Choose a reason for hiding this comment

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

Looks like I forgot to change the base branch... this change belongs to another PR. Sorry about that!

Comment on lines +61 to +62
private migrateToLatest: (m: MigratableWidgetOptions) => Latest,
private parseOtherVersions: Parser<Latest>,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Wait! What? Does this make these two constructor parameters into private class members and assign them automatically? I've never seen this but if that's what it does, that's pretty awesome. :til:

Copy link
Member Author

Choose a reason for hiding this comment

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

Yep! :)

@benchristel benchristel merged commit 4bf4960 into main Jan 7, 2025
8 checks passed
@benchristel benchristel deleted the benc/regression-tests-5 branch January 7, 2025 17:22
SonicScrewdriver added a commit that referenced this pull request Jan 8, 2025
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @khanacademy/[email protected]

### Patch Changes

- [#2064](#2064)
[`55b4615d3`](55b4615)
Thanks [@nishasy](https://github.com/nishasy)! - Remove the
locked-figures-aria flag


- [#2063](#2063)
[`85a5b5e44`](85a5b5e)
Thanks [@nishasy](https://github.com/nishasy)! - Remove the
interactive-graph-locked-features-labels flag


- [#2078](#2078)
[`781cc7df6`](781cc7d)
Thanks [@SonicScrewdriver](https://github.com/SonicScrewdriver)! -
Temporarily fixing pi-based strings for Numeric Input


- [#2065](#2065)
[`eefcf5c5c`](eefcf5c)
Thanks [@nishasy](https://github.com/nishasy)! - Remove the
locked-[figureName]-labels flags


- [#2068](#2068)
[`265a93104`](265a931)
Thanks [@benchristel](https://github.com/benchristel)! - Internal:
Redesign discriminated union type parser to have a simpler and more
intuitive interface.


- [#2073](#2073)
[`4bf4960d4`](4bf4960)
Thanks [@benchristel](https://github.com/benchristel)! - Internal:
improve Perseus JSON parsers so they can handle all English-language
exercises


- [#2080](#2080)
[`c9a28b34c`](c9a28b3)
Thanks [@mark-fitzgerald](https://github.com/mark-fitzgerald)! -
[Dropdown] Bugfix - Text in dropdown not in correct vertical position


- [#2073](#2073)
[`4bf4960d4`](4bf4960)
Thanks [@benchristel](https://github.com/benchristel)! - Internal:
improve the error messages produced by the versionedWidgetOptions parser

## @khanacademy/[email protected]

### Patch Changes

- [#2064](#2064)
[`55b4615d3`](55b4615)
Thanks [@nishasy](https://github.com/nishasy)! - Remove the
locked-figures-aria flag


- [#2063](#2063)
[`85a5b5e44`](85a5b5e)
Thanks [@nishasy](https://github.com/nishasy)! - Remove the
interactive-graph-locked-features-labels flag


- [#2065](#2065)
[`eefcf5c5c`](eefcf5c)
Thanks [@nishasy](https://github.com/nishasy)! - Remove the
locked-[figureName]-labels flags

- Updated dependencies
\[[`55b4615d3`](55b4615),
[`85a5b5e44`](85a5b5e),
[`781cc7df6`](781cc7d),
[`eefcf5c5c`](eefcf5c),
[`265a93104`](265a931),
[`4bf4960d4`](4bf4960),
[`c9a28b34c`](c9a28b3),
[`4bf4960d4`](4bf4960)]:
    -   @khanacademy/[email protected]
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