Conversation
There was a problem hiding this comment.
Claude Code Review
This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.
Tip: disable this comment in your organization's Code Review settings.
🗄️ Schema Change: No Changes ✅ |
npm Snapshot: PublishedGood news!! We've packaged up the latest commit from this PR (2c8ade5) and published it to npm. You Example: pnpm add @khanacademy/perseus@PR3468If you are working in Khan Academy's frontend, you can run the below command. ./dev/tools/bump_perseus_version.ts -t PR3468If you are working in Khan Academy's webapp, you can run the below command. ./dev/tools/bump_perseus_version.js -t PR3468 |
🛠️ Item Splitting: Changes Detected
|
|
Size Change: -34 B (-0.01%) Total Size: 497 kB 📦 View Changed
ℹ️ View Unchanged
|
jeremywiebe
left a comment
There was a problem hiding this comment.
Overall I like how the tests now feel more like .. tests!
| // @ts-expect-error - Type '{shape: "extra"}' is not assignable to type 'Figure' | ||
| parser satisfies Parser<Figure>; | ||
| } | ||
| expect(parsed).type.toBe<ParseResult<Figure>>(); |
There was a problem hiding this comment.
I notice that the migrations don't do any negative assertions... is that not needed with tstyche or would it be useful to also assert here something like:
expect(parsed).type.not.toBeAssignableTo<ParseResult<string>>();There was a problem hiding this comment.
.toBe() checks the exact shape of a type. In most cases, assignability can be assumed from this point.
There was a problem hiding this comment.
Yes, the negative assertions in the old tests were a hack to protect against any being silently inferred. The toBe() matcher fails if one, but not both, of the compared types is any.
| } | ||
| it("raises a type error if a variant does not contain the discriminant key", () => { | ||
| // @ts-expect-error Argument of type 'Parser<OptionalizeProperties<{}>>' is not assignable to parameter of type 'Parser<{ shape: Primitive; }>' | ||
| discriminatedUnionOn("shape").withBranch("circle", object({})); |
There was a problem hiding this comment.
This is partly because I haven't worked with these tests much, but it took me a minute to understand that the object({}) was missing a discriminator key. Am I correct in assuming there's no assertion helper that tstyche provides to make this clearer?
There was a problem hiding this comment.
Perhaps .not.toBeCallableWith()?
expect(discriminatedUnionOn("shape").withBranch).type.not.toBeCallableWith("circle", object({}));There was a problem hiding this comment.
Is there a way to assert on the error message when using not.toBeCallableWith()?
There was a problem hiding this comment.
Nope. That’s a good question! I was thinking on this and drafting an API, but it all looked complicated. The conclusion was that any negated assertion (also those for JavaScript frameworks) do not reveal the exact cause of the error. But we can use positive and negative assertion with only one element changed:
expect(add).toBeCallableWith(1, 2)
expect(add).not.toBeCallableWith(1, "2") // all clear why caused the errorOr use @ts-expect-error, as you did already. In a way the message is implementation detail. It might change between TS versions. But sometimes it is useless to see the error as well. TSTyche handles both cases.
| /** | ||
| * Summons a value of type T out of thin air! | ||
| * | ||
| * (Terms and conditions apply. Value will not actually be returned. |
| const alphabet = union(constant("a")) | ||
| .or(constant("a")) |
There was a problem hiding this comment.
nit: is this intentional/significant to use constant("a") twice?
There was a problem hiding this comment.
Nope, that's accidental. Although, it points out an interesting test case that I missed! Perhaps we should test that union(constant("a")).or(constant("a")).parser parses the same type as constant("a").
| coefficient: defaulted(boolean, () => false), | ||
| rightAlign: optional(boolean), | ||
| static: defaulted(boolean, () => false), | ||
| answerForms: optional( |
There was a problem hiding this comment.
Was this removed because it's no longer valid?
There was a problem hiding this comment.
Yes. When I migrated the typetests to TSTyche, I got an error that the parsed type wasn't the same as the data-schema type. This answerForms property, which isn't in data-schema, was the mismatch.
There was a problem hiding this comment.
I noticed some tests remove the use of these types. Are they still of use?
There was a problem hiding this comment.
They are not! Good catch.
jeremywiebe
left a comment
There was a problem hiding this comment.
Oops, hit the wrong option. Approved!
mrazauskas
left a comment
There was a problem hiding this comment.
Glad to see you choose TSTyche. I am its author.
Overall, the tests look very good. Please ping me if there are any questions in the future.
| } | ||
| it("raises a type error if a variant does not contain the discriminant key", () => { | ||
| // @ts-expect-error Argument of type 'Parser<OptionalizeProperties<{}>>' is not assignable to parameter of type 'Parser<{ shape: Primitive; }>' | ||
| discriminatedUnionOn("shape").withBranch("circle", object({})); |
There was a problem hiding this comment.
Perhaps .not.toBeCallableWith()?
expect(discriminatedUnionOn("shape").withBranch).type.not.toBeCallableWith("circle", object({}));| // @ts-expect-error - Type '{shape: "extra"}' is not assignable to type 'Figure' | ||
| parser satisfies Parser<Figure>; | ||
| } | ||
| expect(parsed).type.toBe<ParseResult<Figure>>(); |
There was a problem hiding this comment.
.toBe() checks the exact shape of a type. In most cases, assignability can be assumed from this point.
packages/perseus-core/src/parse-perseus-json/general-purpose-parsers/object-types.typetest.ts
Outdated
Show resolved
Hide resolved
497b1c5 to
cbd310d
Compare
so we can import {describe, it, expect} from 'tstyche'
Co-authored-by: Tom Mrazauskas <[email protected]>
cbd310d to
2c8ade5
Compare
Pursuant to ADR #923, we are adopting TSTyche for type testing in TypeScript code!
Issue: LEMS-3992
Test plan:
CI checks should pass.