How to print arguments' list in javascript? - javascript

Is there a way to print arguments' list in full or in parts in JavaScript?
Example:
from within the function my_assert(a!=b) I'd like to print a!=b, or even 2!=3 for a particular function call.

you can't. a!=b is executed first and only the result of this (true or false) is given to your function so you don't have a chance to get back a!=b or 2!=3.

console.log (arguments)
will print the arguments given to the function, but in your case, all your function sees is a boolean, because a != b will be evaluated first, and only the result passed as a parameter in the function call.

umm... here, I'll google it for you :)
http://www.seifi.org/javascript/javascript-arguments.html
As some others pointed out, passing in a test (a != b) will only get you a boolean value (true|false) as your argument. But if you call myAssert(a,b), you can then evaluate the arguments and test their equality, as well as print their values, following the advice in the link I pasted.

Here you go:
my_assert = (test) ->
str = my_assert.caller.toString()
match = /return my_assert\((.*)\)/.exec str
console.log match[1], test
a = '1'
b = '2'
do -> my_assert(a!=b)
do -> my_assert(b!=a)
> a !== b true
> b !== a true
http://jsfiddle.net/m7qRN/
The only caveat is you have to call your my_assert calls from separate anonymous functions in order to be able to reliably get the source code of the assertion call.
In CoffeeScript its not so bad using the do -> notation.
In JS this is: (function(){my_assert(a!=b)})();.
You could pass in the test as a function like so:
my_assert -> a!=b
my_assert(function(){a!=b});

//
// A variation on vaughan's answer, from Oct 1 '13
// Includes simple unit test to debug the regex for multiline assert expressions
// Use console.error and/or 'throw new Error' depending how you handle errors
//
function test_assert() {
try {
(function () { assert(3 === 'a') })();
(function () {
assert('foo' !== 'bar')
})();
(function () {
assert('foo' ===
'bar')
})();
} catch (e) {
console.error(e.stack)
}
} // test_assert
function assert(expression) {
if (!expression) {
let caller = assert.caller.toString()
let test = caller.match(/assert[^]*\)/)
//throw new Error(test[0] + ' failed');
console.error('%s failed', test[0])
}
} // assert
/////////////////////////////////
// Here's a simple assert()
function assert2(condition, message) {
if (!condition) {
console.error('assert (%s) failed: "%s"', condition, message)
throw new Error("Assertion failed: " + message);
}
}

You can't do it. When you have the following line:
my_assert(a!=b);
The expression a!=b will first be evaluated and its result will be passed to my_assert.
Assuming your my_assert() function is used specifically for your own testing and you can control how it works and what you pass into it you could do something like this:
my_assert(a!=b, "a!=b");
I.e., pass an extra parameter to the function with a string representation of what is being tested. Obviously that doesn't stop you accidentally saying my_assert(a!=b, "a==b");, and it's clunky, but I can't think of another way to do it.

Related

custom test function - JS

I want to create a function like below.
This is the expect function of jest. I want to create this function in Javascript.
Is this do-able??
let type = 'apple'
expect(type).toBe('apple')
//pass a string to "expect" function and it checks with 'toBe' function if the string is similar
Update: I know we can do something like below but i am unable to do something like this "expect().toBe()"
var Expect = Expect || {};
Expect.String = function() {
var toBe = "tobe";
var toBe = function() {
console.log("toBE function");
};
return {
toBe: toBe
}
}()
Expect.String.toBe(); // this will log "toBe function"
This is just a small example of what you are likely going for. You want expect to be a function that returns an object where one of the keys, toBe, is a function. In this example, I just have it returning true or false depending on whether the actual equals expected value.
function expect(actual) {
return {
toBe: function(expected) {
return actual === expected;
}
}
}
console.log(
expect("foo").toBe("foo")
);
console.log(
expect("foo").toBe("bar")
);
It is recommended to not reinvent the wheel, but since you are already there, here is what I recommend in a nutshell:
The function expect() takes a first thing(a.k.a actual) and returns an object that contains yet another function: toBe()
The function toBe() takes second thing (a.k.a expected) as a parameter, uses some form of comparator against the first thing, and returns a boolean
For simplicity, the comparator can be ==
Based on these three elements, Your re-invented expect() function can take the alike of the following shape:
function expect(actual){
return {
toBe: function(expected){
return actual == expected;
}
}
}
The actual implementation is a little more complicated than this answer ~ For the real-world implementation of expect in Jest is at this GitHub address
The "matchers" (as they call alikes of toBe(), toEqual(), etc) can also be found in this source code

What does Return do in here?

I have problem with 'return' means in this code.
1.
function func4() {
var str = "function works.";
console.log(str);
}
func4();
2.
function func4() {
var str = "function works.";
return str;
}
var value = func4();
console.log(value);
Both of them, their result is 'function works.'.
I know that return used for exit function but I'm still confuse when I have to use return exactly.
Sorry about my super basic question :(
As far as I understand 'return' assigns value to a function and returns it, so you're displaying function's value. In the first case you are just simply invoking a function to display a string.
Let's analize this two scenarios:
You have a function that initialize a variable with a predefinided value, and then, you log the value. Then, outside the function you execute it
You have the same variable but with the difference that instead of loggin the value inside the function, you returned it from it. So you can initialize the funcion and store the value on another variable var value = func4();.
Let me try to explain it with some requirements.
I want a function which returns me some data instead of passing a variable and updating the variable in function.
You call a function and it is always best to test negative scenarios first. So in case of negative scenario you can return it from there it self.
In your second case if you see you are getting a value from that function and then printing it. Same thing you can not do using first function.
Always there are workarounds for everything. In the end it depends on your need and what is best suited for that situation.
Both of those functions don't equal the same thing, but they do log the same string.
func4() in #1 is equal to undefined, because it returns nothing.
func4() in #2 returns (gives back) the value "function works.", a string, which is then given to console.log outside of the function.
function func1() {
var str = "function works.";
// console.log(str);
}
func1();
function func2() {
var str = "function works.";
return str;
}
// console.log(func2());
console.log(func1() === undefined);
console.log(func2() === 'function works.');
If you want to use the func4() value for further calculations without calling it again, then you would return {value}.
For e.g
function func4(userInput) {
return userInput % 2 == 0;
}
var response = func4(userInput);
if(response == true) {
console.log('user entered an even number');
} else {
console.log('user entered a odd number');
}
// from here you can use the value of response n times without calling the function again.
Whereas, if you don't return then you will have to call the function x number of times whenever you want to re-user the response of it.
function func4(){
var str = "function works.";
return str;
}
var value = func4();
console.log(value);
//here return means you are returning the value of variable 'str'.
You can find the details here.
https://learn.microsoft.com/en-us/cpp/c-language/return-statement-c?view=vs-2019#:~:text=A%20return%20statement%20ends%20the,value%20to%20the%20calling%20function

Writing JavaScript tests that test other functions are called, without actually calling them

I have been tasked with writing unit tests for some AngularJS code that was written by another team, who didn't write any tests
They have written the following function but I cannot figure out how to test it
function showCallAlerts(callRecord, isInEditMode, callBack) {
var callAlerts = populateCallAlertOnEditCall(callRecord.callAlert);
var callModalInstance = openAlertModalInstance('Call', callAlerts, callBack);
if (callModalInstance !== undefined && callModalInstance !== null) {
callModalInstance.result.then(function() {
// Show equipment alerts based on company details
showEquipmentAlertsBasedOnCompanyDetails(callRecord, isInEditMode, callBack);
});
} else {
// Show equipment alerts based on company details
showEquipmentAlertsBasedOnCompanyDetails(callRecord, isInEditMode, callBack);
}
}
I need to test that each of the functions are called, not worrying about what they do as I'll test them separate, just that they are called.
When populateCallAlertOnEditCall is called it needs to either return an empty array or an array with some items in it
When openAlertModalInstance is called it needs to either return undefined or something that passes through to showEquipmentAlertsBasedOnCompanyDetails
showEquipmentAlertsBasedOnCompanyDetails should actually be called, I'll test that method separate, just that it was called
I have manged to write code to test simple functions but nothing like this one so any help will be much appreciated, I spent most of this afternoon trying to figure it out
You can use jasmine to mock the function calls that you are not interested in testing. For example, you can tell jasmine to return an empty array every time 'populateCallAlertOnEditCall' is called. I will write an example that might give you an insight:
describe('My Test Spec', function() {
var myController;
...
beforeEach( inject(($controller) => {
myController = $controller("myControllerName");
}));
it('Testing showCallAlerts when populateCallAlertOnEditCall returns an empty array', inject(function($controller) {
//setup
//this will replace every call to populateCallAlertOnEditCall with
//the function inside callFake
spyOn(myController, 'populateCallAlertOnEditCall ').and.callFake(function() {
return []; //returning an empty array.
});
//action
myController.showCallAlerts(...);
//assert
//Do your checking here.
}));
it('Testing showCallAlerts when populateCallAlertOnEditCall returns a non-empty array', inject(function($controller) {
//setup
//this will replace every call to populateCallAlertOnEditCall with
//the function inside callFake
spyOn(myController, 'populateCallAlertOnEditCall ').and.callFake(function() {
return [1,2,3,4]; //returning a non-empty array.
});
//action
myController.showCallAlerts(...);
//assert
//Do your checking here.
}));
});
the test that something has been called, you can use a Spy
your assertion would look like:
spyOn(obj, 'populateCallAlertOnEditCall')
expect(obj.method).toHaveBeenCalled()
UPDATED:
populateCallAlertOnEditCall = {}
spyOn(obj, 'populateCallAlertOnEditCall.result')
expect(obj.method).toHaveBeenCalled()
The kind of behaviour you want is called mocking
In Jasmine, mocking is done with Spy Objects, you can read more about those here
Basically, you can use mocks to test if functions were called with the expected parameters.
var xhr = mock( XMLHttpRequest );
xhr.send();
expect( xhr.send ).toHaveBeenCalled();

Why does this JavaScript function always returns 'undefined' – and how to fix that?

I'm using phonegap with application preferences plugin and trying to make a helper function to get a value from it. However the function is not returning a correct value. I know this has to do with asynchronous thingy but unfortunately I don't know how to fix it. (I've tried to search help here, and found little, and tried to implement it in helper method)
What I want to achieve is:
function populateList() {
var a = 1;
var number = getSettingFromApplicationPreferences('number');
// number is always undefined
var letter = getSettingFromApplicationPreferences('letter');
// letter is always undefined
number = (number) ? number : 1;
letter = (letter) ? letter : 'b';
// Here I'll do some DOM manipulation and use 'number' and 'letter' on it, and
// define new variables based on 'number' and 'letter'
}
here's the helper function that I need help with:
function getSettingFromApplicationPreferences(setting) {
var x = (function () {
window.plugins.applicationPreferences.get(
// setting
setting,
// success callback
function(returnValue) {
console.log(setting + ': ' + returnValue);
return returnValue;
},
// error callback
function(error) {
alert("Failed to get a setting: " + error);
return false;
}
);
})();
return x;
}
Question
How is it possible to return the 'returnValue' from application preferences with that helper function?
The problem is, your callback doesn't actually set a value for x. So, you're going to have some other way to do whatever you're doing, because return values will not work.
You are using an asynchronous function incorrectly, you cannot assign like you are because the function hasn't returned yet and so you get an undefined. You need to use a callback function instead.
That means that inside the success function you would do whatever you need to do with the "returnValue".

Generating a function from a string in Javascript

I am using jQuery to take data from an xml file and save it to a string. The string is a switch statement which I want to become a function.
$.get('type.xml', function(xml) {
var cases=[];
$(xml).find('type').each(function(){
index=parseInt($(this).find('earn').text());
if($.isArray(cases[index])){
cases[index].push($(this).find('name').text());
}else{
arr=$.makeArray($(this).find('name').text());
cases[index]=arr;
}
});
var autoearn="function(x){switch(x){";
for(i=0;i<=100;i+=5){
if($.isArray(cases[i])){
$.each(cases[i], function(index,v){
autoearn+='case "'+v+'":';
});
autoearn+='$("input[name^=\'earn\']").val('+i+');break;';
}}
autoearn+='}}';
});
The first section makes a 2D array that associates an array of cases to their resultant output by their index. So that something that earns $10 (e.g. Meeting) will be stored in cases[10] (Meeting=cases[10][0]).
The second part writes a string that makes a puts into a switch statement that looks something like this:
function(x){
switch(x){
case "Meeting":
$("input[name^='earn']").val(10);
break;
case "Event1":
case "Event2":
$("input[name^='earn']").val(20);
break;
}
}
Note that the syntax for the switch cases make Event1 and Event2 have the same result.
Now autoearn is just a string that has the code for the function I want. How do make into a function? Is there a better way to do this? I'm thinking of sending it through PHP to return it back to jQuery but this whole thing seems really indirect and there is probably an easier way to do this.
First of all, make sure the code in the string is trusted, or you'll run into problems by executing arbitrary code.
You can create a function from a string as follows:
var f = new Function('arg1', 'arg2', ..., 'function code');
The above is equivalent to:
function f(arg1, arg2, ...) {
function code
}
In your case, you would want to remove the function(x) and the opening/closing braces from the autoearn string and create the function like this:
new Function('x', autoearn)
Here's a small piece of code to take a script from a string and execute it:
function loadScript(script) {
var func = null;
if (script) {
try {
func = new Function(script);
} catch (eParse) {
console.error("Error parsing script.");
console.debug(" error : %o", eParse);
console.debug(" script: %s", script);
}
}
if (func) {
try {
func(); // beware of scoping here, you might want to call this differently
} catch (eExec) {
console.error("Error running code.");
console.debug(" error : %o", eExec);
}
}
}
BEWARE: Using new Function is basically as dangerous as using an eval statement. Be sure of what you receive for the script parameter.

Categories