Using node.js, nodeunit, and ES6/Harmony - javascript

Right now I have a unit testing build environment using node.js and nodeunit. Very happy with these but now I need TCO. I know that TCO has been added into the ES6 standard, but I don't know how to allow it for use with my project. Tried the Harmony flag, but couldn't get it to work with nodeunit. Any help?
Got the idea for using Harmony here:
Node.js tail-call optimization: possible or not?
I like the way these guys think, but I can't do the first answer because then other working on the project would also be forced to change their nodeunit.cmd files (which may screw up other projects they are working on) and the second answer doesn't appear to work:
NodeUnit enable harmony features

From what I understand, it looks like you want to write unit tests in ES5 using nodeunit to test your code written in ES6.
If I understood well, then you can check out this post which shows how to achieve that.
This solution requires you to npm install traceur and then you can require() your ES6 module from within your tests like so :
var traceur = require('traceur');
traceur.require.makeDefault(function(filename) {
return filename.indexOf('node_modules') === -1; // Don't parse node modules
});
var myModule = require('./../path/to/my/module.js');
module.exports = {
// ... tests ...
};
Now you should be able to run that with nodeunit.

Related

Testing JavaScript Written for the Browser in Node JS

I have some JavaScript that is going to run in the browser, but I have broken the logic based functions that have nothing to do with the DOM into their own js files.
If it's possible, I would prefer to test these files via command line, why have to open a browser just to test code logic? After digging through multiple testing libraries for Node.js. I suppose it's not a big deal, but that seems to require that I build a whole node project, which requires that I provide a main, which doesn't really exist in my project since it's just functions that get fired from a web page.
Is there a solution for testing JavaScript functions that can be as simple as just writing a .js file with tests in it and calling a utility to run those tests? Something more simple than having to set up a runner, or build a project and manage dependencies? Something that feels like writing and running JUnit Tests in Eclipse, and a little less like having to set up a Maven project just to run MVN test?
As a follow-up question, is this even the right way to go about it? Is it normal to be running tests for JavaScript that is meant to run in the browser in Node.js?
Use test runners like mocha or jasmine. Very easy to setup and start writing test code. In mocha for example, you can write simple test cases like
var assert = require('assert');
var helper = require('../src/scripts/modules/helper.js');
var model = require('../src/scripts/modules/model.js');
model.first.setMenuItem ({
'title': 'Veggie Burger',
'count': 257,
'id': 1
});
describe('increment', function(){
console.log ("Count : " + model.first.getMenuItem().count);
it('should increment the menu item', function(){
helper.increment();
assert.equal(model.first.getMenuItem().count, 258);
});
});
and run them like
$ ./node_modules/mocha/bin/mocha test/*.js
where test/*.js are the specifications file (unit test file like the one above)
the output will be something like:
Count : 257
increment
✓ should increment the menu item
1 passing (5ms)
You can even use headless browser like PhantomJS to test containing DOM manipulation code.
I'm going to accept Ari Singh's answer for recommending Mocha, and special kudos to Ayush Gupta for leading me down a road that eventually let me write my js files in a format that could be ran in the browser and node.js.
Just to expand on Ari's answer a bit on some things that made life a little easier.
I installed mocha globally using npm install -g mocha. Additionally, I created a test directory that I put all my test in. By doing this, all I had to do to run my unit tests was call mocha test. No package.json, no lengthy paths into node_modules to run mocha.
Node js requires you to export the functions in one file that you want to use in another file, which JavaScript in browsers does not. In order to support both Node.js and JavaScript, I did the following:
In my root directory, I have foo.js with the following contents:
function bar() {
console.log("Hi")
}
module.export = bar
Then in the test directory I have test_foo.js with the following contents (Note this example doesn't have a test, see Ari's answer for an example of writing tests in Mocha):
var bar = require('../foo.js')
bar()
Using this approach, I can test the bar function in node using mocha test and still use it in my HTML page by importing it as a script.

why export and import error in node.js 9?

I am learning the javascript not long. I make two files like bellow.
app.js:
import * as Conf from './conf'
console.log(Conf.a)
conf.js:
export let a = 1
And i just run the command in console:
node app.js
It was err. The err msg:
(function (exports, require, module, __filename, __dirname) { import *
as Conf from './conf'
SyntaxError: Unexpected token import
Can anyone tell me why? And what is about the javascript and babel and so on. I am not so familiar about the concepts. Thanks.
There is a comity that each year promote a new javascript norm that are called ECMA 2015 (ES6), ECMA 2016 (ES7), ECMA 2017 (ES8) ...
Each norm describe the functionality javascript must have.
It exists multiple javascript engines in the market:
V8 from google (and node)
Chakra from microsoft
Rhino from mozilla
and so on
Theses engines try to keep up to the norm, but are not 100% compliant.
here you can see a compatibility table about the engines and ES6.
The problem you can imagine now, is "Why if I want to use the brand new ES8 right away?". There is two answer: Either you wait for node.js to implement it, either you use a transpiler like Babel.
Babel takes the code you do and transpile it into an older norm (ES5) which is fully compatible with node.js.
For example, you want to use import which is an ES6 feature. Babel gonna transform your import into require so node.js can execute it.
It's very usefull and powerfull to use a transpiler so you an use right away the last feature that are improving the productivity of your developper team.
Like #Tuan Anh Tran said, you can use a flag to say to node.js to run it's experimental features, which represent the features it's implementing right now (not particulary safe so for production).
Here is an article about ES6 features.
Here is an article about ES7 features.
Here about ES8 features.
import is ESM keyword and it's in experimental. See nodejs documentation on esm
If you really want to use it, you can either use babel or run your app with --experimental-modules flag and name your file .mjs extension
You need to install Babel or another transpiler to use ES6 import/export in NodeJS.
Babel installation you can find here: https://babeljs.io/docs/setup/#installation
Also you can use NodeJS module loading system.
Docs: https://nodejs.org/api/modules.html
In your case:
app.js
var conf = require('./conf');
console.log(conf);
conf.js
let a = 1;
module.exports = a;
Or
app.js
var conf = require('./conf');
console.log(conf.a);
conf.js
let a = 1;
exports.a = a;
As the other answers already pointed out, the keywords import and export are experimental.
That's why I'd suggest using require():
Your app.js:
let conf = require("./conf");
console.log(conf.a);
Your conf.js:
let a = 1;
exports.a = a;
node app.js will then print 1 to the console.

Anyone has experience using NightWatch with TypeScript?

I am using NightWatch for my e2e testing and want to move towards ES6 way of writing tests.
I was able to do it with Babel and it worked fine but I want to use typescript.
I could not find much documentation of NightWatch with TypeScript. Found some github repositories:
https://github.com/rkavalap/NightWatchTest
https://github.com/DonPage/Nightwatch-Typescript-example
https://github.com/remojansen/TypeScriptTestingExamples
But these do not contain any detailed documentation around typescript.
Any help would be appreciated!
I haven't tried this, but on other TS projects, I use ts-node as the interpreter.
ts-node ./node_modules/.bin/nightwatch test.ts
You can do this with #vue/cli-plugin-e2e-nightwatch as well.
Try this GitHub Nightwatch TypeScript example project. It uses the #types/nightwatch npm package for the Nightwatch type definition imports including support for the page object model and works with Nightwatch 2.0. The readme file in there has links to compiled documentation for further reading beyond the source code.
There is no real difference using nightwatch with typescript. You can use setup somewhat similar to this:
nightwatch.ts:
var nightwatch = require('nightwatch');
import * as child_process from 'child_process';
var nightwatchOptions = {
config: './path/to/nightwatch.json',
env: 'default'
};
var httpServerProc = child_process.spawn(
'node',
[
'node_modules/http-server/bin/http-server',
'path/to/your/client_to_test',
'-p 8082'
],
{
stdio: 'inherit'
}
);
nightwatch.runner(nightwatchOptions, function(success)
{
httpServerProc.kill('SIGINT');
});
Note - here I start http-server, you can use any other or maybe start it outside of the nightwatch testing procedure.
nightwatch.json - is your config settings for nightwatch.
Then all you need is to transpile nightwatch.ts as part of your solution and run resulting nightwatch.js under nodejs as usual.

Webpack & Testing: Helper to delete/replace modules from the require cache

For our tests we need to be able to replace or delete modules from the require cache, e.g. to replace them with a fake implementation.
In order to achieve this we implemented a little helper function:
fakeModule = function(modulePath, fakeExportsObject){
require.cache[require.resolve(modulePath)] = {exports: fakeExportsObject}
}
However when we run this through webpack we get the following critical warning: "the request of a dependency is an expression" and all JavaScript files in the project are included in the webpack build.
Is there any possibility to disable the interpretation of the helper function? In our tests we can safely assume that we are only deleting/replacing existent modules from the require cache. Even if not, it wouldn´t really matter.
Have you looked at rewire and rewire-webpack? I just started looking into testing with webpack and will need to find a way to accomplish this as well. Rewire sounds promising, but I haven't used it yet.

Better coffeescript workaround to load this node.js module

I would like to use this node.js module https://github.com/mlin/node-assert-type
Based on documentation, to declare the module;
var ty = require("assert-type"); //https://github.com/mlin/node-assert-type
var T = ty.Assert;
In actual practice, this does not work. Some coffeescript error appears.
I have to make the following workaround;
var cs = require("coffee-script/register");//this line needed to require("assert-type")
var ty = require("assert-type"); //https://github.com/mlin/node-assert-type
var T = ty.Assert;
To use this module, I am forced to install coffeescript with npm install -g coffeescript.
Is there some way to omit the line var cs = require("coffee-script/register");? After all, the module itself is using coffeescript locally. Am I doing it the right way?
Is it a normal practice to add a line to load coffeescript for node.js modules which use coffee-script?
It is not normal practice. I mean, it would be inevitable that coffeescript gets installed since it is a dependency but the user of the module should not worry about it.
I just took a quick look at the source code of the assert-type and this is what I found:
the project is 3 years old. That's a lot!
the package.json is listing coffeescript as a dependency BUT it is using latest instead of locking a version of coffeescript which is a terrible practice.
My guess is that what it changed was coffeescript module, that instead of needing require('coffeescript') you now need require('coffeescript/register'). (Take a look at the index.js in the repo)
Based on that I'd say it is fine that you write that line. A better option would be to make the changes in the node-assert-type repo and submit a PR with the fixes for #2 and #3.
Hope that helps.

Categories

Resources