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

I'm Afraid of JavaScript

I'm Afraid of JavaScript

Justin Searls

November 05, 2011
Tweet

More Decks by Justin Searls

Other Decks in Programming

Transcript

  1. stupid things we do: we pair less often we share

    less often we change less often
  2. we defer too often stupid things we do: we defend

    too often we deflect too often
  3. just throw away classes & interfaces strong typing most keywords

    ORACLE (or MS) JAVASCRIPT IS BASICALLY JAVA (OR C#)
  4. JAVASCRIPT IS BASICALLY JAVA (OR C#) and then add 1st

    class functions object literals tons of gotchas healthy open source libs
  5. just throw away mixins & modules method_missing def and end

    easy debugging COFFEESCRIPT IS BASICALLY RUBY (OR PYTHON)
  6. and then add list comprehension object literals existential operator huge

    install base COFFEESCRIPT IS BASICALLY RUBY (OR PYTHON)
  7.          

           
  8. run it yourself! http://is.gd/logic1 describe('CallList', function() { describe("#moveUp", function() {

    context("moving up C", function() { it("places it above B", function() { }); }); }); });
  9. run it yourself! http://is.gd/logic1 describe('CallList', function() { var subject; beforeEach(function()

    { subject = new CallList({items: ['A','B','C']}); }); describe("#moveUp", function() { context("moving up C", function() { it("places it above B", function() { }); }); }); });
  10. run it yourself! http://is.gd/logic1 describe('CallList', function() { var subject; beforeEach(function()

    { subject = new CallList({items: ['A','B','C']}); }); describe("#moveUp", function() { context("moving up C", function() { beforeEach(function() { subject.moveUp('C'); }); it("places it above B", function() { }); }); }); });
  11. run it yourself! http://is.gd/logic1 describe('CallList', function() { var subject; beforeEach(function()

    { subject = new CallList({items: ['A','B','C']}); }); describe("#moveUp", function() { context("moving up C", function() { beforeEach(function() { subject.moveUp('C'); }); it("places it above B", function() { expect(subject.get('items')).toEqual(['A','C','B']); }); }); }); });
  12. run it yourself! http://is.gd/logic2 describe('CallList', function() { var subject; beforeEach(function()

    { subject = new CallList({items: ['A','B','C']}); }); describe("#moveUp", function() { context("moving up C", function() {...}); context("moving up B", function() { }); }); });
  13. run it yourself! http://is.gd/logic2 describe('CallList', function() { var subject; beforeEach(function()

    { subject = new CallList({items: ['A','B','C']}); }); describe("#moveUp", function() { context("moving up C", function() {...}); context("moving up B", function() { it("places B above A", function() { }); }); }); });
  14. run it yourself! http://is.gd/logic2 describe('CallList', function() { var subject; beforeEach(function()

    { subject = new CallList({items: ['A','B','C']}); }); describe("#moveUp", function() { context("moving up C", function() {...}); context("moving up B", function() { beforeEach(function() { subject.moveUp('B'); }); it("places B above A", function() { }); }); }); });
  15. run it yourself! http://is.gd/logic2 describe('CallList', function() { var subject; beforeEach(function()

    { subject = new CallList({items: ['A','B','C']}); }); describe("#moveUp", function() { context("moving up C", function() {...}); context("moving up B", function() { beforeEach(function() { subject.moveUp('B'); }); it("places B above A", function() { expect(subject.get('items')).toEqual(['B','A','C']); }); }); }); });
  16. run it yourself! http://is.gd/logic2 window.CallList = Backbone.Model.extend({ moveUp: function(item) {

    var items = this.get('items'); var index = _(items).indexOf(item) - 1; } });
  17. run it yourself! http://is.gd/logic2 window.CallList = Backbone.Model.extend({ moveUp: function(item) {

    var items = this.get('items'); var index = _(items).indexOf(item) - 1; items.splice(index,2,item,items[index]); } });
  18. run it yourself! http://is.gd/logic3 describe('CallList', function() { var subject; beforeEach(function()

    { subject = new CallList({items: ['A','B','C']}); }); describe("#moveUp", function() { context("moving up C", function() {...}); context("moving up B", function() {...}); context("moving up A", function() { }); }); });
  19. run it yourself! http://is.gd/logic3 describe('CallList', function() { var subject; beforeEach(function()

    { subject = new CallList({items: ['A','B','C']}); }); describe("#moveUp", function() { context("moving up C", function() {...}); context("moving up B", function() {...}); context("moving up A", function() { it("leaves the items as they were", function() { }); }); }); });
  20. run it yourself! http://is.gd/logic3 describe('CallList', function() { var subject; beforeEach(function()

    { subject = new CallList({items: ['A','B','C']}); }); describe("#moveUp", function() { context("moving up C", function() {...}); context("moving up B", function() {...}); context("moving up A", function() { beforeEach(function() { subject.moveUp('A'); }); it("leaves the items as they were", function() { }); }); }); });
  21. run it yourself! http://is.gd/logic3 describe('CallList', function() { var subject; beforeEach(function()

    { subject = new CallList({items: ['A','B','C']}); }); describe("#moveUp", function() { context("moving up C", function() {...}); context("moving up B", function() {...}); context("moving up A", function() { beforeEach(function() { subject.moveUp('A'); }); it("leaves the items as they were", function() { expect(subject.get('items')).toEqual(['A','B','C']); }); }); }); });
  22. run it yourself! http://is.gd/logic3 window.CallList = Backbone.Model.extend({ moveUp: function(item) {

    var items = this.get('items'); var index = _(items).indexOf(item) - 1; items.splice(index,2,item,items[index]); } });
  23. run it yourself! http://is.gd/logic3 window.CallList = Backbone.Model.extend({ moveUp: function(item) {

    var items = this.get('items'); var index = _(items).indexOf(item) - 1; if(index >= 0) { items.splice(index,2,item,items[index]); } } });
  24. ->

  25. run it yourself! http://is.gd/view1 describe "CallListView", -> beforeEach -> @subject

    = new CallListView describe "events", -> it "binds to up-arrow clicks", -> expect(@subject.events).toEqual "click .up-arrow": 'moveUp'
  26. run it yourself! http://is.gd/view2 describe "CallListView", -> beforeEach -> @subject

    = new CallListView describe "events", -> it "binds to up-arrow clicks", -> expect(@subject.events).toEqual "click .up-arrow": 'moveUp' describe "#moveUp", -> it "tells the model to move up the arrow's text", ->
  27. run it yourself! http://is.gd/view2 describe "CallListView", -> beforeEach -> @model

    = jasmine.createSpyObj('CallList',['bind','moveUp']) @subject = new CallListView model: @model describe "events", -> it "binds to up-arrow clicks", -> expect(@subject.events).toEqual "click .up-arrow": 'moveUp' describe "#moveUp", -> it "tells the model to move up the arrow's text", ->
  28. run it yourself! http://is.gd/view2 describe "CallListView", -> beforeEach -> @model

    = jasmine.createSpyObj('CallList',['bind','moveUp']) @subject = new CallListView model: @model describe "events", -> it "binds to up-arrow clicks", -> expect(@subject.events).toEqual "click .up-arrow": 'moveUp' describe "#moveUp", -> beforeEach -> $upArrow = $(@subject.el).inject('up-arrow').text('C') it "tells the model to move up the arrow's text", ->
  29. run it yourself! http://is.gd/view2 describe "CallListView", -> beforeEach -> @model

    = jasmine.createSpyObj('CallList',['bind','moveUp']) @subject = new CallListView model: @model describe "events", -> it "binds to up-arrow clicks", -> expect(@subject.events).toEqual "click .up-arrow": 'moveUp' describe "#moveUp", -> beforeEach -> $upArrow = $(@subject.el).inject('up-arrow').text('C') it "tells the model to move up the arrow's text", -> jasmine-fixture https://github.com/searls/jasmine-fixture
  30. run it yourself! http://is.gd/view2 describe "CallListView", -> beforeEach -> @model

    = jasmine.createSpyObj('CallList',['bind','moveUp']) @subject = new CallListView model: @model describe "events", -> it "binds to up-arrow clicks", -> expect(@subject.events).toEqual "click .up-arrow": 'moveUp' describe "#moveUp", -> beforeEach -> $upArrow = $(@subject.el).inject('up-arrow').text('C') @subject.moveUp target: $upArrow[0] it "tells the model to move up the arrow's text", ->
  31. run it yourself! http://is.gd/view2 describe "CallListView", -> beforeEach -> @model

    = jasmine.createSpyObj('CallList',['bind','moveUp']) @subject = new CallListView model: @model describe "events", -> it "binds to up-arrow clicks", -> expect(@subject.events).toEqual "click .up-arrow": 'moveUp' describe "#moveUp", -> beforeEach -> $upArrow = $(@subject.el).inject('up-arrow').text('C') @subject.moveUp target: $upArrow[0] it "tells the model to move up the arrow's text", -> expect(@model.moveUp).toHaveBeenCalledWith 'C'
  32. run it yourself! http://is.gd/view2 class CallListView extends Backbone.View events: "click

    .up-arrow": "moveUp" moveUp: (e) -> @model.moveUp $(e.target).text()
  33. run it yourself! http://is.gd/template1 describe "CallListView", -> beforeEach -> @model

    = jasmine.createSpyObj('CallList',['bind','moveUp']) @subject = new CallListView model: @model describe "events", -> ... describe "#moveUp", -> ... describe "#render", -> it "renders the template with the model's JSON", ->
  34. run it yourself! http://is.gd/template1 describe "CallListView", -> beforeEach -> @model

    = jasmine.createSpyObj('CallList',['bind','moveUp']) @subject = new CallListView model: @model describe "events", -> ... describe "#moveUp", -> ... describe "#render", -> it "renders the template with the model's JSON", -> expect($(@subject.el)).toHaveHtml('HTML <b>for</b> bar')
  35. run it yourself! http://is.gd/template1 describe "CallListView", -> beforeEach -> @model

    = jasmine.createSpyObj('CallList',['bind','moveUp']) @subject = new CallListView model: @model describe "events", -> ... describe "#moveUp", -> ... describe "#render", -> it "renders the template with the model's JSON", -> expect($(@subject.el)).toHaveHtml('HTML <b>for</b> bar') jasmine-jquery https://github.com/velesin/jasmine-jquery
  36. run it yourself! http://is.gd/template1 describe "CallListView", -> beforeEach -> @model

    = jasmine.createSpyObj('CallList',['bind','moveUp']) @subject = new CallListView model: @model describe "events", -> ... describe "#moveUp", -> ... describe "#render", -> beforeEach -> @subject.render() it "renders the template with the model's JSON", -> expect($(@subject.el)).toHaveHtml('HTML <b>for</b> bar')
  37. run it yourself! http://is.gd/template1 describe "CallListView", -> beforeEach -> @model

    = jasmine.createSpyObj('CallList',['bind','moveUp','toJSON']) @subject = new CallListView model: @model describe "events", -> ... describe "#moveUp", -> ... describe "#render", -> beforeEach -> @model.toJSON.andReturn foo: "bar" @subject.render() it "renders the template with the model's JSON", -> expect($(@subject.el)).toHaveHtml('HTML <b>for</b> bar')
  38. run it yourself! http://is.gd/template1 describe "CallListView", -> beforeEach -> $template

    = inject('<script id="call-list-template" type="text/html"></script>') $template.html('HTML <b>for</b> <%= foo %>') @model = jasmine.createSpyObj('CallList',['bind','moveUp','toJSON']) @subject = new CallListView model: @model describe "events", -> ... describe "#moveUp", -> ... describe "#render", -> beforeEach -> @model.toJSON.andReturn foo: "bar" @subject.render() it "renders the template with the model's JSON", -> expect($(@subject.el)).toHaveHtml('HTML <b>for</b> bar')
  39. run it yourself! http://is.gd/template1 class CallListView extends Backbone.View events: "click

    .up-arrow": "moveUp" initialize: -> @template = _.template($('#call-list-template').html()) moveUp: (e) -> @model.moveUp $(e.target).text()
  40. run it yourself! http://is.gd/template1 class CallListView extends Backbone.View events: "click

    .up-arrow": "moveUp" initialize: -> @template = _.template($('#call-list-template').html()) moveUp: (e) -> @model.moveUp $(e.target).text() render: -> $(@el).html(@template(@model.toJSON()))
  41. jasmine helpers jQuery Spec’n https://github.com/velesin/jasmine-jquery HTML Inject’n https://github.com/searls/jasmine-fixture Conditional Stub’n

    https://github.com/searls/jasmine-stealth Given-When-Then’n https://github.com/searls/jasmine-given
  42. •g l e e * for the color scheme •clafouti

    for the despair statue •SteveFE for the pouting girl •ifollowtherabbit for another color scheme •mokra for the jaw-dropped baby •Epicality for the third color scheme credits