Entries Tagged 'Ruby' ↓
December 18th, 2008 — General, Rails, Ruby
I see unit testing as a way to test each possible snippet of functionality and route the code in question can take. With Ruby being such a dynamic language and allowing shortcuts to common problems, sometimes it can seem somewhat of a mystery, how to test these snippets of functionality.
Using Memoization as an example:
class MyClass
def lazy_initialized_value
@lazy_initialized_value ||= Expensive.request
end
end
There are actually 3 separate snippets of functionality that need testing here, however it is not immediately obvious from the example. Lets be slightly more verbose about what is actually happening:
class MyClass
def lazy_initialized_value
@lazy_initialized_value = Expensive.request unless @lazy_initialized_value
@lazy_initialized_value
end
end
Now it is much easier to see the 3 steps the code should take:
- Store result of expensive request in instance variable
- Leave instance variable alone when it is already set
- Return the value of the instance variable
Now we have this information, our tests become (using Mocha to mock external methods):
class Expensive; end
module Tests::MyClass
# lazy_initialized_value
# ----------------------
class LazyInitializedValueTest < Test::Unit::TestCase
def test_should_respond
assert_respond_to MyClass.new, :lazy_initialized_value
end
def test_should_store_result_of_expensive_request_in_instance_variable
instance = MyClass.new
Expensive.stubs(:request).with().returns('expensive value')
instance.lazy_initialized_value
assert_equal 'expensive value', instance.instance_variable_get('@lazy_initialized_value')
end
def test_should_return_value_of_instance_varable
instance = MyClass.new
instance.instance_variable_set '@lazy_initialized_value', 'the value'
Expensive.stubs(:request)
assert_equal 'the value', instance.lazy_initialized_value
end
def test_should_maintain_existing_instance_variable_value_when_already_set
instance = MyClass.new
instance.instance_variable_set '@lazy_initialized_value', 'existing value'
Expensive.stubs(:request)
instance.lazy_initialized_value
assert_equal 'existing value', instance.instance_variable_get('@lazy_initialized_value')
end
end
end
Now we have these tests in place, we can go back and refractor the code ’til our heart’s content using all the tricks in the book but by simplifying the problem in the first place, it gives us a solid test suite and the confidence to make changes without breaking functionality.
If you were solving this problem test-first then you wouldn’t (but more likely, shouldn’t) have written the first example until re-factoring stage anyway, however when these shortcuts become engrained in your brain, it’s all too easy to forget what they are actually doing.
So there we go, simplify the initial implementation, get a solid test suite in order, then re-factor.
| Tags: Ruby, test, testing, unit
September 5th, 2007 — Rails, Ruby
Myself and a colleague have just managed to waste away a good couple of hours trying to figure out Autotests strange ’style’ mechanism to add the ability to test in the way Jay Fields explains using UnitRecord.
You can grab our plugin to enable UnitRecord when using Autotest below:
http://svn.soniciq.com/public/rails/plugins/iq_autotest
By default, running autotest in the Rails directory will run the unit tests. To run the functional tests, do: AUTOTEST='functional' autotest
I hope this saves some people some time!!
| Tags: autotest, Rails, Ruby, test, unit_record
August 28th, 2007 — Rails, Ruby, SonicIQ
We are looking for a Ruby on Rails, XHTML & CSS Developer to join our team at SonicIQ. Head over to 43folders job board to view our ad.
These are exiting times with projects like Propel’r in the pipeline, along with the ever-growing opportunities for new and interesting client projects.
If you are a highly motivated developer and can see yourself in a Ruby on Rails position in sunny (sometimes) Bournemouth, UK then apply at 43folders.
| Tags: CSS, jobs, Rails, Ruby, xhtml
August 24th, 2007 — Rails, Rake, Ruby
To view the coverage of your plugins using Rcov, first install the rcov gem with sudo gem install rcov, then copy and paste the following onto the end of the Rakefile inside your plugin directory:
require 'rcov/rcovtask'
desc 'Measures test coverage using rcov'
namespace :rcov do
desc 'Output unit test coverage of plugin.'
Rcov::RcovTask.new(:unit) do |rcov|
rcov.pattern = 'test/unit/**/*_test.rb'
rcov.output_dir = 'rcov'
rcov.verbose = true
end
desc 'Output functional test coverage of plugin.'
Rcov::RcovTask.new(:functional) do |rcov|
rcov.pattern = 'test/functional/**/*_test.rb'
rcov.output_dir = 'rcov'
rcov.verbose = true
end
end
You can now simply run rake rcov from inside your plugin directory which will generate an rcov directory with the results. Open rcov/index.html (if you are on OSX this will open automatically) in a browser to view the results.
Thanks to Mike Clark for his Rcov rake task for Rails which this task is based on.
Update (11-11-08): Changed code to use the RcovTask class.
| Tags: coverage, plugins, Rails, rcov, tests
August 23rd, 2007 — Ruby
Just noticed something interesting (well not that interesting). Ternary operators in Ruby can be re-written using Boolean operators e.g.
method = object.respond_to?(:foo) ? :foo : :bar
would become…
method = object.respond_to?(:foo) && :foo || :bar
Simply replace ? with && and : with ||
I don’t know if there is any performance gain here, anyone care to investigate?
| Tags: boolean, operator, Ruby, ternary
August 17th, 2007 — Rails, Ruby, Typo
Is anyone else having problems with Typo 4.1 taking ages to process new comments. If anyone has any suggestions I would love to hear them (If you can be bothered to wait for the comment to go through!)
| Tags: comments, slow, Typo
July 30th, 2007 — Mac / OS X, Rails, Rake, Ruby
John Nunemaker posted a handy tip on setting up autotest to work with Growl
I use this all the time now however I didn’t like the ugly smilies (call me shallow if you like). I used Wolfgang Bartelme’s Smily Devkit to make a couple of PNG’s slightly more pleasing to the eye.

The zip file can be downloaded here: autotest_images.zip
Update 17-08-07: Added ‘pending’ image for RSpec as requested by Aslak Hellesoy
| Tags: autotest, Rails, rspec, smily, testing
July 25th, 2007 — Ruby
I often need to do a reject! and return the rejected items instead of the modified collection. This saves having to do a select beforehand.
An example of how accomplish this:
options = { :a => 1, :b => 2, :c => 3 }
rejects = Hash[*options.select { |k, v| k == :b && options.delete(k) }.flatten]
assert_equal { :a => 1, :c => 3 }, options
assert_equal { :b => 2 }, rejects
This could be written as a method of the Hash class and an alternative for Array.
For Hash, the code would look something like:
class Hash
def extract!
Hash[*self.select { |k, v| yield(k, v) && self.delete(k) }.flatten]
end
end
options = { :a => 1, :b => 2, :c => 3 }
rejects = options.extract! { |k, v| k == :b }
assert_equal { :a => 1, :c => 3 }, options
assert_equal { :b => 2 }, rejects
If I am missing something obvious in Ruby that accomplishes the same, please leave a comment.
| Tags: hash, reject, Ruby
May 16th, 2007 — Ajax, Rails, Rake, Ruby
Following my previous post, below is a modified version of John Nunemaker’s ‘Renaming RHTML to ERB’ to take into account the format in the extension, and handle the RJS issues I was having.
namespace 'views' do
desc 'Renames all .rhtml views to .html.erb, .rjs to .js.rjs, .rxml to .xml.builder and .haml to .html.haml'
task 'rename' do
Dir.glob('app/views/**/[^_]*.rhtml').each do |file|
puts `svn mv #{file} #{file.gsub(/\.rhtml$/, '.html.erb')}`
end
Dir.glob('app/views/**/[^_]*.rjs').each do |file|
puts `svn mv #{file} #{file.gsub(/\.rjs$/, '.js.rjs')}`
end
Dir.glob('app/views/**/[^_]*.rxml').each do |file|
puts `svn mv #{file} #{file.gsub(/\.rxml$/, '.xml.builder')}`
end
Dir.glob('app/views/**/[^_]*.haml').each do |file|
puts `svn mv #{file} #{file.gsub(/\.haml$/, '.html.haml')}`
end
end
end
Update
Added haml conversion.
| Tags: edge, erb, Rails, rjs, views
May 16th, 2007 — Ajax, Rails, Ruby
It seems that on edge revision 6502 and later, the way that view file extensions has changed considerably.
I couldn’t work out why my tests were breaking when doing an xhr request to a new action which had a respond_to block setup for both html and js. It was returning the html instead of the rjs??
It turns out (after tearing my hair out for over three hours) that Changeset 6499 changes things in such a way that the normal new.rjs naming will not get picked up on an xhr request, you now need to add the request format to the extension before the template type i.e. new.js.rjs
This seemed a little odd at first but I am guessing it means you could have a new.js.erb file which is pretty cool as you could achieve the same as Dan Webb’s MinusR plugin.
What does seem a little odd is that a new.rjs will get picked up if you don’t give a respond_to at-all (I don’t know if this is a “feature” or a bug).
I’m am hoping that this may save someone some time.
| Tags: edge, Rails, rjs, views