Archive for July, 2009

How Rails made me a better developer

Posted in Uncategorized on July 31st, 2009 by Marcelo de Moraes Serpa – Be the first to comment

Rails has made me a better developer. Not because of the code itself or all the productivity gains only. Actually, Rails has brought me to Agility, and made me study about the agile methodology and its agile process component. Also, it taught me the importance of “testing”, but not testing in the common-sense of playing around the running application to see if it is working (acceptance testing), but unit-testing, more specifically Test-Driven Development, and later on, Behavior-Driven Development.

I will never look at software development in the same way.

It created the perception in me that software without unit-tests is crap. This might sound harsh, and you might have a different opinion, but that’s how I see things now and many past experiences from projects I have worked on prove this affirmation.

I love Ruby and Rails and all its eco-system, however, I’m pragmatic and willing to learn and use other technologies if needed or if they seem interesting to me. I never programmed Java, but the point here is, if I ever do, all this skills that Rails led me to learn, will be applied — e.g: I cannot do any serious software application without tests, and the outside-in philosophy is impregnated in my mind.

So, cheers for Rails!

Custom CruiseControl.rb conf – running from a different base directory

Posted in Uncategorized on July 29th, 2009 by Marcelo de Moraes Serpa – Be the first to comment

I’m testing CruiseControl.rb locally, and I wanted to use my sample git repo, which is actually a git repo with some Rails applications as subdirectories. The problem is that CruiseControl.rb assumes your repo root dir is also RAILS_ROOT. I didn’t find a way to change the base CC.rb project working dir, but here’s the workaround that worked for me:

The directory structure looks like this:

~/.cruise/projects/myproject
 - work
  - (lots of unrelated files)
  - my_rails_app/

So, CC.rb by default will try to run the rake tasks relative to ~/.cruise/projects/myproject/work, which is not a Rails application.

First, open [cruise_data]/projects/myproject/cruise_config.rb and uncomment the project.build_command line. Set it to “sh build_my_app.ssh”.

The solution was to create a shell script (which I named build_my_app.sh, as suggested by the CruiseControl.rb documentation, and because I’m lazy). The role of this shell script is to change the current working directory so that rake will be called from the right context:

cd my_rails_app
ruby1.8 -e “require ‘rubygems’ rescue nil; require ‘rake’; load ‘[cruise]/tasks/cc_build.rake’; ARGV << '--nosearch' << 'cc:build'; Rake.application.run; ARGV.clear"

* requires ‘rubygem’ so we will be able to load the gems;
* requires ‘rake’, so we will be able to run our tasks;
* load the default CC.rb rake task suite, which contains the build task;
* Populate the ARGV global array with some arguments, that will be used by Rake;
* Call Rake programmatically. Rake will look into ARGV to check for the arguments and will run the task cc:build, which is available in the current namespace, since we loaded it earlier.
* We have a task named cruise, which is enough, cc:build will check for it and run it if available.

This is just an isolated case, and I’m sure it won’t be common. Nevertheless, it’s good to know how to do it when you have an uncommon directory structure. There might be a better way to do that, so, if you are a CruiseControl.rb guru and know, please don’t hesitate to share!

I’m setting up CruiseControl for rSpec and Cucumber+WebRat and Selenium, if I find something noteworthy I’ll post here soon.

Remember to replace in the code above the tag [cruise] with the path to where you installed cruise and [cruise_data] to where the cruise projects directory is (by default it is /home/yourusername/.cruise).

EDIT: If you are using SVN, you can just do a narrow checkout like:

cruise add yourproject -r svn://my.svn.com/creative-allies/your/sub/dir/to/the/app

With that you don’t need the workaround above. I don’t use svn, but git. Narrow checkouts like this are not possible with git as far as I know (you shouldn’t have a structure like that though, each project should have it’s own repo).

Drying up a spec

Posted in Uncategorized on July 28th, 2009 by Marcelo de Moraes Serpa – Be the first to comment

Long time, no see!

I’ve been busy trying to get some personal issues solved and settling up in México. Well, this is probably a subject for another post (how I came to be in México, and how I ended up falling in love with the country, its culture and deciding to stay here).

Anyway, in this last months, I have been preparing lots of good stuff to post here, as this site desperately needs some fresh stuff. The point of this weblog is, after all, to share useful and interesting things, and I haven’t doing that lately, well, hope to kill the inertia again!

Today, a co-worker and friend of mine asked me if he could DRY-up his rspec examples, that looked like this:

describe "path/to/myview.erb" do
  context "the form, GET /new" do
   it "should display the name input field in the form" do
     get :new
     response.should have_selector("form") do
       (...)
     end
   it "should something else..." do
     get :new
     response.should have_selector("form") do
       (...)
     end
    (...)
   end
end

I’m sorry for the meaningless spec, but it is not the point of this post, and I’m sleepy right now :) . Anyway, can you see the duplication? Yeah, the “response.should have_selector(“form”) is used in many examples. Of course, it’s okay, since it’s better to have clarity over cleverness, but I also think this is a matter of taste.

There are many was you could make the spec DRIer, and you could find other articles that teach you how to that, even generating examples dynamically using the metaprogramming capabilities of Ruby. Well, in my case it’s simpler and not so evil (using too much magic in specs/tests is discouraged).

Well, the basic idea is to wrap/encapsulate this code in a central place in the code. The simplest solution is to define a method somewhere in the spec source file to encapsulate it (I have defined it in the bottom of the code):

def exp
  response.should have_selector("form") { |form| yield form }
end

And you can use like:

 it "should have a yay! in the form" do
   exp do |form|
     form.should contain("yay!")
   end
 end

What happens is that we yield the form object to the exp method, so it is available to the block passed to exp. Nice uh?

NOTE: The yield call is the yield for the exp method (it is called in the scope of exp, but with access with the form param yielded to the block), it seems. I’m not entirely sure how it works, but I’m working on a new article to explore this, expect it here soon.

NOTE 2: It doesn’t matter where you define the method as long as it is available for the current scope, since this code will only be ran when the def is called, there is no need to put it into the before block. It is like in “suspended animation”, until it is called.