Say I have the following broken example function in a google-apps script. The function is intended to be called from a google sheet with a string argument:
function myFunction(input) {
var caps = input.toUpperCase()
var output = caps.substrin(1, 4)
return output
}
While this example script should break on line 3 when you select myFunction and press debug, as there is no such method as "substrin()," it will break on line 2, because you can't put undefined in all caps:
TypeError: Cannot call method "toUpperCase" of undefined. (line 2,
file "Code")
Question:
Is there an official way to pass a string to a google-apps script for testing/debugging without making an additional function
function myOtherFunction() {
myFunction("testString")
}
and debugging that?
The function as you wrote it does need a parameter and there is no way to avoid that except by including a default value in the function itself. See example below
function myFunction(input) {
input= input||'test';
var caps = input.toUpperCase();
var output = caps.substrin(1, 4);
return output;
}
Related
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.
the following code works perfect of Firefox but crashes on Chrome, with the following error: Uncaught TypeError: Property 'pos' of object [object Object] is not a function
Here is the code, with comments:
var CantidadMenu = $('div[class^=container_menu_]').length;
var position = $("#menu_unidades").position();
var IzAdd = 0;
var w = $("#menu_unidades").width();
var h = $("#menu_unidades").height();
for (i=0;i<CantidadMenu;i++){
var pos = 'pos'+(i+1); //I create a variable that will hold a string like: pos1,pos2...
IzAdd = IzAdd+25;
function pos(div){ //on this line I use the variable I created, which crashes on Chrome
var estilo1 = $(div).css({'left':IzAdd+25,'top':position.top+(IzAdd-25)});
return estilo1;
}
pos('.container_menu_'+(i+1));
$('.container_menu_'+(i+1)).css({'z-index':297+i,'width':w,'height':h});
}
Here you define a function named pos:
function pos(div){ //on this line I use the variable I created, which crashes on Chrome
var estilo1 = $(div).css({'left':IzAdd+25,'top':position.top+(IzAdd-25)});
return estilo1;
}
console.log(pos) // function ....
Here you overwrite it with a string:
var pos = 'pos'+(i+1);
console.log(pos) // string....
You should name either the function or the string to something else.
PS: I know that in your code the order is reversed, but function declarations are hoisted to the top of the scope, so the JS interpreter "sees" them in the order i wrote them in: first function, then the string.
PSS: The crash is actually on this line:
pos('.container_menu_'+(i+1));
function pos(div) is the same as var pos = function(div)... (except the former is defined at the parse-time, and the latter at the run-time, but that's irrelevant for your code), so if you expected by defining that pos = 'pos1';, for example, you'd get function pos(div) to become function pos1(div), it won't.
It will just overwrite the pos variable, and it will no longer be a string, but a function.
To fix your code, write a single function at the top of your code, outside of the for loop, add another parameter to it (IzAdd) and make sure you fix the function calls appropriately.
The function should look something like this:
function pos(div, IzAdd){
return $(div).css({'left':IzAdd+25,'top':position.top+(IzAdd-25)});
}
I am attempting to ExternalInterface.call() from inside my SWF.
Note the call comes from inside a SWF I have embedded into another SWF (the _root SWF I have no control over).
Here is my JavaScript:
function player_DoFSCommand(command, args)
{
args = String(args);
command = String(command);
var arrArgs = args.split(g_strDelim);
switch (command)
{
case "CC_ClosePlayer":
console.log("yo");
break;
default:
// alert(command);
break;
}
}
Here is my AS2 code:
import flash.external.ExternalInterface;
var quiz = _root;
quiz.g_mcFrame.mcFinish.swapDepths(quiz.getNextHighestDepth());
quiz.g_mcFrame.mcFinish._visible = false;
quiz.oSlide.m_oInteraction.m_oVariableMgr.m_arrBoolResumeData = false;
var arrVars:Object = quiz.oSlide.m_oActionHandler.m_oFrame.m_oVariableMgr.m_arrVariables;
var args:Array = [
arrVars[2].m_nNumber, // Points awarded
arrVars[3].m_nNumber, // Max points
arrVars[5].m_nNumber, // Pass percentage
arrVars[6].m_nNumber, // Pass points
arrVars[7].m_nNumber, // Score percent
arrVars[10].m_strString // Result
];
ExternalInterface.call('player_DoFSCommand("CC_ClosePlayer", args)');
ExternalInterface.call('console.log("hello")');
The problem is ExternalInterface.call('player_DoFSCommand("CC_ClosePlayer", args)') doesn't work, or atleast "yo" doesn't appear in the console as expected.
The script is definitely loaded by the time the ExternalInterface is called. The second call works and "hello" appears in the console, however the first function doesn't fire.
I can verify the function works by typing directly into the console player_DoFSCommand("CC_ClosePlayer", args) and it logs successfully.
Can you verify that allowScriptAccess is set to true in the embed code?
Try this:
var isAvailable:Boolean = ExternalInterface.available;
trace(isAvailable);
You also want to use ExternalInterface like this, with your arguments passed as the second variable:
ExternalInterface.call("player_DoFSCommand",args);
or
ExternalInterface.call("console.log","testing...");
I want to pass the result of a js function into actionscript when the js function is called from actionscript. The js parses a url and returns the var in the url.
In actionscript the functions are declared:
function gup(name1:String) :void {
flash.external.ExternalInterface.call("gup", name1);
}
function printAlert(group2:String) :void {
flash.external.ExternalInterface.call("printAlert", group2);
}
then later in actions I call gup() which should return the var which I turn around and print as an alert to check what value is there. "group" is the name of the var I want to get out of the url to use for branching in the swf. If I just define whichGroup the alert works fine. trying to get the return value of the js function the alert value is null
var whichGroup = gup("group");
printAlert(whichGroup);
ActionScript
function printAlert(group2:String):void {
var retValue:String = ExternalInterface.call("printAlert", group2);
trace(retValue);
}
javascript:
function printAlert(grp) {
return "Received group " + grp;
}
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.