How to get Babel to compile using webpack-style 'modulesDirectories'? - mocha.js

Following this gist here
https://gist.github.com/ryanflorence/daafb1e3cb8ad740b346
I was able to set up a cool folder structure for a pretty complex app using Webpack's 'resolve.modulesDirectories' - I can reference shared components via module-type imports :
import MyModule from 'modules/MyModule';
where the file is in
src/app/modules/Foo/modules/Bar/modules/Baz/component.jsx
and MyModule is in
src/app/shared/modules/MyModule
The trouble is, when I try to run tests
mocha --compilers js:babel-core/register $(find src/app -name *.test.jsx)
the Babel compiler throws saying it can't find anything in 'modules/MyModule'...
Is there an analog to Webpack's 'modulesDirectories' in the Babel compiler config ?

You should be able to use Babel's resolveModuleSource option to essentially rewrite the import paths, but you'd need to use the programmatic API to do it. So instead of using Mocha's --compilers option, use --require to load a script that calls Babel's require hook and passes the resolveModuleSource option. If you're using Babel v6 use the babel-register package and it'd look something like:
require("babel-register")({
resolveModuleSource: function (source, filename) {
return filename.replace(/^modules\/.+/, "/abs/path/to/src/app/shared/$0");
},
});

You'll have to compile your tests using webpack:
https://webpack.github.io/docs/testing.html

Related

How transpile via IDE ES6 to ES5 (and React-JSX) with WebStorm on Win10 with Babel6?

A lot of sources explain that for this you need to
create a "File Watcher"-Job in the WebStorm-Settings (Tools)
define a "Scope" in WebStorm for the files you want to process
define a .babelrc file for configuration. Babel will use this automatically so you save some params in the call
{
"presets": ["es2015", "react"],
"plugins": ["transform-es2015-arrow-functions"]
}
npm install --save-dev the corresponding packages together with the babel-cli package.
BUT... how can I run the babel-Command on Windows when babel-cli module just delivers a "babel.js" file in its bin-folder? However Windows can only execute .exe, .bat or .cmd-files.
I tried to wrap the call in a cmd-script containing babel %* as I found a solution in one web article, but this did not work for me.
The solution for me was to fill the File Watcher form in a way to have the call of the node executable as Program and add the call for babel.js as first of the Arguments
Program: C:\Program Files\nodejs\node.exe
Arguments: $ProjectFileDir$/node_modules/babel-cli/bin/babel.js $FilePathRelativeToProjectRoot$ --source-maps --out-dir src/test/js
Working Directory: $ProjectFileDir$
Output paths to refresh: $ProjectFileDir$\src\test\js
This makes the babel.js callable for the File Watcher.

error makeNodePromisified is not a function when bundling bluebird with webpack

When I bundle bluebird with webpack and target node I'm getting the following error -
makeNodePromisified(key, THIS, key, fn, suffix, multiArgs);
^
TypeError: makeNodePromisified is not a function
at promisifyAll (...)
at Function.e.24.module.exports.Promise.promisifyAll (...)
It appears to be pulling in ./node_modules/bluebird/browser/bluebird.js which has __BROWSER__ replaced with true. How do I pull in the non-browser version?
Don't pull bluebird directly from webpack, the source isn't designed to work this way because of optimizations performed.
Instead, include the minfieid result and set an alias to the minified end-result file:
externals: {
"Promise": "Promise"
}
In your Webpack configuration file. Alternatively you can ignore it as suggested here if you don't need the type feedback (not using TypeScript for instance).

How to use Mocha require option in Karma

I've been trying to use the mocha require option:
mocha mytest.js --require myglobals.js
But I don't know how to do it from karma. The idea is to run karma start and it will automatically require myglobals.js.
Is that possible to do it from within karma.conf.js or somehow else?
Maybe I'm not using karma/mocha in the right way.
My idea is:
I want to have unit/integration tests for both the client (react) and the server (node/express)
I want to just run karma start and both client and server tests are tested
I found very useful to have the following file pre-required, in order to avoid requiring some things in all tests:
myglobals.js:
const chai = require('chai');
// Load Chai assertions
global.expect = chai.expect;
global.assert = chai.assert;
chai.should();
// Load Sinon
global.sinon = require('sinon');
// Initialize Chai plugins
chai.use(require('sinon-chai'));
chai.use(require('chai-as-promised'));
chai.use(require('chai-things'));
For the server side I've made it work using the command:
mocha mytest.js --require myglobals.js
But still, I wanted to keep it running under the npm run test (which calls karma start) instead of creating another npm run test:server command.
Furthermore, I wanted to do the same on the client. I'm using webpack there as a preprocessor.
Any ideas if it is possible to accomplish that? Or maybe I'm in the wrong way?
Short Answer
Mocha in the browser does not support an equivalent of the --require option, but you do not need it. You can just load whatever you need ahead of your tests listing the files you want to load in files in front of your test files. Or if you use a loader like RequireJS, write a test-main.js that loads the modules you would load with --require first, and then load your test files.
Long Answer
If you look at Mocha's code you'll see that the only place --require is used is in the bin/_mocha file. This option is not passed further into the Mocha code but is immediately used to load the requested modules:
requires.forEach(function(mod) {
require(mod);
});
When you run Mocha in the browser, none of this code is run, and if you look in the rest of the Mocha code you won't find a similar facility anywhere else. Why?
Because it would serve no purpose. The --require option is very useful at the command line. Without it, the only way to load modules before Mocha loads the test files would be to either write custom code to start Mocha or put the necessary require calls at the start of every single test file.
In the browser, if you do not use a module loader, you can just load the code you'd load using --require by putting the script elements that load them in front of the script elements that load your tests. In Karma, this means putting these files earlier in the list of files you have in your karma.conf.js. Or if you use RequireJS, for instance, you write test-main.js so that the loading is done in two phases: one that loads the modules you'd load through --require on the command-line, and a second that loads your test files. It could be something like:
const allTestFiles = [];
const TEST_REGEXP = /test\/test.*\.js$/i;
Object.keys(window.__karma__.files).forEach((file) => {
if (TEST_REGEXP.test(file)) {
const normalizedTestModule = file.replace(/^\/base\/|\.js$/g, "");
allTestFiles.push(normalizedTestModule);
}
});
require.config({
baseUrl: "/base",
paths: {
...
},
});
// This guarantees that "a", "b", "c" loads before any other module
require(["a", "b", "c", ...], () => {
require(allTestFiles, window.__karma__.start);
});

error loading css when running mocha tests with babel-node and babel-istanbul

I am having a problem testing UI components that import .scss with webpack. I am testing the component code directly, not the exported webpack bundle.
In my SUT
I have some code that imports scss:
import '!style!css!sass!postcss-loader!../style.scss'
This code causes an error when I run tests:
Error: Cannot find module '!style!css!sass!postcss-loader!../../stylesheets/parts/Breadcrumbs.scss'
at Function.Module._resolveFilename (module.js:336:15)
at Function.Module._load (module.js:286:25)
at Module.require (module.js:365:17)
at require (module.js:384:17)
Cheap workaround
I've been working around this issue with:
try {
require('!style!css!sass!postcss-loader!../style.scss');
} catch(err) { console.log('Not webpack'); }
But this smells dirty, and I would rather not have this code in my SUT.
Running Tests
I can't figure out how to work in the solutions that I have found for this when using babel-node and babel-istanbul instead of mocha directly. Here is how I am currently running tests:
$ babel-node babel-istanbul cover _mocha -- --require ./test/setup.js --recursive
All of the answers I have found are for mocha directly, but I am not running tests with:
$ mocha --compilers js:babel-core/register --require ./test/setup.js --recursive
?
How can I work in a compiler or setup file to tell mocha to ignore .scss files. I am going to have this problem next with .svg files too I am sure.
What about github.com/css-modules/css-modules-require-hook or if you wanna just ignore the css npmjs.com/package/ignore-styles
EDIT:
If you install ignore-style module and then run:
babel-node babel-istanbul cover _mocha -- --require ./test/setup.js --require node_modules/ignore-styles --recursive
im sure it will work, bare in mind you might need to change the path node_modules/ignore-styles im assuming you have your node_modules in the root of your project.
So I had a similar problem trying to require with a webpack-loader prefix and failing as not in the context of webpack.
prunk was better than rewire etc as covered me for all files as was able to do path matching and replacement.
var prunk = require('prunk');
prunk.alias(/^(your loader prefix)/, '');
Then I modified requires extension handling to replace what was being imported.
require.extensions['.scss'] = function (module, filename) {
module.exports = 'whatever you want';
};
(exactly what style-loader does but style-loader cleans itself up! Also note style loader is misnamed and can handle many extensions))
I added this at the top of my test runner and no unfound modules!
Note I actually went further and used the original loader by itself by reading in the file with fs and passing it to the loader but that may have been over kill and should be using webpack to transpile tests with that sole loader in the first place!

How do use node-qunit?

The info on this page seems less-than-forth-coming -- https://github.com/kof/node-qunit. I've got a setup where I installed nodejs and installed the node-quit module. I have test runner and executed the command node /path/to/runner.js. Below is an example of my setup. Any ideas or examples on how to do this or maybe I'm using it wrong. I previous ran qunit tests using Rhino and EnvJs without any issues but I figured I try nodejs since I using it for other things and the packaging system can be scripted in my build. Maybe I missing an option to node to include Qunit or some environment variable not set -- that would make sense.
File Structure
node/
public/
js/
main.js
tests/
js/
testrunner.js
tests.js
Installation
cd node
npm install qunit
This will now update the file structure.
node/
node_modules/
qunit/
tests/js/testrunner.js
var runner = require("../../node/node_modules/qunit");
runner.run({
code : "/full/path/to/public/js/main.js",
tests : "/full/path/to/tests/js/tests.js"
});
tests/js/tests.js
test("Hello World", function() {
ok(true);
});
Command
node tests/js/testrunner.js
It appears that you need to use full paths to the main.js and tests.js files and also include a relative path to the qunit module. I updated the code above as an example for others.

Resources