I have a case where it's necessary to find the path of the currently executing path. Does this exist anywhere in Jest?
Did some digging and found that it's available on the global scope as jasmine.testPath (at least on version 23.4.2, but presumably as long as Jasmine is handling test runs under the hood)
Related
Is there an elegant way to detect the flags passed to the node runtime in code?
node --no-opt app.js
I'm trying to detect if the --no-opt option was passed in.
Unfortunately process.argv doesn't work and v8 doesn't seem to be giving any information either.
Apparently there is another field on process that we can check
process.execArgv.includes('--no-opt')
I have the following TypeScript code:
const myMap = new Map([["name", 5]]);
for (const foo of myMap.values()) {
console.log(foo);
}
When I run this code in node (v8.12.0) directly, it works and prints out "5" to console.
If I run this exact same code in a Jest test, it never executes the contents of the for loop. It runs the for condition and then just skips past the loop, never actually enumerating the values.
Why is that? Is there something about the JS runtime used by Jest (isn't it node?) that doesn't support for..of over iterables?
Thanks!
After a very long investigation, I have gotten to the bottom of this. Important background information about the solution:
When targeting older ECMAscript versions like ES3 and ES5 with the TypeScript compiler, using for..of loops to iterate over Iterable collections is not supported by default. If you want to use for..of with Iterable, you have to either target something newer than ES5 or use the --downlevelIteration flag.
To use Jest with a TypeScript project, you use ts-jest. At least, I was. I think you can also use babel somehow but I think ts-jest is preferred.
When using ts-jest, by default it tries to use the tsconfig.json file that the project uses -- which, as far as I can tell, means the one that is next to the jest.config.js file you are using (or the current directory if you aren't specifying a jest.config.js file). If it cannot find a tsconfig.json file in the project directory, it uses the default TypeScript compiler options. The default compiler options cause the TypeScript compiler to target ES3 or ES5 (the ts-jest docs claim it defaults to ES3 but that ts-jest overrides the default in this case to be ES5). --downlevelIteration is not on by default.
With all this in mind, I was able to figure out that ts-jest was not able to find my project's tsconfig.json file and so it was running my tests using the default settings, which meant targeting ES5 and not allowing downlevelIteration, so all my for..of loops over Iterable didn't work. The reason it couldn't find my tsconfig.json file is because my jest.config.js file was in a different directory (higher up in the tree) and even though I was running jest from a directory with a tsconfig.json file, ts-jest was not looking in the "current" directory but was instead looking in the directory that I pointed jest at for my jest.config.js file, which did not contain a tsconfig.json.
My solution to this was to rework my directory structure a bit and leverage the tsConfig option of ts-jest to tell it where to find my tsconfig.json file, which made everything "magically" work since my tsconfig.json file targets es2018, which supports for..of iteration over Iterable.
One alternative solution I considered but quickly disregarded was feature of the aforementioned tsConfig setting to directly set the --downlevelIteration compiler option in the jest config. I chose not to do that because, while it would have fixed this specific problem, it would not have fixed the larger problem which is that my Jest tests were compiling my TypeScript with different flags than my production code! It just so happens that only current problem caused by this was my for..of loop misery.
A quick postscript: the way I eventually made headway on this issue is by stumbling across the diagnostics option in ts-jest. Once I set it to true, when I tried to run my tests, an error like this was displayed:
TypeScript diagnostics (customize using [jest-config].globals.ts-jest.diagnostics option): src/foo.ts:163:47 - error TS2569: Type 'Map<Guid, FooInfo>' is not an array type or a string type. Use compiler option '--downlevelIteration' to allow iterating of iterators.
It seems like TS compiler errors should be displayed (and cause test failures) regardless of whether or not ts-jest "diagnostics" are enabled but shrug.
I built a node module for others to import into their node projects. I use config.js. I'm having issues telling their scripts where to look for my config directory is.
I'm using this code to define it within my module, but its doesn't cover all possible scenarios.
var config_dir = path.dirname(process.mainModule.filename)+path.sep+'node_modules'+path.sep+'open-payments'+path.sep+'config';
process.env.NODE_CONFIG_DIR=config_dir
I need something that will tell my module where to look regardless of what or where the script is that's using my module.
You can use __dirname to get the full path for the current executing script (i.e. not necessarily the one that was called with node, but the one where __dirname was queried).
See this question for more details: How to get path to current script with node.js?
We have a node project that does not require our own submodules from a relative path, but instead needs the NODE_PATH environment variable be set to lib to find all submodules.
I wanted to handle this standard case within the program source code but it seems like it is impossible by now.
I found several solutions which all do not work as expected.
module.paths.push("./lib");
Was suggested in another stackoverflow article but this causes an error message in the newer Node versions and refers the developer to using NODE_PATH.
Instead I tried to do the following as the very first line of my program.
process.env['NODE_PATH']="./lib";
This does not cause an error message but it does not work either. I think that this variable is read on the application start and not read lateron when requiering stuff.
All information you can find out from the source: module.js
... NODE_PATH error is thrown only when accessing via require.paths.
Search for _nodeModulePaths function: Module instance has generic Array object paths, with all lookup paths in it.
module.paths.unshift('./foo-baz');
var x = require('some-lib-name');
console.log(x);
So now, if you have the required module under ./foo-baz/some-lib-name/ it would be properly picked up.
What node version and what system you have?
I'm just getting started with Component package manager. I understand that I can require in other local modules by adding the module to the local key in the component.json file, but what if I don't want to treat every file as a module?
In the (very minimal) documentation for Component, it's developer TJ says that I can add any other relevant scripts (that live in the same directory) to the scripts array. And yet, on doing so, I'm unable to require or reference any of the peripheral scripts' methods from my main file.
The require method fails on trying to load in the script, and any attempt to reference the methods or variables from that script from the 'bootstrap' file are futile. My build.js shows that the script has been compiled in, but I just can't seem to figure out the correct way to reference it from other scripts...
Help?
I just thought I'd post the answer to this question so anybody with the same problem can find it quickly/painlessly.
The answer is to reference the script with a pointer to it's current directory like so:
var script = require('./script.js');
Note the ./ at the beginning of the file name.
An easy mistake to make/rectify.