I'm developing a NodeJS application and use Mocha for unit testing.
Let's say i have two very similar test suits.
In fact those are tests for two classes which
implement the same interface.
For example:
suit_a.js
var A = require('./a');
describe(function () {
var instance;
beforeEach(function () {
instance = new A();
});
it(function () {
assert(instance.getSomeValue() === 1);
});
});
suit_b.js
var B = require('./b');
describe(function () {
var instance;
beforeEach(function () {
instance = new B({option: "option-value"});
});
it(function () {
assert(instance.getSomeValue() === 1);
});
});
Is there a way to remove code repetition? Is there a way to have two
different test suits, using same assertion code, but with different configuration
or something like that?
The only idea I have right now is to use some kind of source code generation,
but I would like to avoid that if possible.
Move the inner function to an extra file and require it.
In your case you need new A() and new B(...) extra, so either make them available outside or include them as a parameter to the require-result:
var t = require('innerTestGen');
var t1 = t.create(new A())
describe(t1);
var t2 = t.create(new B(...))
describe(t2);
Hope that helps?
Related
What is the equivalent code of window["functionName"](arguments) in NodeJS server-side?
If you need such a capability within a module, one hack is to store such module functions in variables within the module and then call them by accessing them from the module object properties. Example:
var x = { }; // better would be to have module create an object
x.f1 = function()
{
console.log('Call me as a string!');
}
Now, within the module, you can call it using the value from a string:
var funcstr = "f1";
x[funcstr]();
I am learning the ropes with Node myself, the above is probably all sorts of wrong :-). Perhaps a marginally better way to write this example would be (for the module m.js):
module.exports =
{
f1: function() { console.log("Call me from a string!"); },
f2: function(str1) { this[str1](); }
}
Now you can:
var m = require('m.js');
m.f2('f1');
Or even just:
var m = require('m.js');
m['f1']();
FWIW!
you're looking for global
Note, however, that in modules nothing is ever exposed to this level
1) If methods are in same js file
define all methods as properties of Handler:
var Handler={};
Handler.application_run = function (name) {
console.log(name)
}
Now call it like this
var somefunc = "application_run";
Handler[somefunc]('jerry codes');
Output: jerry codes
2) If you want to keep methods in a different js file
// Handler.js
module.exports={
application_run: function (name) {
console.log(name)
}
}
Use method defined in Handler.js in different.js:
// different.js
var methods = require('./Handler.js') // path to Handler.js
methods['application_run']('jerry codes')
Output: jerry codes
If you want to call a class level function using this then following is the solution and it worked for me
class Hello {
sayHello(name) {
console.log("Hello " + name)
}
callVariableMethod() {
let method_name = 'sayHello'
this[`${method_name}`]("Zeal Nagar!")
}
}
If You need it in module scope, You can use something like this
var module = require('moduleName');
module['functionName'](arguments);
Honestly, looking at all these answers they seem a bit too much work. I was playing around to look for other ways around this. You can use the eval() command to print a variable as text then call it as a function
I.e
let commands = ['add', 'remove', 'test'];
for (i in commands) {
if (commands[i] == command) {
var c = "proxy_"+command;
eval(c)(proxy);
}
}
eval(string)(arg1, arg2);
This example script would execute the function proxy_test(proxy)
You know, the OP's code inspired me to try this:
global.test = function(inVal){
console.log(inVal);
}
global['test']('3 is the value')
But now that I think about it, it's no better than #Ravi' s answer.
I use this for node, see if this approach works for you
var _ = require('lodash');
var fnA1 = require('functions/fnA1');
var fnA2 = require('functions/fnA2');
module.exports = {
run: function(fnName, options, callback) {
'use strict';
var nameSpace = fnName.toString().split('.');
// if function name contains namespace, resolve that first before calling
if (nameSpace.length > 1) {
var resolvedFnName = this;
_.forEach(nameSpace, function(name){
resolvedFnName = resolvedFnName[name];
});
resolvedFnName(options, callback);
} else {
this[fnName](options, callback);
}
},
fnA1: fnA1,
fnA2: fnA2
};
call this like
importVariable.run('fnA1.subfunction', data, function(err, result){
if (err) {return callback(err);}
return callback(null, result);
});
That is not specific to the window object. In JavaScript any property of the object can be accessed this way. For example,
var test = {
prop1 : true
};
console.log(test.prop1); // true
console.log(test["prop1"]); // also true
Read more here : https://developer.mozilla.org/en/JavaScript/Guide/Working_with_Objects
I have two javascript modules which act on different parts of the page. Now at moment as you can see I'm using the PubSubJS library to publish and subscribe and transfer data if need be from one module to another module in a decoupled way. But I was thinking whether I can altogether omit the PubSubJS library use JQuery promises(or any other native JQuery method) instead to achieve the same. I'm not so good with JQuery promises hence the need for this question. Can somebody provide me any better solution with JQuery.
var salesOrder = (function() {
"use strict";
var $root, $salesOrderNo, $closeButton;
var _init = function() {
$root = $("#sales-order")
$closeButton = $root.find("#close-button");
_attachEvents();
};
var _attachEvents = function() {
$closeButton.on("click", _closeSalesOrder);
};
var _closeSalesOrder = function() {
PubSub.publish("ui.unloadShell", "closed"); //Here I'm publishing
}
return {
init: _init
}
})();
$(document).ready(salesOrder.init);
And the second module as so
var erpTest = (function() {
"use strict";
var $root, $btnMenu, $shell;
var _init = function() {
$root = $("body")
$btnMenu = $root.find(".menu-button");
$shell = $root.find("#shell");
_attachEvents();
}
var _attachEvents = function() {
$btnMenu.on("click", _loadShell);
PubSub.subscribe('ui.unloadShell', _unloadShell); //Here I'm subscribing
}
var _loadShell = function(evt) {
var url = $(evt.target).data("url");
if (url && url.length) {
$shell.load(url, _loadCompleted);
}
};
var _unloadShell = function(evt, data) {
$shell.html(null); //Here is the subscribed handler
};
var _loadCompleted = function(evt) {
$.each([buttonModule.init, nameModule.init], function(index, func) {
func($shell);
});
};
return {
init: _init
}
})();
$(document).ready(erpTest.init);
I use the PubSub pattern extensively. Your questions are the ones I was looking into a while ago. Here are my comments:
jQuery Promises: Promises are by nature async; do you really want an async channel of communication between components? Using Promises, you'd expect that any subscribers respond properly as your publisher might take action back using .then. Things will become complex as soon as you expect subscribers to respond accordingly to events.
jQuery has .on, .off, .one to publish events; you simply need to pass {} as aggregator. See that topic for further details: Passing an empty object into jQuery function. However jQuery has some overhead compared to a simple pubSub/aggreagator mechanism.
I built several labs of incremental complexity focused on the PubSub pattern that you can consult below. LineApp is the entry point.
https://pubsub-message-component-1975.herokuapp.com
Kindly help me to find the solution just wanted know how to export 2 functions into spec or in another js file. pls check my below code for ur reference. This is some agentdetails.js file. I want to call the below functions in spec(both the functions) some times i use only one
var AddAgent = function()
{
var AGP = require('D:/Automation/ServCloud/PageObjects/AgentDetailsObjects.js');
var Login = require('D:/Automation/ServCloud/Test DATA/TestData.json');
AGP.Agent.click();
AGP.AddAgentbtn.click();
AGP.Supervisor.click();
AGP.AgtSave.click();
}
module.exports = new AddAgent();
var EditAgent = function()
{
var AGP = require('D:/Automation/ServCloud/PageObjects/AgentDetailsObjects.js');
var Login = require('D:/Automation/ServCloud/Test DATA/TestData.json');
AGP.AgentEdit.click();
AGP.AgtSave.click();
browser.sleep(3000);
var alertDialog = browser.switchTo().alert(); }
module.exports = new EditAgent();
I have tried like this. (FYI - I can make this into one function and i can call it but i wanted to split into 2 functions and call both in one spec separately so that i can comment which ever is not required at times
it('Add Agent Details', function()
{
var aa = require('D:/Automation/ServCloud/Actions/AgentAction.js');
aa.AddAgent();
aa.EditAgent();
});
I don`t think it is possible,
You can do:
varr AggentFunctions = function() {
this.AddAgent = function(){
//some code
};
this.EditAgent = function(){
//some code
};
};
module.exports = AggentFunctions;
Then you can use it like this:
var agentsFuncs = require('yourAgentFile');
var agents = new agentsFuncs;
//and call what you want
agents.AddAgent();
agents.EditAgent();
What is the equivalent code of window["functionName"](arguments) in NodeJS server-side?
If you need such a capability within a module, one hack is to store such module functions in variables within the module and then call them by accessing them from the module object properties. Example:
var x = { }; // better would be to have module create an object
x.f1 = function()
{
console.log('Call me as a string!');
}
Now, within the module, you can call it using the value from a string:
var funcstr = "f1";
x[funcstr]();
I am learning the ropes with Node myself, the above is probably all sorts of wrong :-). Perhaps a marginally better way to write this example would be (for the module m.js):
module.exports =
{
f1: function() { console.log("Call me from a string!"); },
f2: function(str1) { this[str1](); }
}
Now you can:
var m = require('m.js');
m.f2('f1');
Or even just:
var m = require('m.js');
m['f1']();
FWIW!
you're looking for global
Note, however, that in modules nothing is ever exposed to this level
1) If methods are in same js file
define all methods as properties of Handler:
var Handler={};
Handler.application_run = function (name) {
console.log(name)
}
Now call it like this
var somefunc = "application_run";
Handler[somefunc]('jerry codes');
Output: jerry codes
2) If you want to keep methods in a different js file
// Handler.js
module.exports={
application_run: function (name) {
console.log(name)
}
}
Use method defined in Handler.js in different.js:
// different.js
var methods = require('./Handler.js') // path to Handler.js
methods['application_run']('jerry codes')
Output: jerry codes
If you want to call a class level function using this then following is the solution and it worked for me
class Hello {
sayHello(name) {
console.log("Hello " + name)
}
callVariableMethod() {
let method_name = 'sayHello'
this[`${method_name}`]("Zeal Nagar!")
}
}
If You need it in module scope, You can use something like this
var module = require('moduleName');
module['functionName'](arguments);
Honestly, looking at all these answers they seem a bit too much work. I was playing around to look for other ways around this. You can use the eval() command to print a variable as text then call it as a function
I.e
let commands = ['add', 'remove', 'test'];
for (i in commands) {
if (commands[i] == command) {
var c = "proxy_"+command;
eval(c)(proxy);
}
}
eval(string)(arg1, arg2);
This example script would execute the function proxy_test(proxy)
You know, the OP's code inspired me to try this:
global.test = function(inVal){
console.log(inVal);
}
global['test']('3 is the value')
But now that I think about it, it's no better than #Ravi' s answer.
I use this for node, see if this approach works for you
var _ = require('lodash');
var fnA1 = require('functions/fnA1');
var fnA2 = require('functions/fnA2');
module.exports = {
run: function(fnName, options, callback) {
'use strict';
var nameSpace = fnName.toString().split('.');
// if function name contains namespace, resolve that first before calling
if (nameSpace.length > 1) {
var resolvedFnName = this;
_.forEach(nameSpace, function(name){
resolvedFnName = resolvedFnName[name];
});
resolvedFnName(options, callback);
} else {
this[fnName](options, callback);
}
},
fnA1: fnA1,
fnA2: fnA2
};
call this like
importVariable.run('fnA1.subfunction', data, function(err, result){
if (err) {return callback(err);}
return callback(null, result);
});
That is not specific to the window object. In JavaScript any property of the object can be accessed this way. For example,
var test = {
prop1 : true
};
console.log(test.prop1); // true
console.log(test["prop1"]); // also true
Read more here : https://developer.mozilla.org/en/JavaScript/Guide/Working_with_Objects
I'm using the following format to avoid possible naming conflicts.
My main aim is to keep the parts of the program in different files during development and then later combine it
Editor is the
main.js
Editor=function(){
this.manage=function(){
}
}
var editor= new Editor;
a.js
Editor.prototype.A=function(){
this.afunct=function(){
}
}
b.js
Editor.prototype.B=function(){
var this.var1;
var this.var2;
this.bfunct=function(){
//call afunct() here
}
}
A is a set of functions that does some testing,modification etc.
afunct is a tester function which needs to be used in all the other files.
B is supposed to act as a data package and new instances of it will be created to pass around.
How will I call afunct inside bfunct?
Please help me understand how I can do this. Thank You in advance.
PS. I'm kind of a newbie in Javascript and please pardon any flaw in my logic.
It's obscure, but this might do it:
(function() {
var Editor = function() {
};
Editor.prototype = {
A: {
afunct: function() {
// Other functionality here.
}
},
B: {
bfunct: function() {
Editor.prototype.A.afunct.call(this);
}
}
};
window.Editor = Editor;
})();
var editor = new Editor();
editor.B.bfunct();
From inside B this should work
Editor.A.apply(this)
Try this from inside Editor.prototype.B:
Editor.prototype.B=function(){
var this.var1;
var this.var2;
var self = this;
this.bfunct=function(){
//call afunct() here
self.prototype.B.afunct();
}
}