-
Notifications
You must be signed in to change notification settings - Fork 350
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
[Client Validation] Fixes after merging main #2122
[Client Validation] Fixes after merging main #2122
Conversation
npm Snapshot: PublishedGood news!! We've packaged up the latest commit from this PR (75bab8b) and published it to npm. You Example: yarn add @khanacademy/perseus@PR2122 If you are working in Khan Academy's webapp, you can run: ./dev/tools/bump_perseus_version.sh -t PR2122 |
Size Change: +120 B (+0.01%) Total Size: 1.47 MB
ℹ️ View Unchanged
|
@@ -144,7 +144,6 @@ export interface PerseusWidgetTypes { | |||
matcher: MatcherWidget; | |||
matrix: MatrixWidget; | |||
measurer: MeasurerWidget; | |||
"mock-widget": MockWidget; |
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.
Removing here as we don't want the MockWidget to be part of the public set of widget types. It is an internal, test-only widget.
@@ -346,8 +345,6 @@ export type MatrixWidget = WidgetOptions<'matrix', PerseusMatrixWidgetOptions>; | |||
// prettier-ignore | |||
export type MeasurerWidget = WidgetOptions<'measurer', PerseusMeasurerWidgetOptions>; | |||
// prettier-ignore | |||
export type MockWidget = WidgetOptions<'mock-widget', MockWidgetOptions>; |
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 moved all types related to the MockWidget into its directory so that we don't have test pieces intermingled/shipped with our production code.
| TableWidget | ||
| VideoWidget | ||
| DeprecatedStandinWidget; | ||
export type PerseusWidget = PerseusWidgetTypes[keyof PerseusWidgetTypes]; |
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.
Now that we have the PerseusWidgetTypes interface (which can be properly extended in test code and/or externally), we can derive this union from that (meaning we don't have to maintain two official set of widget types.
@@ -40,7 +41,7 @@ export const itemWithNumericInput: PerseusItem = { | |||
labelText: "What's the answer?", | |||
size: "normal", | |||
}, | |||
} as NumericInputWidget, | |||
} satisfies 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.
satisfies
The new satisfies operator lets us validate that the type of an expression matches some type, without changing the resulting type of that expression.
Compare to as
which does some type checking but is not as robust and can end up hiding test data that doesn't actually fully match the as
type.
declare module "@khanacademy/perseus-core" { | ||
export interface PerseusWidgetTypes { | ||
"mock-widget": MockWidget; | ||
} | ||
} |
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 is the magic sauce that extends the set of PerseusWidgetTypes
to include the mock widget. Anything that ends up importing this file will "see" the mock-widget
... meaning tests, but not production code!
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 don't really understand the code and after looking it up I still don't understand the code. I wonder if would be worth adding a link to something that explains the goal here.
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'll expand the comment. Honestly, I wasn't able to find a really clear description for the case we're using this for. The bottom line is that when this file is imported (should be from tests only), the PerseusWidgetTypes
type from @khanacademy/perseus-core
is extended to include the MockWidget
. Our other types that define the unions of widget options types, etc. are all based on PerseusWidgetTypes
. So once we extend PerseusWidgetTypes
with this mock widget type, all the other widget option unions know about the mock widget also. This means that our tests and test data understand that mock-widget 1
refers to a mock widget, but if you were to try it in webapp, it wouldn't know about mock widgets (rightfully).
… be seen only in tests)
@@ -380,43 +389,6 @@ export type VideoWidget = WidgetOptions<'video', PerseusVideoWidgetOptions>; | |||
//prettier-ignore | |||
export type DeprecatedStandinWidget = WidgetOptions<'deprecated-standin', object>; | |||
|
|||
export type PerseusWidget = |
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.
Moved up to Line 183.
@@ -6,18 +6,15 @@ import * as React from "react"; | |||
import {getPromptJSON as _getPromptJSON} from "../../widget-ai-utils/mock-widget/prompt-utils"; | |||
|
|||
import scoreMockWidget from "./score-mock-widget"; | |||
import validateMockWidget from "./validate-mock-widget"; |
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.
Not related to your PR, but I wonder if all this mock widget stuff should even be in /packages
when it could possibly live in /testing
.
declare module "@khanacademy/perseus-core" { | ||
export interface PerseusWidgetTypes { | ||
"mock-widget": MockWidget; | ||
} | ||
} |
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 don't really understand the code and after looking it up I still don't understand the code. I wonder if would be worth adding a link to something that explains the goal here.
import type mockWidget from "../../widgets/mock-widgets/mock-widget"; | ||
import type {PerseusMockWidgetUserInput} from "../../widgets/mock-widgets/mock-widget-types"; |
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.
Why do we need AI prompt utils for a mock widget?
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 think just to "round out" the implementation of the mock widget. I don't think we actually use it. Perhaps it'd be better if we deleted this to avoid confusion and have folks think it serves some purpose.
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.
Changed my mind. There's tests that exercise the Renderer
calling the widget's getPromptJSON()
using the mock widget. I'll leave it in place as that feels like a valid use of the mock widget. I'd also like to avoid doing this sort of refactoring in this PR as I'm trying to stick to just dealing with after effects from merging main
. :)
* | ||
* @see MockWidget for an example | ||
*/ | ||
export type PerseusWidget = PerseusWidgetTypes[keyof PerseusWidgetTypes]; |
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.
Nice
Summary:
I recently merged
main
and the introduction ofMockWidget
caused some tests to break. I've fixed them in this PR and adjusted the MockWidget to be simpler (ie. not use KhanAnswerTypes) as I don't think that's needed.I also fixed up some related types so that the MockWidget does not exist in our production Widget types, only in tests. The new
MockWidget
illustrates this "test-only" expansion of the widget types.Issue: LEMS-2561
Test plan:
yarn test
yarn typecheck