updates, time to do this

This commit is contained in:
John Bintz 2012-03-24 10:20:56 -04:00
parent c631bb6279
commit c654a753c5
13 changed files with 160 additions and 1570 deletions

3
.gitignore vendored
View File

@ -1,3 +1,4 @@
.DS_Store
.sass-cache/
_export/
_site/

View File

@ -11,6 +11,7 @@ PATH
pygments.rb
rack (~> 1.4.0)
rdiscount
selenium-webdriver
sinatra
sprockets
sprockets-sass
@ -53,6 +54,8 @@ GEM
rails (>= 3.0.0)
blankslate (2.1.2.4)
builder (3.0.0)
childprocess (0.3.1)
ffi (~> 1.0.6)
chunky_png (1.2.5)
coffee-script (2.2.0)
coffee-script-source
@ -128,7 +131,13 @@ GEM
rubypython (0.5.3)
blankslate (>= 2.1.2.3)
ffi (~> 1.0.7)
rubyzip (0.9.6.1)
sass (3.1.15)
selenium-webdriver (2.20.0)
childprocess (>= 0.2.5)
ffi (~> 1.0)
multi_json (~> 1.0)
rubyzip
sinatra (1.3.2)
rack (~> 1.3, >= 1.3.6)
rack-protection (~> 1.2)

File diff suppressed because it is too large Load Diff

View File

@ -3,5 +3,7 @@ require 'rack-livereload'
Attentive.configure do |c|
c.title = "Tea Time: A Beginner's Guide to Jasmine"
c.middleware << Rack::LiveReload
#c.export_size = '1280x1024'
end

View File

@ -20,10 +20,8 @@
!SLIDE
# Fortunately, we're beyond that nowadays
!SLIDE larger
!SLIDE even-larger
``` ruby
require 'spec_helper'
describe MyCoolWebsite do
let(:website) { described_class.new }
@ -34,7 +32,8 @@ describe MyCoolWebsite do
let(:double_cool) { 'double cool' }
before do
website.stubs(:whoa_cool).returns(oh_yeah)
website.stubs(:whoa_cool).
returns(oh_yeah)
end
it { should == double_cool }
@ -52,31 +51,38 @@ end
onmouseout="this.src='normal.gif'" />
```
!SLIDE
``` html
<script type="text/javascript">
!SLIDE even-larger
``` javascript
function showMyCoolTitle(title, length) {
if (length == null) { length = 0; }
if (length <= title.length) {
document.title = title.substr(0, length);
document.title =
title.substr(0, length);
length++;
setTimeout(function() { showMyCoolTitle(title, length); }, 75);
setTimeout(function() {
showMyCoolTitle(title, length);
}, 75);
}
}
```
!SLIDE even-larger
``` javascript
window.onload = function() {
showMyCoolTitle("My cool website! Whoaaaaa!");
showMyCoolTitle(
"My cool website! Whoaaaaa!"
);
}
</script>
```
!SLIDE
# jQuery
!SLIDE
# Backbone
# Backbone.js
!SLIDE
# Sprockets and RequireJS
@ -84,10 +90,8 @@ window.onload = function() {
!SLIDE
# Automated testing is important
!SLIDE larger
!SLIDE even-larger
``` ruby
require 'spec_helper'
describe MyCoolWebsite do
let(:website) { described_class.new }
@ -98,7 +102,8 @@ describe MyCoolWebsite do
let(:double_cool) { 'double cool' }
before do
website.stubs(:whoa_cool).returns(oh_yeah)
website.stubs(:whoa_cool).
returns(oh_yeah)
end
it { should == double_cool }
@ -106,23 +111,22 @@ describe MyCoolWebsite do
end
```
!SLIDE larger
!SLIDE even-larger
``` coffeescript
describe 'MyCoolWebsiteView', ->
website = null
beforeEach ->
website = new MyCoolWebsiteView()
@website = new MyCoolWebsiteView()
describe '#coolMethod', ->
doubleCool = 'double cool'
ohYeah = [ doubleCool ]
beforeEach ->
website.whoaCool = -> ohYeah
@website.whoaCool = -> ohYeah
it 'should be double cool', ->
expect(website.coolMethod()).toEqual(doubleCool)
expect(@website.coolMethod()).
toEqual(doubleCool)
```
!SLIDE

View File

@ -22,16 +22,17 @@ describe 'Cat', ->
!SLIDE image-80-percent
<img src="assets/cat-meow.jpg" />
!SLIDE larger
!SLIDE even-larger
``` coffeescript
describe 'Cat', ->
describe '#meow', ->
# description of the meow behavior goes here
# description of the
# meow behavior goes here
```
!SLIDE
!SLIDE larger
# John behavior #1
## Use Ruby-style indicators for instance- and class-level methods, even in Jasmine
## Use Ruby-style indicators for instance- and class-level methods
``` coffeescript
describe 'John', ->

View File

@ -29,7 +29,7 @@ describe 'Cat', ->
``` coffeescript
# code-under-test
class this.Cat
class @Cat
meow: ->
```
@ -37,7 +37,6 @@ class this.Cat
``` javascript
// safety wrapper to prevent global pollution
(function() {
// ...but we want to pollute the Cat class
this.Cat = (function() {
function Cat() {}
Cat.prototype.meow = function() {};
@ -61,7 +60,7 @@ Expected undefined to equal 'meow'.
!SLIDE even-larger
``` coffeescript
class this.Cat
class @Cat
meow: -> "meow"
```
@ -87,6 +86,6 @@ describe 'Cat', ->
``` coffeescript
# code-under-test
class this.Cat
class @Cat
meow: -> "meow"
```

View File

@ -10,7 +10,7 @@
!SLIDE
# Nested `describe`
!SLIDE larger
!SLIDE even-larger
``` coffeescript
describe 'Cat', ->
describe '#meow', ->
@ -23,25 +23,26 @@ describe 'Cat', ->
# the cat knows it's vet time
```
!SLIDE larger
!SLIDE even-larger
``` coffeescript
describe 'Cat', ->
describe '#meow', ->
describe 'hungry', ->
it 'should be a mournful meow', ->
cat = new Cat()
cat.state = -> Cat.HUNGRY
# ...just like cat.stubs(:state)
describe 'hungry', ->
it 'should be a mournful meow', ->
cat = new Cat()
cat.state = -> Cat.HUNGRY
# ...just like cat.stubs(:state)
expect(cat.meow()).toEqual("meeeyaow")
expect(cat.meow()).toEqual("meeeyaow")
```
describe 'going to the vet', ->
it 'should be an evil meow', ->
cat = new Cat()
cat.state = -> Cat.VET_PSYCHIC
# ...just like the one above
!SLIDE even-larger
``` coffeescript
describe 'going to the vet', ->
it 'should be an evil meow', ->
cat = new Cat()
cat.state = -> Cat.VET_PSYCHIC
# ...just like the one above
expect(cat.meow()).toEqual("raowwww")
expect(cat.meow()).toEqual("raowwww")
```
!SLIDE image-80-percent
@ -95,23 +96,29 @@ it "should be in the same context", ->
expect(@instanceVariable).toEqual("yes")
```
!SLIDE larger
!SLIDE even-larger
``` coffeescript
describe 'Cat', ->
describe '#meow', ->
beforeEach ->
@cat = new Cat()
describe 'hungry', ->
it 'should be a mournful meow', ->
@cat.state = -> Cat.HUNGRY
expect(@cat.meow()).toEqual("meeeyaow")
describe 'going to the vet', ->
it 'should be an evil meow', ->
@cat.state = -> Cat.VET_PSYCHIC
expect(@cat.meow()).toEqual("raowwww")
```
!SLIDE even-larger
``` coffeescript
describe 'hungry', ->
it 'should be a mournful meow', ->
@cat.state = -> Cat.HUNGRY
expect(@cat.meow()).toEqual("meeeyaow")
```
!SLIDE even-larger
``` coffeescript
describe 'going to the vet', ->
it 'should be an evil meow', ->
@cat.state = -> Cat.VET_PSYCHIC
expect(@cat.meow()).toEqual("raowwww")
```

View File

@ -15,7 +15,7 @@ describe 'Cat', ->
!SLIDE
# This works, but it can be clearer
!SLIDE
!SLIDE even-larger
``` ruby
describe Cat do
describe '#meow' do
@ -41,12 +41,13 @@ end
alias :context :describe
```
!SLIDE larger
!SLIDE even-larger
``` ruby
describe Cat do
let(:cat) { described_class.new }
# save describe for things or behaviors...
# save describe for
# things or behaviors...
describe '#meow' do
subject { cat.meow }
@ -110,7 +111,7 @@ describe 'Cat', ->
!SLIDE even-larger
``` coffeescript
class this.Cat
class @Cat
@HUNGRY = 'hungry'
@VET_PSYCHIC = 'vet psychic'

View File

@ -12,7 +12,7 @@ cat.should_not be_hungry
!SLIDE even-larger
``` coffeescript
expect(cat.meow()).toEqual("meow")
expect(cat.prototype).toEqual(Cat.prototype)
expect(cat.constructor).toEqual(Cat)
expect(cat.isHungry()).not.toBeTruthy()
```
@ -46,7 +46,10 @@ MyMatchers =
beforeEach ->
this.addMatchers(MyMatchers)
```
!SLIDE even-larger
``` coffeescript
describe 'Cat', ->
beforeEach ->
@cat = new Cat()

View File

@ -36,19 +36,19 @@ describe 'John', ->
!SLIDE image-80-percent
<img src="assets/beer-cat.jpg" />
!SLIDE larger
!SLIDE even-larger
``` gherkin
Feature: Cat Behaviors
Scenario: Hungry cats meow a particular way
Scenario: Hungry cats meow a certain way
Given I have a cat
And the cat is hungry
When the cat meows
Then the meow should sound like "meeyaow"
Then the meow should be a "meeyaow"
```
!SLIDE even-larger
``` coffeescript
class this.Cat
class @Cat
@FOOD_THRESHOLD = 20
@HUNGRY = 'hungry'
@ -64,7 +64,7 @@ class this.Cat
Cat.HUNGRY
```
!SLIDE larger
!SLIDE even-larger
``` coffeescript
describe 'Cat', ->
describe '#meow', ->
@ -73,17 +73,19 @@ describe 'Cat', ->
cat = new Cat()
cat.foodLevel = 15
expect(cat.meow()).toEqual("meeeyaow")
expect(cat.meow()).
toEqual("meeeyaow")
```
!SLIDE
# A perfectly cromulent test
!SLIDE larger
!SLIDE even-larger
``` coffeescript
class this.Cat
class @Cat
meow: ->
switch this.state() # <= dependent code executed
switch this.state()
# ^^^ dependent code executed
when Cat.HUNGRY
"meeyaow"
```
@ -91,25 +93,24 @@ class this.Cat
!SLIDE
# Why make your unit tests fragile?
!SLIDE larger
!SLIDE even-larger
``` coffeescript
cat.foodLevel = 15
# do we care about food level in this test?
# all we care about is that the cat is hungry
# do we care about food level?
```
!SLIDE larger
!SLIDE even-larger
``` coffeescript
describe 'Cat', ->
describe '#meow', ->
describe 'hungry', ->
context 'hungry', ->
it 'should be a mournful meow', ->
cat = new Cat()
cat.state = -> Cat.HUNGRY
# ^^^ we don't care how state works,
# we just want a hungry cat
# ^^^ we just want a hungry cat
expect(cat.meow()).toEqual("meeeyaow")
expect(cat.meow()).
toEqual("meeeyaow")
```
!SLIDE
@ -117,7 +118,7 @@ describe 'Cat', ->
## Just replace the method on the instance
``` coffeescript
class this.Cat
class @Cat
state: ->
# cat codes
@ -148,7 +149,7 @@ cat.state = -> "whatever"
!SLIDE even-larger
``` coffeescript
class this.Cat
class @Cat
vocalProcessor: (speech) =>
if this.isAirborne()
this.modifyForAirborne(speech)
@ -156,7 +157,7 @@ class this.Cat
this.modifyForGround(speech)
```
!SLIDE
!SLIDE larger
``` coffeescript
describe 'Cat#vocalProcessor', ->
speech = "speech"
@ -171,7 +172,8 @@ describe 'Cat#vocalProcessor', ->
it 'should be modified for flight', ->
@cat.vocalProcessor(speech)
expect(@cat.modifyForAirborne).toHaveBeenCalledWith(speech)
expect(@cat.modifyForAirborne).
toHaveBeenCalledWith(speech)
```
!SLIDE even-larger
@ -187,48 +189,53 @@ spyOn(@cat, 'modifyForAirborne')
!SLIDE
# Two basic ways to make sure a spy is called
!SLIDE
!SLIDE even-larger
## `toHaveBeenCalledWith(args...)`
### Called least once with the given parameters
``` coffeescript
expect(@cat.modifyForAirborne).toHaveBeenCalledWith(speech)
expect(@cat.modifyForAirborne).
toHaveBeenCalledWith(speech)
```
!SLIDE
!SLIDE even-larger
## `toHaveBeenCalled()`
### Just called, no parameter check
``` coffeescript
expect(@cat.modifyForAirborne).toHaveBeenCalled()
expect(@cat.modifyForAirborne).
toHaveBeenCalled()
```
!SLIDE larger
!SLIDE even-larger
# Instance Mocks/Spies in JavaScript
## Use `spyOn`/`toHaveBeenCalled` matchers
``` coffeescript
class this.Cat
class @Cat
state: ->
# cat codes
cat = new Cat()
spyOn(cat, 'state')
expect(cat.state).toHaveBeenCalled()
expect(cat.state).
toHaveBeenCalled()
```
!SLIDE
# `spyOn` works great with class-level stubs and mocks, too
!SLIDE
!SLIDE larger
``` coffeescript
class this.Cat
class @Cat
@generateFurColor: (base) ->
# magicks to make a fur color given a base
regrowFur: (damagedHairs) ->
for follicle in damagedHairs
follicle.regrow(Cat.generateFurColor(this.baseColor))
follicle.regrow(
Cat.generateFurColor(this.baseColor)
)
```
!SLIDE larger
@ -237,26 +244,26 @@ Cat.generateFurColor = ->
"whoops i nuked this method for every other test"
```
!SLIDE
!SLIDE larger
``` coffeescript
describe 'Cat#regrowFur', ->
color = 'color'
beforeEach ->
@cat = new Cat()
@follicle =
regrow: ->
@follicle = { regrow: -> null }
@follicles = [ follicle ]
spyOn(Cat, 'generateFurColor').andReturn(color)
# ^^^ original is replaced when done
spyOn(Cat, 'generateFurColor').
# ^^^ original replaced when done
andReturn(color)
spyOn(@follicle, 'regrow')
it 'should regrow', ->
@cat.regrowFur(@follicles)
expect(@follicle.regrow).toHaveBeenCalledWith(color)
expect(@follicle.regrow).
toHaveBeenCalledWith(color)
```
!SLIDE larger
@ -329,7 +336,7 @@ describe 'Cat#fetch', ->
!SLIDE
# Sometimes you just need a big blob of unit tests
!SLIDE
!SLIDE larger
``` coffeescript
# fast and focused!
@ -339,8 +346,11 @@ describe 'Cat#respondsTo', ->
context 'successes', ->
it 'should respond', ->
for request in [ 'kitty kitty', 'pookums', 'hisshead' ]
expect(@cat.respondsTo(request)).toBeTruthy()
for request in [ 'kitty kitty',
'pookums',
'hisshead' ]
expect(@cat.respondsTo(request)).
toBeTruthy()
```
!SLIDE larger

View File

@ -7,16 +7,20 @@
!SLIDE
# Mocking and stubbing `$.fn` calls
!SLIDE
!SLIDE even-larger
``` coffeescript
this.containerWaiter = ->
$('#container').addClass('wait').append('<div class="waiting" />')
$('#container').
addClass('wait').
append('<div class="waiting" />')
```
!SLIDE
!SLIDE even-larger
``` coffeescript
$.fn.makeWait = ->
$(this).addClass('wait').append('<div class="waiting" />')
$(this).
addClass('wait').
append('<div class="waiting" />')
this
```
@ -29,7 +33,7 @@ this.containerWaiter = ->
!SLIDE
# `jquery-jasmine`
!SLIDE larger
!SLIDE even-larger
``` coffeescript
describe 'container', ->
beforeEach ->
@ -37,8 +41,11 @@ describe 'container', ->
it 'should make it wait', ->
containerWaiter()
expect($('#container')).toHaveClass('wait')
expect($('#container')).toContain('div.waiting')
expect($('#container')).
toHaveClass('wait')
expect($('#container')).
toContain('div.waiting')
```
!SLIDE image-80-percent
@ -67,7 +74,8 @@ describe 'container', ->
it 'should make it wait', ->
containerWaiter()
expect($.fn.makeWait).toHaveBeenCalled()
expect($.fn.makeWait).
toHaveBeenCalled()
```
!SLIDE
@ -78,7 +86,7 @@ describe 'container', ->
!SLIDE even-larger
``` coffeescript
class Cat
class @Cat
constructor: ->
@mood = "happy"

View File

@ -45,6 +45,4 @@ runs()
!SLIDE
# Thank you!
## [@johnbintz](http://twitter.com/johnbintz/)
## [GitHub](http://github.com/johnbintz/)