423 lines
8.8 KiB
Markdown
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)
|
|
|