How to generate unit tests from a JS module automatically? - javascript

I have inherited a project with multiple JavaScript files. Each of them has a bunch of functions; the files are defined in AMD style.
For instance:
math.js
define([], function () {
return {
func1: function (a, b) {
return a + b;
},
func2: function (c, d) {
return c + d;
},
};
});
I would like to generate a new file in the tests folder with the name (math.js) that will contain the boilerplate code for the unit tests in tdd style for the intern framework.
I have used the intern-generator, a Yeoman generator that will do scaffolding and generate a test file with a specified name and path, however, this one won't let me create unit tests that refer to the functions from the JS file.
So, for the math.js source file, I'd like to create a test file (automatically):
define(function (require) {
var tdd = require('intern!tdd');
var assert = require('intern/chai!assert');
var math = require('src/app/math');
tdd.suite('Suite name', function () {
tdd.test1('Test foo', function () {
math.func1('breaks');
});
tdd.test('Test bar', function () {
math.func2('breaks');
});
});
});
This way, I can start with all unit tests files pre-created and I know that all my unit tests will initially break and I will make them pass one by one. Also, this way I can be sure that I got all functions from my source script files into tests.
Naturally, I would like to generate those tests .js files for all my source .js files. Is there any generator or a library/script that will let me do this?

Related

How to use and merge JS modules into 1 file?

I would like to create 1 single javascript file out of multiple files and modules to ship as one single js file for a small library that will be used in the browser (and reuse some part on nodejs).
How can I achieve this?
(function() {
// Modules are minified
var blake = require('blakejs'); // The "entire" module in here ~350 lines...
// Other files are obfuscated
// File1.js
var first = function() {}
first.prototype.doHash = function() {}
// File2.js
var second = function() {}
second.prototype.doSomethingElse = function() {}
//OtherFile.js
//Webworker.js
}).call(this)
I'm using Javascript Obfuscator to obfuscate the script, but I'd like to apply other minification/obfuscation settings to modules, as they wouldn't need obfuscation, only minification.
gulp.task('minify', function () {
return gulp
.src('./src/file1.js')
.pipe(rename({suffix: '.min'}))
.pipe(javascriptObfuscator())
.pipe(gulp.dest('public'))
})
Is it possible?

In the building tool `parcelJs` : generated code that can't run

when parcel compile my code it build js file started like this :
"use strict";
// modules are defined as an array
// [ module function, map of requires ]
//
// map of requires is short require name -> numeric require
//
// anything defined in a previous bundle is accessed via the
// orig method which is the require for previous bundles
require = function (_require) {
function require(_x, _x2, _x3) {
return _require.apply(this, arguments);
}
require.toString = function () {
return _require.toString();
};
return require;
}(function (modules, cache, entry) {
...
that code can't run because it try to define variable require without var|let|const in "use strict" mode .
So my qustion is : why it generate bad code like that ?
So in this tread they say that upgrade node to 8.0.0 or above solve the problem.
In a funny way BTW... it magically remove the use strict from the generated file

Jasmine testing with external javascript

Well I am trying to fire up my first Jasmine test with Karma. I want to test my main javascript file declared functions, but I'm stuck on it... In my specRunner.html I included every files which needed, in karma.conf.js I added both my test specification and main js files also files: ['src/scripts/main.js','src/tests/mySpec.js'].
In my main.js there is the function I want to use
function testFunctionOne(a, b) {
return a * b;
}
So in mySpec.js file there is the test:
describe('testFunctionOne function', function () {
it('should return a * b', function () {
expect(testFunctionOne(2,4).toEqual(8));
});
});
My question is what am I forgot? What am I making wrong? Keep in mind, this is my first attempt for Jasmine testing.
expect(testFunctionOne(2,4)).toEqual(8); not expect(testFunctionOne(2,4).toEqual(8)); I think

Ordening files in Grunt with external file

I'm configuring Grunt with grunt-contrib-concat to concatenate like 20 javascript files. They have to be in a specific order and I'm wondering if there is a neat way to do this, without messing up my Gruntfile.js.
What I did and what worked well, was declaring an variable called 'libraries' with a function which returned a string with all the files in the right order.
var libraries = new (function () {
return [
'/javascript/libs/jquery.min.js',
'/javascript/libs/jquery.address.js',
'/javascript/libs/jquery.console.js'
];
});
And then concat (simplified, just an example):
concat: {
libs: {
files: {
'libs.js' : [libraries],
},
},
main: {
files: {
'main.js' : [main]
}
}
},
So when I call 'libraries' in my task configuration everything works fine, but I would like to declare this list in a separate file.
Unfortunately I couldn't find anything, nor do I know if this is even possible. Hope that someone could help me out! Thanks in advance :-)
I found a solution! Since Grunt is build on NodeJS, it's possible to use module.exports. What I did was setting an external file called libraries.js, which is in my Grunt directory.
var exports = module.exports = {};
exports.customLibrary = function () {
return [
// Path to a library
// Path to another library
// and so on...
];
};
exports.mainScripts = function () {
return [
// Path to a library
// Path to another library
// and so on...
];
};
Then I import this module by declaring a variable in Gruntfile.js
var libraries = require('../javascript/libraries.js');
To use the methods declared in libraries.js I set two more variables which returns a string with all the necessary files in the desired order:
var customLibrary = libraries.customLibrary();
var mainScripts = libraries.mainScripts();
I use these variables to define the source in the concat task. Hope this is helpful!

Is there a way to dynamically set src and dest in gulpfile.js?

I have multiple sets of js modules that I would like to concat into separate files. I don't want to have to create a seperate concat task for each file. It would make more sense to be able to pass arguments into the gulp task "concat". Unfortunately gulp doesn't allow arguments to be passed into tasks(I'm sure for good reason).
Any ideas of how I can accomplish this?
Use Case
A specific scenario would be website that has a global.js file for all pages as well as page specific js files.
Creating a task for each page specific js file will quickly make the gulpfile.js hard to manage as the site grows.
My dev invironment:
I have a dev/js/ directory which has multiple sub-directories. Each sub-directory contains modules for a specific js file. So each sub-directory needs to be concatenated into it's own file within lib/js/.
Perhaps requirejs?
Maybe I should just look into using a module loader like requirejs.
I needed to take modules from my source sub-directory (src/modules/), concatenate a specific file to each individually (src/distribution), then pipe the result to a sub-directory in my distribution folder (dist/js/modules/).
I wasn't sure how many modules would end up being written for this project so I wanted to do it dynamically and found this to be the best (simplest) solution:
gulp.task("modules:js", () => {
let modules = fs.readdirSync("src/modules");
let concatModule = (module) => {
return gulp.src([
'src/distribution',
module
])
.pipe(concat(module))
.pipe(gulp.dest("build/js/modules"));
}
for (let module of modules) {
concatModule(module);
};
});
You could make concatJS a higher-order function:
var concatJS = function (src, filename, dest) {
return function() {
gulp.src(src)
.pipe(concat(filename))
.pipe(gulp.dest(dest));
};
};
gulp.task('concat-1', concatJS('src/module-1', 'module-1.js', 'build/module-1'));
gulp.task('concat-2', concatJS('src/module-2', 'module-2.js', 'build/module-2'));
//etc...
Note: You'd probably be better off using a bundler like browserify or webpack. Since asking this question I have switched to browserify rather than trying to roll my own solution.
Improved Solution:
var fs = require("fs");
/* other requires omitted */
/* Set JS dev directory in one place */
var jsSrc = "dev/js/";
var jsDest = "lib/js/";
var concat = function (path) {
path = path.replace(/\\/g, "/");
var src = path.replace(/(\/[^\/]+?\.js$)|(\/$)/, "/*.js";
var filename = src.match(/\/([^\/]+?)(\/[^\/]+?\.js$)/)[1] + ".js";
gulp.src(src)
.pipe(concat(filename)
.pipe(gulp.dest(jsDest));
});
/* The concat task just runs the concat function for
* each directory in the javascript development directory.
* It will take a performance hit, but allows concat to be
* run as a dependency in a pinch.
*/
gulp.task("concat", function () {
var dirArr = fs.readdirSync(jsDev);
for (var d in dirArr) {
var path = jsDev+dirArr[d]+"/";
concat(path);
}
});
/* Run "concat" as a dependency of the default task */
gulp.taks("default", ["concat"], function () {
var JSWatcher = gulp.watch([jsSrc+"**/*.js"]);
JSWatcher.on("change", function (event) {
concat(event.path);
});
});
Alright, I think this works. It's a little bit of a hack though, and doesn't work for all use cases.
... removed previous example to save space ...

Categories