Cucumber steps to test input fields for equality (with wildcard support)

Our collection of the most useful Cucumber steps, Spreewald, now supports exact matching of form fields and lets you use wildcards.

Examples:

And the "Money" field should contain "134"
# -> Only is green if that field contains the exact string "134", neither "134,50" nor "1000134"

And the "Name" field should contain "*Peter*"
# -> Accepts if the field contains "Peter" or "Anton Peter" or "Peter Schödl" etc.

And the "Comment" field should contain "Dear*bye"
# -> Accepts if the field contains "De...

Default block arguments for Ruby 1.8.7

When your block takes an argument that should have an default, only in Ruby 1.9 you can say:

block = lambda do |message, options = {}|
  # ...
end

If you are on Ruby 1.8.6 or 1.8.7 you must resort to the following workaround:

block = lambda do |*args|
  message = args[0]
  options = args[1] || {}
end

Git: See all unpushed commits or commits that are not in another branch

If you need to find out which of your local commits are not on the remote server do this:

git cherry -v

The -v option prints out the commit messages. Without it you will see only the SHA1 codes.

You may also compare against another (upstream) branch like that:

git cherry -v origin/somebranch

This tool is especially useful when you have a ton of commits after a merge and want to know the commit differences between branches.

Creating Liquid Layouts with Negative Margins

I was recently confronted with the task of creating a two-column liquid layout with a header and footer in which the content needed to come before the sidebar in the source code. I took opportunity to demonstrate an under-used aspect of CSS: negative margins. Negative margins allow us to push the content area away from the sides of the browser, leaving room for the sidebar.

Git: Define a custom merge driver

The ‘merge.*.driver` variable’s value is used to construct a command to run to merge ancestor’s version, current version and the other branches’ version. The merge driver is expected to leave the result of the merge in the file named with %A by overwriting it, and exit with zero status if it managed to merge them cleanly, or non-zero if there were conflicts.

Overriding unary operators in Ruby

This must be one of the coolest, yet quite unknown, technique in Ruby. For certain types of problems (e.g. when you have a set of rules) this gives you such an elegant way of describing the solution. There’s no meta programming or monkey patching involved, it’s short and sweet and best of all: it’s very intuitive.

Apache: Redirect all requests from one host to another

In order to redirect all requests from redirecting-host.com to desired-host.com while keeping path and query params unchanged, change your Apache VHost to something like this:

ServerName desired-host.com
ServerAlias redirecting-host.com
RewriteEngine On
RewriteCond %{HTTP_HOST} !^desired-host.com$
RewriteRule ^.*$ http://desired-host.com%{REQUEST_URI} [R=301,L]

Take care to keep all those ^, $ and ! as seen in the example.

Word boundaries in MySQL regular expressions

In regular expressions you can use the zero-width pattern \b to match the beginning or end of a word:

note.title =~ /\bfoo\b/

Unfortunately \b is not available in MySQL. You can use [[:<:]] and [[:>:]] to match the beginning and end of a word instead:

SELECT * FROM notes WHERE title REGEXP "[[:<:]]foo[[:>:]]"

These markers are unique to MySQL and not available in Ruby regular expressions.

Apache: Require username/password authentication except from a single IP, host or network

You configured authentication in your Apache configuration that requires username and password but you want a single IP address, host or network to allow access without entering credentials you can use the code below.

To allow a network you can use CIDR notation like this:
Allow from 1.2.3.4/24
This would match 1.2.3.0-255. Simple matching does work as well:
Allow from 1.2.3

<Location />
  AuthType Basic
  AuthName "Secured"
  AuthUserFile /path/to/.htpasswd
  Require valid-user
  Satisfy any
  Deny from...

Parametrized shared example groups in RSpec

RSpec 2

In RSpec 2 shared_examples_for can have parameters. You can simply hand over arguments from it_behaves_like:

shared_examples_for 'string equaling another string' do |expected_string|
  it 'is equal to another string' do
    expect(subject).to eq(expected_string)
  end
end

describe 'some string' do
  subject { 'foo' }
  it_behaves_like 'string equaling...

Rails for Zombies

Learning Rails for the first time should be fun, and Rails for Zombies allows you to get your feet wet without having to worry about configuration. You'll watch five videos, each followed by exercises where you'll be programming Rails in your browser.

Export CSV from MySQL directly

If you need to export data from MySQL to a CSV, you can profit from really fast built-in methods.

This query writes the data to /tmp/geodb_coodinates.csv. And it's fast: Query OK, 337925 rows affected (0.86 sec)

SELECT * INTO OUTFILE '/tmp/geodb_coordinates.csv' FIELDS TERMINATED BY ',' ENCLOSED BY '"' ESCAPED BY '\\' LINES TERMINATED BY '\n' FROM geodb_coordinates;

Proper cross-browser CSS styling for buttons

Styling button tags across all major browsers is not easy.

Many times you should be fine by using the native button style a browser-OS-combination offers you. But if you are trying to style buttons with images (e.g. by nesting a span tag inside them as assigning a background to both button and span) it will look different on each browser.

Use this Sass snippet as a base style:

button
  border: 0
  padding: 0
  cursor: pointer
  overflow: visible // removes padding in IE
  &::-moz-focu...

Reset MySQL query cache

To clear the query cache in your MySQL database manually, e.g. for database profiling, execute the following command in your MySQL console:

RESET QUERY CACHE;

Git: Accessing lost commits

Every time you amend, rebase or reset, git commits get "overwritten".

However, git still allows you to checkout those commits using their SHA1, given you can find it.

One option to do this is

git reflog
# or
git reflog show [BRANCH]

This will show a list of all commits the branch has recently pointed to.

Git might garbage collect those commits eventually, but this should only happen after several weeks.

Apply a new callback to existing records

So you added a new callback to your model that (e.g.) caches some data when it is saved. Now you need to run that callback for the 10000 existing records in the production database. You have two options here:

  1. Write a clever migration, possibly by embedding the model into the migration script.
  2. Open the Rails console after deployment and re-save every single record. You should probably add two chores to your issue tracker so you won't forget t...

Check if a field or button is disabled with Cucumber

Using this step definition you can check if any form field (text field, checkbox, etc) or button is disabled:

Then the "Name" field should be disabled
  And the "Save" button should be disabled
But the "Locked" field should not be disabled

Capybara

This step part of Spreewald.

Webrat

Then /^"([^\"]*)" should( not)? be disabled$/ do |label, negate|
  attributes = field_labeled(label).element.attributes.keys
  attributes.send(negate ? :should_not : :should...

The Ruby Infinite Hash

How to create an infinitely nestable hash that always defaults to a new hash if a key does not map to a value.

Force net/http to verify SSL certificates

Ruby's net/http is setup to never verify SSL certificates by default. Most ruby libraries do the same. That means that you're not verifying the identity of the server you're communicating with and are therefore exposed to man in the middle attacks. This gem monkey-patches net/http to force certificate verification and make turning it off impossible.

ActiveRecord Table Transform

How to write to the db 27,000 times in 24 seconds instead of 9 minutes.

Test that an exception or error page is raised in Capybara

You can use these step definitions:

Then /^I should not see an error$/ do
  (200 .. 399).should include(page.status_code)
end

Then /^I should see an error$/ do
  (400 .. 599).should include(page.status_code)
end

Note that you need to tag the scenario with @allow-rescue to test that an error is shown like this

@allow-rescue
Scenario: Accessing the admin area requires a login
  When I go to the admin area
  Then I should see an error

These step definitions will not work for @javascript scena...

Ruby: Checking if a class is a descendant of another class

If you want to find out whether a Class object is directly inheriting from another class, use superclass:

ActiveRecord::RecordNotFound.super_class == ActiveRecord::ActiveRecordError # => true

To check if another class is an ancestor (not necessarily the direct superclass, but e.g. the superclass of the superclass):

ActiveRecord::RecordNotFound.ancestors.include?(StandardError) # => true

Note that ancestors also includes the receiving class itself as well as any included modules (which is quite...

Check if two arrays contain the same elements in Ruby, RSpec or Test::Unit

RSpec 1, RSpec 2

To test whether two arrays have the same elements regardless of order, RSpec 1 and 2 give you the =~ matcher:

actual_array.should =~ expected_array

Rspec 3

With RSpec 3's expect syntax you can choose one of these two matchers:

expect(actual_array).to match_array(['1', '2', '3'])
expect(actual_array).to contain_exactly('1', '2', '3')

Note how match_array takes an argument, but contain_exactly takes a list of elements as varargs.

Test::Unit

If y...

Encode or decode HTML entities

Use the htmlentities gem.

Encoding works like this:

require 'htmlentities'
coder = HTMLEntities.new
string = "<élan>"
coder.encode(string)               # => "&lt;élan&gt;"
coder.encode(string, :named)       # => "&lt;&eacute;lan&gt;"
coder.encode(string, :decimal)     # => "&#60;&#233;lan&#62;"
coder.encode(string, :hexadecimal) # => "&#x3c;&#xe9;lan&#x3e;"

Decoding works like this:

require 'htmlentities'
coder = HTMLEntities.new
string = "&eacute;lan"
cod...