Let's say I have the following methods:
Controller.prototype.refresh = function () {
console.log('refreshing');
}
Controller.prototype.delete = function (object) {
var self = this;
object.delete({id: object.id}, function () {
self.refresh();
});
}
now in my (mocha) test:
beforeEach(function () {
var controller = new Controller();
var proto = controller.__proto__;
var object = {id: 1, delete: function (options, callback) { callback (); };
sinon.stub(proto, 'refresh', function {console.log('refreshing stub')});
controller.delete(object);
});
it('doesnt work', function () {
expect(object.delete.callCount).to.equal(1);
expect(proto.refresh.callCount).to.equal(1);
});
This, however, prints "refreshing" to the console. Is there a way to use sinon to stub a live prototype?
This is how I would do it:
describe('test', function() {
before(function() {
// stub the prototype's `refresh` method
sinon.stub(Controller.prototype, 'refresh');
this.object = {
id: 1,
delete: function (options, callback) { callback (); }
};
// spy on the object's `delete` method
sinon.spy(this.object, 'delete');
});
beforeEach(function () {
// do your thing ...
this.controller = new Controller();
this.controller.delete(this.object);
});
after(function() {
// restore stubs/spies after I'm done
Controller.prototype.refresh.restore();
this.object.delete.restore();
});
it('doesnt work', function () {
expect(this.object.delete.callCount).to.equal(1);
expect(this.controller.refresh.callCount).to.equal(1);
});
});
Related
I am trying to get the name of the parent function of the function being called.
For example if I have these functions:
var functions = {
coolfunction1: {
add: function () {
},
delete: function () {
},
save: function () {
}
},
coolfunction2: {
add: function () {
// i want to console.log() the name of the parent of this function,
// output: coolfunction2
},
delete: function () {
},
save: function () {
}
}
}
When I call functions.coolfunction2.add(), is there a way to log the name of the parent function that was run?
I know I can use the variable this but that only outputs the names of the children functions, add(), delete(), save().
How can I know that the coolfuntion2 was run?
I know this can be done manually, by rewriting the function name in the add() function, but is there a way to get the name dynamically?
You can add a getter to those methods as
Object.keys(functions).forEach(t =>
Object.keys(functions[t]).forEach(t2 => {
var func = functions[t][t2]; //save a reference to function since it won't be a function anymore once a getter is assigned
Object.defineProperty(functions[t], t2, {
get: function() {
console.log(t); //print the name of parent property or grand-parent property, etc
//func();
return func; //return the reference to this function
}
});
})
);
Demo
var functions = {
coolfunction1: {
add: function() {
},
delete: function() {
},
save: function() {
}
},
coolfunction2: {
add: function() {
console.log("a is invoked");
},
delete: function() {
},
save: function() {
}
}
};
Object.keys(functions).forEach(t =>
Object.keys(functions[t]).forEach(t2 => {
var func = functions[t][t2];
Object.defineProperty(functions[t], t2, {
get: function() {
console.log(t);
//func();
return func;
}
});
})
);
functions.coolfunction2.add();
functions.coolfunction2.add();
functions.coolfunction1.add();
When I'm declaring instance methods in JS I often use this syntax:
var MyObj = function (p1) {
this.p1 = p1;
};
MyObj.prototype = {
method1: function() {},
method2: function() {},
method2: function() {}
};
Is there a similar way to declare "static" methods instead of doing this:
MyObj.static1 = function() {
};
MyObj.static2 = function() {
};
MyObj.static3 = function() {
};
The only thing I can think of is doing it in two steps:
var staticMethods = {
static1: function () {
},
static2: function () {
},
static3: function () {
}
};
Then use this function
function registerStaticMethods(aClass, staticMethods) {
for (var methodName in staticMethods) {
aClass[methodName] = staticMethods[methodName];
}
}
You would use it like this
registerStaticMethods(MyObj, staticMethods);
Sometimes in JavaScript I need many constructors and objects for pseudo-classes because I like objective very much so I do something like:
var anyClass = (function (settings) {
var staticPrivate = {}, staticPublic = function () {
var public = this, private = {};
(function constructor (here, the, args) {
this.hta = [here, the, args, arguments];
}).apply(this, arguments);
arguments = undefined;delete arguments;
private.stuff = function () {}
Object.defineProperties(public, {
"e.g. length": {
get: function () {
return private.length;
},
set: function (newValue) {
return;
},
enumerable: false
}
});
};
Object.defineProperties(staticPublic, {
"staticFinalHiddenString": {
get: function () {
return "YEAH, I'm static and final and hidden...";
},
set: function (newValue) {
return "You cannot set me.. :P";
},
enumerable: false
}
});
staticPrivate.some = function (init) {
if (settings.some == "settings") init();
}
window.requestAnimationFrame(function () {
staticPrivate.some(function (I) {
run(on, first, render);
});
});
return staticPublic;
})({
some: "settings",
here: null
});
And that every time, so now I want a constructor that creates a new class for me. I think on this:
new Class({
constructor: function (here) {
is(my + constructor);
},
properties: {
name: {
getter: function () {},
setter: function (newValue) {},
hidden: false,
static: false,
final: false
},
version: {
getter: function () {
return 0.3;
},
setter: function (newValue) {},
hidden: true,
static: true,
final: true
}
}
});
but my problem is that I have no idea how to create an prototype/constructor with an constructor class.prototype.prototype does not work.
I just tried that:
var Class = (function () {
var Class = (function () {
var constructor = function () {
return (function (information) {
this.prototype = {};
var properties = {};
for(var key in information.properties) {
properties[key] = {
get: information.properties[key].getter,
set: information.properties[key].setter,
enumerable: !information.properties[key].hidden || true
};
};
Object.defineProperties(this.prototype, properties);
return this;
}).apply(this, arguments);
};
return constructor;
})();
return Class;
})();
That does not work for me :C
I hope you can help me. Thanks...
I understood my mistake and now I can return somthing when I have an constructor.
The var Class = function () {}; and the Class.prototype in the closure function with .apply(this, arguments) does the thing, that is why I can return Class in the constructor function, if I would just do
var Class = function () {
var ClassICreate = function () {};
...
return ClassICreat;
}
it would not work, because you cannot return from a constructor, because it is an object.
That is how it works for my:
var Class = (function () {
var Class = function () {
return (function (information) {
var Class = function () {};
var properties = {};
for(var key in information.properties) {
properties[key] = {
get: information.properties[key].getter,
set: information.properties[key].setter,
enumerable: !information.properties[key].hidden || true
};
};
Object.defineProperties(Class.prototype, properties);
return Class;
}).apply(this, arguments);
};
return Class;
})();
After I found the answer it looked so easy to me, and thanks for the comments, they helped my to find the right answer...
I have the following javascript code using http://fr.jqueryboilerplate.com/
;(function ($, window, document, undefined) {
var pluginName = "PluginName",
defaults = {
overlay: {
BgColor: "#000",
opacity: "0.6"
}
};
function Plugin(element, options) {
this.element = $(element);
this.options = $.extend({}, defaults, options);
this._defaults = defaults;
this._name = pluginName;
this.init();
}
Plugin.prototype = {
init: function () {
console.log("init");
var overlay = jQuery("<div/>", {
id: "ModalOverlay",
click: function () {
Plugin.prototype.Mymethod();
}
});
},
Mymethod: function () {}
};
Anyone could teach me how can access to variables, whose are into
function Plugin(){}
from
Mymethod: function() {}
maybe something like that :
add store object
Plugin.prototype = {
store: {
_overlay: null
}
Into init function
Plugin.prototype.store._overlay = overlay;
And then access it like :
Mymethod: function () {
console.log(Plugin.prototype.store._overlay);
},
I'm pretty sure that's work, but i think that's very dirty.
Try this code, I have not tested it. but worth try . If does not work let me know and i will delete.
Plugin.prototype = {
init: function () {
var myThis=this;
console.log("init");
var overlay = jQuery("<div/>", {
id: "ModalOverlay",
click: function () {
myThis.Mymethod();
}
});
},
Mymethod: function () {
alert(this._name);
alert(this.options);
alert(this.options.overlay);
console.log(this.options.overlay);
}
};
I'm wanting to know how to create my own custom events for my plugin and how to fire the event. My addItem function works but I don't know how to make my own custom event to work does anyone know?
$('#TreeView').Web().DropDownList().onload(function () {
alert('loaded function event');
}).click(function () {
$(this).addItem('Hello World');
});
$.fn.Web = function () {
var $this = this;
return {
TreeView: function () {
return $this.each(function () {
alert('TreeViewControl');
})
},
DropDownList: function () {
var methods = {
addItem: function () {
alert('AddItem');
}, removeItem: function () {
alert('removeItem');
}
}
return $this.each(function () {
//methods.addItem.apply(this, arguments);
for (var method in methods) {
methods[method].apply(this, arguments);
}
return this;
})
}
}
};