Uncategorized

Separating the Steak

Posted in Uncategorized on June 23rd, 2010 by Marcelo de Moraes Serpa – Be the first to comment

Steak is a great lightweight replacement for Cucumber. I’m not going to dig into it here since it’s not the point of this post, but suffice to say it is basically rSpec for acceptance/integration tests (aka features in the Cucumber world, whatever you prefer).

I’ve been having some issues with Steak though. The default Steak generator creates the infra-structure under spec/. At first sight, it doesn ‘t seem that bad, after all, acceptance tests are just specs with added sugar, right? Well, not really.

Even though Steak acceptance tests are just rSpec at its core, the nature of it make them a different beast. First, you often need to use Culerity with them. This also brings the need to use DatabaseCleaner. If you keep all of this under spec/, the rake spec task will load and run it all, including the DatabaseCleaner configuration, wreaking havoc with your rSpec unit-tests. Also, you often don’t want to run acceptance tests when running the suite of unit-tests, acceptance/integration tests are often much slower.

I’ve already opened an issue here on Steak’s github issues page. However, if you want to fix it now, here’s what you need to do.

1) First, move the acceptance directory out of spec/. I recommend moving it to the application’s top-level directory (RAILS_ROOT);
2) Now, open acceptance/acceptance_helper.rb and correct the require for spec_helper. If you’ve put the acceptance directory on RAILS_ROOT, the require should look like this:

"require File.dirname(__FILE__) + "/../spec/spec_helper"

3) Open lib/tasks/steak.rake, and correct all the references to the acceptance directory, again, if you’ve put on RAILS_ROOT, you just remove the “spec/” part on the path string. It would look like:

nless ARGV.any? {|a| a =~ /^gems/} # Don't load anything when running the gems:* tasks

  require 'spec/rake/spectask'

  ENV['RAILS_ENV'] = 'development'
namespace :spec do
  desc "Run the code examples in spec/acceptance"
  Spec::Rake::SpecTask.new(:acceptance => "db:test:prepare") do |t|
    t.spec_opts = ['--options', "\"#{RAILS_ROOT}/spec/spec.opts\""]
    t.spec_files = FileList["acceptance/**/*_spec.rb"]
  end

  # Setup stats to include acceptance specs
  task :statsetup do
    require 'code_statistics'
    ::STATS_DIRECTORIES << %w(Acceptance\ specs spec/acceptance) if File.exist?('acceptance')
    ::CodeStatistics::TEST_TYPES << "Acceptance specs" if File.exist?('acceptance')
  end
end

end

Now you can run "rake spec:acceptance" for Steak acceptance tests, and "rake spec" for the rest of unit-tests.

Get them straight from their source – RubyGems and rake

Posted in Uncategorized on June 10th, 2010 by Marcelo de Moraes Serpa – Be the first to comment

Don’t ever install rake and or rubygems from debs (or any other distro package manager). For rubygems, get from rubygems.org, for rake, install it through gem. If you are using Ubuntu, for example, don’t use apt-get to install rake, nor rubygems, you’ll waste your time wondering aftewards why rake can’t find gems, for example.

Making Culerity play along well with Capybara

Posted in Uncategorized on June 9th, 2010 by Marcelo de Moraes Serpa – 1 Comment

It’s never an easy task to refactor infra-strcuture, specially if it uses different libraries. That’s the case with my latest endeavour of migrating from the Cucumber+WebRat+Selenium combo to Steak+Capybara+Culerity combo. The reason? Simplify. The process? Boring and troublesome, but *** happens and we have to deal with it :)

Anyway, if you are getting the following error when trying to run your acceptnace test spec/Cucumber feature when using Capybara+Culerity/Celerity:

custom_require.rb:31:in `require': no such file to load -- celerity (LoadError)

This is because (well, at least was for me) you haven’t installed the celerity gem on your local ruby (note the empahasis — not jruby!) installation. Do so:

 $ sudo gem install celerity

Now, I will blame this confusion on the Culerity docs. The documentation states:

You will need the celerity gem installed into JRuby:

jruby -S gem install celerity

Now install the Culerity gem:

gem install culerity –source http://gemcutter.org

So, it instructs you to install celerity on jruby but not on ruby. But this didn’t work for me at all.

Anyway, feel free to comment/contact me if you could make it work the way it’s told on the documenation. Hope this saves someone else’s time :)

Fixing Culerity (BROKENPIPE error)

Posted in Uncategorized on June 8th, 2010 by Marcelo de Moraes Serpa – Be the first to comment

So, today I decided to replace Cucumber with Steak + Capybara and Culerity. Albeit I believe this has been a good choice (I’ve found Cucumber too heavy for our needs, and since the stakeholders are also developers, we don’t really need, nor used Cucumber, so it wasn’t aggregating any value at all), I’ve had a small issue with Culerity, more specifically with its culerity:rails:start rake task.

If you check the documentation, you’ll see that before running your feature/acceptance specs that use Culerity (and hence, Celerity) you will need to start a Rails server, which will be used by the Celerity HTMLUnit client. Ok, so far, no problems, Cucumber and Webrat used to do that automatically for us, but it’s not a big deal. So I went to the terminal and typed:

$ rake culerity:rails:start

Boom! Got the following output:

rake culerity:rails:start/Library/Ruby/Gems/1.8/gems/rails-2.3.5/lib/commands/server.rb:104:in `write': Broken pipe (Errno::EPIPE)
from /Library/Ruby/Gems/1.8/gems/rails-2.3.5/lib/commands/server.rb:104:in `puts'
from /Library/Ruby/Gems/1.8/gems/rails-2.3.5/lib/commands/server.rb:104
from script/server:3:in `require'
from script/server:3

I’ve opened the server.rb, and the line 104 for Rails 2.3.5, has the following code:

puts "=> Call with -d to detach"

Hmm… after a moment, I also realized this wasn’t a “fatal error”. The server was actually being started succesfully, behind the scenes. The issue was that the output was not being redirected to stdout, thus, a Errno::EPIPE (I’m not sure which component throws this exception though, if someone knows, please shed some light).

So, if you can live with it, just wait a few seconds and everything should work out fine.

However, it would be good to:
* See the output of your test Rails server;
* Use the debugger on this Rails server;
* Have the damn pid file removed when you send a SIGINT (Ctrl+C) to the rake task.

Well, fear not. Just replace the code for the task :start on RAILS_ROOT/lib/tasks/culerity.rake with the following code and go get some fresh coffee:

task :start do
port = ENV['PORT'] || 3001
environment = 'test'
pid_file = RAILS_ROOT + "/tmp/culerity_rails_server.pid"
if File.exists?(pid_file)
puts "culerity rails server already running; if not, delete tmp/culerity_rails_server.pid and try again"
exit 1
end
rails_server = IO.popen("script/server -e #{environment} -p #{port}", 'r+')
File.open(pid_file, "w") { |file| file << rails_server.pid }

running = true

Signal.trap('SIGINT') {
puts 'terminating'
running = false
rm = `rm -rf #{RAILS_ROOT}/tmp/culerity_rails_server.pid`
}

while running
$stdout << rails_server.gets
end

end

This works for culerity 0.2.10, as of 8/June 2010.

Another possibility would be to add a & here, like this:

culerity.rake:12

rails_server = IO.popen("script/server -e #{environment} -p #{port} &", 'r+')

I think this was the intended way to use the tasks, since there is also a rake task to stop the process (by using the pid in the pidfile), so probably the missing ampersand could be considered a bug.

Changing bundle_path (Gem Bundler)

Posted in Uncategorized on June 8th, 2010 by Marcelo de Moraes Serpa – Be the first to comment

I was about to run Bundler, and I wanted to test if the command would accept the name of a gem to install as an argument, like this:


bundle install capybara-envjs

This ran the whole bundle, and didn’t install only capybara-envjs, but not a big deal — I just ignored that fact and kept working. Eventually, I noticed the capybara-envjs misteriously sitting at the root of the Rails application. What was that? Happens it contained all the gems from my Gemfile!

Happens that the argument you pass after install tells bundler where you want to install the gems to. Not so obvious.

Anyway, if you happen to fall in the same “trap”, just edit .bundle/config in the root of you Rails app and set the value of BUNDLE_PATH to the correct path (usually ~/.bundle).

Pick anything with Peepopen on emacs

Posted in Uncategorized on May 27th, 2010 by Marcelo de Moraes Serpa – 1 Comment

As you might already know, I use emacs+orgmode for most of my information management needs and GTDness. There’s really nothing else out there that reaches the simplicity of plain text files managed by such a powerful PIM meta-framework.

I’ve been also using Peepopen, the new fuzzy-search based file-picker from topfunky. Peepopen indexes a list of files in a given directory and allows you to reach the wanted file with as few types as possible, taking advantage of fuzzy-search logic.

You could think it would be used only to pick up files from a software project, but the truth is, it can be used to pick files wherever you want.

I keep a reference system by piling up files into my ~/org/wiki directory. If I have something worthy to write about any subject, or if I need to study about something, I, just create a new org file in this directory and start typing.

In this sense, I’m going off the patterns of orgmode, which encourages few big files managed by the powerful agenda view. If I were being a org-purist, I would probably be using a big reference file, and each org top-level headline would separate the different contents. However, I can’t really get used to that and I prefer to separate my subjects physically into different filenames, at least for reference-like data. I might be adding one or two very important files from the wiki dir into the agenda if it is something that I really need to get my attention into currently, but that’s it. Besides, org-agenda doesn’t work well if you add tons of files into its lists, it just gets too slow.

So, what I wanted was a quick and easy way to get to my “wiki” pages — “Well why not use Peepopen” — I asked myself. Well, why not?

What I did was to dig into peepopen.el, I then took a glance at the peepopen-goto-file-gui function. Happened this was the function I needed. Following the path of least effort, I just copied the function definition and pasted on my org.el configuration file. Then I modified it to accept an argument, which is the root path for Peepopen:

(defun peepopen-goto-file-gui-manual (arg)
“Uses external GUI app to quickly jump to a file in the project.”
(interactive)
(defun string-join (separator strings)
“Join all STRINGS using SEPARATOR.”
(mapconcat ‘identity strings separator))
(let ((root arg))
(when (null root)
(error
(concat
“Can’t find a suitable project root (”
(string-join ” ” *textmate-project-roots* )
“)”)))
(shell-command-to-string
(format “open -a PeepOpen ‘%s’”
(expand-file-name root)))))

(defun find-wiki () “Find files in the wiki dir” (interactive) (peepopen-goto-file-gui-manual “~/org/wiki”))

(global-set-key (kbd “s-w”) ‘find-wiki)

I then defined a function find-wiki, which happens to be a simple wrapper that calls peepopen-goto-file-gui-manual with the path I want. Finally, I bind super-w to find-wiki.

Then, whenever I type s-w, Peepopen fires up listing my reference files, and allows me quickly pick and open the one I want in emacs. Beatiful and simple!


The point is, you can use Peepopen to pick anything, anywhere. It will use the current opened file as reference by default, but if you want to force a location, you can use this function and pass the path as argument.

It would be cool if Peepopen would allow me to type in a filename that doesn’t exist and visit this path on emacs ;)

You can check the code for this and more on http://github.com/celoserpa/emacs-starter-kit, forked from topfunky’s starter-kit.

Using emacs from the CLI on OSX

Posted in *nix, Uncategorized on May 27th, 2010 by Marcelo de Moraes Serpa – Be the first to comment

If you are compiling emacs from source on OSX (which you should be doing) or even if you are using a pre-packaged version from emacsformacosx, you might be asking yourself why you can’t run emacs from the CLI.

I didn’t have time to dig into the whys of it, but it has to do with the Emacs binari not finding some resources because of the use of relative paths.

Anyway, I’ve came up with a very simple solution. Just create a executable file with the following contents:


/Applications/Emacs.app/Contents/MacOS/Emacs $@

The $@ will delegate command line arguments passed to this script to the Emacs binary.

Make it executable (chmod +x emacs) and put it on any directory that is part of your PATH, and now you should be good to go.

This is quite useful to, for example, run emacs with –debug-init or any other CLI use for that matter.

Agile web-serving with nginx

Posted in Uncategorized on May 5th, 2010 by Marcelo de Moraes Serpa – Be the first to comment

Now, everytime I think of nginx, I’ll think of agile. Period.

This tiny web server is not only tiny in its implementation, it’s also tiny in the sense of being simple.

Just now I had to setup a Rails app running in a subdomain locally, because first, I was mapping my IP to a dyndns domain in order to test a google gadget, and second, the gadgets.io.makeRequest doesn’t support a URL param with a port number (probably a bug in the iGoogle OpenSocial implemention, but anyway, not the point here), what I did was to add the following to the already configured virtualhost on my nginx.conf:


server {
listen 80
server_name localhost

location ~ ^/railssite/(.*)$ {

proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-FORWARDED_PROTO https;
if (-f /index.html){
rewrite (.*) /index.html last;
}
proxy_pass http://localhost:3000/$1;
}

Restarted nginx and… had the rails site there. I have an issue though, since all resources are mapped to a relative URL to the host and the host doesn’t include /railssite, all of them fail to load (css, js, images), which is not a problem in this specific case, since I only need to access an action that returns some XML to the gadget (But if you know a way to run an app in a path and still load resources without modifying the app itself, please, share!).

Now, I’m sure it would be easy to do that with Apache, I know because I’ve done before. However, what amazed me was the “principle of least surprise” — I didn’t really look into the documentation, just used some common-sense based on previous skills and it worked.

I just like nginx a tad more :)

Why you should not interpolate conditions strings directly in Rails

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

The situation is the following: you have a condition string that you built and, let’s say, to implement a simple search feature on some attributes of a model. To keep things simple, let’s say you have something like:


cond = "lower(name) LIKE '%#{s}%'"
Model.find(:all,:conditions => cond)

Do not do that. Don’t interpolate strings directly into the condition like this. Here’s why:
1) You are doing something Rails is supposed to do for you;
2) It will generate a non-sense query if your search string contains any string in that matches the following regexp:

/([\.a-zA-Z_]+).?\./

Or, in other words, any string like “x.z”, where x and z are also strings and z is optional.

I found about this when I was searching for a model that had a name with a dot (a domain), and postgreSQL was throwing an ambiguous query error. After some minutes digging through the ActiveRecord (2.3.5) codebase, I found the root of the problem on The problem lies on lib/active_record/associations.rb#tables_in_string. This method tries to find additional tables to join in by looking for patterns such as users.name, for example (where users is the table name extracted). However, anything that follows this pattern will be also be considered to be the name of a table, and obviously will wreak havoc the query.

At first, I thought it was an ActiveRecord bug. It indeed could be considered a bug, but after some moments meditating about the subject, I figured out *I* was going ahead of Rails and doing stuff it is supposed to do. So, the way to pass conditions is to always wrap it inside an array, like so:


s = "%searchstring%"
cond = ["lower(name) LIKE ?",?]
Model.find(:all,:conditions => cond)

This way, when this string reaches the tables_in_string method, it won’t have the search string interpolated (yet), and it won’t break the query.

Note to self#1: render :action x render :template

Posted in Uncategorized on March 19th, 2010 by Marcelo de Moraes Serpa – Be the first to comment

render :action => ‘details’ will render the details.html.erb template and or action details (the def doesn’t need to exist, only the template).

render :template => ‘details’ fails. It doesn’t run relative to the controller, so you have to run: render :template => ‘/controller_view_path/details’ for it to work.

In the end, the result is the same.