thinksimple.pl

Naming things

July 23, 2011

Am I obsessing over naming things? Is it really that much of a difference if I say loc instead of location? For a local variable? In a ~10LOC method? Yes, it occupies a part of my brain, and it’s slightly annoying once you get used to having everything pretty, but is it worth nitpicking and deny someone a few saved keystrokes?

As I’m typing this, I have already realised what the answer is. Yes. Yes it is worth it. Because the writer only writes it once, but the reader reads it multiple times. Maybe hundreds of times. And every single time this small part of the reader’s brain is occupied with decoding the variables, what the cryptic name stands for and what the variable contains. Overtime, it adds to productivity loss. Greater than saving those keystrokes. Long term, it’s not worth it. Short term… If you’re coding for short term only, then you’re either lucky, or mistaken. Probably the latter.

Capybara, Selenium and SSL

March 14, 2011

I’ve been looking for a way to get Selenium set up with Capybara. We have a fairly standard dev config, nginx with passenger running the site, Rspec for unit tests, Capybara for integration tests. One bit that was missing was Javascript tests, so I decided to give it a go with Selenium.

First of all, Selenium did not like me trying to log in with SSL. To be honest, it wasn’t really Selenium as much as Webrick which Capybara starts for Selenium. I kept getting ssl_error_rx_record_too_long. Solution: let nginx deal with the SSL bit of the communication and send through a simple HTTP request to Webrick. Bonus points for setting a header which tells Rails that initially it was an SSL request.

Next up: database issues. Our tests rely on two things: seed data and transactions. The idea is to get the seed data in the db and then run each test within a transaction so that it’s quicker to reset. Unfortunately Selenium opens a new database connection, and a new transaction to go with it. Solution: database_cleaner. Strategy – truncation, as mentioned on numerous websites… Oh wait, leave the seed data in! You can pass an :except option to DatabaseCleaner, except that you then can’t create models which are seeded as they will just stay in the db. Oh well, Truncation and loading seeds before each test it is. After painful waiting for the test suite to finish (28min instead of the usual 10) it was clear that this is not a sensible solution. So I tried switching strategies in between tests, from transaction for most tests to truncation for Selenium tests. Worked like a charm.

Lastly, a minor thing compared to everything else – did you know that fixtures are cached? Well they are. So if you try loading them again while running the tests it won’t work. Need a special fix for that.

All in all, it was a painful experience. Below is the code I used, some of it will be deprecated once new Capybara is out, and I might have omitted something accidentally. If so, let me know in the comments. Other than that, enjoy!

nginx.conf:

http {
  # your usual server config goes here

  upstream testing {
    server 127.0.0.1:9000; # Capybara will start Webrick on this port
  }

  server {
    listen 80;
    server_name myapp.testing;
    location / {
      proxy_pass http://testing;
      proxy_set_header Host $host;
    }
  }

  server {
    listen 443;
    server_name myapp.testing;
    location / {
      proxy_pass http://testing;
      proxy_set_header Host $host; # forward the host so that urls use this
      proxy_set_header X_FORWARDED_PROTO 'https'; # this is how Rails finds out if it's an https request
    }
    ssl on;
    ssl_certificate /etc/ssl/certs/myssl.crt;
    ssl_certificate_key /etc/ssl/private/myssl.key;
  }
}

Gemfile

  gem "capybara"
  gem "database_cleaner"

spec_helper.rb

  config.use_transactional_fixtures = false

  config.before(:suite) do
    DatabaseCleaner.strategy = :transaction
  end

  config.before(:each) do
    DatabaseCleaner.start
  end

  config.after(:each) do
    DatabaseCleaner.clean
  end

  Capybara.server_port = 9000
  Capybara.app_host = 'http://myapp.testing'

We also have a special integration_helper.rb included only in integration tests. The DatabaseCleaner mess is to make sure switching from transaction to truncation and vice versa works without any issues.
integration_helper.rb

  config.before(:each) do
    if example.metadata[:js]
      DatabaseCleaner.clean
      DatabaseCleaner.strategy = :truncation
      Capybara.current_driver = :selenium # this can be removed with new Capybara release
    end
  end

  config.after(:each) do
    if example.metadata[:js]
      DatabaseCleaner.clean
      load "#{Rails.root}/db/seeds.rb"
      DatabaseCleaner.strategy = :transaction
      DatabaseCleaner.start

      Capybara.use_default_driver # this can be removed with new Capybara release
    end
  end

You only need this bit if you’re using YAML fixtures/seed data and somewhere in your code you say something like Fixtures.create_fixtures(seed_dir, table).
db/seeds.rb

Fixtures.reset_cache

Rspec integration test

  it "works with Selenium", :js => true do
    visit root_path
  end
Comments: 2

Authlogic gotchas

February 22, 2011

There are two. First one: Authlogic assumes that you want to log your users in with http basic authentication. If you have a staging server protected by basic auth you will get random SQL queries with “WHERE email LIKE LOWER(your_http_auth_login)”.

Solution:

class UserSession < Authlogic::Session::Base
  allow_http_basic_auth false
  # ...
end

Second one: Authlogic provides its own email validation. If you’re using rails3_acts_as_paranoid the deleted_at field will not be taken into account. Resulting in validation errors for emails that exist, but the account has been deleted.

Solution:

class User < ActiveRecord::Base
  acts_as_authentic do |c|
    c.validate_email_field = false
  end

  validates_uniqueness_of :email, :scope => :deleted_at
end

Fixed.

Vim commands for developers, Part 2

September 18, 2010

The longer I work with Vim, the more great stuff I discover. Here’s another chunk.

Did you know there are so many ways to go to insert mode?

  • i, a – insert before/after current character
  • I, A – insert at the beginning/end of the line
  • O, o – insert a line before/after current line
  • gi – go to Insert mode where you last stopped editing

Behold – Folding!

  • zf – fold selected block
  • :{range}fo[ld]
  • zo – open fold
  • :{range}foldo[pen]

Ever changed your .vimrc and had to close Vim to load it? Well no need for that any more!

:source $MYVIMRC

And our plugin of the day is… NERDTree! NERDTree is a project file browser, very useful!

Commands:

:NERDTree [start-dir|bookmark]  # opens NERDTree
:NERDTreeToggle [start-dir|bookmark]
:NERDTreeClose
:NERDTreeFind  # find current file in tree
o, go # open / open and leave cursor in NERDTree
t, T  # open in new tab / open in tab and keep focus on current tab
i, gi # split window
s, gs # vsplit window

Also – you do know about Pathogen, right?

If you missed out on Vim commands for developers, Part 1, here it is.

Comments: 1

Git Extras

September 15, 2010

There’s a fantastic tool on GithubGit Extras. Its readme tells you everything you need to know, but just to give you a taste, here are my favourites:

$ git release 0.1.0

Create a commit and tags it.

$ git delete-branch branch_name

Delete local AND remote branch

$ git undo [number]

Undo one or more commits. Internally does git reset --HARD

$ git commits-since [date]

Lists commits since a specified date, or last week

$ git summary

See who created the most commits in your project

Enjoy!