SlideShare a Scribd company logo
Javascript As A
Programming Language
IS
       Javascript As A
   Programming Language
Versioning, Test Driven Development & Continuous Integration
IS
       Javascript As A
   Programming Language
Versioning, Test Driven Development & Continuous Integration
Hello, who’s speaking?
Hello, who’s speaking?

           Marco Cedaro
             @cedmax
Hello, who’s speaking?

           Marco Cedaro
             @cedmax

           They said I am a...
            Frontend Cowboy
                         Nicola Vitto Jr.
            Javascript Pervert
                        Roberto Felter
            Perfect Stranger
                   basically anyone else
Hello, who’s speaking?

           Marco Cedaro
             @cedmax

           Actually I am:
            a Frontend Developer at
            Spreaker.com
Hello, who’s speaking?

           Marco Cedaro
             @cedmax

           Actually I am:
            a Frontend Developer at
            Spreaker.com
            a conference organizer
            with From The Front
Hello, who’s speaking?

           Marco Cedaro
             @cedmax

           Actually I am:
            a Frontend Developer at
            Spreaker.com
            a conference organizer
            with From The Front
            and a javascript pervert
Bologna, Italy
something in common with
     Robert Nyman
something in common with
     Robert Nyman
I believe I can fly
I believe I can fly
I believe I can fly


 Be brave. Take risks.
Nothing can substitute
     experience.
                   Paulo Coelho
once upon a time
once upon a time


we had no control
once upon a time


we had no control
 javascript was the land of the brave
once upon a time


we had no control
 javascript was the land of the brave
  we were fearless and unconscious
once upon a time


we had no control
 javascript was the land of the brave
  we were fearless and unconscious
    we were proud of being like that
just like them
kitty hawk
but life goes on
once upon a time


web engineer
   had a very bad
opinion of us
but it wasn't fair
but it wasn't fair


we didn't have IDEs & tools they did
but it wasn't fair


we didn't have IDEs & tools they did
 actually it was our own fault
but it wasn't fair


we didn't have IDEs & tools they did
 actually it was our own fault
   we were not ready
but it wasn't fair


we didn't have IDEs & tools they did
 actually it was our own fault
   we were not ready
     and javascript was neither
but, again, life goes on...
...and on...
and on..
it's not about the language itself
GREAT POWERS...
Frontend developers
have to claim their role
in development roadmap and
      business strategy
Javascript is a serious business
how serious?
less bandwidth and
  server load loading
resources and content
     when needed




      something we can achieve
less bandwidth and
                         performance boosts
  server load loading
                        that can lead to better
resources and content
                           conversion rates
     when needed




      something we can achieve
less bandwidth and
                         performance boosts        cross platform
  server load loading
                        that can lead to better   development: less
resources and content
                           conversion rates       maintenance costs
     when needed




      something we can achieve
less bandwidth and
                         performance boosts        cross platform
  server load loading
                        that can lead to better   development: less
resources and content
                           conversion rates       maintenance costs
     when needed




                           money
how serious?
this serious
what's missing?
what's missing?
what's missing?


If I had nine of my fingers
missing I wouldn't type any
           slower.
                     Mitch Hedberg
IDEs & Tools
the attitude
a strategy
The designer
 introduces a slider on
      some websites:
”it’s cool on apple store”.
The developer gets a jQuery
       plugin online




               the small web agency
The designer
 introduces a slider on         Major release of the
      some websites:            most used browser.
”it’s cool on apple store”.        A small fix has been
                              released, they have to change
The developer gets a jQuery   5 files in 5 different projects.
       plugin online




               the small web agency
The designer                                             Oh damn! There’s no
 introduces a slider on         Major release of the
                                                                   mouse wheel
      some websites:            most used browser.
                                                                    integration!
”it’s cool on apple store”.        A small fix has been
                              released, they have to change     should they ask for support
The developer gets a jQuery   5 files in 5 different projects.    or should they change the
       plugin online                                                library by themself?




               the small web agency
am I the only one or there’s
     something wrong?
The client-side
architecture has been
  built on the most
known and supported
      framework

        2006




                        the big corp
The client-side       Everything seems to be
architecture has been     fine, except that the
  built on the most      well known framework
known and supported      was being replaced by a
      framework            powerful new one

        2006                   2008 - 2010




                        the big corp
The client-side       Everything seems to be     They were forced to
architecture has been     fine, except that the       change the whole
  built on the most      well known framework       codebase at once to
known and supported      was being replaced by a    reduce maintenance
      framework            powerful new one        and development costs

        2006                   2008 - 2010                 2011




                        the big corp
here we are again
attitude, strategy...
...and foresight
WARNING!
continuous integration
continuous integration
continuous integration

    A software development
 practice where members of a
   team integrate their work
    frequently [...] to detect
  integration errors as quickly
           as possible.
                         Martin Fowler
I Build So Consistently
I Build So Consistently



identify
I Build So Consistently
                   write a build
                           script



identify
I Build So Consistently
                   write a build
                           script



identify




           share
I Build So Consistently
                   write a build
                           script



identify




                         make it
           share    continuous
How can we take
  advantages from a
continuous integration
       process?
rationalize your workflow
deploy stable versions
Separate the codebase
unit test your code
basically
basically
basically




      ie7
choose your tools
choose your tools
choose your tools


A man cannot be too careful
in the choice of his enemies
                      Oscar Wilde
Paris Web - Javascript as a programming language
JS HI NT
a code quality tool
a code quality tool


like Douglas Crockford's JSLint
a code quality tool


like Douglas Crockford's JSLint
 but
a code quality tool


like Douglas Crockford's JSLint
 but
   customizable
a tool for stupid?
S HI NT
J
R IV ER
     ST D
   TE T
JS H IN
  JS
once upon a time
jsTestDriver
jsTestDriver

works from console
jsTestDriver

works from console
 runs a server
jsTestDriver

works from console
 runs a server
   opens browsers
jsTestDriver

works from console
 runs a server
   opens browsers
    runs test suites
jsTestDriver

works from console
 runs a server
   opens browsers
    runs test suites
      retrieves results in console
build server
build server
build server
how does testing works?
have you seen Lost?
how does it work?
write a test




           how does it work?
write a test   let it fail




           how does it work?
write a test   let it fail   write the code




           how does it work?
write a test     let it fail   write the code

         run the test
         again




           how does it work?
write a test     let it fail              write the code

         run the test          refactor
         again




           how does it work?
the environment
It's the browser, baby
It's the browser, baby
Unit testing is
  supposed to test a
single atomic “unit” of
 functionality without
   dependencies on
     anything else



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



             The curious case of
            Javascript unit testing
Unit testing is                                   What do you test?
                          This is where you start
  supposed to test a                                 Usually how the user
                            to run into serious
single atomic “unit” of                              interface responds to
                           dependency problems
 functionality without                                     user input.
                          due to the interrelation
   dependencies on                                   Actually, the realm of
                            with HTML and CSS
     anything else                                     functional testing



             The curious case of
            Javascript unit testing
keep it real
keep it real
keep it real


To all my homies working
       on the 9 to 5
                       Shaggy
#140bytes
I used to work with these guys
_$ = (function() {
  var registered = {};
  return {
! ! pub: function(event, memo) {
! ! ! if (registered[event] instanceof Array){
! ! ! ! var handlers = [].concat(registered[event]);
! ! ! ! for (var i=0, h; (h = handlers[i]); i++){
! ! ! ! ! h.call(this, memo);
! ! ! ! }
! ! ! }
! ! },
! ! sub: function(event, handler) {
! ! ! if (typeof registered[event] === "undefined"){
! ! ! ! registered[event] = [];
! ! ! }
! ! ! registered[event].push(handler);
! ! }
  };
})();
_$ = (function() {
  var registered = {};
  return {
! ! pub: function(event, memo) {
! ! ! if (registered[event] instanceof Array){
! ! ! ! var handlers = [].concat(registered[event]);
! ! ! ! for (var i=0, h; (h = handlers[i]); i++){
! ! ! ! ! h.call(this, memo);
! ! ! ! }
! ! ! }
! ! },
! ! sub: function(event, handler) {
! ! ! if (typeof registered[event] === "undefined"){
! ! ! ! registered[event] = [];
! ! ! }
! ! ! registered[event].push(handler);
! ! }
  };
})();
_$.sub("customEvent", function(obj) {
! //DO STUFF
});

_$.pub("customEvent");
_$.pub("customEvent", { prop : "value" });
_$.sub("customEvent", function(obj) {
! //DO STUFF
});

_$.pub("customEvent");
_$.pub("customEvent", { prop : "value" });
_$.sub("customEvent", function(obj) {
! //DO STUFF
});

_$.pub("customEvent");
_$.pub("customEvent", { prop : "value" });
_$ = (function() {
  var registered = {};
  return {
! ! pub: function(event, memo) {
! ! ! if (registered[event] instanceof Array){
! ! ! ! var handlers = [].concat(registered[event]);
! ! ! ! for (var i=0, h; (h = handlers[i]); i++){
! ! ! ! ! h.call(this, memo);
! ! ! ! }
! ! ! }
! ! },
! ! sub: function(event, handler) {
! ! ! if (typeof registered[event] === "undefined"){
! ! ! ! registered[event] = [];
! ! ! }
! ! ! registered[event].push(handler);
! ! }
  };
})();
_$ = (function (_) {
! return {
! ! pub: function(a, b, c, d) {
! ! ! for (d=-1, c=[].concat(_[a]); c[++d];) c[d](b)
! ! },
! ! sub: function(a, b) {
! ! ! (_[a] || (_[a] = [])).push(b)
! ! }
! }
})({})
_$ = (function (_) {
! return {
! ! pub: function(a, b, c, d) {
! ! ! for (d=-1, c=[].concat(_[a]); c[++d];) c[d](b)
! ! },
! ! sub: function(a, b) {
! ! ! (_[a] || (_[a] = [])).push(b)
! ! }

                                             tes
! }
})({})
                                     #140 by
_$ = (function() {
  var registered = {};
  return {
! ! pub: function(event, memo) {
! ! ! if (registered[event] instanceof Array){
! ! ! ! var handlers = [].concat(registered[event]);
! ! ! ! for (var i=0, h; (h = handlers[i]); i++){
! ! ! ! ! h.call(this, memo);
! ! ! ! }
! ! ! }
! ! },
! ! sub: function(event, handler) {
! ! ! if (typeof registered[event] === "undefined"){
! ! ! ! registered[event] = [];
! ! ! }
! ! ! registered[event].push(handler);
! ! }
  };
})();
_$ = (function (_) {
! return {
! ! pub: function(a, b, c, d) {
! ! ! for (d=-1, c=[].concat(_[a]); c[++d];) c[d](b)
! ! },
! ! sub: function(a, b) {
! ! ! (_[a] || (_[a] = [])).push(b)
! ! }

                                             tes
! }
})({})
                                     #140 by
_$ = (function() {
  var registered = {};
  return {
! ! pub: function(event, memo) {
! ! ! if (registered[event] instanceof Array){
! ! ! ! var handlers = [].concat(registered[event]);
! ! ! ! for (var i=0, h; (h = handlers[i]); i++){
! ! ! ! ! h.call(this, memo);
! ! ! ! }
! ! ! }
! ! },
! ! sub: function(event, handler) {
! ! ! if (typeof registered[event] === "undefined"){
! ! ! ! registered[event] = [];
! ! ! }
! ! ! registered[event].push(handler);
! ! }
  };
})();
_$ = (function (_) {
! return {
! ! pub: function(a, b, c, d) {
! ! ! for (d=-1, c=[].concat(_[a]); c[++d];) c[d](b)
! ! },
! ! sub: function(a, b) {
! ! ! (_[a] || (_[a] = [])).push(b)
! ! }

                                             tes
! }
})({})
                                     #140 by
_$ = (function (_) {
! return {
! ! pub: function(a, b, c, d) {
! ! ! for (d=-1, c=[].concat(_[a]); c[++d];) c[d](b)
! ! },
! ! sub: function(a, b) {
! ! ! (_[a] || (_[a] = [])).push(b)
! ! }

                                             tes
! }
})({})
                                     #140 by
[...]
  testPub: function(){! !
! ! var a = 0;!
! ! _$.sub('testNotify', function(){ a = 1; });
! ! _$.pub('testNotify');

!   ! assertEquals(1, a);
!   },
!   ! !
!   testNotifyWithMemo: function(){!!
!   ! var a = 0 ;!
!   ! _$.sub('testNotify', function(memo){
!   ! ! ! a = memo.test;
!   ! });
!   ! _$.pub('testNotify', {test: 1});

! ! assertEquals(1, a);
! },
[...]
[...]
  testPub: function(){! !
! ! var a = 0;!
! ! _$.sub('testNotify', function(){ a = 1; });
! ! _$.pub('testNotify');

!   ! assertEquals(1, a);
!   },
!   ! !
!   testNotifyWithMemo: function(){!!
!   ! var a = 0 ;!
!   ! _$.sub('testNotify', function(memo){
!   ! ! ! a = memo.test;
!   ! });
!   ! _$.pub('testNotify', {test: 1});

! ! assertEquals(1, a);
! },
[...]
[...]
  testPub: function(){! !
! ! var a = 0;!
! ! _$.sub('testNotify', function(){ a = 1; });
! ! _$.pub('testNotify');

!   ! assertEquals(1, a);
!   },
!   ! !
!   testNotifyWithMemo: function(){!!
!   ! var a = 0 ;!
!   ! _$.sub('testNotify', function(memo){
!   ! ! ! a = memo.test;
!   ! });
!   ! _$.pub('testNotify', {test: 1});

! ! assertEquals(1, a);
! },
[...]
[...]
  testPub: function(){! !
! ! var a = 0;!
! ! _$.sub('testNotify', function(){ a = 1; });
! ! _$.pub('testNotify');

!   ! assertEquals(1, a);
!   },
!   ! !
!   testNotifyWithMemo: function(){!!
!   ! var a = 0 ;!
!   ! _$.sub('testNotify', function(memo){
!   ! ! ! a = memo.test;
!   ! });
!   ! _$.pub('testNotify', {test: 1});

! ! assertEquals(1, a);
! },
[...]
[...]
  testPub: function(){! !
! ! var a = 0;!
! ! _$.sub('testNotify', function(){ a = 1; });
! ! _$.pub('testNotify');

!   ! assertEquals(1, a);
!   },
!   ! !
!   testNotifyWithMemo: function(){!!
!   ! var a = 0 ;!
!   ! _$.sub('testNotify', function(memo){
!   ! ! ! a = memo.test;
!   ! });
!   ! _$.pub('testNotify', {test: 1});

! ! assertEquals(1, a);
! },
[...]
[...]
  testPub: function(){! !
! ! var a = 0;!
! ! _$.sub('testNotify', function(){ a = 1; });
! ! _$.pub('testNotify');

!   ! assertEquals(1, a);
!   },
!   ! !
!   testNotifyWithMemo: function(){!!
!   ! var a = 0 ;
!   ! _$.sub('testNotify', function(memo){
!   ! ! ! a = memo.test;
!   ! });
!   ! _$.pub('testNotify', {test: 1});

! ! assertEquals(1, a);
! },
[...]
[...]
  testPub: function(){! !
! ! var a = 0;!
! ! _$.sub('testNotify', function(){ a = 1; });
! ! _$.pub('testNotify');

!   ! assertEquals(1, a);
!   },
!   ! !
!   testNotifyWithMemo: function(){!!
!   ! var a = 0 ;!
!   ! _$.sub('testNotify', function(memo){
!   ! ! ! a = memo.test;
!   ! });
!   ! _$.pub('testNotify', {test: 1});

! ! assertEquals(1, a);
! },
[...]
easy, uh?
you will, eventually
R IV ER
     ST D
   TE T
JS H IN
  JS
.JS R
      ON I VE
  S IN D R
      ST
   TE T
JS H IN
  JS
a mock library
SPIES
a function that records
    arguments, return
value, the value of this
and exception thrown
 (if any) for all its calls.




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




                         a mock library
SPIES                      STUBS                     MOCKS
a function that records        functions (spies) with    functions (spies) with
    arguments, return            pre-programmed            pre-programmed
value, the value of this             behavior.          behavior (stubs) as well
and exception thrown                                      as pre-programmed
 (if any) for all its calls.                                 expectations.




                         a mock library
[...]
  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

! },
[...]
SPY
[...]
  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

! },
[...]
SPY
[...]
  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

! },
[...]
SPY
[...]
  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

! },
[...]
SPY
[...]
  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

! },
[...]
STUB
[...]
  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

! },
[...]
STUB
[...]
  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

! },
[...]
STUB
[...]
  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

! },
[...]
STUB
[...]
  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

! },
[...]
MOCK

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

[...]
  //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();
! },
[...]
MOCK

[...]
  //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();
! },
[...]
MOCK

[...]
  //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();
! },
[...]
AJAX CALL
[...]
  testOnSuccessCallback: function(){! !
    var server = sinon.useFakeServer();

   server.respondWith("GET", "/art/12/comments.json",
          [200, {"Content-Type":"application/json"},
          "[{ id:12, text:'Hello'}]"]);

! ! var spy = sinon.spy();
! ! myLib.getCommentsFor("/art/12", spy);

! ! server.respond();

! ! assert(spy.calledWith([{ id:12, text:"Hello"}]));
! },
[...]
AJAX CALL
[...]
  testOnSuccessCallback: function(){! !
    var server = sinon.useFakeServer();

    server.respondWith("GET", "/art/12/comments.json",
           [200, {"Content-Type":"application/json"},
           "[{ id:12, text:'Hello'}]"]);

! ! var spy = sinon.spy();
! ! myLib.getCommentsFor("/art/12", spy);

! ! server.respond();

! ! assert(spy.calledWith([{ id:12, text:"Hello"}]));
! },
[...]
AJAX CALL
[...]
  testOnSuccessCallback: function(){! !
    var server = sinon.useFakeServer();

    server.respondWith("GET", "/art/12/comments.json",
           [200, {"Content-Type":"application/json"},
           "[{ id:12, text:'Hello'}]"]);

! ! var spy = sinon.spy();
! ! myLib.getCommentsFor("/art/12", spy);

! ! server.respond();

! ! assert(spy.calledWith([{ id:12, text:"Hello"}]));
! },
[...]
AJAX CALL
[...]
  testOnSuccessCallback: function(){! !
    var server = sinon.useFakeServer();

    server.respondWith("GET", "/art/12/comments.json",
           [200, {"Content-Type":"application/json"},
           "[{ id:12, text:'Hello'}]"]);

! ! var spy = sinon.spy();
! ! myLib.getCommentsFor("/art/12", spy);

! ! server.respond();

! ! assert(spy.calledWith([{ id:12, text:"Hello"}]));
! },
[...]
AJAX CALL
[...]
  testOnSuccessCallback: function(){! !
    var server = sinon.useFakeServer();

    server.respondWith("GET", "/art/12/comments.json",
           [200, {"Content-Type":"application/json"},
           "[{ id:12, text:'Hello'}]"]);

! ! var spy = sinon.spy();
! ! myLib.getCommentsFor("/art/12", spy);

! ! server.respond();

! ! assert(spy.calledWith([{ id:12, text:"Hello"}]));
! },
[...]
AJAX CALL
[...]
  testOnSuccessCallback: function(){! !
    var server = sinon.useFakeServer();

    server.respondWith("GET", "/art/12/comments.json",
           [200, {"Content-Type":"application/json"},
           "[{ id:12, text:'Hello'}]"]);

! ! var spy = sinon.spy();
! ! myLib.getCommentsFor("/art/12", spy);

! ! server.respond();

! ! assert(spy.calledWith([{ id:12, text:"Hello"}]));
! },
[...]
AJAX CALL
[...]
  testOnSuccessCallback: function(){! !
    var server = sinon.useFakeServer();

    server.respondWith("GET", "/art/12/comments.json",
           [200, {"Content-Type":"application/json"},
           "[{ id:12, text:'Hello'}]"]);

! ! var spy = sinon.spy();
! ! myLib.getCommentsFor("/art/12", spy);

! ! server.respond();

! ! assert(spy.calledWith([{ id:12, text:"Hello"}]));
! },
[...]
AJAX CALL
[...]
  testOnSuccessCallback: function(){! !
    var server = sinon.useFakeServer();

    server.respondWith("GET", "/art/12/comments.json",
           [200, {"Content-Type":"application/json"},
           "[{ id:12, text:'Hello'}]"]);

! ! var spy = sinon.spy();
! ! myLib.getCommentsFor("/art/12", spy);

! ! server.respond();

! ! assert(spy.calledWith([{ id:12, text:"Hello"}]));
! },
[...]
AJAX CALL
[...]
  testOnSuccessCallback: function(){! !
    var server = sinon.useFakeServer();

    server.respondWith("GET", "/art/12/comments.json",
           [200, {"Content-Type":"application/json"},
           "[{ id:12, text:'Hello'}]"]);

! ! var spy = sinon.spy();
! ! myLib.getCommentsFor("/art/12", spy);

! ! server.respond();

! ! assert(spy.calledWith([{ id:12, text:"Hello"}]));
! },
[...]
AJAX CALL
[...]
  testOnSuccessCallback: function(){! !
    var server = sinon.useFakeServer();

    server.respondWith("GET", "/art/12/comments.json",
           [200, {"Content-Type":"application/json"},
           "[{ id:12, text:'Hello'}]"]);

! ! var spy = sinon.spy();
! ! myLib.getCommentsFor("/art/12", spy);

! ! server.respond();

! ! assert(spy.calledWith([{ id:12, text:"Hello"}]));
! },
[...]
AJAX CALL
[...]
  testOnSuccessCallback: function(){! !
    var server = sinon.useFakeServer();

    server.respondWith("GET", "/art/12/comments.json",
           [200, {"Content-Type":"application/json"},
           "[{ id:12, text:'Hello'}]"]);

! ! var spy = sinon.spy();
! ! myLib.getCommentsFor("/art/12", spy);

! ! server.respond();

! ! assert(spy.calledWith([{ id:12, text:"Hello"}]));
! },
[...]
.JS R
      ON I VE
  S IN D R
      ST
   TE T
JS H IN
  JS
E SS OR
          PR
       OM S
Y U I C .J
   S   ON I VE R
     IN D R
       ST
    TE T
JS H IN
   JS
Everyone should be happy
in the wild
in the wild
IN THE WILD


In the wild, there is
   no health care.
              Dwight Schrute (the office)
drawbacks



at the beginning
cost of change
LOOKING FORWARD
LOOKING FORWARD
LOOKING FORWARD
LOOKING FORWARD
LOOKING FORWARD
LOOKING FORWARD



    the further we look at,
  the more control we need
LOOKING FORWARD

    the further we look at,
  the more control we need
LOOKING FORWARD

    the further we look at,
  the more control we need
         let's get ready
LOOKING FORWARD

       the further we look at,
     the more control we need
             let's get ready

javascript is a programming language
LOOKING FORWARD

        the further we look at,
      the more control we need
              let's get ready

 javascript is a programming language
javascript is a serious business.
LOOKING FORWARD

        the further we look at,
      the more control we need
              let's get ready

 javascript is a programming language
javascript is a serious business.
             and, most of all...
javascript kicks asses
javascript kicks asses


           any question?
                http://spkr8.com/t/8718
                http://cedmax.com
                @cedmax

More Related Content

PDF
Javascript Best Practices
PDF
Metaprogramming JavaScript
PPTX
Node.JS error handling best practices
PPTX
Javascript Best Practices and Intro to Titanium
PDF
Metaprogramming with javascript
ZIP
Fundamental JavaScript [In Control 2009]
PDF
Secrets of JavaScript Libraries
Javascript Best Practices
Metaprogramming JavaScript
Node.JS error handling best practices
Javascript Best Practices and Intro to Titanium
Metaprogramming with javascript
Fundamental JavaScript [In Control 2009]
Secrets of JavaScript Libraries

What's hot (20)

PPTX
JavaScript in Object-Oriented Way
PDF
Patterns for JVM languages - Geecon 2014
PPTX
Javascript
PDF
JavaScript guide 2020 Learn JavaScript
PPTX
Object Oriented Programming In JavaScript
PPT
Javascript by geetanjali
PPTX
Advanced Object Oriented JavaScript (prototype, closure, scope, design patterns)
DOCX
Javascript tutorial
PPTX
Javascript
PDF
Unobtrusive JavaScript with jQuery
ODP
Object Oriented Javascript
PPT
Javascript and Jquery Best practices
PPTX
Java script
PDF
Design patterns
PPTX
Getting started with typescript
PDF
How AngularJS Embraced Traditional Design Patterns
PDF
Introduction to Javascript programming
PPTX
Introduction to JavaScript Programming
PDF
Javascript Design Patterns
PDF
JavaScript Best Pratices
JavaScript in Object-Oriented Way
Patterns for JVM languages - Geecon 2014
Javascript
JavaScript guide 2020 Learn JavaScript
Object Oriented Programming In JavaScript
Javascript by geetanjali
Advanced Object Oriented JavaScript (prototype, closure, scope, design patterns)
Javascript tutorial
Javascript
Unobtrusive JavaScript with jQuery
Object Oriented Javascript
Javascript and Jquery Best practices
Java script
Design patterns
Getting started with typescript
How AngularJS Embraced Traditional Design Patterns
Introduction to Javascript programming
Introduction to JavaScript Programming
Javascript Design Patterns
JavaScript Best Pratices
Ad

Viewers also liked (20)

PDF
The JavaScript Programming Language
PDF
Introduction to web programming with JavaScript
PDF
Javascript Tutorial
PDF
JavaScript Programming
PDF
Fabrication and Performance Analysis of Downdraft Biomass Gasifier Using Suga...
KEY
The JavaScript Programming Primer
PPT
The JavaScript Programming Language
PPTX
JavaScript 101
PDF
Reactive Programming with JavaScript
PDF
Functional Programming in JavaScript
PPTX
Biomass gasifier pune
PDF
Downdraft biomass gasification: experimental investigation and aspen plus sim...
PPTX
Biomass Gasification presentation
PDF
PPT
Biomass Gasification
PDF
Biomass heat and power - gasification CHP with universal biomass gasifier
PPTX
biomass gasification
PPTX
Biomass gassifier
PPSX
DIWE - Programming with JavaScript
PDF
Introducing Web 2.0 concepts
The JavaScript Programming Language
Introduction to web programming with JavaScript
Javascript Tutorial
JavaScript Programming
Fabrication and Performance Analysis of Downdraft Biomass Gasifier Using Suga...
The JavaScript Programming Primer
The JavaScript Programming Language
JavaScript 101
Reactive Programming with JavaScript
Functional Programming in JavaScript
Biomass gasifier pune
Downdraft biomass gasification: experimental investigation and aspen plus sim...
Biomass Gasification presentation
Biomass Gasification
Biomass heat and power - gasification CHP with universal biomass gasifier
biomass gasification
Biomass gassifier
DIWE - Programming with JavaScript
Introducing Web 2.0 concepts
Ad

Similar to Paris Web - Javascript as a programming language (20)

KEY
YOOX Launch & Learn - Javascript as a programming language
KEY
jsDay - Javascript as a programming language
PDF
JsDay - It's not you, It's me (or how to avoid being coupled with a Javascrip...
PDF
Javascript FTW
PPTX
Front End Development | Introduction
PDF
Flex For Java Developers - SDForum Java SIG
PDF
Choosing Javascript Libraries to Adopt for Development
PDF
Node.js #digpen presentation
PDF
Finding harmony in web development
PPTX
Part Time Agile
PDF
Professional web development with libraries
PDF
Tools For jQuery Application Architecture (Extended Slides)
PPT
Building Rich User Experiences Without JavaScript Spaghetti
KEY
10 Years of JavaScript
PDF
FFWD.PRO - It's not you, It's me (or how to avoid being coupled with a Javasc...
PDF
The Developers World
KEY
TxJS 2011
PPT
Gluing it all together: How teams can build enterprise JavaScript application...
PPTX
WT Module-3.pptx
PDF
The art and pain of teaching JavaScript
YOOX Launch & Learn - Javascript as a programming language
jsDay - Javascript as a programming language
JsDay - It's not you, It's me (or how to avoid being coupled with a Javascrip...
Javascript FTW
Front End Development | Introduction
Flex For Java Developers - SDForum Java SIG
Choosing Javascript Libraries to Adopt for Development
Node.js #digpen presentation
Finding harmony in web development
Part Time Agile
Professional web development with libraries
Tools For jQuery Application Architecture (Extended Slides)
Building Rich User Experiences Without JavaScript Spaghetti
10 Years of JavaScript
FFWD.PRO - It's not you, It's me (or how to avoid being coupled with a Javasc...
The Developers World
TxJS 2011
Gluing it all together: How teams can build enterprise JavaScript application...
WT Module-3.pptx
The art and pain of teaching JavaScript

Recently uploaded (20)

PDF
Chapter 3 Spatial Domain Image Processing.pdf
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
PDF
NewMind AI Monthly Chronicles - July 2025
PDF
cuic standard and advanced reporting.pdf
PPTX
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
PDF
Network Security Unit 5.pdf for BCA BBA.
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PDF
Machine learning based COVID-19 study performance prediction
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PDF
Advanced Soft Computing BINUS July 2025.pdf
PDF
Bridging biosciences and deep learning for revolutionary discoveries: a compr...
PPTX
breach-and-attack-simulation-cybersecurity-india-chennai-defenderrabbit-2025....
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PDF
GamePlan Trading System Review: Professional Trader's Honest Take
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PDF
Modernizing your data center with Dell and AMD
PDF
KodekX | Application Modernization Development
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
Chapter 3 Spatial Domain Image Processing.pdf
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
NewMind AI Monthly Chronicles - July 2025
cuic standard and advanced reporting.pdf
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
Network Security Unit 5.pdf for BCA BBA.
Reach Out and Touch Someone: Haptics and Empathic Computing
Machine learning based COVID-19 study performance prediction
Mobile App Security Testing_ A Comprehensive Guide.pdf
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
Advanced Soft Computing BINUS July 2025.pdf
Bridging biosciences and deep learning for revolutionary discoveries: a compr...
breach-and-attack-simulation-cybersecurity-india-chennai-defenderrabbit-2025....
Advanced methodologies resolving dimensionality complications for autism neur...
GamePlan Trading System Review: Professional Trader's Honest Take
Diabetes mellitus diagnosis method based random forest with bat algorithm
Modernizing your data center with Dell and AMD
KodekX | Application Modernization Development
Dropbox Q2 2025 Financial Results & Investor Presentation
Per capita expenditure prediction using model stacking based on satellite ima...

Paris Web - Javascript as a programming language

  • 2. IS Javascript As A Programming Language Versioning, Test Driven Development & Continuous Integration
  • 3. IS Javascript As A Programming Language Versioning, Test Driven Development & Continuous Integration
  • 5. Hello, who’s speaking? Marco Cedaro @cedmax
  • 6. Hello, who’s speaking? Marco Cedaro @cedmax They said I am a... Frontend Cowboy Nicola Vitto Jr. Javascript Pervert Roberto Felter Perfect Stranger basically anyone else
  • 7. Hello, who’s speaking? Marco Cedaro @cedmax Actually I am: a Frontend Developer at Spreaker.com
  • 8. Hello, who’s speaking? Marco Cedaro @cedmax Actually I am: a Frontend Developer at Spreaker.com a conference organizer with From The Front
  • 9. Hello, who’s speaking? Marco Cedaro @cedmax Actually I am: a Frontend Developer at Spreaker.com a conference organizer with From The Front and a javascript pervert
  • 11. something in common with Robert Nyman
  • 12. something in common with Robert Nyman
  • 13. I believe I can fly
  • 14. I believe I can fly
  • 15. I believe I can fly Be brave. Take risks. Nothing can substitute experience. Paulo Coelho
  • 16. once upon a time
  • 17. once upon a time we had no control
  • 18. once upon a time we had no control javascript was the land of the brave
  • 19. once upon a time we had no control javascript was the land of the brave we were fearless and unconscious
  • 20. once upon a time we had no control javascript was the land of the brave we were fearless and unconscious we were proud of being like that
  • 24. once upon a time web engineer had a very bad opinion of us
  • 26. but it wasn't fair we didn't have IDEs & tools they did
  • 27. but it wasn't fair we didn't have IDEs & tools they did actually it was our own fault
  • 28. but it wasn't fair we didn't have IDEs & tools they did actually it was our own fault we were not ready
  • 29. but it wasn't fair we didn't have IDEs & tools they did actually it was our own fault we were not ready and javascript was neither
  • 30. but, again, life goes on...
  • 33. it's not about the language itself
  • 35. Frontend developers have to claim their role in development roadmap and business strategy
  • 36. Javascript is a serious business
  • 38. less bandwidth and server load loading resources and content when needed something we can achieve
  • 39. less bandwidth and performance boosts server load loading that can lead to better resources and content conversion rates when needed something we can achieve
  • 40. less bandwidth and performance boosts cross platform server load loading that can lead to better development: less resources and content conversion rates maintenance costs when needed something we can achieve
  • 41. less bandwidth and performance boosts cross platform server load loading that can lead to better development: less resources and content conversion rates maintenance costs when needed money
  • 46. what's missing? If I had nine of my fingers missing I wouldn't type any slower. Mitch Hedberg
  • 50. The designer introduces a slider on some websites: ”it’s cool on apple store”. The developer gets a jQuery plugin online the small web agency
  • 51. The designer introduces a slider on Major release of the some websites: most used browser. ”it’s cool on apple store”. A small fix has been released, they have to change The developer gets a jQuery 5 files in 5 different projects. plugin online the small web agency
  • 52. The designer Oh damn! There’s no introduces a slider on Major release of the mouse wheel some websites: most used browser. integration! ”it’s cool on apple store”. A small fix has been released, they have to change should they ask for support The developer gets a jQuery 5 files in 5 different projects. or should they change the plugin online library by themself? the small web agency
  • 53. am I the only one or there’s something wrong?
  • 54. The client-side architecture has been built on the most known and supported framework 2006 the big corp
  • 55. The client-side Everything seems to be architecture has been fine, except that the built on the most well known framework known and supported was being replaced by a framework powerful new one 2006 2008 - 2010 the big corp
  • 56. The client-side Everything seems to be They were forced to architecture has been fine, except that the change the whole built on the most well known framework codebase at once to known and supported was being replaced by a reduce maintenance framework powerful new one and development costs 2006 2008 - 2010 2011 the big corp
  • 57. here we are again
  • 63. continuous integration A software development practice where members of a team integrate their work frequently [...] to detect integration errors as quickly as possible. Martin Fowler
  • 64. I Build So Consistently
  • 65. I Build So Consistently identify
  • 66. I Build So Consistently write a build script identify
  • 67. I Build So Consistently write a build script identify share
  • 68. I Build So Consistently write a build script identify make it share continuous
  • 69. How can we take advantages from a continuous integration process?
  • 76. basically ie7
  • 79. choose your tools A man cannot be too careful in the choice of his enemies Oscar Wilde
  • 83. a code quality tool like Douglas Crockford's JSLint
  • 84. a code quality tool like Douglas Crockford's JSLint but
  • 85. a code quality tool like Douglas Crockford's JSLint but customizable
  • 86. a tool for stupid?
  • 88. R IV ER ST D TE T JS H IN JS
  • 89. once upon a time
  • 93. jsTestDriver works from console runs a server opens browsers
  • 94. jsTestDriver works from console runs a server opens browsers runs test suites
  • 95. jsTestDriver works from console runs a server opens browsers runs test suites retrieves results in console
  • 100. have you seen Lost?
  • 101. how does it work?
  • 102. write a test how does it work?
  • 103. write a test let it fail how does it work?
  • 104. write a test let it fail write the code how does it work?
  • 105. write a test let it fail write the code run the test again how does it work?
  • 106. write a test let it fail write the code run the test refactor again how does it work?
  • 110. Unit testing is supposed to test a single atomic “unit” of functionality without dependencies on anything else The curious case of Javascript unit testing
  • 111. Unit testing is This is where you start supposed to test a to run into serious single atomic “unit” of dependency problems functionality without due to the interrelation dependencies on with HTML and CSS anything else The curious case of Javascript unit testing
  • 112. Unit testing is What do you test? This is where you start supposed to test a Usually how the user to run into serious single atomic “unit” of interface responds to dependency problems functionality without user input. due to the interrelation dependencies on Actually, the realm of with HTML and CSS anything else functional testing The curious case of Javascript unit testing
  • 115. keep it real To all my homies working on the 9 to 5 Shaggy
  • 117. I used to work with these guys
  • 118. _$ = (function() { var registered = {}; return { ! ! pub: function(event, memo) { ! ! ! if (registered[event] instanceof Array){ ! ! ! ! var handlers = [].concat(registered[event]); ! ! ! ! for (var i=0, h; (h = handlers[i]); i++){ ! ! ! ! ! h.call(this, memo); ! ! ! ! } ! ! ! } ! ! }, ! ! sub: function(event, handler) { ! ! ! if (typeof registered[event] === "undefined"){ ! ! ! ! registered[event] = []; ! ! ! } ! ! ! registered[event].push(handler); ! ! } }; })();
  • 119. _$ = (function() { var registered = {}; return { ! ! pub: function(event, memo) { ! ! ! if (registered[event] instanceof Array){ ! ! ! ! var handlers = [].concat(registered[event]); ! ! ! ! for (var i=0, h; (h = handlers[i]); i++){ ! ! ! ! ! h.call(this, memo); ! ! ! ! } ! ! ! } ! ! }, ! ! sub: function(event, handler) { ! ! ! if (typeof registered[event] === "undefined"){ ! ! ! ! registered[event] = []; ! ! ! } ! ! ! registered[event].push(handler); ! ! } }; })();
  • 120. _$.sub("customEvent", function(obj) { ! //DO STUFF }); _$.pub("customEvent"); _$.pub("customEvent", { prop : "value" });
  • 121. _$.sub("customEvent", function(obj) { ! //DO STUFF }); _$.pub("customEvent"); _$.pub("customEvent", { prop : "value" });
  • 122. _$.sub("customEvent", function(obj) { ! //DO STUFF }); _$.pub("customEvent"); _$.pub("customEvent", { prop : "value" });
  • 123. _$ = (function() { var registered = {}; return { ! ! pub: function(event, memo) { ! ! ! if (registered[event] instanceof Array){ ! ! ! ! var handlers = [].concat(registered[event]); ! ! ! ! for (var i=0, h; (h = handlers[i]); i++){ ! ! ! ! ! h.call(this, memo); ! ! ! ! } ! ! ! } ! ! }, ! ! sub: function(event, handler) { ! ! ! if (typeof registered[event] === "undefined"){ ! ! ! ! registered[event] = []; ! ! ! } ! ! ! registered[event].push(handler); ! ! } }; })();
  • 124. _$ = (function (_) { ! return { ! ! pub: function(a, b, c, d) { ! ! ! for (d=-1, c=[].concat(_[a]); c[++d];) c[d](b) ! ! }, ! ! sub: function(a, b) { ! ! ! (_[a] || (_[a] = [])).push(b) ! ! } ! } })({})
  • 125. _$ = (function (_) { ! return { ! ! pub: function(a, b, c, d) { ! ! ! for (d=-1, c=[].concat(_[a]); c[++d];) c[d](b) ! ! }, ! ! sub: function(a, b) { ! ! ! (_[a] || (_[a] = [])).push(b) ! ! } tes ! } })({}) #140 by
  • 126. _$ = (function() { var registered = {}; return { ! ! pub: function(event, memo) { ! ! ! if (registered[event] instanceof Array){ ! ! ! ! var handlers = [].concat(registered[event]); ! ! ! ! for (var i=0, h; (h = handlers[i]); i++){ ! ! ! ! ! h.call(this, memo); ! ! ! ! } ! ! ! } ! ! }, ! ! sub: function(event, handler) { ! ! ! if (typeof registered[event] === "undefined"){ ! ! ! ! registered[event] = []; ! ! ! } ! ! ! registered[event].push(handler); ! ! } }; })();
  • 127. _$ = (function (_) { ! return { ! ! pub: function(a, b, c, d) { ! ! ! for (d=-1, c=[].concat(_[a]); c[++d];) c[d](b) ! ! }, ! ! sub: function(a, b) { ! ! ! (_[a] || (_[a] = [])).push(b) ! ! } tes ! } })({}) #140 by
  • 128. _$ = (function() { var registered = {}; return { ! ! pub: function(event, memo) { ! ! ! if (registered[event] instanceof Array){ ! ! ! ! var handlers = [].concat(registered[event]); ! ! ! ! for (var i=0, h; (h = handlers[i]); i++){ ! ! ! ! ! h.call(this, memo); ! ! ! ! } ! ! ! } ! ! }, ! ! sub: function(event, handler) { ! ! ! if (typeof registered[event] === "undefined"){ ! ! ! ! registered[event] = []; ! ! ! } ! ! ! registered[event].push(handler); ! ! } }; })();
  • 129. _$ = (function (_) { ! return { ! ! pub: function(a, b, c, d) { ! ! ! for (d=-1, c=[].concat(_[a]); c[++d];) c[d](b) ! ! }, ! ! sub: function(a, b) { ! ! ! (_[a] || (_[a] = [])).push(b) ! ! } tes ! } })({}) #140 by
  • 130. _$ = (function (_) { ! return { ! ! pub: function(a, b, c, d) { ! ! ! for (d=-1, c=[].concat(_[a]); c[++d];) c[d](b) ! ! }, ! ! sub: function(a, b) { ! ! ! (_[a] || (_[a] = [])).push(b) ! ! } tes ! } })({}) #140 by
  • 131. [...] testPub: function(){! ! ! ! var a = 0;! ! ! _$.sub('testNotify', function(){ a = 1; }); ! ! _$.pub('testNotify'); ! ! assertEquals(1, a); ! }, ! ! ! ! testNotifyWithMemo: function(){!! ! ! var a = 0 ;! ! ! _$.sub('testNotify', function(memo){ ! ! ! ! a = memo.test; ! ! }); ! ! _$.pub('testNotify', {test: 1}); ! ! assertEquals(1, a); ! }, [...]
  • 132. [...] testPub: function(){! ! ! ! var a = 0;! ! ! _$.sub('testNotify', function(){ a = 1; }); ! ! _$.pub('testNotify'); ! ! assertEquals(1, a); ! }, ! ! ! ! testNotifyWithMemo: function(){!! ! ! var a = 0 ;! ! ! _$.sub('testNotify', function(memo){ ! ! ! ! a = memo.test; ! ! }); ! ! _$.pub('testNotify', {test: 1}); ! ! assertEquals(1, a); ! }, [...]
  • 133. [...] testPub: function(){! ! ! ! var a = 0;! ! ! _$.sub('testNotify', function(){ a = 1; }); ! ! _$.pub('testNotify'); ! ! assertEquals(1, a); ! }, ! ! ! ! testNotifyWithMemo: function(){!! ! ! var a = 0 ;! ! ! _$.sub('testNotify', function(memo){ ! ! ! ! a = memo.test; ! ! }); ! ! _$.pub('testNotify', {test: 1}); ! ! assertEquals(1, a); ! }, [...]
  • 134. [...] testPub: function(){! ! ! ! var a = 0;! ! ! _$.sub('testNotify', function(){ a = 1; }); ! ! _$.pub('testNotify'); ! ! assertEquals(1, a); ! }, ! ! ! ! testNotifyWithMemo: function(){!! ! ! var a = 0 ;! ! ! _$.sub('testNotify', function(memo){ ! ! ! ! a = memo.test; ! ! }); ! ! _$.pub('testNotify', {test: 1}); ! ! assertEquals(1, a); ! }, [...]
  • 135. [...] testPub: function(){! ! ! ! var a = 0;! ! ! _$.sub('testNotify', function(){ a = 1; }); ! ! _$.pub('testNotify'); ! ! assertEquals(1, a); ! }, ! ! ! ! testNotifyWithMemo: function(){!! ! ! var a = 0 ;! ! ! _$.sub('testNotify', function(memo){ ! ! ! ! a = memo.test; ! ! }); ! ! _$.pub('testNotify', {test: 1}); ! ! assertEquals(1, a); ! }, [...]
  • 136. [...] testPub: function(){! ! ! ! var a = 0;! ! ! _$.sub('testNotify', function(){ a = 1; }); ! ! _$.pub('testNotify'); ! ! assertEquals(1, a); ! }, ! ! ! ! testNotifyWithMemo: function(){!! ! ! var a = 0 ; ! ! _$.sub('testNotify', function(memo){ ! ! ! ! a = memo.test; ! ! }); ! ! _$.pub('testNotify', {test: 1}); ! ! assertEquals(1, a); ! }, [...]
  • 137. [...] testPub: function(){! ! ! ! var a = 0;! ! ! _$.sub('testNotify', function(){ a = 1; }); ! ! _$.pub('testNotify'); ! ! assertEquals(1, a); ! }, ! ! ! ! testNotifyWithMemo: function(){!! ! ! var a = 0 ;! ! ! _$.sub('testNotify', function(memo){ ! ! ! ! a = memo.test; ! ! }); ! ! _$.pub('testNotify', {test: 1}); ! ! assertEquals(1, a); ! }, [...]
  • 140. R IV ER ST D TE T JS H IN JS
  • 141. .JS R ON I VE S IN D R ST TE T JS H IN JS
  • 143. SPIES a function that records arguments, return value, the value of this and exception thrown (if any) for all its calls. a mock library
  • 144. SPIES STUBS a function that records functions (spies) with arguments, return pre-programmed value, the value of this behavior. and exception thrown (if any) for all its calls. a mock library
  • 145. SPIES STUBS MOCKS a function that records functions (spies) with functions (spies) with arguments, return pre-programmed pre-programmed value, the value of this behavior. behavior (stubs) as well and exception thrown as pre-programmed (if any) for all its calls. expectations. a mock library
  • 146. [...] 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 ! }, [...]
  • 147. SPY [...] 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 ! }, [...]
  • 148. SPY [...] 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 ! }, [...]
  • 149. SPY [...] 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 ! }, [...]
  • 150. SPY [...] 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 ! }, [...]
  • 151. STUB [...] 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 ! }, [...]
  • 152. STUB [...] 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 ! }, [...]
  • 153. STUB [...] 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 ! }, [...]
  • 154. STUB [...] 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 ! }, [...]
  • 155. MOCK [...] testMyLibRegistersToSystemOnEvent: function(){! ! ! ! var spy = sinon.spy(_$, 'watch');! ! ! //DO STUFF TO INIT YOUR LIB ! ! assertTrue(spy.calledWith('SystemOn')); ! }, [...]
  • 156. MOCK [...] //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(); ! }, [...]
  • 157. MOCK [...] //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(); ! }, [...]
  • 158. MOCK [...] //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(); ! }, [...]
  • 159. AJAX CALL [...] testOnSuccessCallback: function(){! ! var server = sinon.useFakeServer(); server.respondWith("GET", "/art/12/comments.json", [200, {"Content-Type":"application/json"}, "[{ id:12, text:'Hello'}]"]); ! ! var spy = sinon.spy(); ! ! myLib.getCommentsFor("/art/12", spy); ! ! server.respond(); ! ! assert(spy.calledWith([{ id:12, text:"Hello"}])); ! }, [...]
  • 160. AJAX CALL [...] testOnSuccessCallback: function(){! ! var server = sinon.useFakeServer(); server.respondWith("GET", "/art/12/comments.json", [200, {"Content-Type":"application/json"}, "[{ id:12, text:'Hello'}]"]); ! ! var spy = sinon.spy(); ! ! myLib.getCommentsFor("/art/12", spy); ! ! server.respond(); ! ! assert(spy.calledWith([{ id:12, text:"Hello"}])); ! }, [...]
  • 161. AJAX CALL [...] testOnSuccessCallback: function(){! ! var server = sinon.useFakeServer(); server.respondWith("GET", "/art/12/comments.json", [200, {"Content-Type":"application/json"}, "[{ id:12, text:'Hello'}]"]); ! ! var spy = sinon.spy(); ! ! myLib.getCommentsFor("/art/12", spy); ! ! server.respond(); ! ! assert(spy.calledWith([{ id:12, text:"Hello"}])); ! }, [...]
  • 162. AJAX CALL [...] testOnSuccessCallback: function(){! ! var server = sinon.useFakeServer(); server.respondWith("GET", "/art/12/comments.json", [200, {"Content-Type":"application/json"}, "[{ id:12, text:'Hello'}]"]); ! ! var spy = sinon.spy(); ! ! myLib.getCommentsFor("/art/12", spy); ! ! server.respond(); ! ! assert(spy.calledWith([{ id:12, text:"Hello"}])); ! }, [...]
  • 163. AJAX CALL [...] testOnSuccessCallback: function(){! ! var server = sinon.useFakeServer(); server.respondWith("GET", "/art/12/comments.json", [200, {"Content-Type":"application/json"}, "[{ id:12, text:'Hello'}]"]); ! ! var spy = sinon.spy(); ! ! myLib.getCommentsFor("/art/12", spy); ! ! server.respond(); ! ! assert(spy.calledWith([{ id:12, text:"Hello"}])); ! }, [...]
  • 164. AJAX CALL [...] testOnSuccessCallback: function(){! ! var server = sinon.useFakeServer(); server.respondWith("GET", "/art/12/comments.json", [200, {"Content-Type":"application/json"}, "[{ id:12, text:'Hello'}]"]); ! ! var spy = sinon.spy(); ! ! myLib.getCommentsFor("/art/12", spy); ! ! server.respond(); ! ! assert(spy.calledWith([{ id:12, text:"Hello"}])); ! }, [...]
  • 165. AJAX CALL [...] testOnSuccessCallback: function(){! ! var server = sinon.useFakeServer(); server.respondWith("GET", "/art/12/comments.json", [200, {"Content-Type":"application/json"}, "[{ id:12, text:'Hello'}]"]); ! ! var spy = sinon.spy(); ! ! myLib.getCommentsFor("/art/12", spy); ! ! server.respond(); ! ! assert(spy.calledWith([{ id:12, text:"Hello"}])); ! }, [...]
  • 166. AJAX CALL [...] testOnSuccessCallback: function(){! ! var server = sinon.useFakeServer(); server.respondWith("GET", "/art/12/comments.json", [200, {"Content-Type":"application/json"}, "[{ id:12, text:'Hello'}]"]); ! ! var spy = sinon.spy(); ! ! myLib.getCommentsFor("/art/12", spy); ! ! server.respond(); ! ! assert(spy.calledWith([{ id:12, text:"Hello"}])); ! }, [...]
  • 167. AJAX CALL [...] testOnSuccessCallback: function(){! ! var server = sinon.useFakeServer(); server.respondWith("GET", "/art/12/comments.json", [200, {"Content-Type":"application/json"}, "[{ id:12, text:'Hello'}]"]); ! ! var spy = sinon.spy(); ! ! myLib.getCommentsFor("/art/12", spy); ! ! server.respond(); ! ! assert(spy.calledWith([{ id:12, text:"Hello"}])); ! }, [...]
  • 168. AJAX CALL [...] testOnSuccessCallback: function(){! ! var server = sinon.useFakeServer(); server.respondWith("GET", "/art/12/comments.json", [200, {"Content-Type":"application/json"}, "[{ id:12, text:'Hello'}]"]); ! ! var spy = sinon.spy(); ! ! myLib.getCommentsFor("/art/12", spy); ! ! server.respond(); ! ! assert(spy.calledWith([{ id:12, text:"Hello"}])); ! }, [...]
  • 169. AJAX CALL [...] testOnSuccessCallback: function(){! ! var server = sinon.useFakeServer(); server.respondWith("GET", "/art/12/comments.json", [200, {"Content-Type":"application/json"}, "[{ id:12, text:'Hello'}]"]); ! ! var spy = sinon.spy(); ! ! myLib.getCommentsFor("/art/12", spy); ! ! server.respond(); ! ! assert(spy.calledWith([{ id:12, text:"Hello"}])); ! }, [...]
  • 170. .JS R ON I VE S IN D R ST TE T JS H IN JS
  • 171. E SS OR PR OM S Y U I C .J S ON I VE R IN D R ST TE T JS H IN JS
  • 175. IN THE WILD In the wild, there is no health care. Dwight Schrute (the office)
  • 183. LOOKING FORWARD the further we look at, the more control we need
  • 184. LOOKING FORWARD the further we look at, the more control we need
  • 185. LOOKING FORWARD the further we look at, the more control we need let's get ready
  • 186. LOOKING FORWARD the further we look at, the more control we need let's get ready javascript is a programming language
  • 187. LOOKING FORWARD the further we look at, the more control we need let's get ready javascript is a programming language javascript is a serious business.
  • 188. LOOKING FORWARD the further we look at, the more control we need let's get ready javascript is a programming language javascript is a serious business. and, most of all...
  • 190. javascript kicks asses any question? http://spkr8.com/t/8718 http://cedmax.com @cedmax