Compare commits
No commits in common. "gh-pages" and "master" have entirely different histories.
|
@ -0,0 +1,2 @@
|
|||
.sass-cache/
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
source :rubygems
|
||||
|
||||
group :rack do
|
||||
gem 'rack-livereload'
|
||||
gem 'showoff'
|
||||
end
|
||||
|
||||
gem 'rmagick'
|
||||
|
||||
gem 'thin'
|
||||
|
||||
gem 'guard'
|
||||
gem 'guard-livereload'
|
||||
|
||||
gem 'compass', '~> 0.12.alpha'
|
||||
gem 'sprockets-sass'
|
||||
gem 'sass'
|
||||
gem 'coffee-script'
|
||||
gem 'therubyracer'
|
||||
gem 'sprockets'
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
GEM
|
||||
remote: http://rubygems.org/
|
||||
specs:
|
||||
addressable (2.2.6)
|
||||
blankslate (2.1.2.4)
|
||||
bluecloth (2.2.0)
|
||||
chunky_png (1.2.5)
|
||||
coffee-script (2.2.0)
|
||||
coffee-script-source
|
||||
execjs
|
||||
coffee-script-source (1.1.3)
|
||||
compass (0.12.alpha.2)
|
||||
chunky_png (~> 1.2)
|
||||
fssm (>= 0.2.7)
|
||||
sass (~> 3.1)
|
||||
daemons (1.1.4)
|
||||
em-websocket (0.3.5)
|
||||
addressable (>= 2.1.1)
|
||||
eventmachine (>= 0.12.9)
|
||||
eventmachine (0.12.10)
|
||||
execjs (1.2.11)
|
||||
multi_json (~> 1.0)
|
||||
fssm (0.2.7)
|
||||
gli (1.4.0)
|
||||
guard (0.8.8)
|
||||
thor (~> 0.14.6)
|
||||
guard-livereload (0.3.1)
|
||||
em-websocket (>= 0.2.0)
|
||||
guard (>= 0.4.0)
|
||||
multi_json (~> 1.0.3)
|
||||
hike (1.2.1)
|
||||
json (1.6.3)
|
||||
libv8 (3.3.10.4)
|
||||
multi_json (1.0.4)
|
||||
nokogiri (1.5.0)
|
||||
parslet (1.2.3)
|
||||
blankslate (~> 2.0)
|
||||
rack (1.3.5)
|
||||
rack-livereload (0.3.3)
|
||||
rack
|
||||
rack-protection (1.1.4)
|
||||
rack
|
||||
rmagick (2.13.1)
|
||||
sass (3.1.11)
|
||||
showoff (0.7.0)
|
||||
bluecloth
|
||||
gli (>= 1.3.2)
|
||||
json
|
||||
nokogiri
|
||||
parslet
|
||||
sinatra
|
||||
sinatra (1.3.1)
|
||||
rack (~> 1.3, >= 1.3.4)
|
||||
rack-protection (~> 1.1, >= 1.1.2)
|
||||
tilt (~> 1.3, >= 1.3.3)
|
||||
sprockets (2.1.2)
|
||||
hike (~> 1.2)
|
||||
rack (~> 1.0)
|
||||
tilt (~> 1.1, != 1.3.0)
|
||||
sprockets-sass (0.5.1)
|
||||
sprockets (~> 2.0)
|
||||
tilt (~> 1.1)
|
||||
therubyracer (0.9.9)
|
||||
libv8 (~> 3.3.10)
|
||||
thin (1.3.1)
|
||||
daemons (>= 1.0.9)
|
||||
eventmachine (>= 0.12.6)
|
||||
rack (>= 1.0.0)
|
||||
thor (0.14.6)
|
||||
tilt (1.3.3)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
coffee-script
|
||||
compass (~> 0.12.alpha)
|
||||
guard
|
||||
guard-livereload
|
||||
rack-livereload
|
||||
rmagick
|
||||
sass
|
||||
showoff
|
||||
sprockets
|
||||
sprockets-sass
|
||||
therubyracer
|
||||
thin
|
|
@ -0,0 +1,48 @@
|
|||
# A sample Guardfile
|
||||
# More info at https://github.com/guard/guard#readme
|
||||
|
||||
guard 'livereload' do
|
||||
watch(%r{.*\.(json|md|scss)$})
|
||||
end
|
||||
|
||||
require 'guard/guard'
|
||||
require 'sprockets'
|
||||
|
||||
require 'sprockets-sass'
|
||||
require 'sass'
|
||||
require 'compass'
|
||||
|
||||
module ::Guard
|
||||
class Sprockets < ::Guard::Guard
|
||||
def initialize(watchers = [], options = {})
|
||||
@env = ::Sprockets::Environment.new
|
||||
@env.append_path 'app/assets/stylesheets'
|
||||
@env.append_path 'app/assets/javascripts'
|
||||
super
|
||||
end
|
||||
|
||||
def start
|
||||
::Guard::UI.info "Guard::Sprockets is running..."
|
||||
end
|
||||
|
||||
def run_all
|
||||
%w{presentation.css presentation.js}.each do |file|
|
||||
::Guard::UI.info "Rebuilding #{file}..."
|
||||
|
||||
begin
|
||||
File.open(file, 'wb') { |fh| fh.print @env[file].to_s }
|
||||
rescue StandardError => e
|
||||
puts e.message
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def run_on_change(paths)
|
||||
run_all
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
guard 'sprockets' do
|
||||
watch(%r{^app/assets})
|
||||
end
|
|
@ -0,0 +1,30 @@
|
|||
$(->
|
||||
isTiming = false
|
||||
time = 0
|
||||
delay = 1000
|
||||
|
||||
timer = null
|
||||
timer = ->
|
||||
$('#footer span#timeInfo').remove()
|
||||
$('#footer').append('<span id="timeInfo" />')
|
||||
|
||||
minute = "00#{Math.floor(time / 60)}".substr(-2)
|
||||
second = "00#{time % 60}".substr(-2)
|
||||
|
||||
output = "#{minute}:#{second}"
|
||||
output += " (running)" if isTiming
|
||||
|
||||
$('#footer #timeInfo').text(output)
|
||||
|
||||
time += 1 if isTiming
|
||||
|
||||
setTimeout(timer, delay)
|
||||
timer()
|
||||
|
||||
$(document).keyup (event) ->
|
||||
if event.keyCode == 77
|
||||
isTiming = !isTiming
|
||||
time = 0 if isTiming
|
||||
|
||||
true
|
||||
)
|
|
@ -0,0 +1,85 @@
|
|||
// solarized
|
||||
|
||||
$base03: #002b36;
|
||||
$base02: #073642;
|
||||
$base01: #586e75;
|
||||
$base00: #657b83;
|
||||
$base0: #839496;
|
||||
$base1: #93a1a1;
|
||||
$base2: #eee8d5;
|
||||
$base3: #fdf6e3;
|
||||
$yellow: #b58900;
|
||||
$orange: #cb4b16;
|
||||
$red: #dc322f;
|
||||
$magenta: #d33682;
|
||||
$violet: #6c71c4;
|
||||
$blue: #268bd2;
|
||||
$cyan: #2aa198;
|
||||
$green: #859900;
|
||||
|
||||
$width: 1280px;
|
||||
|
||||
#preso, .slide {
|
||||
width: $width;
|
||||
height: 800px;
|
||||
|
||||
background-color: $base3;
|
||||
}
|
||||
|
||||
@import 'compass';
|
||||
|
||||
#timeInfo {
|
||||
@include float-right;
|
||||
}
|
||||
|
||||
pre.sh_sourceCode, .sh_yaml, .sh_haml {
|
||||
background-color: $base03;
|
||||
|
||||
@include single-box-shadow($base02, 0, 0, 5px);
|
||||
|
||||
code {
|
||||
color: $base3;
|
||||
}
|
||||
|
||||
.sh_string {
|
||||
color: $red;
|
||||
}
|
||||
|
||||
.sh_symbol {
|
||||
color: $orange;
|
||||
}
|
||||
|
||||
.sh_comment {
|
||||
color: $base01;
|
||||
}
|
||||
|
||||
.sh_keyword {
|
||||
color: $yellow;
|
||||
}
|
||||
|
||||
.sh_number {
|
||||
color: $cyan;
|
||||
}
|
||||
|
||||
.sh_function {
|
||||
color: $green;
|
||||
}
|
||||
}
|
||||
|
||||
#footer {
|
||||
width: $width - 20px;
|
||||
}
|
||||
|
||||
body {
|
||||
color: $base03;
|
||||
background-color: $base1;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: $base03;
|
||||
}
|
||||
|
||||
h2 {
|
||||
color: $base02;
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
require 'bundler'
|
||||
|
||||
Bundler.require(:rack)
|
||||
|
||||
use Rack::LiveReload
|
||||
run ShowOff
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
!SLIDE
|
||||
# `jasmine-headless-webkit`
|
||||
## The fastest way to test your browser-targeted JavaScript!
|
||||
|
||||
!SLIDE
|
||||
# JavaScript Testing
|
||||
|
||||
!SLIDE bullets incremental
|
||||
# Ajax-y apps are complex nowadays!
|
||||
|
||||
* jQuery
|
||||
* Backbone
|
||||
* Tons of other JavaScripty things
|
||||
* Client/server communication
|
||||
|
||||
!SLIDE
|
||||
# A lot can break!
|
||||
|
||||
!SLIDE
|
||||
# Lots of different ways to test
|
||||
|
||||
!SLIDE bullets incremental
|
||||
# Standalone JavaScript Engines
|
||||
|
||||
* Node.JS
|
||||
* EnvJS
|
||||
* Rhino
|
||||
* ...and others!
|
||||
|
||||
!SLIDE
|
||||
# Great for testing JS Libraries
|
||||
|
||||
!SLIDE
|
||||
# Not so great in testing in "real" browsers
|
||||
|
||||
!SLIDE
|
||||
# Fake DOMs aren't quite the same
|
||||
|
||||
!SLIDE
|
||||
## (with the way I write tests, at least)
|
||||
|
||||
!SLIDE bullets incremental
|
||||
# Full-stack Integration testing tools
|
||||
|
||||
* Capybara
|
||||
* Cucumber
|
||||
* Selenium
|
||||
|
||||
!SLIDE
|
||||
# Very thorough
|
||||
|
||||
!SLIDE
|
||||
# Sloooooow
|
||||
|
||||
!SLIDE
|
||||
# Server-side dependency management
|
||||
|
||||
!SLIDE
|
||||
# Sprockets
|
||||
|
||||
!SLIDE
|
||||
# Server-based testing tools
|
||||
|
||||
* Jasmine gem
|
||||
* `jasmine-rails`
|
||||
|
||||
!SLIDE
|
||||
# Compiles assets for testing
|
||||
|
||||
!SLIDE
|
||||
# Harder to automate
|
||||
|
||||
!SLIDE bullets incremental
|
||||
# Continuous testing
|
||||
|
||||
* Guard
|
||||
|
||||
!SLIDE
|
||||
# What I wanted is a JS testing tool that...
|
||||
|
||||
* Runs fast
|
||||
* In a real browser so I can use jQuery & Backbone straight
|
||||
* That supports modern Ruby webapp conventions
|
||||
* Is built for continuous testing
|
||||
|
||||
!SLIDE
|
||||
# `jasmine-headless-webkit`!
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
!SLIDE
|
||||
# Installing
|
||||
|
||||
!SLIDE
|
||||
# Qt 4.7 or above
|
||||
|
||||
!SLIDE
|
||||
# johnbintz.github.com/jasmine-headless-webkit
|
||||
|
||||
!SLIDE
|
||||
# `gem install jasmine-headless-webkit`
|
||||
|
||||
!SLIDE
|
||||
# Gemfile
|
||||
@@@ ruby
|
||||
gem 'jasmine-headless-webkit', '~> 0.8.0'
|
||||
|
||||
!SLIDE bullets incremental
|
||||
# Rails 3.1 Application
|
||||
|
||||
* Asset pipeline using Sprockets
|
||||
* `spec/javascripts` holds tests
|
||||
|
||||
!SLIDE
|
||||
# The Pivotal Labs `jasmine` gem
|
||||
|
||||
!SLIDE
|
||||
# spec/javascripts/support/jasmine.yml
|
||||
|
||||
!SLIDE
|
||||
# Supporting the Jasmine gem conventions
|
||||
|
||||
!SLIDE
|
||||
## (easier to convert existing projects to JHW)
|
||||
|
||||
!SLIDE
|
||||
# spec/javascripts/support/jasmine.yml
|
||||
@@@ yaml
|
||||
src_dir: app/assets/javascripts
|
||||
asset_paths:
|
||||
- lib/assets/javascripts
|
||||
- vendor/assets/javascripts
|
||||
src_files: [ '**/*' ]
|
||||
|
||||
spec_dir: spec/javascripts
|
||||
spec_files: [ '**/*[Ss]pec.*' ]
|
||||
helpers: [ 'helpers/**/*' ]
|
||||
|
||||
!SLIDE
|
||||
# JavaScript Load Paths
|
||||
|
||||
!SLIDE
|
||||
# Sprockets and Jasmine load files differently
|
||||
|
||||
!SLIDE
|
||||
# The Sprockets Way
|
||||
|
||||
!SLIDE
|
||||
# spec/javascripts/support/jasmine.yml
|
||||
@@@ yaml
|
||||
src_dir: app/assets/javascripts
|
||||
asset_paths:
|
||||
- lib/assets/javascripts
|
||||
- vendor/assets/javascripts
|
||||
spec_dir: spec/javascripts
|
||||
|
||||
!SLIDE
|
||||
@@@ ruby
|
||||
# ...somewhere in JHW...
|
||||
env.append_path "app/assets/javascripts"
|
||||
env.append_path "lib/assets/javascripts"
|
||||
env.append_path "vendor/assets/javascripts"
|
||||
env.append_path "spec/javascripts"
|
||||
|
||||
!SLIDE
|
||||
@@@ javascript
|
||||
//= require backbone/models/cat
|
||||
//= require backbone/collections/cats
|
||||
//= require backbone/views/global_view
|
||||
|
||||
class window.CatsView extends GlobalView
|
||||
|
||||
!SLIDE
|
||||
# The Jasmine Way
|
||||
@@@ yaml
|
||||
src_dir: app/assets/javascripts
|
||||
src_files: [ '**/*' ]
|
||||
|
||||
spec_dir: spec/javascripts
|
||||
spec_files: [ '**/*[Ss]pec.*' ]
|
||||
helpers: [ 'helpers/**/*' ]
|
||||
|
||||
!SLIDE
|
||||
@@@ ruby
|
||||
Dir["app/assets/javascripts/**/*"]
|
||||
Dir["spec/javascripts/**/*[Ss]pec.*"]
|
||||
Dir["spec/javascripts/helpers/**/*"]
|
||||
|
||||
!SLIDE
|
||||
# JHW ensures that no file is loaded twice
|
||||
|
||||
!SLIDE
|
||||
# Ensures Sprockets dependencies are loaded in the right order
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
!SLIDE
|
||||
# Writing Jasmine Tests
|
||||
|
||||
!SLIDE
|
||||
# RSpec?
|
||||
|
||||
!SLIDE
|
||||
@@@ ruby
|
||||
(2 + 2).should == 4
|
||||
|
||||
!SLIDE
|
||||
# Jasmine!
|
||||
|
||||
!SLIDE
|
||||
@@@ javascript
|
||||
expect(2 + 2).toEqual(4)
|
||||
|
||||
!SLIDE
|
||||
# RSpec?
|
||||
@@@ ruby
|
||||
describe "CatsView" do
|
||||
before do
|
||||
@cats = [ stub ]
|
||||
end
|
||||
|
||||
it 'should show cats' do
|
||||
render
|
||||
|
||||
rendered.should have_css('#cats li')
|
||||
end
|
||||
end
|
||||
|
||||
!SLIDE
|
||||
# JavaScript?
|
||||
@@@ javascript
|
||||
describe("CatsView", function() {
|
||||
var view;
|
||||
|
||||
beforeEach(function() {
|
||||
view = new CatsView({collection: [ {} ]})
|
||||
}):
|
||||
|
||||
it('should show cats', function() {
|
||||
view.render()
|
||||
|
||||
expect($(view.el)).toContain('#cats li')
|
||||
});
|
||||
});
|
||||
|
||||
!SLIDE
|
||||
# CoffeeScript?
|
||||
@@@ coffeescript
|
||||
describe "CatsView", ->
|
||||
view = null
|
||||
|
||||
beforeEach ->
|
||||
view = new CatsView(collection: [ {} ])
|
||||
|
||||
it 'should show cats', ->
|
||||
view.render()
|
||||
|
||||
expect($(view.el)).toContain('#cats li')
|
||||
|
||||
!SLIDE
|
||||
# Plenty of resources to learn Jasmine itself
|
||||
|
||||
!SLIDE
|
||||
# pivotal.github.com/jasmine
|
||||
|
||||
!SLIDE
|
||||
# tryjasmine.com
|
||||
|
||||
!SLIDE
|
||||
# For Backbone and Sinon.js
|
||||
## tinnedfruit.com/2011/03/03/testing-backbone-apps-with-jasmine-sinon.html
|
||||
|
||||
!SLIDE
|
||||
# But once you know Jasmine...
|
||||
|
|
@ -0,0 +1,170 @@
|
|||
!SLIDE
|
||||
# Sprockets fun!
|
||||
|
||||
!SLIDE bullets incremental
|
||||
# Gems with JavaScript assets
|
||||
|
||||
* `jquery-rails`
|
||||
* `backbone-rails`
|
||||
|
||||
!SLIDE
|
||||
@@@ coffeescript
|
||||
#= require jquery
|
||||
$(->
|
||||
alert "this works"
|
||||
)
|
||||
|
||||
!SLIDE
|
||||
# But now that we have Sprockets...
|
||||
|
||||
!SLIDE
|
||||
# Jasmine libraries in gems!
|
||||
|
||||
!SLIDE bullets incremental
|
||||
# `jasmine-spec-extras`
|
||||
|
||||
* `jasmine-jquery`
|
||||
* `sinon`
|
||||
|
||||
!SLIDE
|
||||
## spec/javascripts/helpers/spec_helper.js.coffee
|
||||
@@@ coffeescript
|
||||
#= require jasmine-jquery
|
||||
#= require sinon
|
||||
|
||||
!SLIDE
|
||||
## spec/javascripts/backbone/views/cats\_view\_spec.js.coffee
|
||||
@@@ coffeescript
|
||||
describe 'CatsView', ->
|
||||
it 'should fire the action', ->
|
||||
spy = sinon.spy()
|
||||
view.bind('meow', spy)
|
||||
|
||||
view.$('button').trigger('click')
|
||||
|
||||
expect(spy.called).toBeTruthy()
|
||||
|
||||
!SLIDE smaller
|
||||
## spec/javascripts/backbone/views/cats\_view\_spec.js.coffee
|
||||
@@@ coffeescript
|
||||
describe 'CatsView', ->
|
||||
it 'should hit the server', ->
|
||||
data = [ 'cat' ]
|
||||
|
||||
@server.respondWith('GET', 'cats', this.validResponse(data))
|
||||
view.$('button').trigger('click')
|
||||
@server.respond()
|
||||
|
||||
expect(view.cats).toEqual(data)
|
||||
|
||||
!SLIDE
|
||||
# More Jasmine libraries will be added later!
|
||||
|
||||
!SLIDE bullets incremental
|
||||
# Any of these folders in a loaded gem get added to the asset path
|
||||
|
||||
* app/assets/javascripts
|
||||
* lib/assets/javascripts
|
||||
* vendor/assets/javascripts
|
||||
|
||||
!SLIDE
|
||||
# JST templates
|
||||
|
||||
!SLIDE
|
||||
# templates/cats_view.jst.ejs
|
||||
@@@ html
|
||||
<h1>All the cats</h1>
|
||||
<h2>Owned by <%= owner %></h2>
|
||||
<ul id="#cats"></ul>
|
||||
<h3>List generated: <%= date %></h3>
|
||||
|
||||
!SLIDE
|
||||
# templates/cats_view.jst.hamljs
|
||||
@@@ haml
|
||||
%h1 All the cats
|
||||
%h2 Owned by #{owner}
|
||||
%ul#cats
|
||||
%h3 List generated: #{date}
|
||||
|
||||
!SLIDE
|
||||
## (no highlighting for haml :( )
|
||||
|
||||
!SLIDE
|
||||
# backbone/views/cats_view.js.coffee
|
||||
@@@ coffeescript
|
||||
#= require templates/cats_view.jst.hamljs
|
||||
|
||||
class window.CatsView extends Backbone.View
|
||||
template: JST['templates/cats_view']
|
||||
|
||||
render: =>
|
||||
$(@el).html(this.template(this.templateData()))
|
||||
this
|
||||
|
||||
!SLIDE
|
||||
# EJS and Eco come as part of Sprockets
|
||||
|
||||
!SLIDE
|
||||
# JHW supports `haml-sprockets` for `.hamljs`
|
||||
|
||||
!SLIDE
|
||||
@@@ ruby
|
||||
gem 'jasmine-headless-webkit', '~> 0.8.0'
|
||||
gem 'haml-sprockets'
|
||||
|
||||
!SLIDE
|
||||
# Any gem that plugs into Sprockets is potentially usable
|
||||
|
||||
!SLIDE bullets incremental
|
||||
# ERB files
|
||||
|
||||
* app/assets/javascripts/application.js.coffee.erb
|
||||
|
||||
!SLIDE
|
||||
# ERB integrates with the host application
|
||||
|
||||
!SLIDE
|
||||
# Since it integrates...
|
||||
|
||||
!SLIDE
|
||||
# Integration testing...
|
||||
|
||||
!SLIDE
|
||||
# Not our domain!
|
||||
|
||||
!SLIDE
|
||||
# `.erb` files are actively ignored
|
||||
|
||||
!SLIDE
|
||||
# application.js.coffee.erb
|
||||
@@@ coffeescript
|
||||
window.Routes = <%= Routes.to_json %>
|
||||
window.CatTypes = <%= CatType.all.to_json %>
|
||||
window.DefaultCatName = <%= CatName::DEFAULT %>
|
||||
|
||||
!SLIDE
|
||||
# Testing code that relies on these values?
|
||||
|
||||
!SLIDE
|
||||
# Mock and stub it in a helper!
|
||||
|
||||
!SLIDE
|
||||
# spec/javascripts/support/jasmine.yml
|
||||
@@@ yaml
|
||||
spec_dir: spec/javascripts
|
||||
helpers: [ "helpers/**.*" ]
|
||||
|
||||
!SLIDE
|
||||
# Helpers load after code-under-test, but before specs
|
||||
|
||||
!SLIDE
|
||||
## spec/javascripts/helpers/application_stubs.js.coffee
|
||||
@@@ coffeescript
|
||||
window.Routes = { what: 'ever' }
|
||||
window.CatTypes = [ 'cute', 'mean' ]
|
||||
window.DefaultCatName = "Fluffy"
|
||||
|
||||
|
||||
!SLIDE
|
||||
# Very exciting!
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
!SLIDE
|
||||
# PhantomJS
|
||||
|
||||
!SLIDE
|
||||
# Standalone Qt WebKit widget with JavaScript control
|
||||
|
||||
!SLIDE bullets incremental
|
||||
# Jasmine runner source
|
||||
|
||||
* JHW - Filesystem
|
||||
* PhantomJS - (preferably) Server
|
||||
|
||||
!SLIDE
|
||||
# Sinon.JS XHR Mocking can do a lot
|
||||
|
||||
!SLIDE bullets incremental
|
||||
# Some things don't work
|
||||
|
||||
* IFRAME
|
||||
* Dynamically loading other JS
|
||||
|
||||
!SLIDE
|
||||
# Use PhantomJS and `guard-jasmine`
|
||||
|
||||
!SLIDE
|
||||
# Doesn't bother me!
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
!SLIDE
|
||||
# Debugging
|
||||
|
||||
!SLIDE
|
||||
# Most problems are debuggable
|
||||
|
||||
!SLIDE
|
||||
# Qt WebKit widget has a big limitation...
|
||||
|
||||
!SLIDE
|
||||
# No stack traces!
|
||||
|
||||
!SLIDE
|
||||
# Chrome, Safari, and other WebKit browsers implement their own stack traces
|
||||
|
||||
!SLIDE
|
||||
# How do you debug problems like SyntaxErrors and other weird ones?
|
||||
|
||||
!SLIDE bullets incremental
|
||||
# Write out the runner file!
|
||||
|
||||
* `--keep`
|
||||
* `runner_output`
|
||||
|
||||
!SLIDE
|
||||
# One-time shot?
|
||||
|
||||
!SLIDE
|
||||
# `jasmine-headless-webkit --keep`
|
||||
|
||||
!SLIDE
|
||||
# `--runner-out runner.html`
|
||||
|
||||
!SLIDE
|
||||
# `open runner.html`
|
||||
|
||||
!SLIDE
|
||||
# Write it all the time?
|
||||
|
||||
!SLIDE
|
||||
## spec/javascripts/support/jasmine.yml
|
||||
@@@ yaml
|
||||
runner_output: "runner.html"
|
||||
|
||||
!SLIDE
|
||||
# Debugging Sprockets includes
|
||||
|
||||
!SLIDE
|
||||
# `jasmine-headless-webkit -l`
|
||||
|
||||
!SLIDE
|
||||
# List all files that JHW will include, in order
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
!SLIDE
|
||||
# Conclusion
|
||||
|
||||
!SLIDE
|
||||
# For unit testing JavaScript
|
||||
|
||||
!SLIDE
|
||||
# In a real browser
|
||||
|
||||
!SLIDE
|
||||
# While supporting Rails conventions
|
||||
|
||||
!SLIDE
|
||||
# Try `jasmine-headless-webkit`!
|
||||
|
||||
!SLIDE bullets incremental
|
||||
# Learn more
|
||||
|
||||
* johnbintz.github.com/jasmine-headless-webkit
|
||||
* pivotal.github.com/jasmine
|
||||
* tryjasmine.com
|
||||
* tinnedfruit.com/2011/03/03/testing-backbone-apps-with-jasmine-sinon.html
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"name": "jasmine-headless-webkit",
|
||||
"sections": [
|
||||
{"section": "intro"}
|
||||
]
|
||||
}
|
Before Width: | Height: | Size: 358 B After Width: | Height: | Size: 358 B |
Before Width: | Height: | Size: 157 B After Width: | Height: | Size: 157 B |
Before Width: | Height: | Size: 180 B After Width: | Height: | Size: 180 B |
Before Width: | Height: | Size: 127 B After Width: | Height: | Size: 127 B |
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 114 B After Width: | Height: | Size: 114 B |
Before Width: | Height: | Size: 121 B After Width: | Height: | Size: 121 B |
Before Width: | Height: | Size: 123 B After Width: | Height: | Size: 123 B |
Before Width: | Height: | Size: 130 B After Width: | Height: | Size: 130 B |
Before Width: | Height: | Size: 161 B After Width: | Height: | Size: 161 B |
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.3 KiB |
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
|
@ -0,0 +1,70 @@
|
|||
/* line 22, /Users/john/Projects/jasmine-headless-webkit-presentation/app/assets/stylesheets/presentation.css.scss */
|
||||
#preso, .slide {
|
||||
width: 1280px;
|
||||
height: 800px;
|
||||
background-color: #fdf6e3;
|
||||
}
|
||||
|
||||
/* line 31, /Users/john/Projects/jasmine-headless-webkit-presentation/app/assets/stylesheets/presentation.css.scss */
|
||||
#timeInfo {
|
||||
display: inline;
|
||||
float: right;
|
||||
}
|
||||
|
||||
/* line 35, /Users/john/Projects/jasmine-headless-webkit-presentation/app/assets/stylesheets/presentation.css.scss */
|
||||
pre.sh_sourceCode, .sh_yaml, .sh_haml {
|
||||
background-color: #002b36;
|
||||
-webkit-box-shadow: 0 0 5px #073642;
|
||||
-moz-box-shadow: 0 0 5px #073642;
|
||||
-o-box-shadow: 0 0 5px #073642;
|
||||
box-shadow: 0 0 5px #073642;
|
||||
}
|
||||
/* line 40, /Users/john/Projects/jasmine-headless-webkit-presentation/app/assets/stylesheets/presentation.css.scss */
|
||||
pre.sh_sourceCode code, .sh_yaml code, .sh_haml code {
|
||||
color: #fdf6e3;
|
||||
}
|
||||
/* line 44, /Users/john/Projects/jasmine-headless-webkit-presentation/app/assets/stylesheets/presentation.css.scss */
|
||||
pre.sh_sourceCode .sh_string, .sh_yaml .sh_string, .sh_haml .sh_string {
|
||||
color: #dc322f;
|
||||
}
|
||||
/* line 48, /Users/john/Projects/jasmine-headless-webkit-presentation/app/assets/stylesheets/presentation.css.scss */
|
||||
pre.sh_sourceCode .sh_symbol, .sh_yaml .sh_symbol, .sh_haml .sh_symbol {
|
||||
color: #cb4b16;
|
||||
}
|
||||
/* line 52, /Users/john/Projects/jasmine-headless-webkit-presentation/app/assets/stylesheets/presentation.css.scss */
|
||||
pre.sh_sourceCode .sh_comment, .sh_yaml .sh_comment, .sh_haml .sh_comment {
|
||||
color: #586e75;
|
||||
}
|
||||
/* line 56, /Users/john/Projects/jasmine-headless-webkit-presentation/app/assets/stylesheets/presentation.css.scss */
|
||||
pre.sh_sourceCode .sh_keyword, .sh_yaml .sh_keyword, .sh_haml .sh_keyword {
|
||||
color: #b58900;
|
||||
}
|
||||
/* line 60, /Users/john/Projects/jasmine-headless-webkit-presentation/app/assets/stylesheets/presentation.css.scss */
|
||||
pre.sh_sourceCode .sh_number, .sh_yaml .sh_number, .sh_haml .sh_number {
|
||||
color: #2aa198;
|
||||
}
|
||||
/* line 64, /Users/john/Projects/jasmine-headless-webkit-presentation/app/assets/stylesheets/presentation.css.scss */
|
||||
pre.sh_sourceCode .sh_function, .sh_yaml .sh_function, .sh_haml .sh_function {
|
||||
color: #859900;
|
||||
}
|
||||
|
||||
/* line 69, /Users/john/Projects/jasmine-headless-webkit-presentation/app/assets/stylesheets/presentation.css.scss */
|
||||
#footer {
|
||||
width: 1260px;
|
||||
}
|
||||
|
||||
/* line 73, /Users/john/Projects/jasmine-headless-webkit-presentation/app/assets/stylesheets/presentation.css.scss */
|
||||
body {
|
||||
color: #002b36;
|
||||
background-color: #93a1a1;
|
||||
}
|
||||
|
||||
/* line 78, /Users/john/Projects/jasmine-headless-webkit-presentation/app/assets/stylesheets/presentation.css.scss */
|
||||
h1 {
|
||||
color: #002b36;
|
||||
}
|
||||
|
||||
/* line 82, /Users/john/Projects/jasmine-headless-webkit-presentation/app/assets/stylesheets/presentation.css.scss */
|
||||
h2 {
|
||||
color: #073642;
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
|
||||
$(function() {
|
||||
var delay, isTiming, time, timer;
|
||||
isTiming = false;
|
||||
time = 0;
|
||||
delay = 1000;
|
||||
timer = null;
|
||||
timer = function() {
|
||||
var minute, output, second;
|
||||
$('#footer span#timeInfo').remove();
|
||||
$('#footer').append('<span id="timeInfo" />');
|
||||
minute = ("00" + (Math.floor(time / 60))).substr(-2);
|
||||
second = ("00" + (time % 60)).substr(-2);
|
||||
output = "" + minute + ":" + second;
|
||||
if (isTiming) output += " (running)";
|
||||
$('#footer #timeInfo').text(output);
|
||||
if (isTiming) time += 1;
|
||||
return setTimeout(timer, delay);
|
||||
};
|
||||
timer();
|
||||
return $(document).keyup(function(event) {
|
||||
if (event.keyCode === 77) {
|
||||
isTiming = !isTiming;
|
||||
if (isTiming) time = 0;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
});
|
|
@ -115,10 +115,8 @@
|
|||
<h1>Not so great in testing in "real" browsers</h1></div>
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/01_intro/9">
|
||||
<h1>Fake DOMs aren't quite the same</h1></div>
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/01_intro/10">
|
||||
<h2>(with the way I write tests, at least)</h2></div>
|
||||
</div><div class="slide" data-transition="none"><div class="content bullets incremental" ref="intro/01_intro/11">
|
||||
<h1>Full-stack Integration testing tools</h1>
|
||||
</div><div class="slide" data-transition="none"><div class="content bullets incremental" ref="intro/01_intro/10">
|
||||
<h1>Integration testing tools</h1>
|
||||
|
||||
<ul>
|
||||
<li>Capybara</li>
|
||||
|
@ -126,15 +124,15 @@
|
|||
<li>Selenium</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/01_intro/12">
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/01_intro/11">
|
||||
<h1>Very thorough</h1></div>
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/01_intro/13">
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/01_intro/12">
|
||||
<h1>Sloooooow</h1></div>
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/01_intro/14">
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/01_intro/13">
|
||||
<h1>Server-side dependency management</h1></div>
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/01_intro/15">
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/01_intro/14">
|
||||
<h1>Sprockets</h1></div>
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/01_intro/16">
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/01_intro/15">
|
||||
<h1>Server-based testing tools</h1>
|
||||
|
||||
<ul>
|
||||
|
@ -142,29 +140,29 @@
|
|||
<li><code>jasmine-rails</code></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/01_intro/17">
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/01_intro/16">
|
||||
<h1>Compiles assets for testing</h1></div>
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/01_intro/18">
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/01_intro/17">
|
||||
<h1>Harder to automate</h1></div>
|
||||
</div><div class="slide" data-transition="none"><div class="content bullets incremental" ref="intro/01_intro/19">
|
||||
</div><div class="slide" data-transition="none"><div class="content bullets incremental" ref="intro/01_intro/18">
|
||||
<h1>Continuous testing</h1>
|
||||
|
||||
<ul>
|
||||
<li>Guard</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/01_intro/20">
|
||||
<h1>What I wanted is a JS testing tool that...</h1>
|
||||
</div><div class="slide" data-transition="none"><div class="content bullets incremental" ref="intro/01_intro/19">
|
||||
<h1>A JS testing tool that...</h1>
|
||||
|
||||
<ul>
|
||||
<li>Runs fast</li>
|
||||
<li>In a real browser so I can use jQuery & Backbone straight</li>
|
||||
<li>In a real browser</li>
|
||||
<li>That supports modern Ruby webapp conventions</li>
|
||||
<li>Is built for continuous testing</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/01_intro/21">
|
||||
<h1><code>jasmine-headless-webkit</code>!</h1></div>
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/01_intro/20">
|
||||
<h1>Enter <code>jasmine-headless-webkit</code></h1></div>
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/02_install/1">
|
||||
<h1>Installing</h1></div>
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/02_install/2">
|
||||
|
@ -177,23 +175,11 @@
|
|||
<h1>Gemfile</h1>
|
||||
|
||||
<pre class="sh_ruby"><code>gem 'jasmine-headless-webkit', '~> 0.8.0'</code></pre></div>
|
||||
</div><div class="slide" data-transition="none"><div class="content bullets incremental" ref="intro/02_install/6">
|
||||
<h1>Rails 3.1 Application</h1>
|
||||
|
||||
<ul>
|
||||
<li>Asset pipeline using Sprockets</li>
|
||||
<li><code>spec/javascripts</code> holds tests</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/02_install/6">
|
||||
<h1>Rails 3.1 Application</h1></div>
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/02_install/7">
|
||||
<h1>The Pivotal Labs <code>jasmine</code> gem</h1></div>
|
||||
<h1>Legacy Jasmine gem support</h1></div>
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/02_install/8">
|
||||
<h1>spec/javascripts/support/jasmine.yml</h1></div>
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/02_install/9">
|
||||
<h1>Supporting the Jasmine gem conventions</h1></div>
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/02_install/10">
|
||||
<h2>(easier to convert existing projects to JHW)</h2></div>
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/02_install/11">
|
||||
<h1>spec/javascripts/support/jasmine.yml</h1>
|
||||
|
||||
<pre class="sh_yaml"><code>src_dir: app/assets/javascripts
|
||||
|
@ -205,13 +191,13 @@ src_files: [ '**/*' ]
|
|||
spec_dir: spec/javascripts
|
||||
spec_files: [ '**/*[Ss]pec.*' ]
|
||||
helpers: [ 'helpers/**/*' ]</code></pre></div>
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/02_install/12">
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/02_install/9">
|
||||
<h1>JavaScript Load Paths</h1></div>
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/02_install/13">
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/02_install/10">
|
||||
<h1>Sprockets and Jasmine load files differently</h1></div>
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/02_install/14">
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/02_install/11">
|
||||
<h1>The Sprockets Way</h1></div>
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/02_install/15">
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/02_install/12">
|
||||
<h1>spec/javascripts/support/jasmine.yml</h1>
|
||||
|
||||
<pre class="sh_yaml"><code>src_dir: app/assets/javascripts
|
||||
|
@ -219,19 +205,19 @@ asset_paths:
|
|||
- lib/assets/javascripts
|
||||
- vendor/assets/javascripts
|
||||
spec_dir: spec/javascripts</code></pre></div>
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/02_install/16">
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/02_install/13">
|
||||
<pre class="sh_ruby"><code># ...somewhere in JHW...
|
||||
env.append_path "app/assets/javascripts"
|
||||
env.append_path "lib/assets/javascripts"
|
||||
env.append_path "vendor/assets/javascripts"
|
||||
env.append_path "spec/javascripts"</code></pre></div>
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/02_install/17">
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/02_install/14">
|
||||
<pre class="sh_javascript"><code>//= require backbone/models/cat
|
||||
//= require backbone/collections/cats
|
||||
//= require backbone/views/global_view
|
||||
|
||||
class window.CatsView extends GlobalView</code></pre></div>
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/02_install/18">
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/02_install/15">
|
||||
<h1>The Jasmine Way</h1>
|
||||
|
||||
<pre class="sh_yaml"><code>src_dir: app/assets/javascripts
|
||||
|
@ -240,13 +226,13 @@ src_files: [ '**/*' ]
|
|||
spec_dir: spec/javascripts
|
||||
spec_files: [ '**/*[Ss]pec.*' ]
|
||||
helpers: [ 'helpers/**/*' ]</code></pre></div>
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/02_install/19">
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/02_install/16">
|
||||
<pre class="sh_ruby"><code>Dir["app/assets/javascripts/**/*"]
|
||||
Dir["spec/javascripts/**/*[Ss]pec.*"]
|
||||
Dir["spec/javascripts/helpers/**/*"]</code></pre></div>
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/02_install/20">
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/02_install/17">
|
||||
<h1>JHW ensures that no file is loaded twice</h1></div>
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/02_install/21">
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/02_install/18">
|
||||
<h1>Ensures Sprockets dependencies are loaded in the right order</h1></div>
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/03_jasmine/1">
|
||||
<h1>Writing Jasmine Tests</h1></div>
|
||||
|
@ -304,14 +290,8 @@ end</code></pre></div>
|
|||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/03_jasmine/9">
|
||||
<h1>Plenty of resources to learn Jasmine itself</h1></div>
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/03_jasmine/10">
|
||||
<h1>pivotal.github.com/jasmine</h1></div>
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/03_jasmine/11">
|
||||
<h1>tryjasmine.com</h1></div>
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/03_jasmine/12">
|
||||
<h1>For Backbone and Sinon.js</h1>
|
||||
|
||||
<h2>tinnedfruit.com/2011/03/03/testing-backbone-apps-with-jasmine-sinon.html</h2></div>
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/03_jasmine/13">
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/03_jasmine/11">
|
||||
<h1>But once you know Jasmine...</h1></div>
|
||||
</div><div class="slide" data-transition="none"><div class="content" ref="intro/04_sprockets/1">
|
||||
<h1>Sprockets fun!</h1></div>
|
||||
|
@ -539,10 +519,8 @@ window.DefaultCatName = "Fluffy"</code></pre></div>
|
|||
<h1>Learn more</h1>
|
||||
|
||||
<ul>
|
||||
<li>johnbintz.github.com/jasmine-headless-webkit</li>
|
||||
<li>pivotal.github.com/jasmine</li>
|
||||
<li>tryjasmine.com</li>
|
||||
<li>tinnedfruit.com/2011/03/03/testing-backbone-apps-with-jasmine-sinon.html</li>
|
||||
<li>http://johnbintz.github.com/jasmine-headless-webkit/</li>
|
||||
<li>http://tryjasmine.com/</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div></div>
|