guard-5-min/one/01_slide.md

423 lines
8.8 KiB
Markdown

!SLIDE
# Guard and the Modern Rails App #
!SLIDE
## in 5 minutes ##
!SLIDE
### by John Bintz ###
!SLIDE
# Guard? #
!SLIDE center
![Shell Commands](images/shell-commands.png)
!SLIDE center
![Reload Button](images/reload-button.png)
!SLIDE center
![Pocket Watch by Cyberslayer](images/pocket-watch-cyberslayer.jpg)
[Pocket Watch by Cyberslayer](http://www.flickr.com/photos/cyberslayer/870683349/)
!SLIDE center
![Wrist Brace by lesleyhyphenanne](images/wrist-brace-lesleyhyphenanne.jpg)
[Wrist Brace by lesleyhyphenanne](http://www.flickr.com/photos/lesleyhyphenanne/2878429259/)
!SLIDE
# Get it? #
!SLIDE smaller
@@@ sh
gem install guard
!SLIDE smaller
@@@ sh
gem install guard-annotate guard-bundler guard-chef \
guard-coffeedripper guard-coffeescript guard-compass \
guard-cucumber guard-delayed guard-ego guard-gimli \
guard-haml guard-jammit guard-jasmine-headless-webkit \
guard-jstd guard-koans guard-krl guard-less guard-livereload \
guard-markdown guard-middleman guard-migrate guard-minitest \
guard-mozrepl guard-nanoc guard-passenger guard-pow \
guard-prove guard-pusher guard-rails guard-rspec guard-sass \
guard-shell guard-soca guard-spork guard-sprockets \
guard-stendhal guard-test guard-uglify guard-webrick
!SLIDE bullets incremental
# Guards for... #
* Restarting servers
* Compiling files
* Testing things
* Whatever else you feel like automating
!SLIDE
# Guard and the Modern Rails App #
!SLIDE
# A Modern Rails App #
!SLIDE
# Rails 3.0.x #
!SLIDE
## I will touch on Rails 3.1, but since it's not out yet, and the asset pipeline makes some "easy" things much more difficult, I'm saving it for the end. ##
!SLIDE bullets incremental
# This app uses: #
* CoffeeScript >> JS
* SCSS + Compass >> CSS
* Jasmine Headless WebKit >> JS testing
* A web browser
* RSpec >> Ruby testing
!SLIDE
# OMG RSPEC FLAME WARS ON #
!SLIDE center
![lol flame war](images/flamewar.gif)
!SLIDE bullets incremental
# DON'T PANIC #
* `guard-test`
* `guard-minitest`
* `guard-write-your-own`
!SLIDE bullets incremental
# We want Guard to do this when we save files: #
* Run our tests
* Regenerate our CSS & JS
* Reload the page in our browser
* Restart the dev Rails server
!SLIDE
# Only the files a particular Guard action cares about #
!SLIDE
# `.rb && _spec.rb` #
!SLIDE
# `.scss && .sass` #
!SLIDE
# `.js && .coffee` #
!SLIDE
# `config/.*`
!SLIDE
# How? #
!SLIDE smaller
@@@ sh
cd ~/my-cool-project
!SLIDE smaller
@@@ sh
cd ~/my-cool-project
guard init
!SLIDE smaller
@@@ sh
cd ~/my-cool-project
guard init
guard init rspec
guard init rails
guard init coffeescript
guard init compass
guard init jasmine-headless-webkit
guard init livereload
!SLIDE evensmaller
@@@ ruby
# A sample Guardfile
# More info at https://github.com/guard/guard#readme
guard 'rspec', :version => 2 do
watch(%r{^spec/.+_spec\.rb$})
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
watch('spec/spec_helper.rb') { "spec" }
# Rails example
watch(%r{^spec/.+_spec\.rb$})
watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m|
[ "spec/routing/#{m[1]}_routing_spec.rb",
"spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb",
"spec/acceptance/#{m[1]}_spec.rb" ]
}
watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
watch('spec/spec_helper.rb') { "spec" }
watch('config/routes.rb') { "spec/routing" }
watch('app/controllers/application_controller.rb') { "spec/controllers" }
# Capybara request specs
watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/requests/#{m[1]}_spec.rb" }
end
guard 'rails' do
watch('Gemfile.lock')
watch(%r{^(config|lib)/.*})
end
guard 'coffeescript', :input => 'app/assets/javascripts'
guard 'compass' do
watch('^src/(.*)\.s[ac]ss')
end
!SLIDE evensmaller
@@@ ruby
# Run JS and CoffeeScript files in a typical Rails 3.1 fashion,
# placing Underscore templates in app/views/*.jst
# Your spec files end with _spec.{js,coffee}.
spec_location = "spec/javascripts/%s_spec"
# uncomment if you use NerdCapsSpec.js
# spec_location = "spec/javascripts/%sSpec"
guard 'jasmine-headless-webkit' do
watch(%r{^app/views/.*\.jst})
watch(%r{^public/javascripts/(.*)\.js}) { |m| newest_js_file(spec_location % m[1]) }
watch(%r{^app/assets/javascripts/(.*)\.(js|coffee)}) { |m| newest_js_file(spec_location % m[1]) }
watch(%r{^spec/javascripts/(.*)_spec\..*}) { |m| newest_js_file(spec_location % m[1]) }
end
guard 'livereload' do
watch(%r{app/.+\.(erb|haml)})
watch(%r{app/helpers/.+\.rb})
watch(%r{public/.+\.(css|js|html)})
watch(%r{config/locales/.+\.yml})
end
!SLIDE
## [johnbintz-guard-5-min.heroku.com](http://johnbintz-guard-5-min.heroku.com/) ##
!SLIDE
@@@ sh
guard
# and away you go!
!SLIDE
# Yay we're done everyone go home now bye bye #
!SLIDE
# ...let's make this better... #
!SLIDE
@@@ ruby
guard 'rspec', :version => 2 do
watch(%r{something})
end
guard 'livereload' do
watch(%r{something else})
end
!SLIDE
@@@ ruby
# gem 'guard', '>= 0.4.0'
group :test do
guard 'rspec', :version => 2 do
watch(%r{something})
end
end
group :development do
guard 'livereload' do
watch(%r{something else})
end
end
!SLIDE
@@@ sh
# testing code here
guard -g test
# stuff for a browser here
guard -g development
!SLIDE
# But I want Guard to wash my dishes and fold my laundry and take the dog for a walk and -- #
!SLIDE
# Yes! #
## It can! ##
!SLIDE
@@@ sh
gem install guard-shell
guard init shell
!SLIDE small
@@@ ruby
guard 'shell' do
watch(%r{sink/.*\.dish}) { `wash all` }
watch(%r{dryer/.*\.pants}) { `fold all` }
watch(%r{dog/(.*)\.dog}) { |m| `walk #{m[1]}` }
end
!SLIDE
# BACKTICKS ARE FOR THE WEAK #
!SLIDE small
@@@ ruby
module Guard
class NotAWeakling < Guard
def start
UI.info "Let's do this..."
end
def run_all
lift_heavy_things
run(5.miles)
chin_ups.go!
end
end
end
guard 'not-a-weakling' do
watch(%r{.*})
end
!SLIDE
# Rails 3.1.x and the Asset Pipeline OF DOOM #
!SLIDE
# CSS _should_ be OK... #
!SLIDE
@@@ ruby
guard 'livereload' do
watch(%r{app/.+\.(erb|haml)})
watch(%r{app/helpers/.+\.rb})
watch(%r{public/.+\.(css|js|html)})
watch(%r{config/locales/.+\.yml})
end
!SLIDE bullets incremental
# But JavaScript testing? #
* CoffeeScript compilation
* Gems that provide JS
* `file.coffee.erb`
!SLIDE
# `file.coffee.erb`
!SLIDE
# Uhhh... #
!SLIDE
# Anyway... #
!SLIDE
# Rack-based test solutions that talk Sprockets... #
!SLIDE
# ...may be OK #
!SLIDE bullets incremental
# The Internets are still figuring out the best way... #
* `jasmine-gem`
* `evergreen`
* ...others...
!SLIDE
# PhantomJS against a running Rack server that can serve asset path files #
!SLIDE small
@@@ ruby
guard 'phantomjs', :runner => 'run-jasmine.js' do
# Rails example
watch(%r{public/.+\.js})
watch(%r{^spec/javascripts/.+\.js})
end
!SLIDE bullets incremental
# Non-Rack-based solutions? #
* Node.js
* Rhino + EnvJS
* `jasmine-headless-webkit`
!SLIDE
## (shameless self-promotion warning!)
!SLIDE
# Compile all that yummy Rails-bound JS before running tests #
!SLIDE small
@@@ ruby
# with a newer version of...
gem 'jasmine-headless-webkit'
# and the matching guard, this gets run
# before each test run:
Rake::Task['assets:precompile:for_testing'].invoke
!SLIDE small
@@@ ruby
# Guardfile
guard 'jasmine-headless-webkit', :rails_assets => true do
watch(%r{app/assets/javascripts/.*\.(js|coffee)$})
end
!SLIDE
# spec/javascripts/support/jasmine.yml
src_files:
- public/assets/*-test.js
!SLIDE center
![fffffffuuuuuuuuuuuu](images/RageFace.jpg)
!SLIDE
# Anyway... #
!SLIDE
# In conclusion... #
!SLIDE
# Install Guard #
!SLIDE
# Use Guard #
!SLIDE
# Type Less #
!SLIDE
# More Time For Beer From A Vending Machine #
!SLIDE center
![Beer Vending Machine by Joel Abroad](images/beer-vending-machine-joel-abroad.jpg)
[Beer Vending Machine by Joel Abroad](http://www.flickr.com/photos/40295335@N00/4849603734/)
!SLIDE bullets
# Thanks! #
* [johnbintz-guard-5-min.heroku.com](http://johnbintz-guard-5-min.heroku.com/)
* [@johnbintz](http://twitter.com/johnbintz)
* [github.com/johnbintz](http://github.com/johnbintz)