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
Allow mocha callbacks to use any subclass of Context #69255
base: master
Are you sure you want to change the base?
Conversation
When creating fixtures in Mocha, they get attached to Context, which includes an index signature for this purpose. However, those fixtures will have no type information. If a project wants to strongly type its fixtures, it needs to subclass Context. But then, without this patch, the compiler will reject the use of those subclasses in Mocha callbacks.
@joeyparrish Thank you for submitting this PR! This is a live comment which I will keep updated. 1 package in this PRCode ReviewsBecause you edited one package and updated the tests (👏), I can help you merge this PR once someone else signs off on it. You can test the changes of this PR in the Playground. Status
Once every item on this list is checked, I'll ask you for permission to merge and publish the changes. InactiveThis PR has been inactive for 43 days — it is still unreviewed! Diagnostic Information: What the bot saw about this PR{
"type": "info",
"now": "-",
"pr_number": 69255,
"author": "joeyparrish",
"headCommitOid": "11442cd7cd7fa572b1f0d16ea09a0d4742827356",
"mergeBaseOid": "2554f0f86fba017b07b4c5175e05fed6bafdd452",
"lastPushDate": "2024-04-02T19:56:23.000Z",
"lastActivityDate": "2024-05-06T17:24:36.000Z",
"maintainerBlessed": "Waiting for Code Reviews",
"hasMergeConflict": false,
"isFirstContribution": false,
"tooManyFiles": false,
"hugeChange": false,
"popularityLevel": "Critical",
"pkgInfo": [
{
"name": "mocha",
"kind": "edit",
"files": [
{
"path": "types/mocha/index.d.ts",
"kind": "definition"
},
{
"path": "types/mocha/mocha-tests.ts",
"kind": "test"
}
],
"owners": [
"kazimanzurrashid",
"otiai10",
"enlight",
"cspotcode",
"1999",
"strangedev",
"nicojs"
],
"addedOwners": [],
"deletedOwners": [],
"popularityLevel": "Critical"
}
],
"reviews": [],
"mainBotCommentID": 2032992096,
"ciResult": "pass"
} |
🔔 @kazimanzurrashid @otiai10 @enlight @cspotcode @1999 @strangedev @nicojs — please review this PR in the next few days. Be sure to explicitly select |
@joeyparrish The CI build failed! Please review the logs for more information. Once you've pushed the fixes, the build will automatically re-run. Thanks! Note: builds which are failing do not end up on the list of PRs for the DT maintainers to review. |
…tting in mocha tests
Everything is passing and I'm looking forward to your feedback! |
Re-ping @kazimanzurrashid, @otiai10, @enlight, @cspotcode, @1999, @strangedev, @nicojs: This PR has been out for over a week, yet I haven't seen any reviews. Could someone please give it some attention? Thanks! |
It has been more than two weeks and this PR still has no reviews. I'll bump it to the DT maintainer queue. Thank you for your patience, @joeyparrish. (Ping @kazimanzurrashid, @otiai10, @enlight, @cspotcode, @1999, @strangedev, @nicojs.) |
I know this is 100+ lines changed, but there are really only 2-3 things happening, one of them repeated many, many times. To aid review, I updated the PR description with a better explanation of the change. It details the things that changed, why these are necessary changes, and why the simpler changes I tried don't work. I hope this helps! |
@@ -389,6 +389,8 @@ declare namespace Mocha { | |||
* - _Only available when invoked via the mocha CLI._ | |||
*/ | |||
(fn: Func): void; | |||
// eslint-disable-next-line @definitelytyped/no-unnecessary-generics | |||
<T extends BaseContext>(fn: Func<T>): void; |
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.
Would <T extends BaseContext = Context>(fn: Func<T>): void;
allow you to remove the non-generic version?
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.
No, because then every time I invoke the function, I would have to call it with an explicit subtype, or the compiler would assume Context. This way, the compiler infers the type. It's ugly, I know.
class Context { | ||
private _runnable; | ||
|
||
class BaseContext { |
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.
Does this class actually exist at runtime? This will be exported so implies it can be new'd.
Also, the comment above is attached to the wrong declaration.
When creating fixtures in Mocha, they get attached to Context, which includes an index signature for this purpose. However, those fixtures will have no type information.
If a project wants to strongly type its fixtures, it needs to subclass Context. But then, without this patch, the compiler will reject the use of those subclasses in Mocha callbacks.
Update: a better explanation of the change, to aid review, since this touches 100+ lines.
Context
's index signature prevents strong typing for Mocha fixtures. To address this is a backward-compatible way,Context
was split intoBaseContext
, which contains all the strongly typed fields, andContext
, which extends it with the index signature. Projects that add custom Mocha fixtures and want them strongly-typed can now define those fixtures on an interface extendingBaseContext
.Callback functions
Func
andAsyncFunc
hadthis: Context
, but now are generics withthis: T
andT extends BaseContext = Context
.Leaving out the default
T = Context
breaks compilation, with errors likeGeneric type 'AsyncFunc' requires 1 type argument(s)
. But including it also leads to the assumption that we always pass the index-signature-bearingContext
instead of anyBaseContext
subclass.Changing the default to
T = BaseContext
breaks compatibility with projects that make use of the index-signature I want to avoid in my own project. So that is not an option.The solution is for each usage of
Func
andAsyncFunc
in Mocha's API, to add a generic overload of the method. If I pass a callback that uses strongly-typed fixtures inBaseContext
subclass, the compiler can infer the generic type and properly check my usage of those fixtures.For example, where we had this:
we add this:
Each instance of this fails the linter check
@definitelytyped/no-unnecessary-generics
withType parameter T is used only once
. The generic doesn't influence the return type, so this rule would steer us toward usingany
instead. But this is clearly necessary to use the strongly-typedthis
we need to pass. So each instance is preceded by// eslint-disable-next-line @definitelytyped/no-unnecessary-generics
.If I delete the default version of those methods and only provide a generic method, existing tests break because the compiler assumes the base class
BaseContext
by default, instead of the index-signature-bearingContext
. So the overload is necessary.Please fill in this template.
pnpm test <package to test>
.Select one of these and delete the others:
If changing an existing definition:
package.json
.