thinksimple.pl

Multiline step arguments with Cucumber

September 25, 2009

I’ve been doing lots of Cucumber testing lately and I must say, it’s a great tool. I have stumbled upon one problem though, which are multiline step arguments. The Cucumber wiki covers most cases, but what happens when the HTML list or table you want to check is not a proper table, but just some divs, mixed with tables and/or uls?

There is a pretty easy way to do this. Cucumber History.txt file says that table_at method is deprecated, and we should use element_at instead. Also, element_at takes a CSS selector as an argument. So we can just choose any container element from the HTML, pass it to Nokogiri, and get an array of text.

Example: if we had this HTML code

<div id="search_results">
  <% @people.each do |person| %>
    <div class="result">
      <div class="image"><img src="/img/default.png" /></div>
      <div class="information">
        <ul>
          <li class="name"><%=h person.name %></li>
          <li class="email"><%=link_to h(person.email), "mailto:#{person.email}" %></li>
          <li class=""></li>
        </ul>
      </div>
    </div>
  <% end %>
</div>

and we wanted to check if the search results are what we expect, we could write a Cucumber step that looks like this:

Then /^I should see the following search results$/ do |searches|
  search_results = element_at('div#search_results')
  node = Nokogiri::HTML("<html>#{search_results.element}</html>").css('.information ul li.name')
  actual_table = node.map { |name| name.inner_html.strip }
  searches.diff!(actual_table)
end

and call it like this:

Then I should see the following search results
  | John  |
  | Mike  |
  | Susan |

Done!

Inflector

May 31, 2008

Camelize, pluralize, humanize…
Inflector

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.

RubyMine 1.1

May 30, 2009

There seems to be a lot of buzz lately about the new release (1.1) of RubyMine. I’ve decided to try it out on my Kubuntu 9.04.

The first impression was great, they released versions for Windows, Linux and Mac. Then I found out the editor was written in Java, which made it a whole lot easier. Unfortunately, I also found out that RubyMine eats up massive amounts of memory, a comparable amount to Aptana (about 350MB) and is significantly slower. Actually it’s so slow I can slowly count up to three between clicking and RubyMine’s reaction. Painfully slow, no font anti-aliasing, information about no UTF support (although it did read utf files, so I don’t know what’s with that) — this is definitely not a useful tool for me now. Does anyone else have these issues, maybe it’s just me?

I’ve been using Aptana for a while now, I have now discovered a way to change Netbeans’ look and feel, so I’ll try that. I should never switch editors, it’s always a disappointment, and I get used too quickly. Should’ve stuck with vim when it still worked for me.

How to make an entry preview

April 11, 2009

UPDATE: there is now a plugin doing exactly what is described here. Read all about with_preview plugin!

If you have a blog you sometimes need to see what your entry will look like before you post it. Although the thing might seem complicated, this is quite easy to achieve.

First, let’s have a form for our blog post:

<% form_for :entry, :html => {:id => :entry_form} do |f| %>
  <%= f.text_field :title %>
  <%= f.text_field :tag_names %>
  <%= f.text_area :content %>
  <%= f.submit 'Create' %>
<% end %>

We will split that form into divs:

<% form_for :entry, :html => {:id => :entry_form} do |f| %>
<div id="entry_edit">
  <%= f.text_field :title %>
  <%= f.text_field :tag_names %>
  <%= f.text_area :content %>
</div>
<div id="entry_preview">
</div>
  <%= f.submit 'Create' %>
<% end %>

Now let’s add a button which will send an AJAX request to server with our form data:

<%= button_to_remote :Preview, {
  :update => :entry_preview, 
  :url => preview_entries_path, 
  :method => :post, 
  :with => "$('entry_form').serialize()", 
  :success => "$('entry_edit').hide(); 
    $('entry_preview').show(); 
    $('preview_button').hide(); 
    $('edit_button').show();"
  }, {:id => :preview_button} %>

The controller action is pretty simple. I want to show the date when the post was created, so I just set up the data in the controller.

def preview
  @entry = Entry.new(params[:entry])
  @entry.created_at = Time.now
  render :layout => false
end

And here is the view for the action:

<div class="preview">
<div class="preview_title">Entry preview</div>
  <h1><%=h @entry.title %></h1>
  <h2><%=h @entry.tag_names %></h2>
  <h3><%=h @entry.created_at.to_s(:short) %></h3>
  <p><%=h @entry.content %></p>
</div>

Okay, by now we can see the preview of the post, but we would also like to be able to get back to editing. This is much simpler. First, we need a button called ‘Edit’, right next to the ‘Create’ and ‘Preview’ buttons. Only this time we don’t need AJAX, plain Javascript will do:

<%= button_to_function :Edit, :id => :edit_button do |page|
  page[:entry_preview].hide
  page[:entry_edit].show
  page[:edit_button].hide
  page[:preview_button].show
end %>

Let’s hide the ‘Edit’ button so that it will appear only after the ‘Preview’ button was pressed:

<script type="text/javascript">
  $('edit_button').hide();
</script>

And finally we need to set up a proper route in config/routes.rb file:

map.resources :entries, :collection => {:preview => :put}

That’s all, you can now admire your previews!