Skip to content

Instantly share code, notes, and snippets.

@pengwynn
Created December 24, 2009 21:54
Show Gist options
  • Save pengwynn/263387 to your computer and use it in GitHub Desktop.
Save pengwynn/263387 to your computer and use it in GitHub Desktop.
# Set up .gitignore
file '.gitignore', <<-GITIGNORE
config/database.yml
log/*.log
tmp/**/*
.DS\_Store
.DS_Store
db/test.sqlite3
db/development.sqlite3
/log/*.pid
/coverage/*
public/system/*
.idea/*
tmp/metric_fu/*
tmp/sent_mails/*
.ackrc
GITIGNORE
# Create sample database.yml
run "cp config/database.yml config/database.yml.example"
# Remove unnecessary files
run 'rm "public/index.html"'
# Gems
gem "haml"
gem "authlogic"
gem "formtastic"
gem "faker"
gem "cucumber"
gem "state_machine"
gem "webrat", :version => '>= 0.4.4'
gem "shoulda", :source => 'http://gemcutter.org'
gem "machinist", :source => 'http://gemcutter.org'
rake 'gems:install', :sudo => true
# Set up machinist
file 'test/blueprints.rb', <<-CODE
require 'machinist/active_record'
require 'sham'
CODE
# Set up shoulda/machinist
file 'test/test_helper.rb', <<-CODE
ENV["RAILS_ENV"] = "test"
require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
require File.expand_path(File.dirname(__FILE__) + "/blueprints")
require 'test_help'
require 'authlogic/test_case'
class ActiveSupport::TestCase
self.use_transactional_fixtures = true
self.use_instantiated_fixtures = false
setup { Sham.reset }
end
CODE
# haml!
run "haml --rails ."
initializer 'haml_init.rb', "Haml::Template.options[:format] = :html5"
# default layout
file 'app/views/layouts/application.html.haml', <<-LAYOUT
!!!
%html
%head
%title My Page
= stylesheet_link_tag 'style'
%body
#content
= yield
= javascript_include_tag 'http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js', 'application'
LAYOUT
# Blueprint & Compass
file 'public/stylesheets/sass/_base.sass',
%q{
!blueprint_grid_columns = 24
!blueprint_grid_width = 30px
!blueprint_grid_margin = 10px
!font_color = #333
!page_background = #fff
!container_background = #fff
}
file 'public/stylesheets/sass/application.sass',
%q{@import base.sass
@import blueprint.sass
@import blueprint/modules/scaffolding.sass
@import blueprint/modules/utilities.sass
@import blueprint/modules/colors.sass
@import blueprint/modules/interaction.sass
@import compass/reset.sass
@import compass/utilities.sass
+blueprint-typography
+blueprint-interaction
+blueprint-debug
+blueprint-form
+blueprint-scaffolding
body
background-color= !page_background
#container
+container
background-color= !container_background
#header, #content, #footer
+column(22)
+prepend(1)
+append(1)
#header
padding-top: 2em
position: relative
#user
position: absolute
top: 0
right: 3em
+horizontal-list
#footer
p
+quiet
text-align: center
}
# Authlogic
generate(:model, "user", "first_name:string", "last_name:string", "login:string",
"state:string", "email:string", "crypted_password:string",
"password_salt:string", "persistence_token:string",
"single_access_token:string", "perishable_token:string",
"login_count:integer", "failed_login_count:integer",
"last_request_at:datetime", "current_login_at:datetime",
"last_login_at:datetime", "current_login_ip:string",
"last_login_ip:string")
file 'app/models/user.rb', <<-CODE
class User < ActiveRecord::Base
acts_as_authentic
state_machine :initial => :active do
end
end
CODE
file 'app/models/user_session.rb', <<-CODE
class UserSession < Authlogic::Session::Base
end
CODE
file 'app/controllers/application_controller.rb', <<-CODE
class ApplicationController < ActionController::Base
helper :all
helper_method :current_user_session, :current_user
filter_parameter_logging :password, :password_confirmation
private
def current_user_session
return @current_user_session if defined?(@current_user_session)
@current_user_session = UserSession.find
end
def current_user
return @current_user if defined?(@current_user)
@current_user = current_user_session && current_user_session.record
end
def require_user
unless current_user
store_location
flash[:notice] = "You must be logged in to access this page"
redirect_to new_user_session_url
return false
end
end
def require_no_user
if current_user
store_location
flash[:notice] = "You must be logged out to access this page"
redirect_to account_url
return false
end
end
def store_location
session[:return_to] = request.request_uri
end
def redirect_back_or_default(default)
redirect_to(session[:return_to] || default)
session[:return_to] = nil
end
end
CODE
file 'app/controllers/user_sessions_controller.rb', <<-CODE
class UserSessionsController < ApplicationController
before_filter :require_no_user, :only => [:new, :create]
before_filter :require_user, :only => :destroy
def new
@user_session = UserSession.new
end
def create
@user_session = UserSession.new(params[:user_session])
if @user_session.save
flash[:notice] = "Login successful!"
redirect_back_or_default account_url
else
render :action => :new
end
end
def destroy
current_user_session.destroy
flash[:notice] = "Logout successful!"
redirect_back_or_default new_user_session_url
end
end
CODE
file 'app/controllers/users_controller.rb', <<-CODE
class UsersController < ApplicationController
before_filter :require_no_user, :only => [:new, :create]
before_filter :require_user, :only => [:show, :edit, :update]
def new
@user = User.new
end
def create
@user = User.new(params[:user])
if @user.save
flash[:notice] = "Account registered!"
redirect_back_or_default account_url
else
render :action => :new
end
end
def show
@user = @current_user
end
def edit
@user = @current_user
end
def update
@user = @current_user # makes our views "cleaner" and more consistent
if @user.update_attributes(params[:user])
flash[:notice] = "Account updated!"
redirect_to account_url
else
render :action => :edit
end
end
end
CODE
file 'app/views/users/_form.haml', <<-CODE
= form.label :login
%br
= form.text_field :login
%br
%br
= form.label :email
%br
= form.text_field :email
%br
%br
= form.label :password, form.object.new_record? ? nil : "Change password"
%br
= form.password_field :password
%br
%br
= form.label :password_confirmation
%br
= form.password_field :password_confirmation
%br
CODE
file 'app/views/users/edit.html.haml', <<-CODE
%h1 Edit My Account
- form_for @user, :url => account_path do |f|
= f.error_messages
= render :partial => "form", :object => f
= f.submit "Update"
%br
= link_to "My Profile", account_path
CODE
file 'app/views/users/new.html.haml', <<-CODE
%h1 Register
- form_for @user, :url => account_path do |f|
= f.error_messages
= render :partial => "form", :object => f
= f.submit "Sign Up"
CODE
file 'app/views/users/show.html.haml', <<-CODE
%p
%b Login:
=h @user.login
%p
%b Login count:
=h @user.login_count
%p
%b Last request at:
=h @user.last_request_at
%p
%b Last login at:
=h @user.last_login_at
%p
%b Current login at:
=h @user.current_login_at
%p
%b Last login ip:
=h @user.last_login_ip
%p
%bCurrent login ip:
=h @user.current_login_ip
= link_to 'Edit', edit_account_path
CODE
file 'app/views/user_sessions/new.html.haml', <<-CODE
%h1 Login
- form_for @user_session, :url => user_session_path do |f|
= f.error_messages
= f.label :login
%br
= f.text_field :login
%br
%br
= f.label :password
%br
= f.password_field :password
%br
%br
= f.check_box :remember_me
= f.label :remember_me
%br
%br
= f.submit "Login"
CODE
route "map.resource :user_session"
route "map.resource :account, :controller => 'users'"
route "map.resources :users"
route "map.login 'login', :controller => 'user_sessions', :action => 'new'"
route "map.logout 'logout', :controller => 'user_sessions', :action => 'destroy'"
generate(:controller, "site", "index")
route "map.root :controller => :site"
# Set up compass
run "compass --rails -f blueprint --sass-dir=public/stylesheets/sass --css-dir=public/stylesheets/ ."
rake 'db:create'
# Create sessions table migration and migrate
rake 'db:sessions:create'
rake 'db:migrate'
generate :cucumber
# Cucumber steps for Authlogic
file "features/authentication.feature", <<-EOF
Feature: Authentication
In order to have people use my application
As a developer
I want to provide sign up, login, activation and password resetting
Scenario: Signing Up
Given I am on new_user
And I am a new user
When I fill in "user[login]" with "some_user"
And I fill in "user[email]" with "some_user@email.com"
And I fill in "user[password]" with "password"
And I fill in "user[password_confirmation]" with "password"
And I press "Sign Up"
Then I should see "Account registered!"
And I should be on my account page
Scenario: Logging In
Given I am an existing user
And I am on new_user_session
When I fill in "user_session[login]" with "valid_user"
And I fill in "user_session[password]" with "password"
And I press "Login"
Then I should be on my account page
EOF
file "features/step_definitions/authentication_steps.rb", <<-EOF
Given /^I am an existing user$/ do
@user = User.make(:login => 'valid_user', :password => 'password',
:password_confirmation => 'password')
end
Given /^I am a new user$/ do
@user = User.make_unsaved
end
Given /^I requested a password reset$/ do
@user.reset_perishable_token!
end
EOF
file "features/support/paths.rb",
%q{module NavigationHelpers
def path_to(page_name)
case page_name
when /the homepage/
'/'
when /my account page/
account_path
when /new_user_session/
new_user_session_path
when /my password reset page/
edit_password_reset_path(:id => User.last.perishable_token)
when /the login page/
new_user_session_path
else
begin
eval(page_name+'_path')
rescue
raise "Can't find mapping from \"#{page_name}\" to a path.\n" +
"Now, go and add a mapping in #{__FILE__}"
end
end
end
end
World(NavigationHelpers)
}
file 'features/support/env.rb',
%q{# Sets up the Rails environment for Cucumber
ENV["RAILS_ENV"] ||= "cucumber"
require File.expand_path(File.dirname(__FILE__) + '/../../config/environment')
require 'cucumber/rails/world'
# Comment out the next line if you don't want Cucumber Unicode support
require 'cucumber/formatter/unicode'
# Comment out the next line if you don't want transactions to
# open/roll back around each scenario
Cucumber::Rails.use_transactional_fixtures
# Comment out the next line if you want Rails' own error handling
# (e.g. rescue_action_in_public / rescue_responses / rescue_from)
Cucumber::Rails.bypass_rescue
require 'webrat'
require 'cucumber/webrat/element_locator' # Lets you do table.diff!(element_at('#my_table_or_dl_or_ul_or_ol').to_table)
Webrat.configure do |config|
config.mode = :rails
end
require 'webrat/core/matchers'
require File.join(RAILS_ROOT, 'test', 'blueprints')
require "authlogic/test_case"
Before do
activate_authlogic
end
}
file 'test/blueprints.rb',
%q{require 'machinist/active_record'
require 'sham'
require 'faker'
User.blueprint do
login Faker::Internet.user_name
email Faker::Internet.email
password Faker::Lorem.words.join
password_confirmation password
end
}
file 'features/step_definitions/webrat_steps.rb',
%q{require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "paths"))
# Commonly used webrat steps
# http://github.com/brynary/webrat
Given /^I am on (.+)$/ do |page_name|
visit path_to(page_name)
end
When /^I go to (.+)$/ do |page_name|
visit path_to(page_name)
end
When /^I press "([^\"]*)"$/ do |button|
click_button(button)
end
When /^I follow "([^\"]*)"$/ do |link|
click_link(link)
end
When /^I follow "([^\"]*)" within "([^\"]*)"$/ do |link, parent|
click_link_within(parent, link)
end
When /^I fill in "([^\"]*)" with "([^\"]*)"$/ do |field, value|
fill_in(field, :with => value)
end
When /^I fill in "([^\"]*)" for "([^\"]*)"$/ do |value, field|
fill_in(field, :with => value)
end
# Use this to fill in an entire form with data from a table. Example:
#
# When I fill in the following:
# | Account Number | 5002 |
# | Expiry date | 2009-11-01 |
# | Note | Nice guy |
# | Wants Email? | |
#
# TODO: Add support for checkbox, select og option
# based on naming conventions.
#
When /^I fill in the following:$/ do |fields|
fields.rows_hash.each do |name, value|
When %{I fill in "#{name}" with "#{value}"}
end
end
When /^I select "([^\"]*)" from "([^\"]*)"$/ do |value, field|
select(value, :from => field)
end
# Use this step in conjunction with Rail's datetime_select helper. For example:
# When I select "December 25, 2008 10:00" as the date and time
When /^I select "([^\"]*)" as the date and time$/ do |time|
select_datetime(time)
end
# Use this step when using multiple datetime_select helpers on a page or
# you want to specify which datetime to select. Given the following view:
# <%= f.label :preferred %><br />
# <%= f.datetime_select :preferred %>
# <%= f.label :alternative %><br />
# <%= f.datetime_select :alternative %>
# The following steps would fill out the form:
# When I select "November 23, 2004 11:20" as the "Preferred" date and time
# And I select "November 25, 2004 10:30" as the "Alternative" date and time
When /^I select "([^\"]*)" as the "([^\"]*)" date and time$/ do |datetime, datetime_label|
select_datetime(datetime, :from => datetime_label)
end
# Use this step in conjunction with Rail's time_select helper. For example:
# When I select "2:20PM" as the time
# Note: Rail's default time helper provides 24-hour time-- not 12 hour time. Webrat
# will convert the 2:20PM to 14:20 and then select it.
When /^I select "([^\"]*)" as the time$/ do |time|
select_time(time)
end
# Use this step when using multiple time_select helpers on a page or you want to
# specify the name of the time on the form. For example:
# When I select "7:30AM" as the "Gym" time
When /^I select "([^\"]*)" as the "([^\"]*)" time$/ do |time, time_label|
select_time(time, :from => time_label)
end
# Use this step in conjunction with Rail's date_select helper. For example:
# When I select "February 20, 1981" as the date
When /^I select "([^\"]*)" as the date$/ do |date|
select_date(date)
end
# Use this step when using multiple date_select helpers on one page or
# you want to specify the name of the date on the form. For example:
# When I select "April 26, 1982" as the "Date of Birth" date
When /^I select "([^\"]*)" as the "([^\"]*)" date$/ do |date, date_label|
select_date(date, :from => date_label)
end
When /^I check "([^\"]*)"$/ do |field|
check(field)
end
When /^I uncheck "([^\"]*)"$/ do |field|
uncheck(field)
end
When /^I choose "([^\"]*)"$/ do |field|
choose(field)
end
When /^I attach the file at "([^\"]*)" to "([^\"]*)"$/ do |path, field|
attach_file(field, path)
end
Then /^I should see "([^\"]*)"$/ do |text|
assert_match /#{text}/m, @response.body
end
Then /^I should not see "([^\"]*)"$/ do |text|
assert_no_match /#{text}/m, @response.body
end
Then /^the "([^\"]*)" field should contain "([^\"]*)"$/ do |field, value|
assert_match /#{value}/, field_labeled(field).value
end
Then /^the "([^\"]*)" field should not contain "([^\"]*)"$/ do |field, value|
assert_no_match /#{value}/, field_labeled(field).value
end
Then /^the "([^\"]*)" checkbox should be checked$/ do |label|
assert field_labeled(label).checked?
end
Then /^the "([^\"]*)" checkbox should not be checked$/ do |label|
assert !field_labeled(label).checked?
end
Then /^I should be on (.+)$/ do |page_name|
assert_equal path_to(page_name), URI.parse(current_url).path
end
Then /^show me the page$/ do
save_and_open_page
end
}
git :init
git :add => "."
git :commit => "-a -m 'Initial commit'"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment