Sinon stub body code? - sinon

odd. if I stub a method and try to look at the stub, I don't see it. how can this be???
var myclass = {
mymethod: function( console.log('ok'); }
};
var mym = sinon.stub(myclass, 'mymethod');
console.log(mym.toString());
console.log(myclass.mymethod.toString());
what I get in the above is:
mym
mym
but I expected to see the body of the replacement function! what's going on here?

Related

calling .next() recursively from a generator

I'm going through Kyle Simpson's Rethinking Async on Frontend Masters, and in the lecture on async generators, there is an example of calling .next() recursively. The gist of it goes as follows:
function *main() {
var x = (yield setTimeout(function() {return a.next(2)},0));
console.log(x)
}
var a = main();
a.next();
Which prints 2
Correct me if I'm wrong. What I understand from this is that the encounter with yield pauses execution and waits for a value. The functionRef from setTimeout is placed on the stack and is called next, returning the value 2.
Essentially this is the same as
function *main() {
var x = yield ;
console.log(x);
}
var a = main();
a.next()
a.next(2)
Now I try to do the following, thinking the result will be the same:
function *main() {
var x = (yield a.next(2));
console.log(x)
}
var a = main();
a.next();
and it throws the error TypeError: Generator is already running
Why?
Further, I expected this to print 2 but instead in prints undefined
function *main() {
var x = yield 2;
console.log(x)
}
var a = main();
a.next()
a.next()
Evidently, yield behaves rather a bit differently when assigned to a variable versus when it is not, but I can't quite put a finger on it.

Use fibers/future for async callback client side

I have a similar code:
Template.mytemplate.pippo = function() {
var returnValue;
asyncFunc(function (dataReturned) {
returnValue = dataReturned;
});
return returnValue;
}
I have try to load future on client side
var Future = Npm.require('fibers/future');
but don't work :(
How can I wait that asyncFunc return callBack finish to return template value returnValue
thanks!
There is a bit of a question of where you should be calling asyncFunc, but once you figure that out, your code should look something like this:
asyncFunc(function (dataReturned) {
Session.set('returnValue', dataReturned);
});
...
Session.setDefault('returnValue', "loading.."); // or some other default that is safe
Template.mytemplate.pippo = function() {
return Session.get('returnValue');
}

Can I pass a function closure (with my parameters) as Firebase's set() method 'oncomplete' argument?

I want to do further processing depending on the success or failure of the set() method, but I need the context of some objects at the time I call the set() method. Otherwise my objects will be out of scope when the oncomplete function is called unless I put them in global - which I don't really want to do.
Here is an example:
function oncomplete_AddTran(tran,client,appt,balance){
/* if named argument 'balance' exists it is safe to assume
Firebase has not 'stepped on' the arguments with it's single
Error object or null */
if(balance typeof object) console.log("my parameters made it here");
}
function addTran(tran, client, appt, balance) {
var TRANS_LOCATION = 'https://xxx.firebaseIO.com/testing/transactions';
var tranListRef = new Firebase(TRANS_LOCATION);
var oncomplete = function() {
oncomplete_AddTran(tran, client, appt, balance); };
var tranref = tranListRef.child(tran.name).set(tran.literal, oncomplete);
}
Yes, it is possible. I am too impatient waiting for the confirmation I was looking for and decided to test myself. Here is the code I used (that works for my purpose):
function oncomplete_AddTran(tran,client,appt,balance){
console.log("arguments passed:" + arguments.length);
// firebase original arguments :: arguments.callee.caller.arguments
var fbargs = arguments.callee.caller.arguments;
}
function addTran(tran, client, appt, balance) {
var TRANS_LOCATION = "https://xxx.firebaseIO.com/testing/transactions";
var tranListRef = new Firebase(TRANS_LOCATION);
var oncomplete = function() {
oncomplete_AddTran(tran, client, appt, balance); };
var tranref = tranListRef.child(tran.name).set(tran.literal, oncomplete);
}
function main() {
var tran = {}; tran.name = "test1"; tran.literal = { tran: "tran" };
var client = {}; client.literal = { client: "client" };
var appt = {}; appt.literal = { appt:"appt" };
var balance = {}; balance.literal = { balance:"balance" };
addTran(tran,client,appt,balance);
}
The arguments were passed as expected but I still don't know how Firebase's set() method will pass the error object to the callback (in the event of an error) because I haven't tried reproducing an error and don't really know if I can.
The default null, and another (undefined) that is supposed to be passed when there is no error is not found in arguments.callee.caller.arguments (see callback function in example above). I am not sure that what I am doing is good practice - seems a bit hacky to me so I won't accept this answer to the question (yet).

Understanding OOP in Actionscript

A.as :
public class A {
public function getFunction():Function {
return function():void {
if(this is C) {
trace("C");
} else {
trace("not C");
}
}
}
public function func1():void {
var internalFunc:Function = getFunction();
internalFunc();
}
}
B.as :
public class B extends A implements C {
}
In some other class :
var b:B = new B();
B.func1();
Output is :
"Not C"
I was expecting the trace output to be
"C"
Can someone explain why?
An anonymous function, if called directly, is scoped to the global object. If you trace this inside it, you will see [object global] instead of [object B], as you would, if this refered to b.
A common workaround is using a closure:
var self:A = this;
return function():void {
if(self is C) {
trace("C");
} else {
trace("not C");
}
}
Please note however, the instance-members of a class defining an anonymous function are available from within. This works, because they are resolved at compile time.
edit in response to Amarghosh's question:
Yes, this points to the global object, but that doesn't mean, you cannot access the instance members of the declaring class. This little piece of code should explain the details:
package {
import flash.display.Sprite;
public class Test extends Sprite {
private var foo:String = "foo";
public function Test() {
var anonymous:Function = function ():void {
trace(foo);//foo
trace(this.foo);//undefined
};
anonymous();
}
}
}
greetz
back2dos
A few things with the code that I assume are just typos?
The getFunction() method doesn't return anything and will thus cause a compiler error.
Your call code calls func1() as a static method, not as a method on an instance of the B. This will also cause a compiler error. I believe these are typos.
In my tests, using your modified code. The output is C. There must be something else going on with your code. Here are my mods to A:
public function getFunction():Function {
if(this is C) {
trace("C");
} else {
trace("not C");
}
return getFunction;
}
Here is my mod to the runnable code, which I put in creationComplete of an empty MXML Application file:
var b:B = new B();
b.func1();
I assume your "real world" code is more extensive than the sample and there must be something else going on.

Access the function object (closure) of a setter

Assume I have the following class:
class Example
{
function set something(value:String):void
{
trace("set something");
}
function doSomething():void
{
trace("something");
}
}
I can access the functions as objects like this:
var example:Example = new Example();
var asdf:Function = example.doSomething;
// this also works - example["doSomething"];
asdf(); // this trace: "something"
You do this all the time with events, for example. So, my big question is: Is there any way to get a handle on the setter? Is there some crazy function on Object or somewhere that I don't know about (please say yes :)
I want something like the following
var example:Example = new Example();
// the following won't work, because example.something is a string
var asdf:Function = example.something;
asdf("a value"); // this trace: "something"
The statement var asdf:Function = example.something; won't work because compiler treats example.something as a getter and returns string (or throws a write-only error if the getter is not implemented).
But since something is a property, you can do something like:
example["something"] = "a value"; //will trace 'set something'
//or
var property:String = "something";
example[property] = "some value"; //will trace 'set something'
You may try this:
class Example{
function set something(value:String):void{
trace("set something");
}
function doSomething():void{
trace("something");
}
}
class AnotherClass{
function callOtherClassFunction(funcObj:Obj):void{
if (funcObj.type == "method") {
funcObj.func.apply();
}
else if (funcObj.type == "setter") {
funcObj.obj[funcObj.func] = "something";
}
else if (funcObj.type == "getter") {
trace(funcObj.obj[funcObj.func]);
}
}
}
class Test{
function Test():void{
var e:Example = new Example();
var a:AnotherClass = new AnotherClass();
a.callOtherClassFunction({obj:e, type:"setter", func:"something"});
a.callOtherClassFunction({obj:e, type:"method", func:e.doSomething});
}
}

Resources