deno
deno copied to clipboard
Proposal: import.meta.test gating pattern
I'm wondering if this might be a nice pattern for inline tests:
if (import.meta.test) {
Deno.test("test", async function () {
assert(fn(), 'value');
});
}
Where the import.meta.test
guard is automatically optimized out for bundling / runtime builds.
The above pattern would then integrate into deno test
invocation as necessary.
Oooh, I like that idea. I think with the new bundling that is being worked on, those would be elided quite easily.
Great to hear. Note that the benefit of having this on import.meta
is that per-module filtering can be applied to which tests run.
Note that the benefit of having this on
import.meta
is that per-module filtering can be applied to which tests run.
Still not sure I understand why this belongs in import.meta
. How does the value vary between modules?
It is better than putting it in the Deno
namespace, but any node that we can detect and elide. We will be moving to a Rust/swc emit for everything, and being able to co-locate runtime code with test code would really improve the ease of use of testing... So we would just elide the node from the emit with deno run
and deno bundle
but when we go with deno test
we wouldn't drop it. So it is effectively spec compliant way of achieving something like #[cfg(test)]
that we have in Rust.
Also, if we put the flag in the Deno
namespace, then that module becomes potentially a lot less portable, where if it is import.meta.test
then it should effectively just be a no-op.
So effectively people could write code like this:
export function myGreatFunction() {
// ...
}
if (import.meta.test) {
Deno.test("test my function", () => {
// ...
});
}
Which allows them to co-locate all the test code in the same module, have 0 "production" runtime load, be stripped for bundles, and still work unaltered (potentially) in a browser.
Strongly against then. This is a flagrant misuse of import.meta
as it isn't module-specific metadata and it's hard to see the point when import.meta.test
is still not generally detectable.
If the end-feature is so important, statically analysable (and portable) directives are supposed to use code comments, as adopted by Deno in lots of other places. import.meta
is completely random.
I strongly agree with @nayeemrmn on this one, import.meta.test
would depend on runtime "mode" and not concrete module which seems like a misuse of import.meta
. Also I don't really see any gain from this pattern - it would complicate transpilation pipeline significantly as one would get different results depending on subcommand used (in addition to different tsconfig).
I'm surprised Deno.test(...)
even makes it into bundled builds. Would this issue even be a problem if Deno.test()
statements were stripped out of deno bundle
-bundles (optionally with cli flag)? Would that lead to other problems/am I missing something?
I'm surprised
Deno.test(...)
even makes it into bundled builds. Would this issue even be a problem ifDeno.test()
statements were stripped out ofdeno bundle
-bundles (optionally with cli flag)? Would that lead to other problems/am I missing something?
Not really, in theory there's no problem with that, but it might involve significant effort to achieve, eg. Deno.test
could be aliased in user code to test
- we'd need to involve scope analysis to make this work which would be a huge task.
Is their a downside to just using if (Deno.test) { ... }
Is their a downside to just using
if (Deno.test) { ... }
Deno.test
is always defined, even if not using deno test
subcommand - in such case this function is a noop.
Oh, what is the advised way to put tests in the same file as your code (ala rust), otherwise I think this suggestion or something like it is a good idea.
You can put them directly in the file using Deno.test()
. Unless you use deno test
that code will be ignored and test cases never run.