Ever needed to debug how your Class instances fire Events? It can be frustrating and messy, especially if you do not have access to the original Class prototype source. But, you can hack your way around this and create a transparent spy on all fireEvent methods on any Class instance. Here is how:
(function() { var spyId = 'spyEvent'; Class.extend({ addEventSpy: function (instance) { /* accepts one argument - Class instance. works by adding a local fireEvent method on the instance instead of going TO proto chain to Class.Event::fireEvent */ // check if there's a local fireEvent method or already installed spy if (instance.hasOwnProperty('fireEvent') && instance.fireEvent.name == spyId) { console.log('ERROR: Already have a local fireEvent method'); return; } // Events need to be mixed in. if (!instance.fireEvent) { console.log('ERROR: Can only spy on class instances with an Events mixin'); return; } // store original var orig = instance.fireEvent; instance.fireEvent = function spyEvent() { // log to console or do your own observer logic console.log('EVENT SPY', this, 'fired', arguments); // allow chaining. return orig.apply(this, arguments); }; }, removeEventSpy: function(instance) { // clean up that restores orignal if possible. // not needed? already using proto one. if (!instance.hasOwnProperty('fireEvent')) return; // it has a local fireEvent but it needs to be our spy, else it's unsafe. if (!instance.fireEvent.name || instance.fireEvent.name != spyId) { console.log('ERROR: Somebody else has done this fireEvent'); return; } // remove it. delete instance.fireEvent; } }); }());
This is the setup code. Now, you can use it on a Class and test it:
// define a class that uses events var a = new Class({ Implements: Events, initialize: function() { this.events = 0; }, doEvent: function() { this.events++; console.log('do event', this.events); return this.fireEvent('awesome'); } }); // make the instance var b = new a(); // subscribe to all events Class.addEventSpy(b) // try firing 2 quick events b.doEvent().doEvent(); // clean up spy. Class.removeEventSpy(b); // test spy is gone. b.doEvent();
I hope it is of some use to you. See it in action in this fiddle
GitHub flavoured markdown enabled.