Test individual line in javascript unit testing - javascript

I have a javascript function like this
function formatInput(input) {
//want to test only this immediate statement
var type = input.ipType.toString().toLowerCase().trim();
var afterVormat = someFunction(type);
return afterFormat;
}
I am able to test this function(value of afterFormat) correctly , but is it possible/how to test a specific line in function since I am not returning type.
For example I want to test if var type is as it is expected

Is it possible/how to test a specific line in function?
The immediate answer: no.
The solution
One of the outcomes of adhering to TDD is that it forces you to build code in isolated, testable blocks. This is a direct consequence of the fact that you cannot perform test(s) of the individual lines of a function. In your case the solution is to restructure your code to:
var type = function(){
return input.ipType.toString().toLowercase().trim();
};
function formatInput(input) {
var type2 = type();
var afterVormat = someFunction(type);
return afterFormat;
}
Now you have made type an isolated block that you can test.
If you combine this with use of Sinon.JS you can use a spy to test that an invocation of function formatInput() will also result in the invocation of type() and thereby you know for sure that var type2 has been assigned the intended value.

I’m not aware of any specific and more advanced unit testing method/system for javascript, but you can have a simple assertion function to test individual lines of code for debugging purpose like this:
function assert(condition, message) {
if (!condition) {
message = message || "Assertion failed";
if (typeof Error !== "undefined") {
throw new Error(message);
}
throw message; // Fallback
}
}
(Code taken from TJ Crowder's answer to another question.)
Then you can just use it to check for instance the var type like this:
assert(type == "something expected here and shall throw an error otherwise");

You can use console.log() function for that. As below.
function formatInput(input) {
var type = input.ipType.toString().toLowerCase().trim();
console.log(type);
var afterVormat = someFunction(type);
return afterFormat;
}
Also you can use debugger; also, to debug the code line by line.
function formatInput(input) {
var type = input.ipType.toString().toLowerCase().trim();
debugger;
var afterVormat = someFunction(type);
return afterFormat;
}
and just press F10 key to debug the code and you can check the values in console.

Related

How to use Teaspoon for JS testing

I'm new to JS testing and I would like to understand how to test a JS function I have. I'm using Teaspoon-mocha as the testing library and the function I would like to test is:
var C_FORM = "http://www.exmple.com/SomeForm#Form";
function getNamespace(uri) {
var parts = uri.split("#");
if (parts.length == 2) {
return parts[0];
} else {
return "";
}
}
I would like to have an example how to test this specific function.
This function actually getNamespace from the final part of a specific URI which is defined by that var C_FORM so the result is that is getting the namespace which is Form.
I would like to test this function if it is doing this by Teaspoon but as above I'm not familiar with this kind of testing, I need just an example to get familiar.
I tried the next solution but I get that equal is undefined:
describe("Application", function() {
it("Gets Namespace", function() {
var uri = "http://www.test.com/SomeTest#Test";
expect(getNamespace(uri).to.equal("http://www.test.com/SomeTest"))
})
});
Please try this way:
expect(getNamespace(uri)).to.equal("http://www.test.com/SomeTest")

ES6 Proxies: trapping undefined function executions

Let's say I have the following object with two functions as properties:
const foo = {
f1: () => {...},
f2: () => {...},
}
I would like to perform a specific action (for example, throw a custom error) when someone tries to execute a function that doesn't exist on the foo object.
I've tried using a get proxy, but that throws an error even when I'm not trying to execute f3, such as in the following code:
if (foo.f3) {...}
So how can I write my proxy in such a way that foo.f3 returns undefined as it usually would, but foo.f3() does throw an error?
Here's a partial solution, inspired by Unmiss.
const handler = {
get: function(obj, prop) {
if (prop in obj) {
return obj[prop];
} else {
return () => {
throw new Error(`Foo.${prop} is undefined`);
}
}
}
};
The problem with this is that while it accomplishes the goal of only throwing an error when you actually try to execute Foo.f3(), since Foo.f3 is now equal to that anonymous function is doesn't return undefined anymore, meaning that (as far as I can tell) if (Foo.f3) {...} will always return true.
Edit: as #paulpro points out:
You absolutely cannot do that. foo.f3 is either undefined or some
callable with custom logic; it cannot be both.
The best we could do is trap f3 in foo statements using the has trap, but this would mean if (f3 in foo) and if (foo.f3) would now have different results, which seems like a big red flag.
Is this what your asking for?
https://jsfiddle.net/MasterJames/bhesz1p7/23/
[obviously you need to F12 your dev tools to see the console output or change as desired]
Only real difference is to return undefined after throwing. It's as if the function executed without doing anything since it doesn't exist.
I'm sure there's a different solution based on the actual use case, but I like the idea/question. Keeps things more stable etc.
let foo = new Proxy(
{
f1: function (val) {
console.log(' F1 value:' + val);
return 'called OKAY with', val;
}
},
{
get: function(obj, prop) {
console.log("obj:", obj, " prop:", prop);
if (prop in obj) {
console.log("Found:", prop);
return obj[prop];
}
else {
console.log("Did NOT find:", prop);
throw new Error(`Foo.${prop} is undefined not called returning undefined`);
return undefined;
}
}
});
console.log("\nFoo Tester started");
console.log(' Does F1 exists', foo.f1 !== undefined);
console.log(' called F1 result:', foo.f1('passed') );
try {
console.log(' Does F2 exists', foo.f2 !== undefined);
console.log(' called F2 result:', foo.f2('passed') );
}
catch (err) {
console.log(' Error calling F2:', err );
}
console.log("Foo Tester finished");
Not sure you want to try-catch or not that's also up to you so in the end checking if it's real and a function is the same difference depending on how your going to handle the error.
if (foo.f2 && foo.f2.constructor === Function && foo.f2()) console.log("okay!");
Again you call build a safeCall wrapper more like this or something in between?
possible calling foo's 'customThrow' if it exists or what-have-you, so many possibilities with JS.
Okay so it took me sometime but I have a solution now.
I was not fully understanding your question, which I reformulated as a question within the question for myself to understand the issue better as it is complicated.
Basically you want to know if it's being called or not so the function you need in the proxies 'get' is 'isCalling'.
The solution is not clean in JS Fiddle because it's messy there at least for this kind of problem's solution.
Basically the solution is a sentence is, "you have to use an error to get a stack trace then retrace the source code that is calling and look for a right bracket or not.", to determine how it's being called and return whatever you want then).
[Please note this depends on your code and how you call it so you would adjust as needed.]
Since you have to find the location in the source code that's being called from it's way better if there is no inline script tag as is the case in this JSFiddle example. I'm using outerHTML to get the source, when arguments.callee.caller.toString() is better from an actual JS file. You'll also not the location from the stacktrace is skewed by odd behavior here, so with a normal JS file the code would align properly using other solutions are recommended. If anyone knows how to get a clean source that aligns with the error trace every time with script-tag blocks etc. Also note coming but not existing yet are things like Error.lineNumber.
[Please don't bother with the version history it was a nightmare to sort this one out. And again you would be better to use other npm packages to do the source code from stack trace parts.]
Anyway the example I believe achieves what you want but in principle demonstrates what you'd need to do better in a given real (no Fiddle) situation. I'm pretty sure doing this is not a great solution in production either and I've not tested the timing (performance speed) but if it really was that important to your cause (and no other better solution which I doubt) then it will work.
Originally I discovered this technique when I was doing something experimental, and instead of just sending another argument I was checking to see what was actually calling it and adjusting the functions action depending.
Usages are extensive when you start to think more about it as I did last year when I first did something like this. Examples are as an extra function execution Security Check, Realtime mystery-bug Debug Solution, a way to execute the function differently without passing more arguments, runaway recursive loops (how long is the stack), to name a few.
https://jsfiddle.net/MasterJames/bhesz1p7/90/
let foo = new Proxy(
{
f1: function (val) {
console.log(' F1 value:' + val);
return 'called OKAY with', val;
}
},
{
isCalling: function() {
let stk = new Error();
let sFrms = this.stkFrms(stk.stack);
console.log("stkFrms:", sFrms);
//BETTER From real pure JS Source
//let srcCod = arguments.callee.caller.toString()
let srcCod = document.getElementsByTagName('html')[0].outerHTML.split("\n");
let cItm = sFrms[(sFrms.length - 1)];
if(cItm !== undefined) {
let cRow = (parseInt(cItm[1]) - 3);
let cCol = (parseInt(cItm[2]) + 1);
let cLine = srcCod[cRow];
let cCod = cLine.substr(cCol, 1);
if(cCod === '(') return true;
}
return false;
},
stkFrms: function (stk) {
let frmRegex1 = /^.*at.*\(.*\:([0-9]*)\:([0-9]*)\)$/;
let frmRegex2 = new RegExp(frmRegex1.source, 'gm');
let res = [], prc, mtch, frms = stk.match(frmRegex2);
for(mtch of frms) {
prc = frmRegex1.exec(mtch);
res.push(prc);
}
return res;
},
get: function(obj, prop) {
if (prop in obj) {
console.log("Found:", prop);
return obj[prop];
}
else {
if(this.isCalling() === false) {
console.log("Did NOT find:", prop);
return undefined;
}
else {
console.log("Did NOT find return custom throw function:", prop);
return function() {throw new Error(`Foo.${prop} is undefined`);}
}
}
}
});
console.log("foo.f1:", foo.f1);
console.log("foo.f1('passed'):", foo.f1('passed'));
console.log("foo.f2:", foo.f2);
try {
console.log("foo.f2('passed2'):", foo.f2('passed2'));
}
catch(err) {
console.log("foo.f2('passed2') FAILED:", err);
}
console.log("'f2' in foo:", 'f2' in foo);
Okay so a verbal run through:
You want to check foo.f2 is undefined so it returns that because it's not being called.
If you do call it (f2) without simply checking first and erroring as needed, and you don't want to try-catch to throw your custom error based on the function name, you want it to return an actual function that will throw a custom error.
You also want to use 'in' to see that it's undefined, which is the same as false (maybe hack it further to send false instead of undefined via something like isCallingFromIn too.
Did I miss anything? Is this not what you all thought was impossible?

Console integration: get number of errors/warnings thrown?

So if you open up the inspector, you get this (if you're unlucky):
I'm building a tiny JS component which displays debugging information - is there any way to read the number of encountered errors and warnings so far?
A hacky solution I could come up with involves a bit of trickery by replacing the console.(error|log|warn) functions with my own, but I'm yet to test if it works for all cases (e.g. outside of code I own).
Is there a better way to do this?
As noted in this answer, it's generally not a good idea to change the behavior of native objects/methods. However, the following code should get you what you need in a fairly innocuous manner:
// Add this IIFE to your codebase:
(() => {
// Get all of the property names of the console:
const methodsToTrack = Object.keys(window.console);
// Create an object to collect total usage tallies in:
const usageRegistry = {};
for (let i = 0, j = methodsToTrack.length; i < j; i++) {
let methodName = methodsToTrack[i];
// If the property is not a method, don't touch it:
if(typeof window.console[methodName] !== 'function') {
continue;
}
// Cache the original console method here:
let consoleMethod = window.console[methodName];
// Overwrite console's method to increment the counter:
window.console[methodName] = function () {
// Defining registry properties here, so the registry only contains values for methods that were accessed:
usageRegistry[methodName] = usageRegistry[methodName] || 0;
// Execute the original method's behavior, capturing the returned value (if any) in a var, to return it at the end:
const returnedValue = consoleMethod(...arguments);
// Increment the usage registry for the executed method:
usageRegistry[methodName]++;
// Return the value the console's method would have returned, so the new method has the same signature as the old.
return returnedValue;
};
}
// Define a funciton to output the totals to a console log, then clean up after itself:
window.showConsoleTallies = function () {
window.console.log(usageRegistry);
usageRegistry['log']--;
}
})();
// Examples:
showConsoleTallies();
console.log('log 1');
console.error('error 1');
console.log('log 2');
console.warn('warn 1');
console.error('error 2');
console.log('log 3');
showConsoleTallies();
PS: That's the ECMA6 version, but feel free to run it through Babel if you'd like it to be compiled for use in older browsers.

javascript: dynamic call of nested function

in an existing implementation (can't change the structure much), i'm trying to call a function which is nested inside another function:
function outer(innerFunction, obj) {
//TODO: call innerFunction here, passing obj as first parameter
function inner1(obj) {
alert(obj.key);
}
}
outer('inner1', {key:'value'});
jsfiddle is here: http://jsfiddle.net/tbyyw/
i've alreay thought about using eval(), but i don't know how to pass an object - and they say 'eval is evil' ;)
another solution i've come up with is checking the innerFunction string, but this means i have to know which inner functions exist (besides, adding new functions would mean having to write extra checks then):
if(innerFunction == 'inner1') inner1(obj);
so is there another way without changing the overall implementation?
Without changing the overall structure eval appears to be the only option:
function outer(funcName, obj) {
var func = eval(funcName);
func(obj);
function inner1(obj) {
alert(obj.key);
}
}
There's nothing particularly "evil" about eval as long as you have full control over the code, but if you want, you can insert an additional security check:
if (funcName.match(/\W/))
throw "invalid function name!";
var func = eval(funcName);
This will raise an exception if someone tries to pass anything else than a simple identifier, i.e. a function name.
Is this what you wanted?
function outer(innerFunction, obj) {
var fn = {
inner1: function (obj) {
alert(obj.key);
}
};
fn[innerFunction](obj);
}
outer('inner1', {key:'value'});
http://jsfiddle.net/tbyyw/1/
A simple switch statement would be least intrusive. Or is the function name completely dynamic?
function outer(innerFunction, obj) {
switch (innerFunction) {
case "inner1": inner1(obj); break;
}
function inner1(obj) {
alert(obj.key);
}
}
outer('inner1', {key:'value'});
​

console.log does not print undefined?

I am new to Javascript. I am trying to understand where "this" is bound to using different examples. I am using console.log to print some values as shown below.
function FuncObject(value) {
this.answer = value;
this.get_answer = function () {
return this.answer;
}
};
var f = new FuncObject(42);
var fanswer = f.get_answer;
console.log(fanswer())
console.log prints "function" instead of "undefined". document.writeln seems to print "undefined" which is the right one because this is bound to the window object which does not have answer. Now printing function confuses me. Now I am wondering what i should be using for logging. I am unable to find an explanation for this.
thanks mohan
Just incase you didn't notice, there's a typo in your posted code of
this.get_answer = funcition ()
With that in mind, I'm not entirely sure of your experience level so let me cover all the bases.
function FuncObject(value) {
this.answer = value;
this.get_answer = function () {
return this.answer;
}
};
var f = new FuncObject(42);
var fanswer = f.get_answer;
console.log(fanswer())
You're setting fanswer = f.get_answer where f.get_answer is a function, so as such it sets fanswer to the function equivalent of this.get_answer.
If you want the return value of f.get_answer you need to call f.get_answer(), which returns 42.
With what you put, console.log(fanswer()) does print undefined as expected.
If you simply do console.log(fanswer) it records it as function, also as expected.
I'm not sure why you would receive function as you stated in your question, because I definitely do not, jsbin.

Categories