Spec correct routing of custom URLs

When you roll custom URLs with hacks like routing-filter, you can put a spec like this into spec/routing/routing_spec.rb:

Test e-mail dispatch in Cucumber

Spreewald has steps that let you test that e-mails have been sent, using arbitrary conditions in any combination.

The attached file is for legacy purposes only.

Testing validates_format_of with Shoulda matchers

Don't use should validate_format_of(...) because that matcher works in weird ways. Use the allow_value matcher instead:

describe Email, '#sender' do
  # > Rspec 3 should syntax
  it { should allow_value("email@addresse.foo").for(:sender) }
  it { should_not allow_value("foo").for(:sender) }
  
  # Rspec 3 expect syntax
  it { is_expected.to allow_value("email@addresse.foo").for(:sender) }
  it { is_expected.not_to allow_value("foo").for(:sender) }
end

Errors that may occur if you do use should validate_format_of(...):
...

Forward HTTP through an intermediary server (Local Port Forwarding)

This will tunnel HTTP requests to one given domain and port through an intermediary SSH server:

ssh -L 8080:targethost:80 tunnelhost

http://localhost:8080 will now connect you to http://targethost:80, tunnelling all data through tunnelhost via SSH.

Note that the connection between tunnelhost and targethost will still be unencrypted in this example.

Fixing Webrat after following an external link

When a Cucumber feature leaves your page through an external Link, Webrat has problems like "Could not find field: "E-mail" (Webrat::NotFoundError)" using your page afterwards. It will also have trouble following redirects.

Fix it with this step:

Given /^I am back on my page$/ do
  webrat_session.header("Host", "www.example.com")
end

MySQL replication how-to

This may be awkward to set up, but will work once you're done.

Fun facts:

  • In case of a connection loss the slave will try to reconnect to the master server and resume replication for the next 24 hours
  • If you want to use your slave as a "real" MySQL server, you basically need to switch off replication (STOP SLAVE; RESET SLAVE; and reset your my.cnf) and restart the MySQL daemon.

Master server configuration

  • Create replication user
    : In the MySQL shell:

      CREATE USER 'replicator'@'%' IDENTI...
    

Cucumber Webrat steps

Most of these will not work in newer projects because these use the Capybara/Rack::Test combo in lieu of Webrat.

Find input fields

Then /^there should be a "([^"]+)" field$/ do |name|
  lambda { webrat.current_scope.send(:locate_field, name) }.should_not raise_error(Webrat::NotFoundError)
end

Then /^there should be no "([^"]+)" field$/ do |name|
  lambda { webrat.current_scope.send(:locate_field, name) }.should raise_error(Webrat::NotFoundError)
end

Find html content

Then /^I should see "([^\"]*)...

Aggregated RSpec/Cucumber test coverage with RCov

With defaults, RCov doesn't work the way you how you would like it to. To create a nice test coverage report, copy the attached file to lib/tasks/rcov.rake. After that rake rcov:all will run all RSpec examples and Cucumber features. The report will be written RAILS_ROOT/coverage/index.html.

Here is what the task does in detail:

  • Generates aggregated coverage of both RSpec and Cucumber
  • Works with Rails 2 and Rails 3
  • Reports for app/**/*.rb and nothing else
  • If called with an environment variable IGNORE_SHARED_TRAITS=true it ...

Test concurrent Ruby code

To test concurrent code, you will need to run multiple threads. Unfortunately, when you use blocking system calls (e.g. locks on the database), Ruby 1.8 threads won't work because system calls will block the whole interpreter.

Luckily you can use processes instead. fork spins off a new process, IO.pipe sends messages between processes, Process.exit! kills the current process. You will need to take care of ActiveRecord database connections.

Here is a full-fledged example:

describe Lock, '.acquire' do

  before :each do
  ...

Better Output for RSpec

rspec_spinner is a progress bar for RSpec which outputs failing examples as they happen (instead of all at the end).

Installation

gem install rspec_spinner

Usage

script/spec -r rspec_spinner -f RspecSpinner::Bar -c

To make a shortcut in your .bashrc

alias ss='script/spec -r rspec_spinner -f RspecSpinner::Bar -c'

There's also an alternate runner RSpecSpinner::Spinner which shows a spinner and the name of the current spec instead of a progress bar.

Concurrent Tests

Install gem and plugin

sudo gem install parallel
script/plugin install git://github.com/grosser/parallel_tests.git

Adapt config/database.yml

test:
  database: xxx_test<%= ENV['TEST_ENV_NUMBER'] %>

Create test databases

script/dbconsole -p
CREATE DATABASE `xxx_test2`;
...

Generate RSpec files

script/generate rspec

(you'll probably only let it overwrite files in script/)

Prepare test databases...

Rails - Multi Language with Fast_Gettext

  • sudo gem install gettext --no-ri --no-rdoc
  • sudo gem install fast_gettext --no-ri --no-rdoc
  • script/plugin install git://github.com/grosser/gettext_i18n_rails.git (didn't work as gem)
  • environment.rb: see code example at the bottom
  • if this is your first translation: cp locale/app.pot locale/de/app.po for every locale you want to use
  • use method "_" like _('text') in your rails code
  • run rake gettext:find to let GetText find all translations used
  • translate messages in 'locale/de/app.po' (leave msgstr blank and ms...

Freeze (vendor, unpack) a single Ruby gem with and without Bundler

When you need to patch an existing gem, one way is to "vendor" the gem by copying it into the vendor/gems directory of your Rails project. You can then make any changes you require and Rails will use the vendored version of the gem after a server restart. Unfortunately you need to perform some additional steps to marry Rails and the copied gem. This notes describes what to do.

With Bundler

This is super-painful. If you just copy the gem to vendor/gems, Rails will complain:

Unpacked gem foolib in vendor/gems has no s...

Run a single test in Test::Unit

To run a single test file:

rake test:units TEST=test/unit/post_test.rb
rake test:functionals TEST=test/functional/posts_controller_test.rb
rake test:integration TEST=test/integration/admin_news_posts_test.rb

You may even run a single test method:

ruby -I test test/unit/post_test.rb -n "name of the test"
ruby -I test test/functional/posts_controller_test.rb -n test_name_of_the_test # underscored, prefixed with 'test_'

Or all tests matching a regular expression:

ruby -I test test/integration/admin_news_posts_test.r...

Configuring Git with .gitconfig

Basic configuration

Please keep this config simple. It should be a starting point for new developers learning Git.

[user]
  name = Your Name
  email = your.name@domain.com

[branch]
  sort = -committerdate
[color]
   ui = auto
[color "branch"]
  current = yellow reverse
  local = yellow
  remote = green
[color "diff"]
  whitespace = white reverse
  meta = blue reverse
  frag = blue reverse
  old = red
  new = green
[color "status"]
  added = green
  changed = yellow
  untracked = cyan
[interactive]
  singlekey = true # Do not requir...

Basic git commands

This is for people recovering from Subversion.

Get an existing from the server for the first time

git clone git@example.com:repositoryname

See what's changed

git status

Check in locally

git commit -m "good description"

Push local commits to the server

git push

Get and merge updates from the server

git pull

Stage a file for the next local commit

git add file

Stage all files for the next local commit

git add .

Create a new local branch and check it out

git checkout -b branchname

...

Test if a checkbox is checked in jQuery

jqueryElement.is(':checked')