Skip to content

Instantly share code, notes, and snippets.

@ringe
Created February 7, 2012 09:41
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ringe/1758731 to your computer and use it in GitHub Desktop.
Save ringe/1758731 to your computer and use it in GitHub Desktop.
Rails Template with Cucumber, RSpec, FactoryGirl, Capybara, Spork, Watchr, Devise on MySQL in a Vagrant environment
# Add to the given file the given lines, after the line with the given text, or replace the content
def add_to_file(path, text, after=nil, replace=false)
lines = []
if replace
lines = text
else
File.readlines(path).each do |line|
if after != nil and line.include?(after)
lines << line
lines << text
else
lines << line
end
end
lines << text if after == nil
end
File.open(path, 'w') do |file|
file.puts lines
end
end
# Find app name
app_name = open('config/application.rb').grep(/module\ /)[0].sub('module ', '').sub("\n",'')
# Add default gems
gem 'devise'
gem 'mysql2'
gem 'execjs'
gem 'therubyracer'
gems = "group :test, :development do
gem 'ruby-debug19', :require => 'ruby-debug'
gem 'turn', :require => false
gem 'database_cleaner'
gem 'factory_girl_rails'
gem 'cucumber'
gem 'cucumber-rails'
gem 'rspec-rails'
gem 'capybara'
gem 'watchr'
gem 'spork'
gem 'spork-rails'
gem 'minitest'
end"
add_to_file("Gemfile", gems)
run "bundle install"
# Remove default html file
run "rm public/index.html"
# Customize generators
generators = " config.generators do |g|
g.orm :active_record
g.template_engine :erb
g.test_framework :rspec, :fixture => true, :views => false
g.fixture_replacement :factory_girl, :dir => \"spec/factories\"
g.stylesheets false
end"
add_to_file('config/application.rb', generators, "Rails::Application")
run "rails generate rspec:install"
# Change rspec setup
rspecy = "require 'rubygems'
require 'spork'
require 'spork/ext/ruby-debug'
Spork.prefork do
# Loading more in this block will cause your tests to run faster. However,
# if you change any configuration or code from libraries loaded here, you'll
# need to restart spork for it take effect.
# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV[\"RAILS_ENV\"] ||= 'test'
require File.expand_path(\"../../config/environment\", __FILE__)
require 'rspec/rails'
require 'rspec/autorun'
require 'capybara/rspec'
require 'capybara/rails'
# Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories.
Dir[Rails.root.join(\"spec/support/**/*.rb\")].each {|f| require f}
RSpec.configure do |config|
# ## Mock Framework
#
# If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
#
# config.mock_with :mocha
# config.mock_with :flexmock
# config.mock_with :rr
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = \"\#{::Rails.root}/spec/fixtures\"
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
config.use_transactional_fixtures = true
# If true, the base class of anonymous controllers will be inferred
# automatically. This will be the default behavior in future versions of
# rspec-rails.
config.infer_base_class_for_anonymous_controllers = false
end
end
Spork.each_run do
# This code will be run each time you run your specs.
end"
add_to_file('spec/spec_helper.rb', rspecy, nil, true)
# Set up Cucumber
run "rails generate cucumber:install --rspec --capybara"
cucum = "require 'rubygems'
require 'spork'
Spork.prefork do
# Loading more in this block will cause your tests to run faster. However,
# if you change any configuration or code from libraries loaded here, you'll
# need to restart spork for it take effect.
# IMPORTANT: This file is generated by cucumber-rails - edit at your own peril.
# It is recommended to regenerate this file in the future when you upgrade to a
# newer version of cucumber-rails. Consider adding your own code to a new file
# instead of editing this one. Cucumber will automatically load all features/**/*.rb
# files.
require 'cucumber/formatter/unicode' # Remove this line if you don't want Cucumber Unicode support
require 'cucumber/rails'
require 'capybara/rails'
require 'capybara/cucumber'
require 'capybara/session'
# step definitions that make calling factories from Cucumber easier
require 'factory_girl/step_definitions'
# Capybara defaults to XPath selectors rather than Webrat's default of CSS3. In
# order to ease the transition to Capybara we set the default here. If you'd
# prefer to use XPath just remove this line and adjust any selectors in your
# steps to use the XPath syntax.
Capybara.default_selector = :css
end
Spork.each_run do
# This code will be run each time you run your specs.
# By default, any exception happening in your Rails application will bubble up
# to Cucumber so that your scenario will fail. This is a different from how
# your application behaves in the production environment, where an error page will
# be rendered instead.
#
# Sometimes we want to override this default behaviour and allow Rails to rescue
# exceptions and display an error page (just like when the app is running in production).
# Typical scenarios where you want to do this is when you test your error pages.
# There are two ways to allow Rails to rescue exceptions:
#
# 1) Tag your scenario (or feature) with @allow-rescue
#
# 2) Set the value below to true. Beware that doing this globally is not
# recommended as it will mask a lot of errors for you!
#
ActionController::Base.allow_rescue = false
# Remove/comment out the lines below if your app doesn't have a database.
# For some databases (like MongoDB and CouchDB) you may need to use :truncation instead.
begin
DatabaseCleaner.strategy = :transaction
rescue NameError
raise \"You need to add database_cleaner to your Gemfile (in the :test group) if you wish to use it.\"
end
# You may also want to configure DatabaseCleaner to use different strategies for certain features and scenarios.
# See the DatabaseCleaner documentation for details. Example:
#
# Before('@no-txn,@selenium,@culerity,@celerity,@javascript') do
# DatabaseCleaner.strategy = :truncation, {:except => %w[widgets]}
# end
#
# Before('~@no-txn', '~@selenium', '~@culerity', '~@celerity', '~@javascript') do
# DatabaseCleaner.strategy = :transaction
# end
#
# Possible values are :truncation and :transaction
# The :transaction strategy is faster, but might give you threading problems.
# See https://github.com/cucumber/cucumber-rails/blob/master/features/choose_javascript_database_strategy.feature
Cucumber::Rails::Database.javascript_strategy = :truncation
end"
add_to_file('features/support/env.rb', cucum, nil, true)
cuyml = "<%
rerun = File.file?('rerun.txt') ? IO.read('rerun.txt') : \"\"
rerun_opts = rerun.to_s.strip.empty? ? \"--format \#{ENV['CUCUMBER_FORMAT'] || 'progress'} features\" : \"--format \#{ENV['CUCUMBER_FORMAT'] || 'pretty'} \#{rerun}\"
std_opts = \"--format \#{ENV['CUCUMBER_FORMAT'] || 'pretty'} --strict --tags ~@wip --drb\"
%>
default: <%= std_opts %> features
wip: --tags @wip:3 --wip features --drb
rerun: <%= rerun_opts %> --format rerun --out rerun.txt --strict --tags ~@wip --drb"
add_to_file('config/cucumber.yml', cuyml, nil, true)
# Set up Devise
run "rails generate devise:install"
# Create database setup
dbconf = "development:
adapter: mysql2
encoding: utf8
reconnect: false
database: #{app_name.downcase}_development
pool: 5
username: root
password: 'vagrant'
socket: /var/run/mysqld/mysqld.sock
# Warning: The database defined as \"test\" will be erased and
# re-generated from your development database when you run \"rake\".
# Do not set this db to the same as development or production.
test:
adapter: mysql2
encoding: utf8
reconnect: false
database: #{app_name.downcase}_test
pool: 5
username: root
password: 'vagrant'
socket: /var/run/mysqld/mysqld.sock
production:
adapter: mysql2
encoding: utf8
reconnect: false
database: #{app_name.downcase}_production
pool: 5
username: root
password: 'vagrant'
socket: /var/run/mysqld/mysqld.sock"
add_to_file("config/database.yml", dbconf, nil, true)
# Set up Watchr
watchme = "# This usually sits at the root of the project and is called .watchr
@spec_cmd = \"bundle exec rspec\"
@cuc_cmd = \"bundle exec cucumber\"
# Convenience methods ########################################################
# Working on eventually adding Growl support. The problem right now is catching
# the output of a command, while at the same time piping it out to the stdout.
# Right now I don't know how to do it without stripping the ANSI color tags.
# def growl(message)
# if message.match /(\d+)\s(errors?|failures?)/ # Rspec failures
# Growl.notify \"\#{$1} spec \#{$2}\", :title => 'Watchr: specs failing'
# elsif message.match /(\d+)\sfailed/ # Cucumber failures
# Growl.notify \"\#{$1} features failed\", :title => 'Watchr: features failing'
# end
# end
def run(command)
puts \"\\n\\n\"
puts command
system command
puts \"\\n\\n\"
@interrupted = false
end
def run_all_specs
result = run \"\#{@spec_cmd} spec/\"
end
def run_spec(spec)
result = run \"\#{@spec_cmd} \#{spec}\"
end
def related_specs(path)
Dir['spec/**/*.rb'].select do |file|
file =~ /\#{File.basename(path).split('.').first}_spec.rb/
end
end
def run_all_features
result = run @cuc_cmd
end
def run_feature(feature)
result = run \"\#{@cuc_cmd} \#{feature}\"
end
def run_suite
run_all_specs
run_all_features
end
def trap_quit
puts \" --- Running all specs ---\\n\\n\"
run_all_specs
end
# Watchr rules ###############################################################
watch('spec/spec_helper\\.rb') { run_all_specs }
watch('spec/support/.*') { run_all_specs }
watch('spec/.*_spec\\.rb') { |m| run_spec m[0] }
watch('app/.*\\.rb') { |m| related_specs(m[0]).map { |s| run_spec s } }
watch('lib/.*\\.rb') { |m| related_specs(m[0]).map { |s| run_spec s } }
watch('features/support/.*') { |m| run_all_features }
watch('features/.*\\.feature') { |m| run_feature m[0] }
watch('features/step_definitions/.*\\.rb') { |m| run_feature m[0].sub('/step_definitions','').sub('_steps','').sub('.rb', '.feature') }
# Signals ####################################################################
@interrupted = false
Signal.trap 'INT' do # CTRL-C
if @interrupted
abort \"\\n\"
else
puts 'Interrupt a second time to quit'
#puts \" --- Running entire test suite ---\\n\\n\"
@interrupted = true
#sleep 1.5
#run_suite
end
end"
add_to_file(".watchr", watchme, nil, true)
testy = "namespace :test do
desc \"WARNING: Drop db and redo all migrations - all data gone!\"
task :remi do
Rake::Task['db:drop'].invoke
Rake::Task['db:create'].invoke
Rake::Task['db:migrate'].invoke
end
desc \"Watch for file changes, run tests on change\"
task :watch do
sh %{bundle exec watchr .watchr}
end
desc \"Load Spork Cucumber listener\"
task :auto do
sh %{bundle exec spork cucumber}
end
desc \"Load Spork RSpec2 listener\"
task :autospec do
sh %{bundle exec spork rspec}
end
end"
add_to_file("lib/tasks/testing.rake", testy, nil, true)
run "rake db:create"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment