Rob Olson's blog
One property of the Ruby object model and object oriented programming in general is that a subclass of an object automatically inherits all of the methods of its superclass. Classes can further expand the number of methods available by mixing in a Module, or several.
Because of mixins and subclassing even a class that has declared just a few methods can actually have hundreds of methods on it. In Ruby, all classes subclass Object by default which declares a hefty 45 methods, guaranteeing you to have at least that many. Out of the box in 1.8.7, a Ruby String object has 176 instance methods. If you are programming on top of the Rails framework, ActiveSupport adds 98 methods bringing the total to 274!
On numerous occasions I have needed to see what methods are available on an object I am working with I will type the following in irb.
myobject.methods - Object.instance_methods
This prints out a large array of instance methods with the methods inherited from Object removed from the list. This is useful but what if the object I am working with mixed in several modules and I am left with a list of over a hundred methods? It would be great to view which Class or Module each method came from. Well, actually there's a gem for that.™
Looksee
Looksee is a new gem by George Ogata that examines the method lookup path of any object. To use it add require 'looksee/shortcuts' to your ~/.irbrc. This will add a lp ("lookup path") method to your irb environment. When passed an object lp prints out a colored display showing where each of an object's methods lives.
Ask for Help
"We are attempting to upgrade one of our projects using Fixture Scenarios to Rails 2.3.2. When we attempt to run our tests we get errors about a corrupt fixture file. Is anyone successfully using Fixture Scenarios with Rails 2.3?"
Interesting Things
It is really easy to declare an additional route just for use in a controller test. All that is needed is to recall ActionController::Routing::Routes.draw at the top of your spec file. One situation in which this can be useful is if you are creating a new controller just for testing purposes.
class DummiesController < ApplicationController before_filter :require_profile def index end end ActionController::Routing::Routes.draw do |map| map.resources :dummies end describe DummiesController do ... end
Ask for Help
"When attempting to upload files with the aws-s3 gem I am receiving a lot of timeouts. This seems to happen with both small and large files. Has anyone run into this before?"
It was hypothesized that this could be the result of a slow internet connection and saturating the upload stream. Does anyone know of a fix for s3 timeouts?
Ask for Help
"Is there a good way to temporarily redefine a method on a controller during a functional test?"
Reopening a controller and overriding a method affects all tests in a suite. Is there a good way to redefine a controller method for a single test?
Interesting Things
- Rails 2.3.3 was released yesterday. It is a minor point release but a notable new feature is a faster decoding backend for JSON.
- The Evening with Palm webOS event is tonight at 6:30!
- There is a new mailing list for the Jasmine Javascript testing framework.
- Braid gotcha be careful when using Braid to checkout a specific branch of a Git repository. If you checkout a repository with Braid, and then later decide that you want to switch to a different branch (i.e. going from master to 2-3-stable with Rails) doing a
braid remove vendor/railsis not sufficient! The reason is when you add a external with Braid it also adds a remote branch in your Git repository. If you re-add the external, the old remote will be reused, even if you specify a different branch. To avoid this, remove the remote in addition to removing the external. To view your remotes rungit remoteand remove a remote withgit remove rm some/remote/name.
Weirdness with using serialized with Single Table Inheritance in Rails
If you have a class that uses a serialized categories attribute like this:
class Wibble < ActiveRecord::Base
serialized :categories
end
Interesting Things
Prior to RSpec 1.2.7, render_template in rspec-rails had a bug where render_template('new') would pass if 'newer' was rendered (or anything that started with 'new'). Internally render_template was converting the string argument to a regular expression which was allowing 'new' to positively match 'newer' even though it was not an exact match. In RSpec-Rails 1.2.7 this bug has been fixed.
Assertions such as assert_select, assert_tag, and css_select are powerful tools in view tests. Since view helpers generate a chunk of HTML, it is sometimes practical to use these assertions to test their return value.
If you attempt to use assert_select it will fail because there has not been a call to render, as is done in a view test. To get around this you can store the result of the helper method in @response.body. Once @response.body is populated, the assertions will work like expected.
Update: For people using RSpec, Pat Maddox posted a helpful suggestion in the comments showing how to use have_tag to accomplish the same thing in RSpec style.
Example
describe TagsHelper do
describe "#tag_list"
describe "when the user is not an admin"
it "should not have links to delete the tags" do
@response.body = helper.tag_list
assert_select "a", 0
end
end
end
end
I like Autotest because it allows me to stay within my code editor and let my test suite run automatically in the background. After each run I get a nice, unobtrusive, growl notification informing me whether my most recent change caused the tests to fail or pass.
It used to be that setting up and configuring Autotest for the OS X with pretty growl notifications was a nontrivial task. I remember that I spent several hours getting it working a year ago. However, there has been several developments with Autotest in recent months that greatly simplify the process. One of those enhancements is that Autotest can now use FSEvent introduced in OS X Leopard so that it no longer has to continuously poll the filesystem. This has the advantage of vastly reducing Autotest's CPU usage when idle.
