Flowdock

Notes posted by mutru

RSS feed
June 3, 2010
0 thanks

Testing Net:HTTP connections

You can use this excellent library to stub Net:HTTP connections in your automatic tests:

http://github.com/bblimke/webmock

October 18, 2009
1 thank

Receiving data over UDP

It’s perfectly normal to receive ‘X’ strings with Ruby’s UDP sockets before the actual content.

Consider the following example:

require 'socket'

PORT = 5500

socket = UDPSocket.new
socket.bind('', PORT)

for i in 1..10
  IO.select([socket])
  p socket.recvfrom_nonblock(4096)
end

Now, sending data with netcat:

echo "Hello APIdock" | nc -vv -u 127.0.0.1 5500

The application would output:

["X", ["AF_INET", 61755, "localhost", "127.0.0.1"]]
["X", ["AF_INET", 61755, "localhost", "127.0.0.1"]]
["X", ["AF_INET", 61755, "localhost", "127.0.0.1"]]
["X", ["AF_INET", 61755, "localhost", "127.0.0.1"]]
["Hello APIdock\n", ["AF_INET", 61755, "localhost", "127.0.0.1"]]
October 7, 2009
3 thanks

Streaming XML with Builder

To generate larger XMLs, it’s a good idea to a) stream the XML and b) use Active Record batch finders.

Here’s one way of doing it:

def my_action
  @items = Enumerable::Enumerator.new(
    Item.some_named_scope,
    :find_each,
    :batch_size => 500)

  respond_to do |format|
    format.xml do
      render :text => lambda { |response, output|
        extend ApplicationHelper

        xml = Builder::XmlMarkup.new(
          :target => StreamingOutputWrapper.new(output),
          :indent => 2)
        eval(default_template.source, binding, default_template.path)
      }
    end
  end
end

The Builder template does not need to be modified.

June 1, 2009
1 thank

Shared examples

Use it together with share_examples_for like this:

share_examples_for "a shape" do
  it "should have a color" do
    # ...
  end

  it "should have a center point" do
    # ...
  end
end

describe "a circle" do
  it_should_behave_like "a shape"

  it "should be round" do
    # ...
  end
end
June 1, 2009
0 thanks

Typical stub! usage

Typically you would call

my_object.stub!(:updated_at).and_return(time_object)
February 24, 2009
2 thanks

Test if one array includes the elements of another v2

Maybe a bit more readable way to write the previous snippet would’ve been

puts "yay" if [1, 2, 3].all? { |i| (1..9).include?(i) }
# => "yay"

puts "nope" if [1, 2, 3, 'A'].any? { |i| not (1..9).include?(i) }
# => "nope"
February 17, 2009
7 thanks

Usage examples

Basic usage:

User.should_receive(:find).with(:all, anything).and_return("hello world")

Now:

User.find(:all, :conditions => "foo")  #=> "hello world"

But you can also use blocks for more complex matching logic. For example:

User.should_receive(:find) { |*args|
  if args.size == 2
    "received two arguments"
  else
    "something else"
  end
}.at_least(:once)

Now:

User.find(:all, :conditions => "bar")  #=> "received two arguments"
User.find(5)                           #=> "something else"

Of course normally you’d return mocks instead of strings.

February 4, 2009
3 thanks

Multiline regexps

A shortcut for multiline regular expressions is

/First line.*Other line/m

(notice the trailing /m)

For example:

text = <<-END
  Hello world!
  This is a test.
END

text.match(/world.*test/m).nil?  #=> false
text.match(/world.*test/).nil?   #=> true
October 10, 2008
8 thanks

Implemented in database adapters

These methods are not implemented in the abstract classes. Instead, all database adapters implement these separately, if the feature is supported.

July 13, 2008
5 thanks

Convert strings to Dates

Uses the undocumented Date._parse method. Some usage examples:

'06/15/2008'.to_date         # => Sun, 15 Jun 2008
'20080615'.to_date           # => Sun, 15 Jun 2008
'2008-06-15'.to_date         # => Sun, 15 Jun 2008
'Sun, 15 Jun 2008'.to_date   # => Sun, 15 Jun 2008
July 5, 2008
23 thanks

Using counters with collections

When you’re rendering a collection partial, the partial_name_counter variable contains the position of the current element in the collection. For example:

<%= render(:partial => 'example', :collection => %w(rails-doc is cool)) %>

Now in _example.html.erb:

<p>Element: <%= example %> (index: <%= example_counter %>)</p>

It would produce:

<p>Element: rails-doc (index: 1)</p>
<p>Element: is (index: 2)</p>
<p>Element: cool (index: 3)</p>

As you can see, indexing starts from 1.

July 4, 2008
2 thanks

around_filter code example

This is how it’s used:

around_filter do |controller, action|
  do_your(:stuff) do
    action.call
  end
end
July 2, 2008
6 thanks

Rails 2.1 caching internals

Rails 2.1 caching features are pretty much undocumented. Rob Anderton has documented some internal stuff here:

http://www.thewebfellas.com/blog/2008/6/9/rails-2-1-now-with-better-integrated-caching

June 18, 2008
8 thanks

Using memcached as a session store

Because of Ruby’s CGI library limitations, store cannot have any configuration options. Basically this means that you cannot easily run memcached on a different port (or with any non-default settings for that matter).

You can bypass this limitation with this ugly hack (environment.rb):

cache_params = *([memcache_servers, memcache_options].flatten)
CACHE = MemCache.new(*cache_params)
ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS.merge!({ 'cache' => CACHE })

In your initializer block, just configure session_store normally:

config.session_store = :mem_cache_store

I think this should be fixed to work like cache_store= does.