-
Notifications
You must be signed in to change notification settings - Fork 0
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
feat: super basic test suite support #4
base: main
Are you sure you want to change the base?
Conversation
|
||
describe("AssertionError", () => { | ||
it("is an Error", () => { | ||
expect<AssertionError>().type.toBeAssignableTo<Error>(); |
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!
Because I forgot `import.meta.dirname` is only in more recent versions of node. Also: - added DEVELOPMENT.md, with docs on how to use fnm for testing
TIL biome's `lint` may not fail, even if `format` would make changes. Odd, but okay.
Heads up ... you may want something like this in TSTyche's let reporterScript = path.resolve(scriptDir, "AsMochaReporter.js");
if (/^\w:/.test(reporterScript)) {
// Because Windows drive letters foul up ESM dynamic imports
// with ERR_UNSUPPORTED_ESM_URL_SCHEME errors.
reporterScript = pathToFileURL(reporterScript).toString();
} The one in if (optionValue.startsWith(".")) {
optionValue = pathToFileURL(Path.relative(".", Path.resolve(rootPath, optionValue))).toString();
} else {
optionValue = import.meta.resolve(optionValue);
} |
You can then see everything as a user would, by running TSTyche against some example tests: | ||
|
||
```shell | ||
yarn test:tstyche | ||
``` | ||
|
||
Which is just an alias for: | ||
|
||
```shell | ||
tstyche ./type-test | ||
``` |
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.
Hm.. Not sure this is applicable in this repo. Or?
If I remember it right, support for absolute paths is not implemented. Ah, right! My thinking was that this must be a module specifier. Hence relative paths are resolved as URL strings to work with |
source/mocha.ts
Outdated
// Clear out the default Line and Summary reporters. | ||
resolvedConfig.reporters = []; | ||
resolvedConfig.reporters = [reporterScript]; |
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.
See #4 (comment). And also this example from TSTyche repo: https://github.com/tstyche/tstyche/blob/0261af0c5f4591329e650fad602f41ccd19d46cb/examples/example-plugin.tst.js#L10
Perhaps it is worth to simply normalize into URL string here:
resolvedConfig.reporters = [reporterScript]; | |
resolvedConfig.reporters = [pathToFileURL(reporterScript).toString()]; |
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'm going to rubber duck this out, because it's a little convoluted.
Use-case
Given a developer using an IDE
And a project configured with `tstyche`, `mocha`, and `tstyche-as-mocha`
And the project has some unit tests which use TSTyche `expect` and `describe`
When the developer adds a run configuration for those tests with tstyche-as-mocha
And the developer runs the configuration
Then tstyche-as-mocha will run TSTyche
And tstyche-as-mocha will translate TSTyche test results into the expected Mocha format
And the developer should be able to see those results in their IDE
Details
The execution chain looks like:
- IDE thinks it is running Mocha. Actually runs tstyche-as-mocha:
node node_modules/tstyche-as-mocha --reporter /some/path/to/IDE/reporter.js --additional --mocha --options
- Node.js runs the
bin
script specified intstyche-as-mocha/package.json
, which just points to the compiledmocha.ts
. - The
mocha.js
script translates the Mocha CLI options to something TSTyche understands, specifying the path to the (compiled)AsMochaReporter.js
as the only TSTyche Reporter, and runs TSTyche. - TSTyche runs with the provided config, loading up the AsMochaReporter via the path provided to it.
- The AsMochaReporter takes the path provided by the IDE, to its Mocha Reporter, and loads it.
- As TSTyche runs, the AsMochaReporter translates its events to Mocha format, passing them on to the IDE's Mocha Reporter.
- The user sees the TSTyche results. Magic!
There are several imports happening, with various formats of specifiers:
- The tstyche-as-mocha CLI loads TSTyche. This is straightforward, as the import specifier is just the package subpath:
tstyche/tstyche
. - As part of that config, the as-mocha CLI passes the AsMochaReport's import specifier to TSTyche.
Hmm. I wonder if we could be clever here and make the import specifier something another subpath, like
tstyche-as-mocha/reporter
, and not a filesystem path? It should work, as both packages should be installed. It would break in scenarios where the developer hasn't actually added a dependency on tstyche-as-mocha ... but do we care? - TSTyche loads the AsMochaReporter, using whatever it's given.
- The AsMochaReporter loads the IDE's Mocha Reporter, using the filesystem path given to the CLI.
The trick for that last one is that these paths will, in most cases, be provided as absolute filesystem paths by the IDE, and completely out of the user's control. And in many cases, will be completely obscured from the user, as all they did was click the little green "run this test" button in their IDE. But, ultimately, the AsMochaReporter will need to correctly translate them into import specifiers. For example, the one from JetBrains on macOS will end up looking like:
--reporter "/Users/ricko/Applications/IntelliJ IDEA Ultimate.app/Contents/plugins/nodeJS/js/mocha-intellij/lib/mochaIntellijReporter.js"
So I think that gives me two avenues to work on:
- Set up a subpath in tstyche-as-mocha so its reporter can be accessed via something like
tstyche-as-mocha/reporter
and not a filesystem path. This will eliminate all that really grossscriptDir
stuff if it works. Yay! - Add some more unit tests for the AsMochaReport to handle the various types of import specifiers it should be ready to handle.
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.
Thanks for the details. Now I understand the internals better. Using subpath sounds like a good idea indeed.
By the way, this made me intrigued:
--reporter "/Users/ricko/Applications/IntelliJ IDEA Ultimate.app/Contents/plugins/nodeJS/js/mocha-intellij/lib/mochaIntellijReporter.js"
I did not expect to see IntelliJ using JavaScript. Very surprising. Does this mean IntelliJ IDEs would be able somehow to spawn tstyche
and they just need to get back report in certain shape? Not today, but I will dig around.
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.
In theory, yes. But I admit, I don't know how they accept submissions for supporting a new reporter. Maybe an issue in YouTrack? For example:
For the most part, it's actually a pretty seamless UX for devs. You just write some code which looks vaguely like a describe
block and the IDE gives you a set of 🟩
jetbrains-test-ux-1mb.mp4
You don't even have to configure anything explicitly. The IDE figures out that your project has mocha installed and just dynamically sets up a run config for it the first time you use one of the affordances. Same for Jest, Vitest, etc.
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.
What about vendoring mocha-intellij
into this repo? (This is the same code they ship, right?) It did not change for eight years. Looks stable.
Might be I missed something. The benefits of vending would be:
- no need to translate the path to Mocha reporter,
- also no need for Add an (optional) Reporter method to wait for setup to complete tstyche#400,
- in the future the code could be reworked so that TSTyche reporter could emit all what is needed without delegating the task to
mocha-intellij
.
And some years later that TSTyche reporter can be used to build native IntelliJ plugin. At the moment, this is just a dream, but I feel happy looking at this plan. What you think?
Okay, I spent some time on the CommonJS code. I did see that you can get tsc to output CommonJS, regardless of the errors it produces. However, when you try to actually run the code, it doesn't get very far:
But the funny thing is, you can't actually get that to work because tsc always transpiles the dynamic import to a I even spent a bit of time doing really icky stuff like this: const dynamicImport = new Function("return import('tstyche/tstyche')") as () => Promise<LibLike>; That works for the export default class AsMochaReporter extends BaseReporter { And that So ... long story short, as long as I did attempt to build a CommonJS springoard: module.exports = function requireCommon(specifier) {
return require(specifier);
}; Which I can then use in the const springBoard = (await import("../cjs/springboard.cjs")).default as unknown;
if (typeof springBoard !== "function") {
throw new Error("SpringBoard is not a function.");
}
const reporterModule = (springBoard as (specifier: string) => unknown)(reporterName); This does actually import everything correctly ... but because node started in an ESM context, the CommonJS Yuck. And, going through the Mocha docs:
So, filing a YouTrack ticket to have JetBrains add ESM support for their Mocha Reporter library seems like it probably wouldn't go anywhere. Okay ... path forward for me:
|
Out of curiosity I created a simple project with Mocha and used And I also looked into IDEs source (the |
This also includes the prototype for loading the runner via a script name instead of as a live object. Seems to work! This would mean we don't need to expose a
Runner.addReporter
function upstream.