• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Back To The Front - Javascript Test Driven Development is between us (workshop)
 

Back To The Front - Javascript Test Driven Development is between us (workshop)

on

  • 888 views

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 ...

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.
presented at italian Back To The Front conference /w @sirLisko

Statistics

Views

Total Views
888
Views on SlideShare
853
Embed Views
35

Actions

Likes
1
Downloads
17
Comments
0

3 Embeds 35

http://lanyrd.com 25
http://www.linkedin.com 9
https://www.linkedin.com 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n

Back To The Front - Javascript Test Driven Development is between us (workshop) Back To The Front - Javascript Test Driven Development is between us (workshop) Presentation Transcript

  • back to the frontjavascript tdd is between us
  • Who are we?Marco Cedaro Luca Lischettijavascript pirate, arr 8-bit lover and super heroSpreaker Frontend Developer (almost) Shazam Frontend Developer
  • Who are we?Marco Cedaro Luca Lischettijavascript pirate, arr 8-bit lover and super heroSpreaker Frontend Developer (almost) Shazam Frontend Developer The content of this workshop do not necessarily reflect the opinion of authors employers
  • Who are we?Marco Cedaro Luca Lischettijavascript pirate, arr 8-bit lover and super heroSpreaker Frontend Developer (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
  • I believe I can fly
  • Fearless & Unconscious
  • Fearless & Unconscious
  • But Life Goes On
  • TDD is about control
  • and about DESIGN too
  • The curious case of JavaScript unit testing
  • Unit Test and Functional Test
  • Pro/Cons test consistency controlinteraction against execution test over between external time integration codebase libraries changes
  • Thats the browsers, baby
  • Unit testing issupposed to test asingle atomic “unit” of functionality without dependencies on anything else
  • Unit testing is This is where yousupposed to test a start to run intosingle atomic “unit” serious dependency of functionality problems due to the without interrelation HTML dependencies on and CSS anything else
  • Unit testing is This is where you What do you test?supposed to test a start to run into Usually how the usersingle atomic “unit” serious dependency interface responds of functionality problems due to the to user input. without interrelation HTML Actually, the realm of dependencies on and CSS functional testing anything else
  • How does it work?
  • have you seen LOST?
  • Write a new test
  • Write a new testRun test & let it fail
  • Write a new testRun test & let it failWrite the code
  • Write a new testRun test & let it failWrite the codeRun test & let it succeed
  • Write a new testRun test & let it failWrite the codeRun test & let it succeedRefactor your code
  • Coding
  • _$ = (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);! ! } };})();
  • pub.. What?
  • _$ = (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);! ! } };})();
  • _$.watch("customEvent", function(obj) {! //DO STUFF});_$.notify("customEvent");_$.notify("customEvent", { prop : "value" });
  • _$.watch("customEvent", function(obj) {! //DO STUFF});_$.notify("customEvent");_$.notify("customEvent", { prop : "value" });
  • _$ = (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);! ! } };})();
  • _$ = (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);! ! } };})();
  • _$ = (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);! ! } };})();
  • _$ = (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);! ! } };})();
  • _$ = (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);! ! } };})();
  • _$ = (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);! ! } };})();
  • _$.watch("customEvent", function(obj) {! //DO STUFF});_$.notify("customEvent");_$.notify("customEvent", { prop : "value" });
  • _$ = (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);! ! } };})();
  • _$ = (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);! ! } };})();
  • _$ = (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);! ! } };})();
  • _$ = (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);! ! } };})();
  • _$ = (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);! ! } };})();
  • _$ = (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);! ! } };})();
  • _$ = (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);! ! } };})();
  • _$ = (function (_) { return { 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); } }})({});
  • [...] 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);! },[...]
  • [...] 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);! },[...]
  • [...] 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);! },[...]
  • [...] 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);! },[...]
  • [...] 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);! },[...]
  • [...] 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);! },[...]
  • [...] 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);! },[...]
  • [...]! 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);! },[...]
  • [...]! 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);! },[...]
  • [...]! 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);! },[...]
  • [...] 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);! },[...]
  • [...] 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);! },[...]
  • [...] 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);! },[...]
  • [...] 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);! },[...]
  • [...] 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);! },[...]
  • [...] 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);! },[...]
  • [...] 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);! },[...]
  • [...] 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);! },[...]
  • [...] 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);! },[...]
  • [...] 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);! },[...]
  • Theres no parachute Theres a major bug, lets take another look at the code...
  • _$ = (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);! ! } };})();
  • _$ = (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);! ! } };})();
  • Theres no parachute How would you write a test to check it?
  • [...]! 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);! },[...]
  • [...]! 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);! },[...]
  • _$ = (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); }! ! } };})();
  • _$ = (function (_) { return { 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); } }})({});
  • Spy, Stub & Mock
  • Fake objects & methods
  • Sinon.js
  • Spies a function thatrecords arguments, return value, the value of this andexception thrown (if any) for all its calls.
  • Spies Stub a function that functions (spies) withrecords arguments, pre-programmed return value, the behavior. value of this andexception thrown (if any) for all its calls.
  • Spies Stub Mock a function that functions (spies) with functions (spies) withrecords arguments, pre-programmed pre-programmed return value, the behavior. behavior (stubs) as value of this and well as pre-exception thrown (if programmed any) for all its calls. expectations.
  • [...] 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! },[...]
  • [...] 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! },[...]
  • [...] "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! },[...]
  • [...] 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! },[...]
  • [...] 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! },[...]
  • [...] 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! },[...]
  • [...] 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! },[...]
  • [...] 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! },[...]
  • [...] 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! },[...]
  • [...] 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! },[...]
  • [...] testMyLibRegistersToSystemOnEvent: function(){!!! ! var spy = sinon.spy(_$, watch);!! ! //DO STUFF TO INIT YOUR LIB! ! assertTrue(spy.calledWith(SystemOn));! },[...]
  • [...] //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();! },[...]
  • [...] //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();! },[...]
  • What are we going to do
  • svn co https://svn.dsgn.it/jstddcheatconfigdistlibstoolsworkshopbuild.shbuild.batreadme.txt
  • svn co https://svn.dsgn.it/jstddcheat /config/config browsers.propdist build.xmllibs default.proptoolsworkshopbuild.shbuild.batreadme.txt
  • svn co https://svn.dsgn.it/jstddcheat /config/config browsers.propdist /libs/ build.xmllibs base.js default.proptools sinon.jsworkshopbuild.shbuild.batreadme.txt
  • svn co https://svn.dsgn.it/jstddcheat /config/config browsers.propdist /libs/ build.xmllibs base.js default.proptools /tools/ sinon.jsworkshop antbuild.sh browserbuild.bat jslintreadme.txt JsTestDriver
  • svn co https://svn.dsgn.it/jstddcheat /config/config browsers.propdist /libs/ build.xmllibs base.js default.proptools /tools/ sinon.jsworkshop antbuild.sh browserbuild.bat jslintreadme.txt JsTestDriver /workshop/ append find syntax
  • svn co https://svn.dsgn.it/jstddcheat /config/config browsers.propdist /libs/ build.xmllibs base.js default.proptools /tools/ sinon.jsworkshop antbuild.sh browserbuild.bat jslint /append/readme.txt JsTestDriver src append.js /workshop/ test append append.test.js find jsTestDriver.conf syntax
  • svn co https://svn.dsgn.it/jstddcheat /config/config browsers.propdist /libs/ build.xmllibs base.js default.proptools /tools/ sinon.jsworkshop antbuild.sh browserbuild.bat jslint /append/readme.txt JsTestDriver src append.js /workshop/ test append append.test.js find jsTestDriver.conf syntax build append | sh build.sh append
  • A simple modular event driven app a javascript code highlighter with 3 components: syntax highlighter selected word highlighter finder
  • 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}}}
  • 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>
  • 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}}"}
  • Where are we now?
  • Costs of change
  • I Build So Consistently
  • Identify Build I Build So ConsistentlyShare make it Continuous