Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Javascript Test Driven Development is between us (Workshop)

Marco Cedaro
September 29, 2011

Javascript Test Driven Development is between us (Workshop)

Javascript & browsers have been for years a complex and unsafe environment for a web developer, now we have the right tools to gain control on what we are distributing in our web applications. During the workshop you will learn first-hand basic Javascript Test Driven Development practices including testing, refactoring and related agile practices such as continuous integration and pair programming.

From The Front, Back To The Front (Cesena, Sept 29th, 2011)
@cedmax
http://cedmax.com

Marco Cedaro

September 29, 2011
Tweet

More Decks by Marco Cedaro

Other Decks in Programming

Transcript

  1. Who are we? Marco Cedaro javascript pirate, arr Spreaker Frontend

    Developer Luca Lischetti 8-bit lover and super hero (almost) Shazam Frontend Developer
  2. Who are we? Marco Cedaro javascript pirate, arr Spreaker Frontend

    Developer Luca Lischetti 8-bit lover and super hero (almost) Shazam Frontend Developer The content of this workshop do not necessarily reflect the opinion of authors employers
  3. Who are we? Marco Cedaro javascript pirate, arr Spreaker Frontend

    Developer Luca Lischetti 8-bit lover and super hero (almost) Shazam Frontend Developer The content of this workshop do not necessarily reflect the opinion of authors employers Authors employers are not responsible in any way of authors bad coding and funny spoken english
  4. Unit testing is supposed to test a single atomic “unit”

    of functionality without dependencies on anything else
  5. This is where you start to run into serious dependency

    problems due to the interrelation HTML and CSS Unit testing is supposed to test a single atomic “unit” of functionality without dependencies on anything else
  6. This is where you start to run into serious dependency

    problems due to the interrelation HTML and CSS Unit testing is supposed to test a single atomic “unit” of functionality without dependencies on anything else What do you test? Usually how the user interface responds to user input. Actually, the realm of functional testing
  7. Write a new test Run test & let it fail

    Write the code Run test & let it succeed
  8. Write a new test Refactor your code Run test &

    let it fail Write the code Run test & let it succeed
  9. _$ = (function() { var registered = {}; return {

    ! ! notify: function(event, memo) { ! ! ! if (registered[event] instanceof Array){ ! ! ! ! var handlers = [].concat(registered[event]); ! ! ! ! for (var i=0, handler; (handler = handlers[i]); i++){ ! ! ! ! ! handler.call(this, memo); ! ! ! ! } ! ! ! } ! ! }, ! ! ! ! ! watch: function(event, handler) { ! ! ! if (typeof registered[event] === "undefined"){ ! ! ! ! registered[event] = []; ! ! ! } ! ! ! registered[event].push(handler); ! ! } }; })();
  10. _$ = (function() { var registered = {}; return {

    ! ! notify: function(event, memo) { ! ! ! if (registered[event] instanceof Array){ ! ! ! ! var handlers = [].concat(registered[event]); ! ! ! ! for (var i=0, handler; (handler = handlers[i]); i++){ ! ! ! ! ! handler.call(this, memo); ! ! ! ! } ! ! ! } ! ! }, ! ! ! ! ! watch: function(event, handler) { ! ! ! if (typeof registered[event] === "undefined"){ ! ! ! ! registered[event] = []; ! ! ! } ! ! ! registered[event].push(handler); ! ! } }; })();
  11. _$ = (function() { var registered = {}; return {

    ! ! notify: function(event, memo) { ! ! ! if (registered[event] instanceof Array){ ! ! ! ! var handlers = [].concat(registered[event]); ! ! ! ! for (var i=0, handler; (handler = handlers[i]); i++){ ! ! ! ! ! handler.call(this, memo); ! ! ! ! } ! ! ! } ! ! }, ! ! ! ! ! watch: function(event, handler) { ! ! ! if (typeof registered[event] === "undefined"){ ! ! ! ! registered[event] = []; ! ! ! } ! ! ! registered[event].push(handler); ! ! } }; })();
  12. _$ = (function() { var registered = {}; return {

    ! ! notify: function(event, memo) { ! ! ! if (registered[event] instanceof Array){ ! ! ! ! var handlers = [].concat(registered[event]); ! ! ! ! for (var i=0, handler; (handler = handlers[i]); i++){ ! ! ! ! ! handler.call(this, memo); ! ! ! ! } ! ! ! } ! ! }, ! ! ! ! ! watch: function(event, handler) { ! ! ! if (typeof registered[event] === "undefined"){ ! ! ! ! registered[event] = []; ! ! ! } ! ! ! registered[event].push(handler); ! ! } }; })();
  13. _$ = (function() { var registered = {}; return {

    ! ! notify: function(event, memo) { ! ! ! if (registered[event] instanceof Array){ ! ! ! ! var handlers = [].concat(registered[event]); ! ! ! ! for (var i=0, handler; (handler = handlers[i]); i++){ ! ! ! ! ! handler.call(this, memo); ! ! ! ! } ! ! ! } ! ! }, ! ! ! ! ! watch: function(event, handler) { ! ! ! if (typeof registered[event] === "undefined"){ ! ! ! ! registered[event] = []; ! ! ! } ! ! ! registered[event].push(handler); ! ! } }; })();
  14. _$ = (function() { var registered = {}; return {

    ! ! notify: function(event, memo) { ! ! ! if (registered[event] instanceof Array){ ! ! ! ! var handlers = [].concat(registered[event]); ! ! ! ! for (var i=0, handler; (handler = handlers[i]); i++){ ! ! ! ! ! handler.call(this, memo); ! ! ! ! } ! ! ! } ! ! }, ! ! ! ! ! watch: function(event, handler) { ! ! ! if (typeof registered[event] === "undefined"){ ! ! ! ! registered[event] = []; ! ! ! } ! ! ! registered[event].push(handler); ! ! } }; })();
  15. _$ = (function() { var registered = {}; return {

    ! ! notify: function(event, memo) { ! ! ! if (registered[event] instanceof Array){ ! ! ! ! var handlers = [].concat(registered[event]); ! ! ! ! for (var i=0, handler; (handler = handlers[i]); i++){ ! ! ! ! ! handler.call(this, memo); ! ! ! ! } ! ! ! } ! ! }, ! ! ! ! ! watch: function(event, handler) { ! ! ! if (typeof registered[event] === "undefined"){ ! ! ! ! registered[event] = []; ! ! ! } ! ! ! registered[event].push(handler); ! ! } }; })();
  16. _$ = (function() { var registered = {}; return {

    ! ! notify: function(event, memo) { ! ! ! if (registered[event] instanceof Array){ ! ! ! ! var handlers = [].concat(registered[event]); ! ! ! ! for (var i=0, handler; (handler = handlers[i]); i++){ ! ! ! ! ! handler.call(this, memo); ! ! ! ! } ! ! ! } ! ! }, ! ! ! ! ! watch: function(event, handler) { ! ! ! if (typeof registered[event] === "undefined"){ ! ! ! ! registered[event] = []; ! ! ! } ! ! ! registered[event].push(handler); ! ! } }; })();
  17. _$ = (function() { var registered = {}; return {

    ! ! notify: function(event, memo) { ! ! ! if (registered[event] instanceof Array){ ! ! ! ! var handlers = [].concat(registered[event]); ! ! ! ! for (var i=0, handler; (handler = handlers[i]); i++){ ! ! ! ! ! handler.call(this, memo); ! ! ! ! } ! ! ! } ! ! }, ! ! ! ! ! watch: function(event, handler) { ! ! ! if (typeof registered[event] === "undefined"){ ! ! ! ! registered[event] = []; ! ! ! } ! ! ! registered[event].push(handler); ! ! } }; })();
  18. _$ = (function() { var registered = {}; return {

    ! ! notify: function(event, memo) { ! ! ! if (registered[event] instanceof Array){ ! ! ! ! var handlers = [].concat(registered[event]); ! ! ! ! for (var i=0, handler; (handler = handlers[i]); i++){ ! ! ! ! ! handler.call(this, memo); ! ! ! ! } ! ! ! } ! ! }, ! ! ! ! ! watch: function(event, handler) { ! ! ! if (typeof registered[event] === "undefined"){ ! ! ! ! registered[event] = []; ! ! ! } ! ! ! registered[event].push(handler); ! ! } }; })();
  19. _$ = (function() { var registered = {}; return {

    ! ! notify: function(event, memo) { ! ! ! if (registered[event] instanceof Array){ ! ! ! ! var handlers = [].concat(registered[event]); ! ! ! ! for (var i=0, handler; (handler = handlers[i]); i++){ ! ! ! ! ! handler.call(this, memo); ! ! ! ! } ! ! ! } ! ! }, ! ! ! ! ! watch: function(event, handler) { ! ! ! if (typeof registered[event] === "undefined"){ ! ! ! ! registered[event] = []; ! ! ! } ! ! ! registered[event].push(handler); ! ! } }; })();
  20. _$ = (function() { var registered = {}; return {

    ! ! notify: function(event, memo) { ! ! ! if (registered[event] instanceof Array){ ! ! ! ! var handlers = [].concat(registered[event]); ! ! ! ! for (var i=0, handler; (handler = handlers[i]); i++){ ! ! ! ! ! handler.call(this, memo); ! ! ! ! } ! ! ! } ! ! }, ! ! ! ! ! watch: function(event, handler) { ! ! ! if (typeof registered[event] === "undefined"){ ! ! ! ! registered[event] = []; ! ! ! } ! ! ! registered[event].push(handler); ! ! } }; })();
  21. _$ = (function() { var registered = {}; return {

    ! ! notify: function(event, memo) { ! ! ! if (registered[event] instanceof Array){ ! ! ! ! var handlers = [].concat(registered[event]); ! ! ! ! for (var i=0, handler; (handler = handlers[i]); i++){ ! ! ! ! ! handler.call(this, memo); ! ! ! ! } ! ! ! } ! ! }, ! ! ! ! ! watch: function(event, handler) { ! ! ! if (typeof registered[event] === "undefined"){ ! ! ! ! registered[event] = []; ! ! ! } ! ! ! registered[event].push(handler); ! ! } }; })();
  22. _$ = (function() { var registered = {}; return {

    ! ! notify: function(event, memo) { ! ! ! if (registered[event] instanceof Array){ ! ! ! ! var handlers = [].concat(registered[event]); ! ! ! ! for (var i=0, handler; (handler = handlers[i]); i++){ ! ! ! ! ! handler.call(this, memo); ! ! ! ! } ! ! ! } ! ! }, ! ! ! ! ! watch: function(event, handler) { ! ! ! if (typeof registered[event] === "undefined"){ ! ! ! ! registered[event] = []; ! ! ! } ! ! ! registered[event].push(handler); ! ! } }; })();
  23. _$ = (function() { var registered = {}; return {

    ! ! notify: function(event, memo) { ! ! ! if (registered[event] instanceof Array){ ! ! ! ! var handlers = [].concat(registered[event]); ! ! ! ! for (var i=0, handler; (handler = handlers[i]); i++){ ! ! ! ! ! handler.call(this, memo); ! ! ! ! } ! ! ! } ! ! }, ! ! ! ! ! watch: function(event, handler) { ! ! ! if (typeof registered[event] === "undefined"){ ! ! ! ! registered[event] = []; ! ! ! } ! ! ! registered[event].push(handler); ! ! } }; })();
  24. _$ = (function (_) { notify: function (a, b, c,

    d) { for (d = -1, c = [].concat(_[a]); c[++d];) c[d](b); }, watch: function (a, b) { (_[a] || (_[a] = [])).push(b); }, })({});
  25. [...] testNotify: function(){! ! ! ! var a = 0;!

    ! ! _$.watch('testNotify', function(){ a = 1; }); ! ! _$.notify('testNotify'); ! ! assertEquals(1, a); ! }, ! ! ! ! testNotifyWithMemo: function(){! ! ! ! var a = 0 ;! ! ! _$.watch('testNotify', function(memo){ a = memo.test; }); ! ! _$.notify('testNotify', {test: 1}); ! ! assertEquals(1, a); ! }, [...]
  26. [...] testNotify: function(){! ! ! ! var a = 0;!

    ! ! _$.watch('testNotify', function(){ a = 1; }); ! ! _$.notify('testNotify'); ! ! assertEquals(1, a); ! }, ! ! ! ! testNotifyWithMemo: function(){! ! ! ! var a = 0 ;! ! ! _$.watch('testNotify', function(memo){ a = memo.test; }); ! ! _$.notify('testNotify', {test: 1}); ! ! assertEquals(1, a); ! }, [...]
  27. [...] testNotify: function(){! ! ! ! var a = 0;!

    ! ! _$.watch('testNotify', function(){ a = 1; }); ! ! _$.notify('testNotify'); ! ! assertEquals(1, a); ! }, ! ! ! ! testNotifyWithMemo: function(){! ! ! ! var a = 0 ;! ! ! _$.watch('testNotify', function(memo){ a = memo.test; }); ! ! _$.notify('testNotify', {test: 1}); ! ! assertEquals(1, a); ! }, [...]
  28. [...] testNotify: function(){! ! ! ! var a = 0;!

    ! ! _$.watch('testNotify', function(){ a = 1; }); ! ! _$.notify('testNotify'); ! ! assertEquals(1, a); ! }, ! ! ! ! testNotifyWithMemo: function(){! ! ! ! var a = 0 ;! ! ! _$.watch('testNotify', function(memo){ a = memo.test; }); ! ! _$.notify('testNotify', {test: 1}); ! ! assertEquals(1, a); ! }, [...]
  29. [...] testNotify: function(){! ! ! ! var a = 0;!

    ! ! _$.watch('testNotify', function(){ a = 1; }); ! ! _$.notify('testNotify'); ! ! assertEquals(1, a); ! }, ! ! ! ! testNotifyWithMemo: function(){! ! ! ! var a = 0 ;! ! ! _$.watch('testNotify', function(memo){ a = memo.test; }); ! ! _$.notify('testNotify', {test: 1}); ! ! assertEquals(1, a); ! }, [...]
  30. [...] testNotify: function(){! ! ! ! var a = 0;!

    ! ! _$.watch('testNotify', function(){ a = 1; }); ! ! _$.notify('testNotify'); ! ! assertEquals(1, a); ! }, ! ! ! ! testNotifyWithMemo: function(){! ! ! ! var a = 0 ;! ! ! _$.watch('testNotify', function(memo){ a = memo.test; }); ! ! _$.notify('testNotify', {test: 1}); ! ! assertEquals(1, a); ! }, [...]
  31. [...] testNotify: function(){! ! ! ! var a = 0;!

    ! ! _$.watch('testNotify', function(){ a = 1; }); ! ! _$.notify('testNotify'); ! ! assertEquals(1, a); ! }, ! ! ! ! testNotifyWithMemo: function(){! ! ! ! var a = 0 ;! ! ! _$.watch('testNotify', function(memo){ a = memo.test; }); ! ! _$.notify('testNotify', {test: 1}); ! ! assertEquals(1, a); ! }, [...]
  32. [...] ! testNotifyWithMultipleWhatches: function(){! ! ! ! var a =

    0, b = 0;! ! ! _$.watch('testNotify', function(memo){ a = memo.test; }); ! ! _$.watch('testNotify', function(memo){ b = memo.test; }); ! ! _$.notify('testNotify', {test: 1}); ! ! assertEquals(1, a); ! ! assertEquals(1, b); ! }, [...]
  33. [...] ! testNotifyWithMultipleWhatches: function(){! ! ! ! var a =

    0, b = 0;! ! ! _$.watch('testNotify', function(memo){ a = memo.test; }); ! ! _$.watch('testNotify', function(memo){ b = memo.test; }); ! ! _$.notify('testNotify', {test: 1}); ! ! assertEquals(1, a); ! ! assertEquals(1, b); ! }, [...]
  34. [...] ! testNotifyWithMultipleWhatches: function(){! ! ! ! var a =

    0, b = 0;! ! ! _$.watch('testNotify', function(memo){ a = memo.test; }); ! ! _$.watch('testNotify', function(memo){ b = memo.test; }); ! ! _$.notify('testNotify', {test: 1}); ! ! assertEquals(1, a); ! ! assertEquals(1, b); ! }, [...]
  35. [...] testNotifyWithMultipleWhatchesNested: function(){!! ! ! var a = 0, b

    = 0, c=0;! ! ! _$.watch('testNotify', function(memo){ a = memo.test; ! ! ! _$.watch('testNotify', function(memo){ ! ! ! ! if (b<2){ b = memo.test; } else { c = memo.test; } ! ! ! }); ! ! }); ! ! ! ! _$.notify('testNotify', {test: 1}); ! ! assertEquals(1, a); ! ! assertEquals(0, b); ! ! assertEquals(0, c); ! ! ! ! _$.notify('testNotify', {test: 2}); ! ! assertEquals(2, a); ! ! assertEquals(2, b); ! ! assertEquals(0, c); ! ! ! ! _$.notify('testNotify', {test: 3}); ! ! assertEquals(3, a); ! ! assertEquals(2, b); ! ! assertEquals(3, c); ! }, [...]
  36. [...] testNotifyWithMultipleWhatchesNested: function(){!! ! ! var a = 0, b

    = 0, c=0;! ! ! _$.watch('testNotify', function(memo){ a = memo.test; ! ! ! _$.watch('testNotify', function(memo){ ! ! ! ! if (b<2){ b = memo.test; } else { c = memo.test; } ! ! ! }); ! ! }); ! ! ! ! _$.notify('testNotify', {test: 1}); ! ! assertEquals(1, a); ! ! assertEquals(0, b); ! ! assertEquals(0, c); ! ! ! ! _$.notify('testNotify', {test: 2}); ! ! assertEquals(2, a); ! ! assertEquals(2, b); ! ! assertEquals(0, c); ! ! ! ! _$.notify('testNotify', {test: 3}); ! ! assertEquals(3, a); ! ! assertEquals(2, b); ! ! assertEquals(3, c); ! }, [...]
  37. [...] testNotifyWithMultipleWhatchesNested: function(){!! ! ! var a = 0, b

    = 0, c=0;! ! ! _$.watch('testNotify', function(memo){ a = memo.test; ! ! ! _$.watch('testNotify', function(memo){ ! ! ! ! if (b<2){ b = memo.test; } else { c = memo.test; } ! ! ! }); ! ! }); ! ! ! ! _$.notify('testNotify', {test: 1}); ! ! assertEquals(1, a); ! ! assertEquals(0, b); ! ! assertEquals(0, c); ! ! ! ! _$.notify('testNotify', {test: 2}); ! ! assertEquals(2, a); ! ! assertEquals(2, b); ! ! assertEquals(0, c); ! ! ! ! _$.notify('testNotify', {test: 3}); ! ! assertEquals(3, a); ! ! assertEquals(2, b); ! ! assertEquals(3, c); ! }, [...]
  38. [...] testNotifyWithMultipleWhatchesNested: function(){!! ! ! var a = 0, b

    = 0, c=0;! ! ! _$.watch('testNotify', function(memo){ a = memo.test; ! ! ! _$.watch('testNotify', function(memo){ ! ! ! ! if (b<2){ b = memo.test; } else { c = memo.test; } ! ! ! }); ! ! }); ! ! ! ! _$.notify('testNotify', {test: 1}); ! ! assertEquals(1, a); ! ! assertEquals(0, b); ! ! assertEquals(0, c); ! ! ! ! _$.notify('testNotify', {test: 2}); ! ! assertEquals(2, a); ! ! assertEquals(2, b); ! ! assertEquals(0, c); ! ! ! ! _$.notify('testNotify', {test: 3}); ! ! assertEquals(3, a); ! ! assertEquals(2, b); ! ! assertEquals(3, c); ! }, [...]
  39. [...] testNotifyWithMultipleWhatchesNested: function(){!! ! ! var a = 0, b

    = 0, c=0;! ! ! _$.watch('testNotify', function(memo){ a = memo.test; ! ! ! _$.watch('testNotify', function(memo){ ! ! ! ! if (b<2){ b = memo.test; } ! ! ! ! else { c = memo.test; } ! ! ! }); ! ! }); ! ! ! ! _$.notify('testNotify', {test: 1}); ! ! assertEquals(1, a); ! ! assertEquals(0, b); ! ! assertEquals(0, c); ! ! ! ! _$.notify('testNotify', {test: 2}); ! ! assertEquals(2, a); ! ! assertEquals(2, b); ! ! assertEquals(0, c); ! ! ! ! _$.notify('testNotify', {test: 3}); ! ! assertEquals(3, a); ! ! assertEquals(2, b); ! ! assertEquals(3, c); ! }, [...]
  40. [...] testNotifyWithMultipleWhatchesNested: function(){!! ! ! var a = 0, b

    = 0, c=0;! ! ! _$.watch('testNotify', function(memo){ a = memo.test; ! ! ! _$.watch('testNotify', function(memo){ ! ! ! ! if (b<2){ b = memo.test; } else { c = memo.test; } ! ! ! }); ! ! }); ! ! ! ! _$.notify('testNotify', {test: 1}); ! ! assertEquals(1, a); ! ! assertEquals(0, b); ! ! assertEquals(0, c); ! ! ! ! _$.notify('testNotify', {test: 2}); ! ! assertEquals(2, a); ! ! assertEquals(2, b); ! ! assertEquals(0, c); ! ! ! ! _$.notify('testNotify', {test: 3}); ! ! assertEquals(3, a); ! ! assertEquals(2, b); ! ! assertEquals(3, c); ! }, [...]
  41. [...] testNotifyWithMultipleWhatchesNested: function(){!! ! ! var a = 0, b

    = 0, c=0;! ! ! _$.watch('testNotify', function(memo){ a = memo.test; ! ! ! _$.watch('testNotify', function(memo){ ! ! ! ! if (b<2){ b = memo.test; } else { c = memo.test; } ! ! ! }); ! ! }); ! ! ! ! _$.notify('testNotify', {test: 1}); ! ! assertEquals(1, a); ! ! assertEquals(0, b); ! ! assertEquals(0, c); ! ! ! ! _$.notify('testNotify', {test: 2}); ! ! assertEquals(2, a); ! ! assertEquals(2, b); ! ! assertEquals(0, c); ! ! ! ! _$.notify('testNotify', {test: 3}); ! ! assertEquals(3, a); ! ! assertEquals(2, b); ! ! assertEquals(3, c); ! }, [...]
  42. [...] testNotifyWithMultipleWhatchesNested: function(){!! ! ! var a = 0, b

    = 0, c=0;! ! ! _$.watch('testNotify', function(memo){ a = memo.test; ! ! ! _$.watch('testNotify', function(memo){ ! ! ! ! if (b<2){ b = memo.test; } else { c = memo.test; } ! ! ! }); ! ! }); ! ! ! ! _$.notify('testNotify', {test: 1}); ! ! assertEquals(1, a); ! ! assertEquals(0, b); ! ! assertEquals(0, c); ! ! ! ! _$.notify('testNotify', {test: 2}); ! ! assertEquals(2, a); ! ! assertEquals(2, b); ! ! assertEquals(0, c); ! ! ! ! _$.notify('testNotify', {test: 3}); ! ! assertEquals(3, a); ! ! assertEquals(2, b); ! ! assertEquals(3, c); ! }, [...]
  43. [...] testNotifyWithMultipleWhatchesNested: function(){!! ! ! var a = 0, b

    = 0, c=0;! ! ! _$.watch('testNotify', function(memo){ a = memo.test; ! ! ! _$.watch('testNotify', function(memo){ ! ! ! ! if (b<2){ b = memo.test; } else { c = memo.test; } ! ! ! }); ! ! }); ! ! ! ! _$.notify('testNotify', {test: 1}); ! ! assertEquals(1, a); ! ! assertEquals(0, b); ! ! assertEquals(0, c); ! ! ! ! _$.notify('testNotify', {test: 2}); ! ! assertEquals(2, a); ! ! assertEquals(2, b); ! ! assertEquals(0, c); ! ! ! ! _$.notify('testNotify', {test: 3}); ! ! assertEquals(3, a); ! ! assertEquals(2, b); ! ! assertEquals(3, c); ! }, [...]
  44. [...] testNotifyWithMultipleWhatchesNested: function(){!! ! ! var a = 0, b

    = 0, c=0;! ! ! _$.watch('testNotify', function(memo){ a = memo.test; ! ! ! _$.watch('testNotify', function(memo){ ! ! ! ! if (b<2){ b = memo.test; } else { c = memo.test; } ! ! ! }); ! ! }); ! ! ! ! _$.notify('testNotify', {test: 1}); ! ! assertEquals(1, a); ! ! assertEquals(0, b); ! ! assertEquals(0, c); ! ! ! ! _$.notify('testNotify', {test: 2}); ! ! assertEquals(2, a); ! ! assertEquals(2, b); ! ! assertEquals(0, c); ! ! ! ! _$.notify('testNotify', {test: 3}); ! ! assertEquals(3, a); ! ! assertEquals(2, b); ! ! assertEquals(3, c); ! }, [...]
  45. _$ = (function() { var registered = {}; return {

    ! ! notify: function(event, memo) { ! ! ! if (registered[event] instanceof Array){ ! ! ! ! var handlers = [].concat(registered[event]); ! ! ! ! for (var i=0, handler; (handler = handlers[i]); i++){ ! ! ! ! ! handler.call(this, memo); ! ! ! ! } ! ! ! } ! ! }, ! ! ! ! ! watch: function(event, handler) { ! ! ! if (typeof registered[event] === "undefined"){ ! ! ! ! registered[event] = []; ! ! ! } ! ! ! registered[event].push(handler); ! ! } }; })();
  46. _$ = (function() { var registered = {}; return {

    ! ! notify: function(event, memo) { ! ! ! if (registered[event] instanceof Array){ ! ! ! ! var handlers = [].concat(registered[event]); ! ! ! ! for (var i=0, handler; (handler = handlers[i]); i++){ ! ! ! ! ! handler.call(this, memo); ! ! ! ! } ! ! ! } ! ! }, ! ! ! ! ! watch: function(event, handler) { ! ! ! if (typeof registered[event] === "undefined"){ ! ! ! ! registered[event] = []; ! ! ! } ! ! ! registered[event].push(handler); ! ! } }; })();
  47. [...] ! testNotifyWithMultipleWhatches: function(){! ! ! ! var a =

    0, b = 0;! ! ! _$.watch('testNotify', function(memo){ a = memo.test; }); ! ! _$.watch('testNotify', function(memo){ b = memo.test; }); ! ! _$.notify('testNotify', {test: 1}); ! ! assertEquals(1, a); ! ! assertEquals(1, b); ! }, [...]
  48. [...] ! testWhatchWithoutHandler: function(){! ! ! ! var a =

    0, b = 0;! ! ! _$.watch('testNotify', function(memo){ a = memo.test; }); ! ! _$.watch('testNotify'); ! ! _$.watch('testNotify', function(memo){ b = memo.test; }); ! ! _$.notify('testNotify', {test: 1}); ! ! assertEquals(1, a); ! ! assertEquals(1, b); ! }, [...]
  49. _$ = (function() { var registered = {}; return {

    ! ! notify: function(event, memo) { ! ! ! if (registered[event] instanceof Array){ ! ! ! ! var handlers = [].concat(registered[event]); ! ! ! ! for (var i=0, handler; (handler = handlers[i]); i++){ ! ! ! ! ! handler.call(this, memo); ! ! ! ! } ! ! ! } ! ! }, ! ! ! ! ! watch: function(event, handler) { ! ! ! if (handler) { if (typeof registered[event] === "undefined"){ ! ! ! ! registered[event] = []; ! ! ! } ! ! ! registered[event].push(handler); } ! ! } }; })();
  50. _$ = (function (_) { notify: function (a, b, c,

    d) { for (d = -1, c = [].concat(_[a]); c[++d];) c[d](b); }, watch: function (a, b) { if(b)(_[a] || (_[a] = [])).push(b); }, })({});
  51. a function that records arguments, return value, the value of

    this and exception thrown (if any) for all its calls. Spies
  52. functions (spies) with pre-programmed behavior. Stub a function that records

    arguments, return value, the value of this and exception thrown (if any) for all its calls. Spies
  53. functions (spies) with pre-programmed behavior. Stub a function that records

    arguments, return value, the value of this and exception thrown (if any) for all its calls. Spies functions (spies) with pre-programmed behavior (stubs) as well as pre- programmed expectations. Mock
  54. [...] testMyLibRegistersToSystemOnEvent: function(){! ! ! ! var spy = sinon.spy(_$,

    'watch');! ! ! //DO STUFF TO INIT YOUR LIB ! ! assertTrue(spy.calledWith('SysyemOn')); ! }, ! ! ! ! testMyLibLoggedNotLogged: function(){! ! ! ! var stub = sinon.stub(User, 'isLogged');! ! ! stub.returns(true); ! ! //DO STUFF && ASSERTIONS ! ! stub.returns(false); ! ! //DO STUFF && ASSERTIONS ! }, [...]
  55. [...] testMyLibRegistersToSystemOnEvent: function(){! ! ! ! var spy = sinon.spy(_$,

    'watch');! ! ! //DO STUFF TO INIT YOUR LIB ! ! assertTrue(spy.calledWith('SystemOn')); ! }, ! ! ! ! testMyLibLoggedNotLogged: function(){! ! ! ! var stub = sinon.stub(User, 'isLogged');! ! ! stub.returns(true); ! ! //DO STUFF && ASSERTIONS ! ! stub.returns(false); ! ! //DO STUFF && ASSERTIONS ! }, [...]
  56. [...] "test MyLib Registers To 'SystemOn' Event": function(){! ! !

    ! var spy = sinon.spy(_$, 'watch');! ! ! //DO STUFF TO INIT YOUR LIB ! ! assertTrue(spy.calledWith('SystemOn')); ! }, ! ! ! ! testMyLibLoggedNotLogged: function(){! ! ! ! var stub = sinon.stub(User, 'isLogged');! ! ! stub.returns(true); ! ! //DO STUFF && ASSERTIONS ! ! stub.returns(false); ! ! //DO STUFF && ASSERTIONS ! }, [...]
  57. [...] testMyLibRegistersToSystemOnEvent: function(){! ! ! ! var spy = sinon.spy(_$,

    'watch');! ! ! //DO STUFF TO INIT YOUR LIB ! ! assertTrue(spy.calledWith('SystemOn')); ! }, ! ! ! ! testMyLibLoggedNotLogged: function(){! ! ! ! var stub = sinon.stub(User, 'isLogged');! ! ! stub.returns(true); ! ! //DO STUFF && ASSERTIONS ! ! stub.returns(false); ! ! //DO STUFF && ASSERTIONS ! }, [...]
  58. [...] testMyLibRegistersToSystemOnEvent: function(){! ! ! ! var spy = sinon.spy(_$,

    'watch');! ! ! //DO STUFF TO INIT YOUR LIB ! ! assertTrue(spy.calledWith('SystemOn')); ! }, ! ! ! ! testMyLibLoggedNotLogged: function(){! ! ! ! var stub = sinon.stub(User, 'isLogged');! ! ! stub.returns(true); ! ! //DO STUFF && ASSERTIONS ! ! stub.returns(false); ! ! //DO STUFF && ASSERTIONS ! }, [...]
  59. [...] testMyLibRegistersToSystemOnEvent: function(){! ! ! ! var spy = sinon.spy(_$,

    'watch');! ! ! //DO STUFF TO INIT YOUR LIB ! ! assertTrue(spy.calledWith('SystemOn')); ! }, ! ! ! ! testMyLibLoggedNotLogged: function(){! ! ! ! var stub = sinon.stub(User, 'isLogged');! ! ! stub.returns(true); ! ! //DO STUFF && ASSERTIONS ! ! stub.returns(false); ! ! //DO STUFF && ASSERTIONS ! }, [...]
  60. [...] testMyLibRegistersToSystemOnEvent: function(){! ! ! ! var spy = sinon.spy(_$,

    'watch');! ! ! //DO STUFF TO INIT YOUR LIB ! ! assertTrue(spy.calledWith('SystemOn')); ! }, ! ! ! ! testMyLibLoggedNotLogged: function(){! ! ! ! var stub = sinon.stub(User, 'isLogged');! ! ! stub.returns(true); ! ! //DO STUFF && ASSERTIONS ! ! stub.returns(false); ! ! //DO STUFF && ASSERTIONS ! }, [...]
  61. [...] testMyLibRegistersToSystemOnEvent: function(){! ! ! ! var spy = sinon.spy(_$,

    'watch');! ! ! //DO STUFF TO INIT YOUR LIB ! ! assertTrue(spy.calledWith('SystemOn')); ! }, ! ! ! ! testMyLibLoggedNotLogged: function(){! ! ! ! var stub = sinon.stub(User, 'isLogged');! ! ! stub.returns(true); ! ! //DO STUFF && ASSERTIONS ! ! stub.returns(false); ! ! //DO STUFF && ASSERTIONS ! }, [...]
  62. [...] testMyLibRegistersToSystemOnEvent: function(){! ! ! ! var spy = sinon.spy(_$,

    'watch');! ! ! //DO STUFF TO INIT YOUR LIB ! ! assertTrue(spy.calledWith('SystemOn')); ! }, ! ! ! ! testMyLibLoggedNotLogged: function(){! ! ! ! var stub = sinon.stub(User, 'isLogged');! ! ! stub.returns(true); ! ! //DO STUFF && ASSERTIONS ! ! stub.returns(false); ! ! //DO STUFF && ASSERTIONS ! }, [...]
  63. [...] testMyLibRegistersToSystemOnEvent: function(){! ! ! ! var spy = sinon.spy(_$,

    'watch');! ! ! //DO STUFF TO INIT YOUR LIB ! ! assertTrue(spy.calledWith('SystemOn')); ! }, ! ! ! ! testMyLibLoggedNotLogged: function(){! ! ! ! var stub = sinon.stub(User, 'isLogged');! ! ! stub.returns(true); ! ! //DO STUFF && ASSERTIONS ! ! stub.returns(false); ! ! //DO STUFF && ASSERTIONS ! }, [...]
  64. [...] testMyLibRegistersToSystemOnEvent: function(){! ! ! ! var spy = sinon.spy(_$,

    'watch');! ! ! //DO STUFF TO INIT YOUR LIB ! ! assertTrue(spy.calledWith('SystemOn')); ! }, [...]
  65. [...] //testMyLibRegistersToSystemOnEvent: function(){! ! ! ! //var spy = sinon.spy(_$,

    'watch');! ! ! //DO STUFF TO INIT YOUR LIB ! ! //assertTrue(spy.calledWith('SysyemOn')); ! //}, ! ! testMyLibRegistersToSystemOnEvent: function(){! ! ! ! var mock = sinon.mock(_$); ! ! mock.expect('watch').calledWith('SysyemOn'); ! ! //DO STUFF TO INIT YOUR LIB ! ! mock.verify(); ! }, [...]
  66. [...] //testMyLibRegistersToSystemOnEvent: function(){! ! ! ! //var spy = sinon.spy(_$,

    'watch');! ! ! //DO STUFF TO INIT YOUR LIB ! ! //assertTrue(spy.calledWith('SysyemOn')); ! //}, ! ! testMyLibRegistersToSystemOnEvent: function(){! ! ! ! var mock = sinon.mock(_$); ! ! mock.expect('watch').calledWith('SysyemOn'); ! ! //DO STUFF TO INIT YOUR LIB ! ! mock.verify(); ! }, [...]
  67. cheat config dist libs tools workshop build.sh build.bat readme.txt /config/

    browsers.prop build.xml default.prop svn co https://svn.dsgn.it/jstdd
  68. /libs/ base.js sinon.js cheat config dist libs tools workshop build.sh

    build.bat readme.txt /config/ browsers.prop build.xml default.prop svn co https://svn.dsgn.it/jstdd
  69. /libs/ base.js sinon.js cheat config dist libs tools workshop build.sh

    build.bat readme.txt /tools/ ant browser jslint JsTestDriver /config/ browsers.prop build.xml default.prop svn co https://svn.dsgn.it/jstdd
  70. /libs/ base.js sinon.js cheat config dist libs tools workshop build.sh

    build.bat readme.txt /tools/ ant browser jslint JsTestDriver /workshop/ append find syntax /config/ browsers.prop build.xml default.prop svn co https://svn.dsgn.it/jstdd
  71. /libs/ base.js sinon.js cheat config dist libs tools workshop build.sh

    build.bat readme.txt /tools/ ant browser jslint JsTestDriver /workshop/ append find syntax /append/ src append.js test append.test.js jsTestDriver.conf /config/ browsers.prop build.xml default.prop svn co https://svn.dsgn.it/jstdd
  72. /libs/ base.js sinon.js cheat config dist libs tools workshop build.sh

    build.bat readme.txt /tools/ ant browser jslint JsTestDriver /workshop/ append find syntax /append/ src append.js test append.test.js jsTestDriver.conf /config/ browsers.prop build.xml default.prop svn co https://svn.dsgn.it/jstdd build append | sh build.sh append
  73. A simple modular event driven app a javascript code highlighter

    with 3 components: syntax highlighter selected word highlighter finder
  74. First step - syntax watch a SRC_LOADED event with the

    memo {file:'{{FILE_SRC}}'} highlight (wrap in a span with the keyword itself as classname) function => <span class="function">function</span> var, if ... else, for, return, ... notify SRC_READY with the memo {file:'{{EDITED_SRC}}'}
  75. Second step - append watch previous SRC_READY create a div[id="src_container"]

    and fill it with the source append to document llisten dblclick event and notify SRC_HIGHLIGHT with this memo: {keyword:'{{HIGHLIGHTED_WORD}}'} manage the SRC_HIGHLIGHT notification <span class="highlight">{{HIGHLIGHTED_KEYWORKD}}</span>
  76. Third step - find watch to SRC_READY create a div[id=form]

    and append inside of it input[type=text][id=search] input[type=button][id=submitBtn][value=Search] append the div to the document on click on submit notify a SRC_HIGHLIGHT event with memo {keyword:"{{SEARCHED_TEXT}}"}