<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>Simple Chatter</title>
  <id>tag:simplechatter.com,2008:mephisto/</id>
  <generator uri="http://mephistoblog.com" version="0.7.3">Mephisto Noh-Varr</generator>
  <link href="http://simplechatter.com/feed/" rel="self" type="application/atom+xml"/>
  <link href="http://simplechatter.com/" rel="alternate" type="text/html"/>
  <updated>2008-11-20T03:11:37Z</updated>
  <entry xml:base="http://simplechatter.com/">
    <author>
      <name>zach</name>
    </author>
    <id>tag:simplechatter.com,2008-11-20:434</id>
    <published>2008-11-20T03:11:00Z</published>
    <updated>2008-11-20T03:11:37Z</updated>
    <link href="http://simplechatter.com/2008/11/20/rubyconf-2008" rel="alternate" type="text/html"/>
    <title>RubyConf 2008</title>
<content type="html">
            &lt;p&gt;I was lucky enough to attend &lt;a href=&quot;http://rubyconf.org/&quot;&gt;RubyConf 2008&lt;/a&gt;. I really enjoyed last year's conference, and I felt this year was better.&lt;/p&gt;

&lt;p&gt;There was lots of great content, and more than handful of time slots where I wanted to attend both. I'm eagerly waiting for &lt;a href=&quot;http://www.confreaks.com/&quot;&gt;Confreaks&lt;/a&gt; to post all the talks so I could watch the ones I missed, as well as re-watch the ones I attended.&lt;/p&gt;

&lt;p&gt;Among all the talks I attended, there were three talks that really enjoyed.&lt;/p&gt;

&lt;h3&gt;Ruby Heavy-Lifting: Lazy load it, Event it, Defer it, and then Optimize it&lt;/h3&gt;

&lt;p&gt;This was given by Ilya Grigorik of &lt;a href=&quot;http://aiderss.com/&quot;&gt;AideRSS&lt;/a&gt;, and was my favorite talk of the weekend. Ilya went over their experiences developing PostRank and main optimization techniques they used with Ruby.&lt;/p&gt;

&lt;p&gt;Primarily:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Message Queues&lt;/li&gt;
&lt;li&gt;EventMachine&lt;/li&gt;
&lt;li&gt;Process Forking&lt;/li&gt;
&lt;li&gt;Custom C Extensions&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Ilya didn't just gloss over each point in a tutorial fashion, but instead described how they used each item and the resulting effects.&lt;/p&gt;

&lt;p&gt;It was very refreshing to hear someone speak of their roadblocks and creative solutions to work around them. Hearing that PostRank is making around 5 million requests per day, and is spread over 100 servers is pretty inspiring.&lt;/p&gt;

&lt;h3&gt;What Every Rubyist Should Know About Threads&lt;/h3&gt;

&lt;p&gt;Jim Weirich from &lt;a href=&quot;http://theedgecase.com&quot;&gt;EdgeCase&lt;/a&gt; gave this talk. Now I've been interested in fairly interested in concurrency this year. Especially as we see hardware trends stalling out on speed and moving towards multiple cores. I really appreciated this talk for two reasons.&lt;/p&gt;

&lt;p&gt;First, it shamed me. Yup, I'll admit it. As snobby as I acted about concurrency, and as much as I touted I understood deadlocking and thread safety code, Jim's talk exposed me to my ignorance, and for that I'm very grateful.&lt;/p&gt;

&lt;p&gt;This talk may not appeal to others the same way it did to me, however for those interested in threading basics as well as virtual machine quicks this was worthwhile.&lt;/p&gt;

&lt;h3&gt;Dramatis: Actors for Ruby&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://smparkes.net/&quot;&gt;Steven Parks&lt;/a&gt; gave a great talk about his Actor-based Concurrency library for both Ruby and Python &lt;a href=&quot;http://dramatis.mischance.net/&quot;&gt;Dramatis&lt;/a&gt;. Now Dramatis is rather young, but has a lot of potential. Not to mention Steven's presentation and conversation afterwards indicates he has been working in this particular field a while.&lt;/p&gt;

&lt;p&gt;Earlier this year I played with Erlang quite a bit, and despite the syntax annoyances, the actor model was very interesting. Steven mentioned explicit vs implicit receiving, which happens to be one of the bold stances this API takes. Erlang is an explicit receive model. Which means the code has to explicitly request the next message.&lt;/p&gt;

&lt;p&gt;An explicit receive example with Ruby:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;while message = receive
  # do something with the message and then re-loop
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;An implicit receive example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def some_method
  # this will get called when a message is sent
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The second example doesn't look too foreign, and that's because it's not. The entire class becomes an API, and the messaging framework calls the appropriate method. When I worked with Erlang, I liked the Actor model, but I didn't like the boilerplate code that was copy-pasted for every Actor.&lt;/p&gt;

&lt;p&gt;I don't expect everyone to prefer this type of messaging, but for me it makes the concurrency model more transparent, and the actors easier to read as well as easier to test.&lt;/p&gt;

&lt;h3&gt;That's a lot of concurrency&lt;/h3&gt;

&lt;p&gt;As you can tell all my favorite talks all had some connection with concurrency and scale. That's because I've been very interested in scaling Ruby applications. Not because I'm some outside developer who is evaluating Ruby as a language and concerned about FUD. It's because I am a Ruby developer, and I've been writing in Ruby for the past couple years, but I have rarely heard talks addressing scaling.&lt;/p&gt;

&lt;p&gt;There were many other great talks at the conference. For those on the fence on whether to attend next year, I definitely recommend it.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://simplechatter.com/">
    <author>
      <name>zach</name>
    </author>
    <id>tag:simplechatter.com,2008-11-15:435</id>
    <published>2008-11-15T06:01:00Z</published>
    <updated>2008-11-15T06:02:03Z</updated>
    <link href="http://simplechatter.com/2008/11/15/using-cucumber-to-test-generators" rel="alternate" type="text/html"/>
    <title>Using Cucumber to test Generators</title>
<content type="html">
            &lt;p&gt;I've been developing in Ruby (and Rails) for the past 2.5 years. Over time, I've molded my own flavor of CRUD controllers and resulting specs. Unfortunately, it's so different than the Rails and RSpec generated code that it takes me as long to alter the code as it does to create it from scratch. However, in laziness, I've pushed off writing my own generators. Until yesterday.&lt;/p&gt;

&lt;h3&gt;The Issue&lt;/h3&gt;

&lt;p&gt;Now I'm not a big fan of generated code. However I do agree that the templates fit the basic CRUD functionality nicely. Despite their usefulness, one of the things that irks me about generators is making changes and not being confident if the code generated is valid. Parse errors, invalid logic, and variable misspellings are easy examples to get tripped up on. So I wanted these generators to be tested. Sounds odd doesn't it?&lt;/p&gt;

&lt;h3&gt;Enter Cucumber&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://github.com/aslakhellesoy/cucumber/wikis&quot;&gt;Cucumber&lt;/a&gt; is a recent project released that replaces the RSpec Stories Framework. You use it very similarly to the older Stories, but since Cucumber is written with &lt;a href=&quot;http://treetop.rubyforge.org/&quot;&gt;Treetop&lt;/a&gt; it provides a lot more niceties. I won't give a tutorial of Cucumber here (perhaps in another post), but I do want to illustrate the flexibility of the testing framework.&lt;/p&gt;

&lt;p&gt;When first picking up Cucumber, the immediate use that comes to mind is Rails Integration testing (which it is very useful for). However it can also be applied to domains outside of Rails and even web development. When writing these generators I mainly wanted to know: &quot;when I use a generator, is all the code valid, and do all the tests pass?&quot;.&lt;/p&gt;

&lt;p&gt;Here's an example of using Cucumber to describe my intentions:&lt;/p&gt;

&lt;p&gt;Feature: Generating Controller Templates
     In order to generate standard CRUD controllers
     A Developer
     Should be able to generate a CRUD controller and the resulting specs&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; Scenario: Generating Rails CRUD
   Given I'm using a Rails 2.2 code base
   When I generate 'my_controller customer'
   Then 'app/controllers/customers_controller.rb' should be created
   And 'spec/controllers/customers_controller_spec.rb' should be created
   And all the tests should pass
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And here's the backing steps to accomplish the feature:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Given(/^I'm using a (.*) code base$/) do |key|
  key = key.downcase.gsub(&quot; &quot;, &quot;&quot;)
  available_codebases = { &quot;rails2.2&quot; =&amp;gt; File.join(codebases_path, &quot;2.2&quot;) }
  available_codebases.keys.should include(key)

  blast_and_create_tmp!
  extract_codebase!(key)
  @current_codebase = File.join(tmp_path, key)
end

When /^I generate '(.*)'$/ do |command|
  `#{@current_codebase}/script/generate #{command}`
end

Then /^'(.*)' should be created$/ do |file_path|
  File.exist?(File.join(@current_codebase, file_path)).should be_true
end

Then /^all the tests should pass$/ do
  output = `cd #{@current_codebase} &amp;amp;&amp;amp; rake spec`
  output.should_not match(/\s0 examples/i)
  output.should match(/0 failures/i)
  $?.exitstatus.should == 0
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;I have all the code in &lt;a href=&quot;http://github.com/zmoazeni/my_styles/tree/master&quot;&gt;github&lt;/a&gt; if you want to see the working example of code.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Pretty straightforward and sexy.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://simplechatter.com/">
    <author>
      <name>zach</name>
    </author>
    <id>tag:simplechatter.com,2008-11-13:433</id>
    <published>2008-11-13T01:30:00Z</published>
    <updated>2008-11-13T01:34:08Z</updated>
    <link href="http://simplechatter.com/2008/11/13/public-stream-of-consciousness" rel="alternate" type="text/html"/>
    <title>Public Stream of Consciousness</title>
<content type="html">
            &lt;p&gt;I've heard a few people on &lt;a href=&quot;http://twitter.com/&quot;&gt;Twitter&lt;/a&gt; not sure about the etiquette on following others. Particularly:&lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;If you are following me, is it rude if I don't follow you?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Twitter makes this difficult for two reasons&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Twitter is slightly more personal than other social networking applications&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Everyone uses Twitter in a different manner&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;I use Twitter as my Public Stream of Consciousness&lt;/h3&gt;

&lt;p&gt;This means about approximately 93.76% of my posts are dismissible. I have a very scientific process for analyzing my tweets that involves starting with &quot;9&quot;, and choosing three digits at random.&lt;/p&gt;

&lt;p&gt;See? That's a perfect example of the type of garbage that I flood the internet with.&lt;/p&gt;

&lt;p&gt;However, unlike other people, I am perfectly ok with others not following me. I won't be insulted if others don't want to subject themselves to my endless stream of rants. If I do get upset, that's my issue to deal with or adjust my behavior to suit.&lt;/p&gt;

&lt;p&gt;So if Twitter is becoming less fun for you because I'm flooding your fire hose, but you feel I'll think less of you if you don't follow me back; don't worry about it at all.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://simplechatter.com/">
    <author>
      <name>zach</name>
    </author>
    <id>tag:simplechatter.com,2008-09-13:427</id>
    <published>2008-09-13T22:23:00Z</published>
    <updated>2008-09-13T22:24:16Z</updated>
    <link href="http://simplechatter.com/2008/9/13/not-many-recent-postings" rel="alternate" type="text/html"/>
    <title>Not many recent postings</title>
<content type="html">
            &lt;p&gt;I've been pretty quiet on this blog for the past few months. Mostly due to being extremely busy, but I'm sure a part of it is the &quot;Blogger Neglect&quot; that most new writers encounter.&lt;/p&gt;

&lt;p&gt;However I did want to mention that we at Elevator Up have been sending out a newsletter. They really aren't company updates, but rather about ideas, business philosophies, and sometimes our experience playing with new applications. Up to now we've only sent them to a subscriber mailing list. Just recently, we've decided to cross post them on a &lt;a href=&quot;http://elevatorup.com/blog/&quot;&gt;company blog&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Some of my favorite recent articles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://elevatorup.com/blog/2008/03/i-matters/&quot;&gt;&quot;I&quot; Matters&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://elevatorup.com/blog/2008/07/an-argument-against-open-source/&quot;&gt;An Argument Against Open Source&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://elevatorup.com/blog/2008/08/the-real-world-is-poorly-designed/&quot;&gt;The Real World is Poorly Designed&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://elevatorup.com/blog/2008/08/quit-being-a-hero/&quot;&gt;Quit Being a Hero&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
          </content>  </entry>
  <entry xml:base="http://simplechatter.com/">
    <author>
      <name>zach</name>
    </author>
    <id>tag:simplechatter.com,2008-04-01:390</id>
    <published>2008-04-01T19:31:00Z</published>
    <updated>2008-03-31T15:20:08Z</updated>
    <link href="http://simplechatter.com/2008/4/1/custom-textmate-commands" rel="alternate" type="text/html"/>
    <title>Custom Textmate Commands</title>
<content type="html">
            &lt;p&gt;&lt;a href=&quot;http://macromates.com/&quot;&gt;Textmate&lt;/a&gt; is a pretty decent editor for OSX. I'm not in love with it, but we use it frequently at &lt;a href=&quot;http://elevatorup.com/&quot;&gt;Elevator Up&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There is a plethora of plugins for Textmate to ease editing in different contexts, but sometimes you want to hack you're own commands.&lt;/p&gt;

&lt;p&gt;For small scripting tasks, I tend to continue to use &lt;a href=&quot;http://www.ruby-lang.org/en/&quot;&gt;ruby&lt;/a&gt;. So I enjoy it when I can continue using it for the commands.&lt;/p&gt;

&lt;p&gt;You can typically use this shell for a ruby command, and your printed output gets replaced within Textmate:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/usr/bin/env ruby
$: &amp;lt;&amp;lt; ENV['TM_SUPPORT_PATH'] + '/lib'
input_from_tm = STDIN.read
puts &quot;hello world!&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Here is an example of code block toggling for Markdown.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/usr/bin/env ruby
$: &amp;lt;&amp;lt; ENV['TM_SUPPORT_PATH'] + '/lib'

s = STDIN.read
ends_with_newline = s != s.chomp
lines = s.split(&quot;\n&quot;)
lines.each_with_index do |s, index|
  s =~ /^(\t)?(.*)/

  if $1
    print &quot;#{$2}&quot;
  else
    print &quot;\t#{$2}&quot;
  end

  print &quot;\n&quot; if index != lines.size - 1
end

print &quot;\n&quot; if ends_with_newline
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And a screenshot to include the Textmate command options:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/2008/3/29/textmate_markdown_command.png&quot;&gt;&lt;img src=&quot;/assets/2008/3/29/textmate_markdown_command_small.png&quot; alt=&quot;A picture of Textmate Bundle Editor&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://simplechatter.com/">
    <author>
      <name>zach</name>
    </author>
    <id>tag:simplechatter.com,2008-03-31:391</id>
    <published>2008-03-31T14:48:00Z</published>
    <updated>2008-03-31T15:19:52Z</updated>
    <link href="http://simplechatter.com/2008/3/31/using-capistrano-1-4-with-2-x" rel="alternate" type="text/html"/>
    <title>Using Capistrano 1.4 with 2.x</title>
<content type="html">
            &lt;p&gt;At &lt;a href=&quot;http://elevatorup.com&quot;&gt;Elevator Up&lt;/a&gt; we typically use &lt;a href=&quot;http://www.capify.org/&quot;&gt;Capistrano&lt;/a&gt; for deploying our applications. Though I do have a bookmark to investigate &lt;a href=&quot;http://rubyhitsquad.com/Vlad_the_Deployer.html&quot;&gt;Vlad&lt;/a&gt; when I get some time.&lt;/p&gt;

&lt;p&gt;We've been a bit slow to upgrade to Capistrano 2.x, and have a lot of existing applications that depend upon Capistrano 1.4 for deployment. &lt;/p&gt;

&lt;p&gt;One tactic we've taken is to write a custom script to explicitly use 1.4 in conjunction with 2.x. A minor hack from the original, and we have:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/usr/bin/env ruby

begin
  require 'rubygems'
  gem 'capistrano', '&amp;lt;= 1.4.1'
rescue LoadError
  # no rubygems to load, so we fail silently
end

require 'capistrano/cli'

Capistrano::CLI.execute!
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I threw this into a script called &lt;code&gt;cap1.4&lt;/code&gt; in &lt;code&gt;/usr/local&lt;/code&gt; and can now do:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;illian:~ zach$ cap1.4 -V
Capistrano v1.4.1
illian:~ zach$ cap -V
Capistrano v2.1.0
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Obviously, a better approach would be to freeze in the capistrano gems per project, and access them via &lt;code&gt;RAILS_ROOT/script/cap&lt;/code&gt;, but that too has been time sensitive. Notice a trend here?&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://simplechatter.com/">
    <author>
      <name>zach</name>
    </author>
    <id>tag:simplechatter.com,2008-03-30:389</id>
    <published>2008-03-30T18:06:00Z</published>
    <updated>2008-03-29T18:06:40Z</updated>
    <link href="http://simplechatter.com/2008/3/30/commonly-overlooked-usage-of-named-routes" rel="alternate" type="text/html"/>
    <title>Commonly overlooked usage of named routes</title>
<content type="html">
            &lt;p&gt;Given a route :&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ActionController::Routing::Routes.draw do |map|
  map.foo &quot;foo/:first/:second&quot;, :controller =&amp;gt; &quot;foo&quot;, :action =&amp;gt; &quot;something&quot;
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Obviously you can pass in &lt;code&gt;:first&lt;/code&gt; and &lt;code&gt;:second&lt;/code&gt; via:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;foo_path(:first =&amp;gt; &quot;the first param&quot;, :second =&amp;gt; &quot;the second param&quot;)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;However, for a more concise call, you can accomplish the same via:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;foo_path(&quot;the first param&quot;, &quot;the second param&quot;)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It's not explicitly documented, but you end up doing the same thing with nested resource paths&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://simplechatter.com/">
    <author>
      <name>zach</name>
    </author>
    <id>tag:simplechatter.com,2008-03-30:393</id>
    <published>2008-03-30T06:05:00Z</published>
    <updated>2008-03-30T06:07:07Z</updated>
    <link href="http://simplechatter.com/2008/3/30/watch-star-wars-via-telnet" rel="alternate" type="text/html"/>
    <title>Watch Star Wars via Telnet</title>
<content type="html">
            &lt;p&gt;I love stuff like this. You can watch &lt;a href=&quot;telnet://towel.blinkenlights.nl&quot;&gt;Star Wars&lt;/a&gt; via telnet.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/2008/3/30/scene_from_star_wars.png&quot;&gt;&lt;img src=&quot;/assets/2008/3/30/scene_from_star_wars.png&quot; alt=&quot;Scene from Star Wars&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I know it's old, but still fun.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://simplechatter.com/">
    <author>
      <name>zach</name>
    </author>
    <id>tag:simplechatter.com,2008-03-30:392</id>
    <published>2008-03-30T03:03:00Z</published>
    <updated>2008-03-30T03:04:20Z</updated>
    <link href="http://simplechatter.com/2008/3/30/one-of-the-best-html-css-theme-songs" rel="alternate" type="text/html"/>
    <title>One of the best HTML / CSS theme songs</title>
<content type="html">
            &lt;p&gt;I don't normally repost from other sites, but this was too good.&lt;/p&gt;

&lt;p&gt;&amp;lt;object height=&quot;355&quot; width=&quot;425&quot;&gt;&amp;lt;param name=&quot;movie&quot; value=&quot;http://www.youtube.com/v/a0qMe7Z3EYg&quot;&gt;&amp;lt;/param&gt;&amp;lt;param name=&quot;wmode&quot; value=&quot;transparent&quot;&gt;&amp;lt;/param&gt;&amp;lt;embed type=&quot;application/x-shockwave-flash&quot; src=&quot;http://www.youtube.com/v/a0qMe7Z3EYg&quot; height=&quot;355&quot; wmode=&quot;transparent&quot; width=&quot;425&quot;&gt;&amp;lt;/embed&gt;&amp;lt;/object&gt;&lt;/p&gt;

&lt;p&gt;Stolen from &lt;a href=&quot;http://whycurious.tumblr.com/post/30224425&quot;&gt;Janson&lt;/a&gt;, with thanks to &lt;a href=&quot;http://implodr.tumblr.com/post/30201652&quot;&gt;Implodr&lt;/a&gt;.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://simplechatter.com/">
    <author>
      <name>zach</name>
    </author>
    <id>tag:simplechatter.com,2008-03-29:388</id>
    <published>2008-03-29T16:57:00Z</published>
    <updated>2008-03-29T16:58:22Z</updated>
    <link href="http://simplechatter.com/2008/3/29/testing-content_for" rel="alternate" type="text/html"/>
    <title>Testing content_for</title>
<content type="html">
            &lt;p&gt;After we started writing &lt;a href=&quot;/2008/2/16/ascribe-a-case-study-on-view-specs&quot;&gt;view specs&lt;/a&gt; we came across views similar to this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;p&amp;gt;Stuff in the main content area&amp;lt;/p&amp;gt;

&amp;lt;% content_for &quot;secondary_content&quot; do %&amp;gt;
  &amp;lt;p&amp;gt;Stuff that will go in an side panel in the view &amp;lt;/p&amp;gt;
&amp;lt;% end %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Obviously when rendering the view inside the spec, only the blurb about &lt;code&gt;main content area&lt;/code&gt; will be in the &lt;code&gt;response.body&lt;/code&gt;. For instance the second spec written will fail:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;describe &quot;/path/to/view&quot; do
  def do_render
    render &quot;/path/to/view&quot;
  end

  it &quot;should have blurb about main content&quot; do
    do_render
    response.should have_text(/main content/i)
  end

  ##
  # This won't pass.
  ##
  it &quot;should have blub about side panel&quot; do
    do_render
    response.should have_text(/side panel/i)
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;However, you can shove something in your &lt;code&gt;spec_helpers.rb&lt;/code&gt; to test items inside the &lt;code&gt;content_for&lt;/code&gt; blocks.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def content_for(section)
  template.send(:instance_variable_get, &quot;@content_for_#{section}&quot;) || &quot;&quot;
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And rewrite your spec like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;describe &quot;/path/to/view&quot; do
  def do_render
    render &quot;/path/to/view&quot;
  end

  it &quot;should have blurb about main content&quot; do
    do_render
    response.should have_text(/main content/i)
  end

  ##
  # This will now pass
  ##
  it &quot;should have blub about side panel&quot; do
    do_render
    content_for(&quot;secondary_content&quot;).should match(/side panel/i)
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;have_text()&lt;/code&gt; matcher won't work, but you can use the &lt;code&gt;have_tag()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you haven't toyed with &lt;a href=&quot;http://api.rubyonrails.com/classes/ActionView/Helpers/CaptureHelper.html#M001069&quot;&gt;content_for&lt;/a&gt;, I suggest looking into it. It will help clean and organize your views and layout(s).&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://simplechatter.com/">
    <author>
      <name>zach</name>
    </author>
    <id>tag:simplechatter.com,2008-03-24:381</id>
    <published>2008-03-24T00:22:00Z</published>
    <updated>2008-04-02T02:59:39Z</updated>
    <link href="http://simplechatter.com/2008/3/24/education-vs-justification" rel="alternate" type="text/html"/>
    <title>Education vs Justification</title>
<content type="html">
            &lt;p&gt;Aaron, Janson and I were at Applebees a month ago discussing an estimate for a client. We started talking about a particular part of the estimate that would require us to take more time than usual. We worked on their project previously, and used a few testing practices that we've stopped since. I wanted the estimate to include the refactoring of the code, but not publicize the fact. Aaron wanted to communicate with the client our exact intent. &lt;/p&gt;

&lt;p&gt;Now keep in mind, I have no qualms about transparency with clients. And I don't go to great lengths to keep clients in the dark, as some of my previous work environments have. My point was that refactoring the code and the tests was a necessary step of development. I didn't want to publicize those specific intentions because I didn't want to come across that they were optional. In other words, I didn't want our client to think that the one of our  &lt;a href=&quot;http://weblog.raganwald.com/2006/08/difference-between-values-and.html&quot;&gt;values&lt;/a&gt;, quality software in this case, was negotiable.&lt;/p&gt;

&lt;p&gt;Now, I know I may be coming across rather harshly. And I may appear as the developer with blinders, who tells everyone &quot;Just trust me, you won't get screwed.&quot; This was exactly how I portrayed my perspective to Aaron and Janson, who more or less disagreed with me for those exact reasons. We debated for a bit longer, while eating our lunch, and I finally had the Eureka moment.&lt;/p&gt;

&lt;p&gt;Our job is a technical one. Not only does it involve &lt;em&gt;many&lt;/em&gt; hours of learning, but it takes the obsessive-like passion to stay current. It is rather rare for clients to possess the technical knowledge, or the experience involved in constructing quality software. However they know their domain intimately, and for a developer to play the &quot;trust me&quot; card in a bit arrogant. As a developer, I often forget that.&lt;/p&gt;

&lt;h2&gt;Help educate them&lt;/h2&gt;

&lt;p&gt;I was feeling as if I had to justify our development practices to the client. It made me upset that I needed to have them approve my reasoning in deciding to refactor older code. Yet as I was getting worked up, it dawned on me, the client hadn't even seen the estimate. I was already prepping counter arguments, as well as previous experiences to &lt;em&gt;sell&lt;/em&gt; my decisions which required more work.&lt;/p&gt;

&lt;p&gt;Listening to Aaron and Janson, I realized the client didn't need justification. They weren't bringing my decisions into the light in order to criticize my knowledge as a developer. They merely wanted to match the impact of my decisions with what they knew. They sought to understand the reasoning behind my decisions.&lt;/p&gt;

&lt;p&gt;As I've thought more about that conversation I've come to an important resolution in my career. I should never justify myself to a client, however I should &lt;em&gt;always&lt;/em&gt; try to educate our clients. I should spend the effort to tell them the impact of taking alternate routes. I should find better ways to articulate myself and speak their language rather than swamp them with intimidating geek-speak.&lt;/p&gt;

&lt;h2&gt;Justification isn't evil&lt;/h2&gt;

&lt;p&gt;While my client's aren't developers, I am, and so is the rest of my team. This brought up the second big question and resolution &quot;How do I know my decision is right?&quot;, which led me to: Always justify my decisions to myself, and to my team. I believe a key ingredient in improving ourselves is constant introspection. If I make a decision, and I can't debate myself or a team member on the end result, then it's probably heavily influenced by preference, or even fear.&lt;/p&gt;

&lt;p&gt;I should always justify to myself why we test, and the rigorousness of our tests. I should always justify why we should use agile approaches to planning. I should evaluate the reasoning behind using &lt;a href=&quot;http://git.or.cz/&quot;&gt;git&lt;/a&gt; over &lt;a href=&quot;http://subversion.tigris.org/&quot;&gt;svn&lt;/a&gt; and whether programming in &lt;a href=&quot;http://www.ruby-lang.org/en/&quot;&gt;ruby&lt;/a&gt; makes more sense than developing in &lt;a href=&quot;http://www.sun.com/java/&quot;&gt;java&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I've found that it's very easy to surround yourself with a community who evangelizes tools or practices, while not sincerely asking the honest questions. I've also seen a similar pitfalls in ignoring new technologies and trends, because a lack of self-justification.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://simplechatter.com/">
    <author>
      <name>zach</name>
    </author>
    <id>tag:simplechatter.com,2008-02-23:380</id>
    <published>2008-02-23T08:29:00Z</published>
    <updated>2008-02-23T08:29:54Z</updated>
    <link href="http://simplechatter.com/2008/2/23/alive-and-treetop" rel="alternate" type="text/html"/>
    <title>ALIVE and Treetop</title>
<content type="html">
            &lt;h2&gt;A sweet project&lt;/h2&gt;


	&lt;p&gt;I&#8217;m proud to say really fun mini-project went live today. &lt;a href=&quot;http://alive.okwu.edu/&quot;&gt;&lt;span class=&quot;caps&quot;&gt;OKWU&lt;/span&gt; Alive&lt;/a&gt; for &lt;a href=&quot;http://www.okwu.edu/&quot;&gt;Oklahoma Wesleyan University&lt;/a&gt;, a very forward thinking college. They wanted a site that is mainly updated by &lt;a href=&quot;http://twitter.com/&quot;&gt;twitter&lt;/a&gt; messages.&lt;/p&gt;


	&lt;p&gt;We used a combination of &lt;a href=&quot;http://radiantcms.org/&quot;&gt;Radiant&lt;/a&gt;, &lt;a href=&quot;http://twitter4r.rubyforge.org/&quot;&gt;Twitter4R&lt;/a&gt;, and an upcoming library &lt;a href=&quot;http://treetop.rubyforge.org/&quot;&gt;Treetop&lt;/a&gt; that I heard about a RubyConf 2007. Ever since attending &lt;a href=&quot;http://rubyconf2007.confreaks.com/d1t1p5_treetop.html&quot;&gt;Nathan Sobo&#8217;s presentation&lt;/a&gt; I&#8217;ve wanted to put it to use, but kept putting it off.&lt;/p&gt;


	&lt;h2&gt;The &#8220;challenge&#8221;&lt;/h2&gt;


	&lt;p&gt;To give some context to the site, &lt;span class=&quot;caps&quot;&gt;OKWU&lt;/span&gt; wanted to parse direct twitter messages and add them to the site. The thing that made this interesting, is that they wanted to be able to tag each message. Most messages take on the form of:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
  tag : message
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Now I could obviously use regular expressions to parse out both the tag and the message, but what fun is that?&lt;/p&gt;


	&lt;h2&gt;Treetop to the rescue&lt;/h2&gt;


	&lt;p&gt;Treetop is structured to take a grammar file, that can be brought into ruby code. Here is the grammar we used to define the twitter message:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
  grammar Twitter
    rule status
      tag delimiter message
    end

    rule tag
      [a-zA-Z_0-9-]+
    end

    rule message
      .*
    end

    rule delimiter
      space* ':' space*
    end

    rule space
      ' '
    end
  end
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;If you haven&#8217;t worked with grammar specifications before, don&#8217;t feel overwhelmed. What this essentially says is &#8220;a twitter status (another definition of a message from twitter) is composed of a tag followed by a delimiter followed by a message.&#8221; With each part, you can find a more specific definition. For example, a tag can only take the form of alphanumerical characters, underscores and dashes.&lt;/p&gt;


	&lt;h2&gt;&#8220;Ok, that&#8217;s neat, but how is it useful?&#8221;&lt;/h2&gt;


	&lt;p&gt;The coolness comes in with the consumption of the grammar. Here&#8217;s the code that uses Treetop:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
  require &quot;treetop&quot; 
  Treetop.load &quot;twitter&quot; 

  parser = TwitterParser.new
  parsed_results = parser.parse(&quot;awesomified : you won't believe it's that easy&quot;)

  tag = parsed_results.get_tag
  message = parsed_results.get_message
  puts &quot;message: #{message} classified under: #{tag}&quot; 
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;As you can see, Treetop loaded in the grammar and immediately gave me a &lt;tt&gt;TwitterParser&lt;/tt&gt;. From there I parsed an example twitter message, and with the results I retrieved the tag and message.&lt;/p&gt;


	&lt;h2&gt;&#8220;Wait, how did you get the tag and message?&#8221;&lt;/h2&gt;


	&lt;p&gt;Well, I didn&#8217;t exactly show the entire grammar. Here&#8217;s the final one:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
  grammar Twitter
    rule status
      tag delimiter message {
        def get_tag
          tag.text_value
        end

        def get_message
          message.text_value
        end
      }
    end

    rule tag
      [a-zA-Z_0-9-]+
    end

    rule message
      .*
    end

    rule delimiter
      space* ':' space*
    end

    rule space
      ' '
    end
  end
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Almost identical to the above except&#8230;it has friggin&#8217; ruby code attached! That means when given a status, I can call &lt;tt&gt;#get_tag&lt;/tt&gt; and &lt;tt&gt;#get_message&lt;/tt&gt; to return the items. Pretty doggone easy.&lt;/p&gt;


	&lt;h2&gt;&#8220;Impressive, but how is this better than just using regular expressions&#8221;&lt;/h2&gt;


	&lt;p&gt;So I will not deny the same thing could be accomplished with a single regex, but this looks sexy. And it has additional benefits. Lets say in the future they want to:&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;Allow multiple tags&lt;/li&gt;
		&lt;li&gt;Allow spaces, and commas to be valid tag delimiters&lt;/li&gt;
		&lt;li&gt;Allow the tags to be optional&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;Here&#8217;s a grammar modified with those exact requests:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
  grammar Twitter
    rule status
      (tags delimiter)? text {
        def get_tags
          if self.class.method_defined? &quot;tags&quot; 
            tags.get_tags
          else
            []
          end
        end

        def get_message
          text.text_value
        end
      }
    end

    rule tags
      tag optional_tags:(optional_tag*) {
        def get_tags
          [tag.get_tag] + optional_tags.elements.map { |e| e.get_tag }
        end
      }
    end

    rule optional_tag
      tag_delimiter tag {
        def get_tag
          tag.text_value
        end
      }
    end

    rule tag
      [a-zA-Z_0-9-]+ {
        def get_tag
          text_value
        end
      }
    end

    rule text
      .*
    end

    rule delimiter
      space* ':' space*
    end

    rule space
      ' '
    end

    rule tag_delimiter
      space* ',' space* / space+
    end
  end
&lt;/code&gt;&lt;/pre&gt;

Some examples and their output:
&lt;pre&gt;&lt;code&gt;
  results = parser.parse(&quot;tag1 : the message&quot;)
  results.get_tags      # =&amp;gt; [&quot;tag1&quot;]
  results.get_message   # =&amp;gt; &quot;the message&quot; 

  results = parser.parse(&quot;tag1 tag2, tag3 : the message&quot;)
  results.get_tags      # =&amp;gt; [&quot;tag1&quot;, &quot;tag2&quot;, &quot;tag3&quot;]
  results.get_message   # =&amp;gt; &quot;the message&quot; 

  results = parser.parse(&quot;the message&quot;)
  results.get_tags      # =&amp;gt; []
  results.get_message   # =&amp;gt; &quot;the message&quot; 

  results = parser.parse(&quot;: the message&quot;)
  results.get_tags      # =&amp;gt; []
  results.get_message   # =&amp;gt; &quot;: the message&quot; 

  # Yea, well not bad for only 15 min, lets chalk the last one up to user-error.
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;I want to thank &lt;a href=&quot;http://functionalform.blogspot.com/&quot;&gt;Nathan Sobo&lt;/a&gt; for putting together such a useful and intuitive library. For more information about Treetop, you can check out the &lt;a href=&quot;http://treetop.rubyforge.org/&quot;&gt;site&lt;/a&gt; as well as the &lt;a href=&quot;http://groups.google.com/group/treetop-dev&quot;&gt;mailing list&lt;/a&gt;.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://simplechatter.com/">
    <author>
      <name>zach</name>
    </author>
    <id>tag:simplechatter.com,2008-02-19:379</id>
    <published>2008-02-19T04:18:00Z</published>
    <updated>2008-02-19T04:19:20Z</updated>
    <link href="http://simplechatter.com/2008/2/19/combined-pgp-keys-into-one" rel="alternate" type="text/html"/>
    <title>Combined PGP Keys Into One</title>
<content type="html">
            &lt;p&gt;After finding out today that pgp keys can have multiple email addresses, I revoked all but public key and combined all emails into &lt;a href=&quot;/assets/2008/2/19/zach.pub&quot;&gt;one key&lt;/a&gt;.&lt;/p&gt;


	&lt;h2&gt;How&lt;/h2&gt;


	&lt;p&gt;Edit a key in the terminal:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
&amp;gt; gpg --edit-key KEY_ID
Command&amp;gt; adduid
&lt;/code&gt;&lt;/pre&gt;

Add name and email address. Then remember to set a primary uid:
&lt;pre&gt;&lt;code&gt;
Command&amp;gt; uid NUMBER_IN_PARENTHS_TO_SELECT
Command&amp;gt; primary
Command&amp;gt; save
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Should be all good. Remember to revoke the old keys and re-export the public key.&lt;/p&gt;


	&lt;h2&gt;Additional Tip&lt;/h2&gt;


	&lt;p&gt;You can share your public key with others easier by uploading it to a key server like &lt;a href=&quot;http://pgp.mit.edu/&quot;&gt;&lt;span class=&quot;caps&quot;&gt;MIT&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://simplechatter.com/">
    <author>
      <name>zach</name>
    </author>
    <id>tag:simplechatter.com,2008-02-16:373</id>
    <published>2008-02-16T23:37:00Z</published>
    <updated>2008-02-16T23:38:06Z</updated>
    <link href="http://simplechatter.com/2008/2/16/git-stash-is-sweet" rel="alternate" type="text/html"/>
    <title>Git Stash is Sweet</title>
<content type="html">
            &lt;p&gt;&lt;a href=&quot;http://www.simplechatter.com/2008/2/8/using-git&quot;&gt;Earlier&lt;/a&gt; I mentioned a method of storing away changes in a patch, rebasing and then applying the patch so you don&#8217;t have to commit beforehand.&lt;/p&gt;


	&lt;p&gt;Yesterday Janson found git-stash, and it is sweet.&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;type &#8220;git stash&#8221; &lt;/li&gt;
		&lt;li&gt;do your changes&lt;/li&gt;
		&lt;li&gt;type &#8220;git stash apply&#8221; &lt;/li&gt;
		&lt;li&gt;profit!&lt;/li&gt;
	&lt;/ol&gt;
          </content>  </entry>
  <entry xml:base="http://simplechatter.com/">
    <author>
      <name>zach</name>
    </author>
    <id>tag:simplechatter.com,2008-02-16:372</id>
    <published>2008-02-16T23:00:00Z</published>
    <updated>2008-03-07T00:26:12Z</updated>
    <link href="http://simplechatter.com/2008/2/16/ascribe-a-case-study-on-view-specs" rel="alternate" type="text/html"/>
    <title>Ascribe - A Case Study on View Specs</title>
<content type="html">
            &lt;h2&gt;Background&lt;/h2&gt;


	&lt;p&gt;When we started development on &lt;a href=&quot;http://www.ascribehq.com/&quot;&gt;Ascribe&lt;/a&gt; about 3 months ago, I had a hankering to try out RSpec. We used a lot of similar concept on a test/unit side such as small readable tests and mock testing, but we hadn&#8217;t given view specs a try. To be fair, I had been pretty critical of view specs prior to the project; not really seeing the benefits. This is a write up on our experiences. There will be a lot of verbiage like &#8220;felt&#8221;, &#8220;thought&#8221; and not a lot hard numbers.&lt;/p&gt;


	&lt;h2&gt;Expectations&lt;/h2&gt;


	&lt;p&gt;As I said, I had been pretty critical about using view specs. I had seen them used together in functional tests, and I strongly disliked the &#8220;cluttered&#8221; look of controller assertions intermixed with the view assertions. My main concerns using them were:&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;A significant amount of time to initially create the spec&lt;/li&gt;
		&lt;li&gt;The additional rigidity of changing views&lt;/li&gt;
		&lt;li&gt;Brittleness in comparison to other tests we value (unit, controller, and integration)&lt;/li&gt;
		&lt;li&gt;The added technical hurdle for allowing designers or html developers to contribute&lt;/li&gt;
	&lt;/ol&gt;


	&lt;h2&gt;In practice&lt;/h2&gt;


	&lt;h3&gt;&#8220;A significant amount of time to write the specs&#8221;&lt;/h3&gt;


	&lt;p&gt;We were actually quite surprised to find that writing the view specs were the easiest among all of our tests. Essentially, all that is asserted is the presence of text. When in comparison to testing object interaction, or algorithms, this felt brain-dead simple. Further reinforcement is that there shouldn&#8217;t be a lot of code in the views. If you noticed your view or spec getting complicated, it generally helped to pull out code (helpers, additional model behaviors). Of course we found testing pitfalls, and became more judicious in what we would assert.&lt;/p&gt;


Examples of what we would test:
	&lt;ol&gt;
	&lt;li&gt;Presence of html controls like text fields, text areas, select, etc.&lt;/li&gt;
		&lt;li&gt;Presence of labels&lt;/li&gt;
		&lt;li&gt;Important attributes for html controls (names, ids, and sometimes classes&lt;sup&gt;&lt;a href=&quot;#fn1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;)&lt;/li&gt;
		&lt;li&gt;Form actions, and alternate http methods (delete, put)&lt;/li&gt;
		&lt;li&gt;Partial renders&lt;/li&gt;
		&lt;li&gt;Custom helper calls&lt;/li&gt;
		&lt;li&gt;Iterators and If/Else controls&lt;/li&gt;
		&lt;li&gt;Anchors&lt;/li&gt;
	&lt;/ol&gt;


Examples of what we would not test:
	&lt;ol&gt;
	&lt;li&gt;&lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt; Containment. We would only assert this if it was required for &lt;span class=&quot;caps&quot;&gt;RJS&lt;/span&gt;&lt;/li&gt;
		&lt;li&gt;Exact text. More often than not, we wold assert a portion of the text with case insensitive regular expressions&lt;/li&gt;
		&lt;li&gt;Common helpers like &lt;tt&gt;h()&lt;/tt&gt;&lt;/li&gt;
		&lt;li&gt;&lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt; classes not used for client javascript or rjs. We found this hindered css from an html developers point of view, and did not provide a lot of value.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;h3&gt;&#8220;Additional rigidity for changing views&#8221;&lt;/h3&gt;


	&lt;p&gt;To discuss this, it may help to lend insight to our team. There was &lt;a href=&quot;http://whycurious.tumblr.com/&quot;&gt;Janson&lt;/a&gt; and me, both developers who wrote and maintained ruby, all specs, and html / css. We also had &lt;a href=&quot;http://theparagon.org/&quot;&gt;Aaron&lt;/a&gt; who is not a developer, but is really knowledgeable about html / css. One of our concerns was every time Aaron would want to make a change to the design, either we would have to be there with him, or we would have to teach him how to run, fix, and create view specs.&lt;/p&gt;


	&lt;p&gt;We ended up opting for a completely different approach. We told him to ignore the specs in all regards save one. If he was going to add rhtml calls (typically anything with &lt;tt&gt;&amp;lt;%= %&amp;gt;&lt;/tt&gt;) we asked if he would open up the spec for the view and create a pending statement.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
    it &quot;should have a link to the dashboard&quot; 
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;That way we would be able to return later and flesh out the stubbed specs. Although this isn&#8217;t exactly promoting &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt;, it allowed him to keep running, as well as placing a bookmark in the code for us. We never felt as if we were getting bombarded with pending statements, and quickly writing them and moving on didn&#8217;t feel time consuming.&lt;/p&gt;


	&lt;h3&gt;&#8220;Brittleness in comparison to other tests we value (unit, controller, and integration)&#8221;&lt;/h3&gt;


	&lt;p&gt;With Aaron working on the html, we were even more concerned with the brittleness of our tests than if the entire team were ruby developers. At Elevator Up it is very common that we have non-developers contributing to the html / css, so obviously I was apprehensive of being overwhelmed by constantly breaking specs. No developer likes to consistently fix other developers broken tests. And it wasn&#8217;t exactly like we could yell at Aaron for not doing his job. This is one expectation that played out in the course of development, but in a different light.&lt;/p&gt;


	&lt;p&gt;When Aaron would make a commit it was pretty common for him to break tests. In fact I believe his record was 38, and without any numbers, my guess was he averaged around 5 &#8211; 10 breaks per commit. What we didn&#8217;t anticipate was that fixing 30+ tests took no more than 15 minutes. That was a huge shocker to me. A non-developer would rip out the code we were asserting, make additional calls that weren&#8217;t stubbed, and it only took us 15 minutes to fix them all.&lt;/p&gt;


	&lt;p&gt;We found that the biggest breakages were due to calling mocked helpers in a valid, but unexpected manner. Since all other spec relied on a valid render, they would break as well. In some cases, fixing one line, would fix 10-20 assertions. There were also a few instances where the specs actually broke for the right reasons. For example, a &lt;tt&gt;link_to&lt;/tt&gt; was modified and the href wasn&#8217;t pointing to the right location.&lt;/p&gt;


	&lt;h3&gt;&#8220;The added technical hurdle for allowing designers or html developers to contribute&#8221;&lt;/h3&gt;


	&lt;p&gt;With only having Aaron add pending statements on code additions, he didn&#8217;t feel uncomfortable, or feel like he had to learn how to program just to make visual changes. This felt like a huge win for us. While it would be nice to have all html / css developers understand and maintain ruby, this isn&#8217;t realistic at Elevator Up.&lt;/p&gt;


	&lt;h2&gt;Other Surprises&lt;/h2&gt;


	&lt;p&gt;Up to now I&#8217;ve only talked how our expectations matched up to our experiences, however I haven&#8217;t mentioned any benefits of view testing. Talking about the benefits of testing views is just as difficult as talking about the benefits of unit testing, or using mocks. You can&#8217;t convince another developer with anecdotes alone. Using them in practice normally speaks volumes in a much more articulate way.&lt;/p&gt;


	&lt;p&gt;That being said, as we worked on Ascribe, I kept a list of successes that I felt the view specs were the prime contributer to&lt;sup&gt;&lt;a href=&quot;#fn2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;Checking label &#8220;for&#8221; mispellings&lt;/li&gt;
		&lt;li&gt;Ensuring all input fields are present&lt;/li&gt;
		&lt;li&gt;Asserting non &#8220;sunny day&#8221; code paths (if/then)&lt;/li&gt;
		&lt;li&gt;Using fields that could potentially be nil&lt;/li&gt;
		&lt;li&gt;Ensuring links are pointing to the correct places&lt;/li&gt;
		&lt;li&gt;Ensuring forms are posting to the right places&lt;/li&gt;
		&lt;li&gt;Ensuring forms are posting with the right method&lt;/li&gt;
		&lt;li&gt;Incorrect usage of named routes&lt;/li&gt;
		&lt;li&gt;Renaming / Refactoring Routes&lt;/li&gt;
		&lt;li&gt;Ensuring render partials have correct locals&lt;/li&gt;
		&lt;li&gt;Better confidence in refactoring views into partials / or helpers    &lt;/li&gt;
		&lt;li&gt;Ensuring correct usage of helpers &lt;tt&gt;link_to&lt;/tt&gt;, &lt;tt&gt;link_to_remote&lt;/tt&gt;, &lt;tt&gt;form_for&lt;/tt&gt;&lt;/li&gt;
		&lt;li&gt;Better testing-as-documentation for &lt;span class=&quot;caps&quot;&gt;RJS&lt;/span&gt;&lt;/li&gt;
		&lt;li&gt;Using pending tasks as view centric TODOs&lt;/li&gt;
	&lt;/ol&gt;


	&lt;h2&gt;Summary&lt;/h2&gt;


	&lt;p&gt;A realization that sparked while we were at the end of the project, was that compared to unit, controller, and integration tests, view tests are cheap. Their creation and maintenance are very low, and for their small amount of effort, noticeable benefits arise. It feels comparable to investing pennies and earning $200. We were very pleased we went out on a limb and gave them a shot. Elevator Up has made it a point to add view specs to our development routine.&lt;/p&gt;


	&lt;p&gt;&lt;sup&gt;1&lt;/sup&gt; We found this useful since we use dashed ids instead of underscored. Also we found on more than one occasion, we were using rails tags incorrectly. One of the biggest culprits was setting ids and classes on select tags.&lt;/p&gt;


	&lt;p&gt;&lt;sup&gt;2&lt;/sup&gt; I&#8217;m not saying that these are unique to view specs, and can&#8217;t be achieved with other testing techniques.&lt;/p&gt;
          </content>  </entry>
</feed>
