How to provide test ESModule implementation in mocha test? - javascript

I have a mocha test which tests my code. My code uses another "core" npm package (which uses CommonJS modules). One of "core" the files ("synchronizer.js" file) requires "prefs" modules which is assumed to be provided at some point:
const {Prefs} = require("prefs");
In the mocha test i'd like to implement this "prefs" module, so i've created "prefs.mjs" file (with exports that "synchronizer.js" expects). However during the test i have the following error:
Error: Cannot find module 'prefs'
Require stack:
- /Users/developer/Documents/dev/src/project/node_modules/core/lib/synchronizer.js
- /Users/developer/Documents/dev/src/project/node_modules/core/lib/index.js
at Module._resolveFilename (node:internal/modules/cjs/loader:1026:15)
at Module._load (node:internal/modules/cjs/loader:872:27)
at Module.require (node:internal/modules/cjs/loader:1092:19)
at require (node:internal/modules/cjs/helpers:103:18)
at Object.<anonymous> (/Users/developer/Documents/dev/src/project/node_modules/core/lib/synchronizer.js:26:17)
at Module._compile (node:internal/modules/cjs/loader:1205:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1259:10)
at Module.load (node:internal/modules/cjs/loader:1068:32)
at Module._load (node:internal/modules/cjs/loader:909:12)
at Module.require (node:internal/modules/cjs/loader:1092:19)
at require (node:internal/modules/cjs/helpers:103:18)
at Object.<anonymous> (/Users/developer/Documents/dev/src/project/node_modules/core/lib/index.js:33:24)
at Module._compile (node:internal/modules/cjs/loader:1205:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1259:10)
at Module.load (node:internal/modules/cjs/loader:1068:32)
at Module._load (node:internal/modules/cjs/loader:909:12)
at ModuleWrap.<anonymous> (node:internal/modules/esm/translators:169:29)
at ModuleJob.run (node:internal/modules/esm/module_job:194:25)
My project structure:
\sdk
\test
\unit
\ prefs
\prefs.mjs
\test.js
I run the tests (package.json):
"dependencies": {
...
"core": "^0.10.1",
...
},
"scripts": {
...
"unittest": "mocha --recursive ./test/unit/*.js",
...
}
}
test.js looks as follows:
describe("Section1", function() {
beforeEach(async function() {
await configureTestEnv();
// TODO: set "prefs" module
// TODO: set "io" module
// TODO: set "info" module
});
describe("subscriptions", function() {
it("throws if no condition is achieved", async function() {
...
I can run the tests (which does not include "core") successfully, so the testing works in general.
I suspect i have to use smth like webpack or babel, but i'd like to keep it clean and not using any deps or intermediate build steps if possible.
Should i pass modules directories paths to mocha to let node.js somehow find it?

Ended up using webpack and generating a module with aliased modules including prefs.

Related

Importing AMD module in to Mocha test

I am using Mocha to test code exported as AMD module. Running mocha test gives me following error.
ReferenceError: define is not defined
at Object.<anonymous> (/home/malintha/projects/...../xxx.js:1:63)
at Module._compile (module.js:571:32)
at Object.Module._extensions..js (module.js:580:10)
at Module.load (module.js:488:32)
at tryModuleLoad (module.js:447:12)
at Function.Module._load (module.js:439:3)
at Module.require (module.js:498:17)
at require (internal/module.js:20:19)
The source which is tested as floows
define(['lodash', 'log', './yyy'], function(_, log, YYY) {
var xxxy = function() {
};
..............
});
And the mocha test
var expect = require("chai").expect;
var sourceGenVisitor = require("../../xxx")
describe("", function() {
describe("", function() {
it("Checks generated source", function() {
...................
});
});
});
How can I fix this issue ?
You can use amd-loader. I used it for years in a project of mine that was structured as a collection of AMD modules. Install with:
`npm install amd-loader`
It then needs to be loaded before any AMD module. In general:
require("amd-loader");
For Mocha you can use the argument --require amd-loader. You can put it in your test/mocha.opts file if you don't want to have to remember typing it over and over.
If you run mocha test with the typescript. Maybe you do this:
Install amd-loader:
npm install amd-loader --save
Run mocha test:
mocha src/**/*test.ts --require ts-node/register -r amd-loader

not able to require publish module

Im was publish module to npm (very simple module for testing purpose) and it seems that I was not able to require it.
when I do npm install --save I saw that the package is located inside the node_modules (and new entry was created in the package.json) folder and in my server.js file I do
var myModule = require('nodewrapapp');
and I got the following error:
Error: Cannot find module 'nodewrapapp'
at Function.Module._resolveFilename (module.js:338:15)
at Function.Module._load (module.js:289:25)
at Module.require (module.js:366:17)
The module contain only one very simple file :
function startInterval(fn) {
fn(); // do the function right now
return setInterval.apply(this, arguments); // defer to setInterval
}
module.exports = startInterval; // let me be required
what am I doing wrong here?
Change your main to server.js
{
"name": "nodewrapapp",
"version": "0.0.1",
"description": "test",
"main": "server.js", // Here
...
}

How can I use ES2016/ES7 proposal for async/await in my gulpfile.babel.js

I have a very simple gulpfile.babel.js .
import 'babel-polyfill'
let y = ()=>{return Promise.resolve(true)}
async function awaitY() {
let m = await y()
console.log(m)
}
awaitY()
and the following dev dependencies in my package.json
"babel-core": "^6.7.4",
"babel-polyfill": "^6.7.4",
"babel-preset-es2015": "^6.6.0",
"babel-preset-stage-0": "^6.5.0"
and the following in my .babelrc
{
"presets": ["es2015","stage-0"]
}
When I run gulp, i get the following error...
MacBook-Pro-2:gulptest jschlesser$ gulp
[15:26:17] Requiring external module babel-core/register
/Users/jschlesser/Dropbox (Personal)/prj/cursive/spout/gulptest/gulpfile.babel.js:4
var ref = _asyncToGenerator(regeneratorRuntime.mark(function _callee() {
^
ReferenceError: regeneratorRuntime is not defined
at /Users/jschlesser/Dropbox (Personal)/prj/cursive/spout/gulptest/gulpfile.babel.js:4:31
at Object.<anonymous> (gulpfile.babel.js:5:16)
at Module._compile (module.js:435:26)
at loader (/Users/jschlesser/Dropbox (Personal)/prj/cursive/spout/gulptest/node_modules/babel-register/lib/node.js:126:5)
at Object.require.extensions.(anonymous function) [as .js] (/Users/jschlesser/Dropbox (Personal)/prj/cursive/spout/gulptest/node_modules/babel-register/lib/node.js:136:7)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:311:12)
at Module.require (module.js:366:17)
at require (module.js:385:17)
at Liftoff.handleArguments (/Users/jschlesser/.npm-packages/lib/node_modules/gulp/bin/gulp.js:116:3)
MacBook-Pro-2:gulptest jschlesser$
I would like to know what steps are needed to use async/await in a gulpfile. The error implies that gulp used a require hook to run the gulpfile through babel and it transformed the async function into a generator.
It says the error is on line 4.
var ref = _asyncToGenerator(regeneratorRuntime.mark(function _callee() { .
But it looks like its not injecting all of the right stuff into that compiled file to use the regeneratorRuntime.
You need to have a separate entry point that loads the polyfill, and then the main application file.
gulpfile.babel-entry.js
import 'babel-polyfill'
import './gulpfile.babel.js'
gulpfile.babel.js
let y = ()=>{return Promise.resolve(true)}
async function awaitY() {
let m = await y()
console.log(m)
}
awaitY()
more info
Another way to do is by supplying babel-polyfill as gulp parameter.
$ gulp --require babel-polyfill

Testing AMD modules with tape/ES6 unit tests?

I have a web app using:
ES5
RequireJS
Underscore
Backbone
jQuery
I have tried setting up a new unit test suite using:
ES6
Tape
Babel6
My AMD module app/util/stringUtil.js:
define([], function() {
'use strict';
return {
isBlank: function(str) {
return _.isUndefined(str) || _.isNull(str) || _.isString(str) && str.trim().length === 0;
}
};
});
My unit test in tapeTest.js:
import test from 'tape';
import sortUtil from 'app/util/stringUtil';
test('Testing stringUtil', (assert) => {
assert.ok(stringUtil.isBlank(' ')),
'Should be blank');
assert.end();
});
My .babelrc:
{
"presets": ["es2015"]
}
I run the test with tape:
tape -r babel-register tapeTest.js
I get the following error:
app/util/stringUtil.js:1
(function (exports, require, module, __filename, __dirname) { define([], function () {
^
ReferenceError: define is not defined
at Object.<anonymous> (stringUtil.js:1:23)
at Module._compile (module.js:434:26)
at loader (node_modules/babel-register/lib/node.js:126:5)
at Object.require.extensions.(anonymous function) [as .js] (node_modules/babel-register/lib/node.js:136:7)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Module.require (module.js:365:17)
at require (module.js:384:17)
at Object.<anonymous> (tapeTest.js:7:17)
at Module._compile (module.js:434:26)
I'm guessing tape doesn't recognize AMD modules? Can I fix this somehow? Maybe transpile AMD modules to CommonJS modules or something?
You can load AMD modules inside node with requirejs :_)
Read here: http://requirejs.org/docs/node.html
You have to import require and do a little config, something like this:
'use strict';
const test = require('tape');
const requirejs = require('requirejs');
requirejs.config({
baseUrl: __dirname,
nodeRequire: require
});
test('Test something', function (assert) {
requirejs(['app/util/stringUtil'], function (stringUtil) {
assert.ok(stringUtil.isBlank(' '), 'Should be blank');
assert.end();
});
});
I solved it by using karma, webpack and phantomjs launcher:
karma
karma-webpack
karma-phantomjs-launcher
karma-tap
tape
Webpack transpiles the ES6 unit tests to ES5 modules and karma launches and runs the tests in a phantomjs browser.

Gulp Node.js Istanbul Isparta

I'm trying to get unit tests coverage with Istanbul and Isparta, and I'm having some trouble.
Actually, here's my gulp file tasks:
gulp.task('pre-test', ['default'], function() {
return gulp.src('src/app/**/*.js')
.pipe(plumber())
.pipe(istanbul({
instrumenter: isparta.Instrumenter,
includeUntested: true
}))
.pipe(istanbul.hookRequire());
});
gulp.task('test', ['pre-test'], function() {
return gulp.src('src/test/**/*.js')
.pipe(mocha({reporter: 'spec'}))
.pipe(istanbul.writeReports({}));
});
When I start the gulp "test" task, I have the following errors:
[08:34:17] Plumber found unhandled error:
Error in plugin 'gulp-istanbul'
Message:
Unable to parse C:\projects\nodejs\mon-notaire\src\app\core\logger\concrete\ConsoleLogger.js
Line 1: Unexpected token
[08:34:17] Finished 'pre-test' after 2.11 s
[08:34:17] Starting 'test'...
stream.js:94
throw er; // Unhandled stream error in pipe.
^
C:\projects\nodejs\mon-notaire\src\test\core\TestConfReader.js:1
(function (exports, require, module, __filename, __dirname) { import ConfReade
^^^^^^
SyntaxError: Unexpected reserved word
at exports.runInThisContext (vm.js:73:16)
at Module._compile (module.js:443:25)
at Object.Module._extensions..js (module.js:478:10)
at Object.Module._extensions.(anonymous function) [as .js] (C:\projects\nodejs\mon-notaire\node_modules\gulp-istanbul\node_modules\istanbul\lib\hook.js:109:37)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Module.require (module.js:365:17)
at require (module.js:384:17)
at C:\projects\nodejs\mon-notaire\node_modules\mocha\lib\mocha.js:192:27
at Array.forEach (native)
npm ERR! Test failed. See above for more details.
How can I prevent these errors from occurring?
Have you set up .babelrc?
If you're using the latest version of isparta, which depends on babel v6, then you need to set up .babelrc like the following. ( You also need to do npm install --save-dev babel-preset-es2015 )
{
"presets": [
"es2015"
]
}
From gulp-istanbul github page.
var isparta = require('isparta');
var istanbul = require('gulp-istanbul');
gulp.src('lib/**.js')
.pipe(istanbul({
// supports es6
instrumenter: isparta.Instrumenter
}));
This line :
Message:
Unable to parse C:\projects\nodejs\mon-notaire\src\app\core\logger\concrete\ConsoleLogger.js
Means that there is a problem in your code in ConsoleLogger.js , so you might want to check that file out.
This Line :
C:\projects\nodejs\mon-notaire\src\test\core\TestConfReader.js:1
(function (exports, require, module, __filename, __dirname) { import ConfReade
^^^^^^
SyntaxError: Unexpected reserved word
Suggests that you are using ES6, but your gulp task is not transpiling it to ES5 before running it, which is why you are getting the error.
I have made a yeoman generator which creates a project for exactly this purpose (writing nodeJs projects in ES6) and includes code coverage using istanbul with source code mapping. You might want to take a look at that.
Otherwise, here is my working gulpfile from that generator.
I use istanbul, along with a module called remap-istanbul.
The error message indicates that you are using ES6, but the gulp-istanbul doesn't support it by default.
Of course, you can write your functions to compile the ES6 codes, but considering you are using gulp in this case, IMHO the simplest way you can do is to use gulp-babel-istanbul instead of gulp-istanbul, no need to change your code attached above at all.
import istanbul from 'gulp-babel-istanbul'
And the rest of the code remains the same.

Categories

Resources