Mocha, how to ignore node_modules folder - node.js

I am trying to create a test environment which all source file is side by side with its test code. This is due to easy to track which file is without its test code. Below is the example of my directory after run build
built/api/a.js
built/api/a-test.js
built/api/b.js
built/api/b-test.js
built/index.js
built/index-test.js
built/node_modules/...
built/package.json
src/api/a.js
src/api/a-test.js
src/api/b.js
src/api/b-test.js
src/index.js
src/index-test.js
src/package.json
package.json
I am going to run my test by run 'npm test', below is my package.json content:
{ "name": "sample",
"scripts": {
"build": "babel ./src -d ./built && cd built && npm install",
"test": "mocha built/**/*-test.js"
},
"devDependencies": {
"babel-cli": "^6.18.0",
"babel-core": "^6.18.0",
"mocha": "^3.1.2"
}
}
My question is how can I skip those files in node_modules folder coincidently have name end with -test.js

A little late to the party (13+ months!?), but...
Mocha doesn't support this out of the box. You need to use your glob-fu and get a little fancy. Running something like this on your command line should do the trick:
mocha './built/{,!(node_modules)/**}/*-test.js'
The glob pattern {,!(node_modules)/**} says
Take entries in the current directory, or in any subdirectory of the current directory, regardless of depth, except for ones rooted in ./build/node_modules.
Note that the single quotes are essentially required on OS X or Linux boxen. Left as a bareword (unquoted), or quoted with double quotes, you'll get shell globbing instead of the internal glob() used by mocha, so you're unlikely to get the results you might expect... unless you have an atypical shell.
The Windows shell only supports double quoting... and it doesn't have command line globbing, so on Windows, you'll probably want to leave this unquoted (but don't, err, quote me on that).
A better, more platform-agnostic way would be to put the glob pattern in your test/mocha.opts file, thus:
--require ./test/setup.js
--colors
--inline-diffs
./built/{,!(node_modules)/**}/*-test.js
Cheers!

mocha '**/*-test.js' --ignore 'built/node_modules/**/*'

Another alternative to the existing answers... for those who use a mocha config file (.mocharc.js), you can include the ignore parameter:
{
ignore: 'built/node_modules/**/*'
}
Calling this with mocha --config .mocharc.js built/**/*-test.js

Related

pass command line argument in vscode test runner script (index.ts)

Scenario:
script in package.json file looks like:
"test": "node ./out/test/runTest.js"
this runTest.js then calls test runner script src/test/suite/index.ts . Source of this file is : https://code.visualstudio.com/api/working-with-extensions/testing-extension
In the index.ts, it uses source like:
return new Promise((c, e) => {
glob('**/**.test.js', { cwd: testsRoot }, (err, files) => {
Here, glob is pointing to the src files to consider for test run.
Question:
For specific reason, I don't want to test all files using regex like: glob('**/**.test.js'
I want to test specific file and I want to pass it by my test script in package.json file.
For ex: I want
"test": "node ./out/test/runTest.js Filename"
And glob() in index.ts file will consider only this Filename for execution.
I need some help in this regards.
Thanks again
The way to pass arguments from npm scripts inside package.json is via environment variables. The syntax is slightly different depending on the platform. The example below is for Windows.
"test": "set FileName=foo.js&node ./out/test/runTest.js"
The argument and the value is now awailable inside runTest.js in process.env
console.log(process.env.FileName); //foo.js
In the src/test/suite/index.ts open your package.json file and search for the "test" script line and parse it for the arguments.
Edit
I needed something similar and added a file: test-arguments.txt next to index.js or maybe in .vscode folder if you use typescript.
Inside index.js I open the file and parse the arguments. I allow lines to be commented with #.
By adding this test-arguments.txt file to .gitignore I don't have to modify package.json and my team members can have different arguments.

Trying to use mocha, ES6 modules, and ts-node with the --experimental-loader option

I'm trying to get the ts-node option --experimental-loader working along with mocha, and having no luck. Until I started trying to compile ES6 modules, I used to be able to run mocha tests this way:
"test": "nyc --reporter=html mocha --require ts-node/register src/**/*.spec.ts"
That doesn't work anymore when generating ES6 modules.
I'd use the TS_NODE_COMPILER_OPTIONS='{\"module\": \"commonjs\" }' solution for testing, but that won't work for me because of another complication: I'm generating ES6 modules as a first step in my build, but also generating ES5/CommonJS modules using webpack and babel. That last step doesn't work unless I add .js to the end of my local TypeScript import statements.
But adding those .js extensions turns out to break the TS_NODE_COMPILER_OPTIONS='{\"module\": \"commonjs\" }' solution, which will work, however, if I go back and delete all of the .js extensions. I obviously don't want a test and build process where I have to keep going back and forth between adding and removing those extensions.
To simplify for now, I've taken out nyc, and I'm trying to run tests like this:
mocha -r ts-node/register --experimental-loader ./ts-loader.mjs src/**/*.spec.ts
I get no errors this way, but nothing happens either. It's like the src/**/*.spec.ts doesn't exist.
My do-nothing (for now) dummy loader looks like this:
console.log('ts-loader loaded');
export async function resolve(specifier, context, defaultResolve) {
console.log('resolve');
return defaultResolve(specifier, context, defaultResolve);
}
export async function getFormat(url, context, defaultGetFormat) {
console.log('getFormat');
return defaultGetFormat(url, context, defaultGetFormat);
}
export async function getSource(url, context, defaultGetSource) {
console.log('getSource');
return defaultGetSource(url, context, defaultGetSource);
}
export async function transformSource(source, context, defaultTransformSource) {
console.log('transformSource');
return defaultTransformSource(source, context, defaultTransformSource);
}
export function getGlobalPreloadCode() {
console.log('getGlobalPreloadCode');
return '';
}
I can tell it gets loaded because the 'ts-loader loaded' message appears, but none of the functions ever get called.
I've tried other permutations, but just get errors like src/**/*.spec.ts being treated as a literal file name instead of a glob, or errors about modules not being found.
I was hoping to see my loader invoked for every import being handled, and then figuring out how to manipulate the file extensions, but I haven't managed to get that far yet. Any suggestions?
I'm using node v14.15.1. The full code for my project, with a working build, but broken tests, can be found here: https://github.com/kshetline/tubular_math
I finally found a solution, although it wasn't along the lines I was originally looking for. I gave up on trying to make mocha happy with the extra .js extensions, and found a way to make webpack happy without them. So...
import { Angle, Mode, Unit } from './angle.js';
...went back to...
import { Angle, Mode, Unit } from './angle';
My test script looks like this:
"scripts": {
"build": "rimraf dist/ && tsc && webpack && webpack --env target=umd",
"prepublishOnly": "npm run build",
"lint": "eslint 'src/**/*.ts'",
"test": "TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' nyc --reporter=html mocha --require ts-node/register src/**/*.spec.ts"
},
And finally, most importantly, I figured out how to make webpack 5.x (4.x didn't have this issue) happy with local JavaScript imports that don't have a .js extension, which webpack now otherwise insists upon if your package.json says "type": "module":
module: {
rules: [
{ test: /\.js$/, use: 'babel-loader', resolve: { fullySpecified: false } }
]
}
...where setting fullySpecified to false is the key to the solution.
UPDATE: The above example was done working on a deliberately simple project, something easy for a starter to generate an npm package with ESM modules. Now that I'm trying something a little more advanced, I've run into a snag again running unit tests. As soon as a *.spec.ts file directly or indirectly imports external code, module loading fails. I can only test code with no external dependencies until I figure out how to fix that problem. Apparently using "TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' is only letting me go one level deep into fixing the basic problem with running mocha along with ts-node.

Convert an argument passed to an npm script to an environment variable

This is my package.json:
"scripts": {
"start": "bash do_something.sh && jest",
"...": "..."
}
In my package, there is the package.json and do_something.sh files at the package root, and a test_file.spec.ts module in ./src.
So doing npm run start from the CLI first runs the shell script with bash, then when the shell script finishes, it runs jest. This works fine so far.
However, there is a hardcoded constant, say FOO, inside do_something.sh (as FOO="bar") and inside the test module (as const FOO = "bar";). Instead of having to change the constant in both files upon each run, I would like to be able to set it from the CLI when calling the script, by doing something like:
npm run start --FOO=bar
I would then want to intercept that CLI argument from within the npm script definition in the package.json, and set it as an environment variable accessible within the do_something.sh shell script, and within the test_file.spec.ts module.
So in the package.json I would do something like:
"scripts": {
"start": "env FOO=$npm_config_FOO bash do_something.sh && jest",
"...": "..."
}
(I am using the npm_config_ approach from here)
Then from within do_something.sh:
echo $FOO
And within test_file.spec.ts:
console.log(process.env.FOO);
I think I am close to getting it working, just a few missing steps I think.
I think it's very close to what you have
"scripts": {
"start": "export FOO=\"$npm_config_FOO\"; bash do_something.sh && jest"
...
}
which is going to export FOO and it will be available in bash and jest environments.

Babel does not respect ignore API option

Given the following minimal package.json:
{
"babel": {
"presets": ["es2015"],
"ignore": [
"b",
"c",
"node_modules"
]
},
"devDependencies": {
"babel-cli": "^6.8.0",
"babel-preset-es2015": "^6.6.0"
},
"scripts": {
"transpile": "babel *.js **/*.js --out-dir c"
}
}
And a directory structure:
foo.js
a/
bar.js
b/
baz.js
npm run transpile steams through every directory, including the output directory if it exists:
foo.js -> c/foo.js
a/bar.js -> c/a/bar.js
b/baz.js -> c/b/baz.js
c/foo.js -> c/c/foo.js
What am I missing about the behaviour of the ignore option? --ignore node_modules,b,c on the command line works marginally better, although if an --out-dir is specified it seems only to respect the first argument.
Edit: per immediately above, the accepted answer to Babel ignore several directories does not solve the problem. Specifying an output directory seems somehow to cause all but the first directory specified to --ignore to be dropped from the list. In any case it doesn't explain why the .babelrc option seemingly has no effect... it's always tempting to cry 'bug', but I wondered if I'd missed something.
Per the comment above, there's a bug logged at https://phabricator.babeljs.io/T6726. However it seems that the way to work around using the command line syntax is to avoid globs altogether. Instead of:
babel **/*.js --ignore b,c --out-dir c
I've had some success with:
babel . --ignore b,c --out-dir c

Glob wildcards in windows npm

I'm trying to get npm to do a build browserify on a folder of scripts. The problem is, I'm on windows and doing folder/*.js doesn't seem to work. I've tried globally installing glob, but whenever I run a build command, the error comes back saying "Cannot find module 'c:\www\project\static\js\components*.js'.
Here's my package.json:
{
"name": "TEST",
"description": "ITS ME MARIO",
"author": "JJ",
"version": "0.0.1",
"dependencies": {
"connect": "1.8.5",
"express": "2.5.2",
"jade": "0.20.0",
"mongoose": "3.8.x",
"socket.io": "0.8.7"
},
"devDependencies": {
"vows": "0.5.x",
"mocha": "*",
"should": "*",
"jshint": "latest",
"browserify": "latest",
"rimraf": "latest",
"hashmark": "latest",
"stylus": "latest",
"glob": "latest"
},
"scripts": {
"clean": "rimraf dist",
"test": "mocha test/",
"build:components-js": "browserify static/js/components/*.js > static/dist/components.js",
"build:app-js": "browserify static/js/script > static/dist/app.js",
"build:css": "stylus static/css/style.styl > static/dist/main.css",
"build": "npm run build:css && npm run build:components-js && npm run build:app-js"
},
"engine": "node >= 0.6.6"
}
Anyone know what I'm doing wrong?
I don't think you're doing anything wrong; this is basically a limitation of the Windows shell/console/command prompt, although browserify could be 'improved' to sidestep that and use glob / node-glob instead. I'm not sure about browserify, but jshint is similar.
Some ideas:
Try passing the root directory name instead. That's less powerful but seems to work well enough with jshint:
https://github.com/jshint/jshint/issues/1904
Use cygwin as the shell you run npm from. It brings much *nix power to Windows.
Tweak or request a tweak to browserify (and jshint, and... ?) so that they invoke the glob library to handle these file-related parameters. Compare:
https://github.com/jshint/jshint/issues/1998
Wrap said tools with 'translators' such https://www.npmjs.com/package/build-jshint . Note that this is explicitly designed to support ** wildcards etc.
Just guessing, but there might also be a way to
use PowerShell (which comes with recent versions of Windows--see the Get-ChildItem command)
or Hamilton C shell (uses ... instead of **, I think), or something else, as your shell.
use a loop with /r for recursing into subfolders. I'm not recommending this--Windows-specific, not very chainable--but the 'wint' command set up below does 'work' (invoke with npm run wint) if I include the following in my package.json file.
loop for Windows (Note: redirecting the output below to a file isn't a simple > because ...do jshint %f > chk.txt will overwrite itself and ...do jshint %f > %f.chk.txt may generate many chk.txt files sprinkled around):
"scripts": {
"lint": "jshint **.js",
"wint": "for /r %f in (*.js) do jshint %f",
},
But the commands above would generally not be usable cross-platform. Also, using an alternative shell, you don't benefit by default from being able to shift+right-click on a folder and "Open command window here".
Related:
Cannot use GLOB with JSHint in Windows?
https://superuser.com/questions/358863/wildcard-for-all-subdirectories-or-all-descendent-directories-in-windows-command

Resources