Spreewald: When using `patiently do`, don't reuse existing variable names

Spreewald's patiently repeats the given block again and again until it either passes or times out.

Be careful to give patiently a block that can actually be repeated. E.g. the following block can not be repeated:

Given /^the field "(.*?)" is empty$/ do |field|
  patiently do
    field = find_field(field)
    field.text.should be_blank
  end
end

The reason the above code will fa...

def vs. define_method

Ever wondered about the difference between def and define_method? Turns out there are three implicit contexts in Ruby. def and define_method differ in which one they use.

def

  • Ruby keyword, starts a method definition
  • Opens a new, isolated scope. Variables defined outside are not accessible inside and vice versa.
  • Defines an instance method on the receiver (specified before the method name, e.g. def object.foo); implicit receiver is the default definee

The default definee is not self and...

How to make Rational#to_s return strings without denominator 1 again

The way Rational#to_s works on Ruby has changed from Ruby 1.9 on. Here is how to get the old behavior back.

You may want this for things where Rationals are being used, like when subtracting Date objects from one another.

What's happening?

Converting a Rational to a String usually does something like this:

1.8.7 > Rational(2, 3).to_s
=> "2/3"
1.9.3 > Rational(2, 3).to_s
=> "2/3"
2.0.0 > Rational(2, 3).to_s
=> "2/3"

However, when you have a Rational that simplifies to an integer, you will only get a St...

Test redirects to an external URL with Cucumber/Capybara

When a controller action redirects to an external URL (like http://somehost.com/some/path) you will find that this is hard to test with Cucumber and Capybara:

  • A non-Javascript Rack::Test scenario will just ignore the host and try to open /some/path in your local application
  • A Selenium test will actually follow the redirect, which you probably don't want either

There are two workarounds for this. You can use either, or a combination of both.

  1. Write a controller spec

Controller specs can test if a resp...

How to disable cookies in cucumber tests

Unfortunately, Capybara does not offer a switch to disable cookies in your test browser. However, you can work around that by using a tiny Rack middleware -- it works for both Selenium and non-Selenium tests.


Wouldn't it be nice to say something like this?

Given cookies are disabled
When I try to sign in
Then I should see "Can't sign you in. Please enable cookies."

You can! Put the code below into some place like lib/rack/cookie_stripper.rb.

module Rack
  class CookieStripper
    
    ENABLED = false

...

Cucumber step to set cookies in your Capybara session

To set a cookie in your test browser for cucumber tests, you need to know which driver you are using. Use the step below according to your driver.

Rack::Test

Given /^I have a "([^\"]+)" cookie set to "([^\"]+)"$/ do |key, value|
  headers = {}
  Rack::Utils.set_cookie_header!(headers, key, value)
  cookie_string = headers['Set-Cookie']

  Capybara.current_session.driver.browser.set_cookie(cookie_string)
end

Note that Rack::Utils is only used to find out the correct cookie header string (you don't want to generate it yours...

Capybara 0.3.9 Bug: Chaining .find to scope doesn't work

The following code doesn't work like expected:

page.find(css_selector).find(other_css_selector)

The second .find will search the whole dom instead of a scope.

Rumor has it this is fixed in Capybara 0.4.1.

The Plight of Pinocchio: JavaScript's quest to become a real language - opensoul.org

Great presentation about writing Javascript like you write everything else: Well-structured and tested.

JavaScript is no longer a toy language. Many of our applications can’t function without it. If we are going to use JavaScript to do real things, we need to treat it like a real language, adopting the same practices we use with real languages.

This framework agnostic talk takes a serious look at how we develop JavaScript applications. Despite its prototypical nature, good object-oriented programming principles are still relevant. The...

What's in a View? A look at the alternatives

Great look at the tradeoffs between progressive enhancement with jQuery or similiar, vs. client-side views.

Ruby: Debugging a method's source location and code

Access the Method object

Dead simple: Get the method object and ask for its owner:

"foo".method(:upcase)
# =>  #<Method: String#upcase> 

"foo".method(:upcase).owner
# => String

Look up a method's source location

Ruby 1.9 adds a method Method#source_location that returns file and line number where that method is defined.

class Example; def method() end; end
# => nil

Example.new.method(:method).source_location
# => ["(irb)", 11] 
 
"foo".method(:upcase).source_location
# => nil # String#upcase is a native method...

Initiate SSL secured TCP connections to remote services

Establishing a TCP connection to a SSL secured remote service is not possible using telnet or nc.

Though, you can use openssl for that:

openssl s_client -connect www.makandra.com:443

Chart.js - a promising JavaScript charting library with MIT-license

Chart.js seems to be a good alternative to Google's Chart API and other commercial chart drawing libraries.

  • good looking charts
  • canvas based (means less memory consumptive, but no interactivity out of the box)
  • highly configurable
  • good API and documentation
  • just 4.5 kilobytes
  • MIT license
  • Browser support: all browsers supporting the canvas element (for IE8 and below, use the polyfill as describes in the [chart.js documentation...

Comparing Rails' flash hashes will not respect their internal lists of used entries

Rails flashes (FlashHash) track a list of used keys, which is not respected when comparing flash hashes.

This does not concern you under most circumstances.

Basics

When ActionController picks up a flash object, it will call the #sweep method once; that method checks the list of used flash entries and deletes those. All other entries are flagged as used. This means they will be deleted on the next request, but are still be available for rendering during the current request.

Fun facts: When redirecting, this does not happen. Also,...

Fix „rvm no such file to load -- openssl“ or "rvm no such file to load -- zlib"

For example if you use rvm and get this message:

ERROR:  Loading command: install (LoadError)
    no such file to load -- zlib
ERROR:  While executing gem ... (NameError)
    uninitialized constant Gem::Commands::InstallCommand

You've installed your ruby without having all required libraries.

I don't know why there isn't a Warning message if you install a ruby with rvm and didn't have libraries like openssl and zlib.

To fix this you can execute this:

#to show the requirements for your system
rvm requireme...

Tips And Tricks For Print Style Sheets

Smashing Magazine lists some handy tricks for print style sheets, all with CSS:

Interactive generator for gradients, borders, noise textures and box shadows

CSSmatic lets you play around with four rather complex CSS stylings and gives you CSS or SASS code to use your result right away.

  • Gradients
  • Borders
  • Noise textures – offers a texture download
  • Box shadows

Browser Hacks: CSS Rules to Target Specific Browsers And Versions

The linked site lists a wealth of CSS hacks that let you apply styles to just that one browser. You should be using this mostly for fixing browser issues and not give up on creating solid styles.

About progamming with Multi-Touch, Touch- and Mouse-Events in the webbrowser

Since there are more and more touch-capable devices out there, as a web-developer it becomes more and more important to know how to deal with touch events next to mouse events and how you you can combine both worlds (mouse and touch interaction).

Here's a quick introduction to (multi-)touch browser events and an advanced article that deals with touch and mouse events and how they can be combined.

Ruby 1.9 or Ruby 2.0 do not allow using shortcut blocks for private methods

Consider this class:

class Foo

  private
  
  def test
    puts "Hello"
  end
  
end

While you can say create a block to call that method (using ampersand and colon) on Ruby 1.8, ...

1.8.7 > Foo.new.tap(&:test)
Hello
=> #<Foo:0x1e253c8> 

... you cannot do that on Ruby 1.9 or 2.0:

1.9.3 > Foo.new.tap(&:test)
NoMethodError: private method `test' called for #<Foo:0x00000001e8c258>

^
2.0.0 > Foo.new.tap(&:test)
NoMethodError: private method `test' called for #<Foo:0x000000027bc738...

Different behavior for BigDecimal#floor in Ruby 1.8 and Ruby 1.9

Ruby 1.8 (supplied by Rails' ActiveSupport)

>> BigDecimal.new("0.1").floor.class
=> BigDecimal

Ruby 1.9 (supplied by Ruby 1.9 itself)

>> BigDecimal.new("0.1").floor.class
=> Fixnum

In fact, Float#floor has changed from Ruby1.8 to Ruby 1.9 which is used by BigDecimal#floor internally.

Attached initializer backports Ruby 1.9 behavior to Ruby 1.8.

How to copy your „Google Chrome“ or „Chromium“ profile without creating an online account

Google Chrome saves your profile data in ~/.config/google-chrome.
To transfer the profile to for example a system you have setup freshly do following steps:

  • make a copy of ~/.config/google-chrome
  • install google-chrome
  • restore your backuped profile to ~/.config/google-chrome
  • launch google-chrome

(Replace google-chrome by chromium-browser if you use chromium-browser)

How to: Ruby heredoc without interpolation

When you use heredoc, string interpolation is enabled by default:

x = "Universe"
<<-MESSAGE
  Hello #{x}
MESSAGE
# => "Hello Universe"

This may be impractical sometimes. To avoid interpolation in heredoc strings, simply enclose your heredoc marker with single quotes:

x = "Universe"
<<-'MESSAGE'
  Hello #{x}
MESSAGE
# => "Hello #{x}"

That will make the string behave like a single-quoted string, so sequences like \n wil...

Ensure reloading of favicons

Sometimes it seems a favicon does not work because your browser displays an old version or (in case of local development) a favicon of another project you worked on recently.

Though, you can force your browser to really reload the favicon using some kind of additional version parameter string like this:

= favicon_link_tag("/favicon.ico?v=2")