<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>validates_presence_of :purpose : </title>
    <link>http://lenaherrmann.net</link>
    <language>en_US</language>
    <ttl>40</ttl>
    <description>Lena Herrmann</description>
    <item>
      <title>Refactoring asynchronous code</title>
      <description>&lt;p&gt;How to refactor a long chunk of asynchronous code is one thing I learned during my Javascript &amp; CouchDB project. It&amp;#8217;s not a difficult thing, but I thought it was before I figured out how to do it, so I guess it might be interesting for Javascript newbies.&lt;/p&gt;


&lt;h3&gt;Asynchronous code&lt;/h3&gt;


&lt;p&gt;In the first couple of weeks I struggled with this new style of coding before I got the hang of it. If you&amp;#8217;re fairly new to Javascript, you&amp;#8217;re probably used to just assign a variable in one line and use it in the next line. In the asynchronous world you query for a value and do stuff with it &lt;i&gt;in the callback function&lt;/i&gt; of the query.&lt;/p&gt;


&lt;p&gt;To illustrate - &amp;#8220;normal&amp;#8221; code looks like this:

&lt;div class="CodeRay"&gt;&lt;pre&gt;&lt;span class="CodeRay"&gt;&lt;span class="kw"&gt;var&lt;/span&gt; result = db.query(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;select * from T&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;);
&lt;span class="c"&gt;// use result&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;


&lt;p&gt;Althoug writing web applications just screams for doing it like this instead:
  
&lt;div class="CodeRay"&gt;&lt;pre&gt;&lt;span class="CodeRay"&gt;
db.query(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;select..&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="kw"&gt;function&lt;/span&gt; (result) {
&lt;span class="c"&gt;// use result&lt;/span&gt;
});&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;


&lt;p style="font-size:0.8em"&gt;(Examples stolen from &lt;a href="http://nodejs.org/"&gt;Ryan Dahl&amp;#8217;s Presentation about Node.js&lt;/a&gt;.)&lt;/p&gt;


&lt;h3&gt;The Problem&lt;/h3&gt;


&lt;p&gt;&lt;img style="float:left;margin-right:10px;" width="250"  src="http://lenaherrmann.net/files/async-bad.png" alt="Bad asynchronous code" /&gt;&lt;/p&gt;


&lt;p&gt;I have a method that checks if I have to display a notification message. For this it makes a lot of requests to the database, the received data has to be compared with other data, there&amp;#8217;s lots of if/else clauses to consider all kinds of conditions and edge cases. It started simple, but then more and more conditions came in, unless I had the &lt;a href="http://geekandpoke.typepad.com/.a/6a00d8341d3df553ef0128766398f7970c-pi"&gt;much feared diagonal closing bracket line&lt;/a&gt; on my screen. &lt;/p&gt;


&lt;p&gt;You don&amp;#8217;t need to know the details, just look at the picture and you&amp;#8217;ll get the impression.&lt;/p&gt;


&lt;h3 style="clear:left"&gt;Refactoring&lt;/h3&gt;


&lt;p&gt;By way of illustration I made up a much shorter example:

&lt;div class="CodeRay"&gt;&lt;pre&gt;&lt;span class="CodeRay"&gt;
checkForConflicts: &lt;span class="kw"&gt;function&lt;/span&gt;(){
  &lt;span class="c"&gt;//set arguments&lt;/span&gt;
  openDoc(id, &lt;span class="kw"&gt;function&lt;/span&gt;(result){
    &lt;span class="c"&gt;// do stuff with arguments&lt;/span&gt;
    &lt;span class="kw"&gt;if&lt;/span&gt;(result.bar == whatever){
      &lt;span class="c"&gt;// do more stuff with result&lt;/span&gt;
      openAnotherDoc(id2, &lt;span class="kw"&gt;function&lt;/span&gt;(result2){
        &lt;span class="kw"&gt;if&lt;/span&gt;(result2.baz == &lt;span class="kw"&gt;true&lt;/span&gt;){
          &lt;span class="c"&gt;// show notification message with result2&lt;/span&gt;
        }
      });
    }
  });
}&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;


&lt;p&gt;It is time to refactor after you are sure this actually is the way to go and the code basically works (&amp;#8220;make it work, then make it pretty&amp;#8221;). First you group the code into methods: You split the lines by what they do, and then you name each section. I think around 8 LOC is a good length for a method. &lt;/p&gt;


&lt;p&gt;If this was synchronous code, you could just call these methods after each other. But this doesn&amp;#8217;t work here, because &lt;i&gt;result&lt;/i&gt; and &lt;i&gt;result2&lt;/i&gt; are not available outside the function that retrieves them. &lt;/p&gt;


&lt;p&gt;My first approach was to call the functions from within each other. This works - but to see what &lt;i&gt;checkForConflicts&lt;/i&gt; does at its very heart, you have to scroll down through all the methods - not much gained:

&lt;div class="CodeRay"&gt;&lt;pre&gt;&lt;span class="CodeRay"&gt;checkForConflicts: &lt;span class="kw"&gt;function&lt;/span&gt;(){
  &lt;span class="c"&gt;//set arguments&lt;/span&gt;
  doSomething(&lt;span class="lv"&gt;arguments&lt;/span&gt;);
}

doSomething(&lt;span class="lv"&gt;arguments&lt;/span&gt;){
  openDoc(id, &lt;span class="kw"&gt;function&lt;/span&gt;(result){
    &lt;span class="c"&gt;// do stuff with arguments&lt;/span&gt;
    &lt;span class="kw"&gt;if&lt;/span&gt;(result.bar = whatever){
      doSomethingElse(result);
    }
  });
}

doSomethingElse(result){
  &lt;span class="c"&gt;// do more stuff with result&lt;/span&gt;
  openAnotherDoc(id2, &lt;span class="kw"&gt;function&lt;/span&gt;(result2){
    &lt;span class="kw"&gt;if&lt;/span&gt;(result2.baz == &lt;span class="kw"&gt;true&lt;/span&gt;){
      showMessage(result2);
    }
  });
}

showMessage = &lt;span class="kw"&gt;function&lt;/span&gt;(result2){
  &lt;span class="c"&gt;// show notification message with result2&lt;/span&gt;
}&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;


&lt;p&gt;The way to do it is to use &lt;i&gt;callbacks&lt;/i&gt;. Each method gets an anonymous function as (additional) argument: in the method declaration this function has the name &lt;i&gt;callback&lt;/i&gt;. This callback is called if all the conditions within the method are met. The callback gets its arguments from within the method that calls it. You have to specify these arguments again in &lt;i&gt;checkForConflicts&lt;/i&gt; to have a valid function definition.

&lt;div class="CodeRay"&gt;&lt;pre&gt;&lt;span class="CodeRay"&gt;checkForConflicts: &lt;span class="kw"&gt;function&lt;/span&gt;(){
  &lt;span class="c"&gt;//set arguments&lt;/span&gt;
  doSomething(&lt;span class="lv"&gt;arguments&lt;/span&gt;, &lt;span class="kw"&gt;function&lt;/span&gt;(result){
    doSomethingElse(result, &lt;span class="kw"&gt;function&lt;/span&gt;(result2){
      showMessage(result2); 
    });
  });
}

doSomething(&lt;span class="lv"&gt;arguments&lt;/span&gt;, callback){
  openDoc(id, &lt;span class="kw"&gt;function&lt;/span&gt;(result){
    &lt;span class="c"&gt;// do stuff with arguments&lt;/span&gt;
    &lt;span class="kw"&gt;if&lt;/span&gt;(result.bar = whatever){
      callback(result);
    }
  });
}

doSomethingElse(result, callback){
  &lt;span class="c"&gt;// do more stuff with result&lt;/span&gt;
  openAnotherDoc(id2, &lt;span class="kw"&gt;function&lt;/span&gt;(result2){
    &lt;span class="kw"&gt;if&lt;/span&gt;(result2.baz == &lt;span class="kw"&gt;true&lt;/span&gt;){
      callback(result2);
    }
  });
}

showMessage = &lt;span class="kw"&gt;function&lt;/span&gt;(result2){
  &lt;span class="c"&gt;// show notification message with result2&lt;/span&gt;
}&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;


&lt;p&gt;When you look at &lt;i&gt;checkForConflicts&lt;/i&gt;, you now immediately see what it does, without being bothered by the details. As a side effect, deciding which code needs access to which arguments helps you to understand your code better. In my case I was able to optimize the use of passed variables a lot.&lt;/p&gt;


&lt;p&gt;&lt;img style="float:left;margin-right:10px;" width="250"  src="http://lenaherrmann.net/files/async-good.png" alt="Refactored asynchronous code" /&gt;&lt;/p&gt;


&lt;p&gt;You might argue that the code is much longer now. First, longer is not worse if it is more readable. Second, this is only an example - if there was code instead of &lt;i&gt;//do stuff&lt;/i&gt; the few extra lines wouldn&amp;#8217;t carry weight.&lt;/p&gt;


&lt;p&gt;Finally here is a screenshot of my refactored code. All the methods don&amp;#8217;t fit on one screen, but you can see what &lt;i&gt;checkForConflicts&lt;/i&gt; does very quickly.&lt;/p&gt;


&lt;p style="clear:left"/&gt;
&lt;hr /&gt;&lt;p&gt;&lt;small&gt;Original article written by Lena and published on &lt;a href='http://lenaherrmann.net'&gt;validates_presence_of :purpose&lt;/a&gt; | &lt;a href='http://lenaherrmann.net/2010/02/15/refactoring-asynchronous-code'&gt;direct link to this article&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;</description>
      <pubDate>Mon, 15 Feb 2010 16:17:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:8e9117d9-b37a-467b-99ac-b6f035ed1a9e</guid>
      <comments>http://lenaherrmann.net/2010/02/15/refactoring-asynchronous-code#comments</comments>
      <category>javascript</category>
      <category>refactoring</category>
      <category>ajax</category>
      <trackback:ping>http://lenaherrmann.net/trackbacks?article_id=11</trackback:ping>
      <link>http://lenaherrmann.net/2010/02/15/refactoring-asynchronous-code</link>
    </item>
    <item>
      <title>Testing PUT requests with Culerity</title>
      <description>&lt;p&gt;&lt;img style="float:left;margin-right:10px;" width="250"  src="/files/Image/Bildschirmfoto%202010-02-02%20um%2012.38.41.png" alt="All green!" /&gt;&lt;/p&gt;


&lt;p&gt;One major pain at testing with culerity so far was a HtmlUnit bug that causes a ScriptException with PUT AJAX requests in jQuery. When you tried to test an update you got a &amp;#8220;java.lang.IllegalArgumentException: The content cannot be null&amp;#8221;. Fortunately, this bug is fixed now. With latest HtmlUnit build culerity should run fine, and I tell you how.&lt;/p&gt;


&lt;p&gt;I assume you have culerity installed already. If not, follow &lt;a href="http://github.com/langalex/culerity"&gt;these instructions&lt;/a&gt; for testing Rails apps &lt;a href="http://upstre.am/2009/10/25/testing-couchapps-with-cucumber-and-culerity/"&gt;or these&lt;/a&gt; for testing Couchapps.&lt;/p&gt;


&lt;p&gt;1. Make sure you have up-to-date versions of celerity and culerity:&lt;br/&gt;
$ jruby -S gem install celerity #(gives you celerity-0.7.8)&lt;br/&gt;
$ gem install culerity &amp;#8211;source http://gemcutter.org #(gives you culerity-0.2.7)&lt;/p&gt;


&lt;p&gt;2. Get the latest HtmlUnit nightly build:&lt;br/&gt;
$ wget http://build.canoo.com/htmlunit/artifacts/htmlunit-2.7-SNAPSHOT-with-dependencies.zip&lt;br/&gt;
$ unzip htmlunit-2.7-SNAPSHOT-with-dependencies.zip &lt;br/&gt;
$ cd htmlunit-2.7-SNAPSHOT-with-dependencies/lib&lt;br/&gt;
These are the jar files you need to copy into your celerity gem.&lt;/p&gt;


&lt;p&gt;3. Find your celerity gem and copy the files:&lt;br/&gt;
$ jruby -S gem which celerity&lt;br/&gt;
$ cp * PATH_OF_JRUBY_INSTALLATION/lib/ruby/gems/1.8/gems/celerity-0.7.7/lib/celerity/htmlunit&lt;/p&gt;


&lt;p&gt;4. The new HtmlUnit needs JQuery 1.4, so you &lt;a href="http://docs.jquery.com/Downloading_jQuery#Current_Release"&gt;need to upgrade&lt;/a&gt; if you haven&amp;#8217;t done already. There&amp;#8217;s a &lt;a href="http://github.com/jquery/jquery-compat-1.3"&gt;backwards compatibility plugin for 1.3&lt;/a&gt; if this gives you trouble.
&lt;/p&gt;


&lt;p&gt;Have fun!&lt;/p&gt;
&lt;hr /&gt;&lt;p&gt;&lt;small&gt;Original article written by Lena and published on &lt;a href='http://lenaherrmann.net'&gt;validates_presence_of :purpose&lt;/a&gt; | &lt;a href='http://lenaherrmann.net/2010/01/31/testing-put-requests-with-culerity'&gt;direct link to this article&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;</description>
      <pubDate>Sun, 31 Jan 2010 21:22:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:40dcb9ab-9661-4888-bdb1-d9ac36fb7fc2</guid>
      <comments>http://lenaherrmann.net/2010/01/31/testing-put-requests-with-culerity#comments</comments>
      <category>tdd</category>
      <category>culerity</category>
      <category>ajax</category>
      <category>htmlunit</category>
      <category>bug</category>
      <category>celerity</category>
      <trackback:ping>http://lenaherrmann.net/trackbacks?article_id=10</trackback:ping>
      <link>http://lenaherrmann.net/2010/01/31/testing-put-requests-with-culerity</link>
    </item>
    <item>
      <title>JSpec - JavaScript Unit testing how it should be</title>
      <description>&lt;p&gt;Selecting a unit test framework for a JavaScript-only application - not a task with an obvious answer! Coming from the Rails world, where most people work with either TestUnit or RSpec, I was a bit lost when I started researching. &lt;a href="http://en.wikipedia.org/wiki/List_of_unit_testing_frameworks#JavaScript"&gt;This table on wikipedia&lt;/a&gt; was quite helpful for a first overview. But: JsUnit, JSTest, jsUnitTest, jsUnity - these are actually different frameworks, and there&amp;#8217;s even many more &amp;#8230;&lt;/p&gt;


&lt;p&gt;I narrowed the selection down to those being currently developed, or are in use in &amp;#8220;big&amp;#8221; projects. &lt;a href="http://www.jsunit.net/"&gt;JsUnit&lt;/a&gt; seems to be one of the major players, but I found almost no documentation, and the code base hasn&amp;#8217;t changed a lot in the last years. That&amp;#8217;s not a negative thing in itself, but having an active community around is a good thing. &lt;a href="http://docs.jquery.com/QUnit"&gt;QUnit&lt;/a&gt; is used for testing JQuery, it looked like you could work with it as well, but its syntax and setup didn&amp;#8217;t make me go &amp;#8220;wow&amp;#8221; exactly. Same goes for &lt;a href="http://code.google.com/p/jqunit/"&gt;JQUnit&lt;/a&gt;, about which I had read good stuff in several blog posts. It&amp;#8217;s also what Sammy.js is tested with.&lt;/p&gt;


&lt;p&gt;I like RSpec, so when I had my first look at &lt;a href="http://github.com/nkallen/screw-unit"&gt;ScrewUnit&lt;/a&gt;, I was delighted to find there&amp;#8217;s BDD syntax for JavaScript too. ScrewUnit is also a part of &lt;a href="http://github.com/relevance/blue-ridge"&gt;Blue Ridge&lt;/a&gt;, which is sadly still only available as a Rails plugin. So, ScrewUnit looked nice.&lt;/p&gt;


&lt;p&gt;And THEN &amp;#8230; I found &lt;a href="http://visionmedia.github.com/jspec/"&gt;JSpec&lt;/a&gt;. I was thrilled! It&amp;#8217;s a JavaScript framework, but it doesn&amp;#8217;t look like JavaScript at all: no curly brackets, no semicolons, just plain domain language. It just looks like RSpec. Here is a random snippet from my test suite, just have a look:

&lt;div class="CodeRay"&gt;&lt;pre&gt;&lt;span class="CodeRay"&gt;describe &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;NoteCollection&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;
  before_each
    note3 = &lt;span class="kw"&gt;new&lt;/span&gt; Note({&lt;span class="ke"&gt;id&lt;/span&gt;: &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;8c8&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="ke"&gt;text&lt;/span&gt;: &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;three&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;});
    note1 = &lt;span class="kw"&gt;new&lt;/span&gt; Note({&lt;span class="ke"&gt;id&lt;/span&gt;: &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;ae9&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="ke"&gt;text&lt;/span&gt;: &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;one&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="ke"&gt;next_id&lt;/span&gt;: &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;107&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;});
    note2 = &lt;span class="kw"&gt;new&lt;/span&gt; Note({&lt;span class="ke"&gt;id&lt;/span&gt;: &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;107&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="ke"&gt;text&lt;/span&gt;: &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;two&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="ke"&gt;next_id&lt;/span&gt;: &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;8c8&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;});
      
    notes = &lt;span class="kw"&gt;new&lt;/span&gt; NoteCollection([note3, note1, note2]);
  end
  
  describe &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;firstNote&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;
    it &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;should return a note&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;
      notes.firstNote().should.be_an_instance_of Note
    end
    
    it &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;should return the first note&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;
      notes.firstNote().id.should.eql note1.id
    end

    it &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;should throw an error if there is more than one note that could be the first note&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;
      note4 = &lt;span class="kw"&gt;new&lt;/span&gt; Note({&lt;span class="ke"&gt;id&lt;/span&gt;: &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;fff&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="ke"&gt;rev&lt;/span&gt;: &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;2-420&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;});
      notes.notes.push(note4);
      -{notes.firstNote()}.should.throw_error &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;More than one first note found&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;
    end  
  end
end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;


&lt;p&gt;And that are just 3 out of over 45 core matchers. There are also matchers for JQuery, see the next example, where I put the DOM I wanted to test in a fixture called outline.html. In Rails I don&amp;#8217;t use fixtures, but if you want to test an application where all the markup is generated out of many different sources, it makes sense to test little pieces of the DOM in isolation. In ScrewUnit you have only one file for your all your mocked DOM.

&lt;div class="CodeRay"&gt;&lt;pre&gt;&lt;span class="CodeRay"&gt;describe &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;NoteElement&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;
  before_each
    outline = elements(fixture(&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;outline&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;))
    notes = outline.find(&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;li&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;)
  
    parent_note = &lt;span class="kw"&gt;new&lt;/span&gt; NoteElement(&lt;span class="pd"&gt;$&lt;/span&gt;(notes.get(&lt;span class="i"&gt;0&lt;/span&gt;)))
    child_note = &lt;span class="kw"&gt;new&lt;/span&gt; NoteElement(&lt;span class="pd"&gt;$&lt;/span&gt;(notes.get(&lt;span class="i"&gt;1&lt;/span&gt;)))
  end
  
  describe &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;focusNextTextarea&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;
    it &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;should focus the first child note if there is one&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;
      parent_note.focusNextTextarea();
      parent_note.noteLi().should.not.have_attr(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;data-focus&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)
      child_note.noteLi().attr(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;data-focus&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;).should.eql &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;
    end
  end

  describe &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;insertUpdateNotePointers&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;    
    it &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;should call setNextPointerToNewlyInsertedNote&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;
      inserted_note = {&lt;span class="ke"&gt;id&lt;/span&gt;:&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;4&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="ke"&gt;text&lt;/span&gt;: &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;inserted!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;};
      parent_note.should.receive(&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;setNextPointerToNewlyInsertedNote&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;).with_args(inserted_note)
      parent_note.insertUpdateNotePointers(inserted_note);
    end
  end
end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;


&lt;p&gt;Note, if you don&amp;#8217;t like the RSpec-like Syntax, you can also skip the JSpec DSL and just use plain Javascript syntax.&lt;/p&gt;


&lt;p&gt;More JSpec goodness: You can either run the tests in the browser, or in the terminal, so you can include it in your CI. In the terminal you can specify the browsers it should be tested with: The browsers will be opened in the background, but you won&amp;#8217;t see your stuff being run like in Selenium. You can mock timers to test asynchronous calls. You can stub methods, mock AJAX requests, specify shared behaviours, hook into JSpec to specify your own matchers or do whatever else, and &amp;#8230; just &lt;a href="http://github.com/visionmedia/jspec/"&gt;see for yourself&lt;/a&gt;.&lt;/p&gt;


&lt;p&gt;Installation is easy too: just add JSpec.js and JSpec.css to your application. If you need them, add the files for jquery, timers or xhr support too. In spec/index.html you include your application files and specify which tests you want to run. Then open it in the browser, wait a few milliseconds, and see the result. If you want to run JSpec tests in the terminal, just install the JSpec Ruby gem. For this you also have to install &lt;a href="http://www.mozilla.org/rhino/"&gt;Rhino&lt;/a&gt; (a Java-based JavaScript interpreter) - when you are on OS X, &lt;a href="http://peter.michaux.ca/articles/installing-rhino-on-os-x"&gt;this should get you started&lt;/a&gt;.&lt;/p&gt;


&lt;p&gt;What I don&amp;#8217;t like about JSpec &amp;#8230; the BlueRidge browser output is much more clear and pretty. I thought really hard about more things but that&amp;#8217;s it.&lt;/p&gt;


&lt;p&gt;Make sure to read the documentation on &lt;a href="http://jspec.info/"&gt;the JSpec website&lt;/a&gt; as well as the &lt;a href="http://github.com/visionmedia/jspec/"&gt;github Readme&lt;/a&gt;. Both ressources look similar, but at the time of writing there were different things on the two pages.&lt;/p&gt;
&lt;hr /&gt;&lt;p&gt;&lt;small&gt;Original article written by Lena and published on &lt;a href='http://lenaherrmann.net'&gt;validates_presence_of :purpose&lt;/a&gt; | &lt;a href='http://lenaherrmann.net/2010/01/04/jspec-javascript-unit-testing-how-it-should-be'&gt;direct link to this article&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;</description>
      <pubDate>Mon, 04 Jan 2010 12:07:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:c6222c7f-ab27-4e0b-a744-09dde4f35970</guid>
      <comments>http://lenaherrmann.net/2010/01/04/jspec-javascript-unit-testing-how-it-should-be#comments</comments>
      <category>javascript</category>
      <category>tdd</category>
      <category>jspec</category>
      <category>jquery</category>
      <trackback:ping>http://lenaherrmann.net/trackbacks?article_id=9</trackback:ping>
      <link>http://lenaherrmann.net/2010/01/04/jspec-javascript-unit-testing-how-it-should-be</link>
    </item>
    <item>
      <title>Bulk deletion of documents in CouchDB</title>
      <description>&lt;p&gt;For the couchapp I'm writing, I recently wanted to do a bulk delete operation with CouchDB, but found very little about it on the web. I don't know if my approach is the best way to go, but well, it works - if you know a better way, I'm happy to learn about it.&lt;/p&gt;

&lt;p&gt;In the file &lt;a href="http://github.com/lenalena/couchdb/blob/trunk/share/www/script/jquery.couch.js"&gt;jquery.couch.js&lt;/a&gt; that comes with CouchDB there are a couple of convenience methods to help you dealing with the database, documents and views. There is a method for deletion too (removeDoc), but it only can handle one document at a time. In the style of bulkSave, I added a bulkRemove method:

&lt;div class="CodeRay"&gt;&lt;pre&gt;&lt;notextile&gt;&lt;span class="CodeRay"&gt;bulkRemove: &lt;span class="kw"&gt;function&lt;/span&gt;(docs, options){
  docs.docs = &lt;span class="pd"&gt;$&lt;/span&gt;.each(docs.docs, &lt;span class="kw"&gt;function&lt;/span&gt;(i, doc){doc._deleted = &lt;span class="kw"&gt;true&lt;/span&gt;});
  &lt;span class="pd"&gt;$&lt;/span&gt;.extend(options, {&lt;span class="ke"&gt;successStatus&lt;/span&gt;: &lt;span class="i"&gt;201&lt;/span&gt;});
  ajax({
      &lt;span class="ke"&gt;type&lt;/span&gt;: &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;,
      &lt;span class="ke"&gt;contentType&lt;/span&gt;: &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;,
      &lt;span class="ke"&gt;dataType&lt;/span&gt;: &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;json&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, 
      &lt;span class="ke"&gt;data&lt;/span&gt;: toJSON(docs),
      &lt;span class="ke"&gt;url&lt;/span&gt;: &lt;span class="lv"&gt;this&lt;/span&gt;.uri + &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;_bulk_docs&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; + encodeOptions(options)
    },
    options,
    &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;The documents could not be deleted&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
  );
},&lt;/span&gt;&lt;/notextile&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;In here I add the attribute "_deleted = true" to every document I want to delete, and then I do a bulk update with the documents. That's it.&lt;/p&gt;

&lt;p&gt;This is one possible use case: In the delete action of my controller I first fetch an array with the post and its comments from the couch (how to do this see below), and then I call the bulkRemove action on that array.

&lt;div class="CodeRay"&gt;&lt;pre&gt;&lt;notextile&gt;&lt;span class="CodeRay"&gt;couchapp.design.view(&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;post_with_comments&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;, {
  &lt;span class="ke"&gt;startkey&lt;/span&gt;: [params[&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;]],
  &lt;span class="ke"&gt;endkey&lt;/span&gt;: [params[&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;], {}],
  &lt;span class="ke"&gt;success&lt;/span&gt;: &lt;span class="kw"&gt;function&lt;/span&gt;(json) {
    &lt;span class="kw"&gt;if&lt;/span&gt; (json.rows.length &amp;gt; &lt;span class="i"&gt;0&lt;/span&gt;) { 
      &lt;span class="kw"&gt;var&lt;/span&gt; post_and_comments = json.rows.map(&lt;span class="kw"&gt;function&lt;/span&gt;(row) {&lt;span class="kw"&gt;return&lt;/span&gt; row.value}); 
      couchapp.db.bulkRemove({&lt;span class="ke"&gt;docs&lt;/span&gt;: post_and_comments}, {
        &lt;span class="ke"&gt;success&lt;/span&gt;: &lt;span class="kw"&gt;function&lt;/span&gt;() {
          flash = {&lt;span class="ke"&gt;message&lt;/span&gt;: &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;Post deleted.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="ke"&gt;type&lt;/span&gt;: &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;notice&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;}
          redirect(&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;#/outlines&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;, flash);
        },
        &lt;span class="ke"&gt;error&lt;/span&gt;: &lt;span class="kw"&gt;function&lt;/span&gt;(response_code, msg) {
          flash = {&lt;span class="ke"&gt;message&lt;/span&gt;: &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;Error deleting post: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; + msg, &lt;span class="ke"&gt;type&lt;/span&gt;: &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;};
        }
      });
    }      
  }
});&lt;/span&gt;&lt;/notextile&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;Note that the "flash" object I'm using is my own Sammy.js implementation of a Rails-like flash to show a message after a redirect. Maybe I'll share that in another blog post.&lt;/p&gt;

&lt;p&gt;As a bonus, this is the view I'm using to retrieve a post and its comments in one request. I'm following the pattern Christopher Lenz is recommending in his article on &lt;a href="http://www.cmlenz.net/archives/2007/10/couchdb-joins"&gt;CouchDB Joins&lt;/a&gt;.

&lt;div class="CodeRay"&gt;&lt;pre&gt;&lt;notextile&gt;&lt;span class="CodeRay"&gt;&lt;span class="kw"&gt;function&lt;/span&gt;(doc) {
  &lt;span class="kw"&gt;if&lt;/span&gt; (doc.type == &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Post&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;) {
    emit([doc._id, &lt;span class="i"&gt;0&lt;/span&gt;], doc);
  } &lt;span class="kw"&gt;else&lt;/span&gt; &lt;span class="kw"&gt;if&lt;/span&gt; (doc.type == &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Comment&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;) {
    emit([doc.post_id, &lt;span class="i"&gt;1&lt;/span&gt;, Date.parse(doc.created_at)], doc);
  }
}&lt;/span&gt;&lt;/notextile&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;When you call this view with

&lt;div class="CodeRay"&gt;&lt;pre&gt;&lt;notextile&gt;&lt;span class="CodeRay"&gt;startkey: [params[&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;]],
&lt;span class="ke"&gt;endkey&lt;/span&gt;: [params[&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;], {}]&lt;/span&gt;&lt;/notextile&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;you get an array with the post as the first element, and then all the comments that have the post's ID as post_id.&lt;/p&gt;

&lt;p&gt;This can of course also be used for things other than deleting: to show all the comments for a post, I get the array's first element and extract the title and content. Then I remove it from the array with

&lt;div class="CodeRay"&gt;&lt;pre&gt;&lt;notextile&gt;&lt;span class="CodeRay"&gt;json.rows.splice(&lt;span class="i"&gt;0&lt;/span&gt;,&lt;span class="i"&gt;1&lt;/span&gt;);        &lt;/span&gt;&lt;/notextile&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;You now have an array with only the post's comments and you can display them somehow.&lt;/p&gt;

&lt;hr /&gt;&lt;p&gt;&lt;small&gt;Original article written by Lena and published on &lt;a href='http://lenaherrmann.net'&gt;validates_presence_of :purpose&lt;/a&gt; | &lt;a href='http://lenaherrmann.net/2009/12/22/bulk-deletion-of-documents-in-couchdb'&gt;direct link to this article&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;</description>
      <pubDate>Tue, 22 Dec 2009 17:37:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:150befc7-1e89-47d5-ae0c-47d803336e73</guid>
      <comments>http://lenaherrmann.net/2009/12/22/bulk-deletion-of-documents-in-couchdb#comments</comments>
      <category>couchdb</category>
      <category>javascript</category>
      <category>json</category>
      <trackback:ping>http://lenaherrmann.net/trackbacks?article_id=8</trackback:ping>
      <link>http://lenaherrmann.net/2009/12/22/bulk-deletion-of-documents-in-couchdb</link>
    </item>
    <item>
      <title>Testing key events with Culerity</title>
      <description>&lt;p&gt;The application I'm writing depends heavily on key events. When you press enter in a specific text field, some other field opens, when you press tab, the text fields moves, etc. Of course I need to cover this in my cucumber integration tests. The &lt;a href="http://celerity.rubyforge.org/yard/Celerity/Element.html#fire_event-instance_method"&gt;Celerity API&lt;/a&gt; is a bit thin for this purpose: You can fire a, let's say, keydown event - but it doesn't pass through the specific key code.&lt;/p&gt;


&lt;p&gt;Actually it's easy when you know how. You can execute any javascript directly on the Culerity RemoteBrowserProxy object. In order to fire a specific key event, you have to create a KeyboardEvent, initialize it with whatever you want, and dispatch it on the element.&lt;/p&gt;


&lt;p&gt;Read up the details, especially the meaning of initKeyEvent's parameters &lt;a href="http://help.dottoro.com/ljbwbehw.php"&gt;in this Javascript API&lt;/a&gt;.&lt;/p&gt;


&lt;p&gt;I ended up with this cucumber step:&lt;/p&gt;


&lt;div class="CodeRay"&gt;&lt;pre&gt;&lt;span class="CodeRay"&gt;&lt;span class="co"&gt;When&lt;/span&gt; &lt;span class="rx"&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;span class="k"&gt;^I hit &amp;quot;([^&lt;/span&gt;&lt;span class="ch"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;]*)&amp;quot; in a text_field with id &amp;quot;([^&lt;/span&gt;&lt;span class="ch"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;]*)&amp;quot;$&lt;/span&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt; |key, id|
  key_code = &lt;span class="r"&gt;case&lt;/span&gt; key
    &lt;span class="r"&gt;when&lt;/span&gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;enter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;
      &lt;span class="i"&gt;13&lt;/span&gt;
    &lt;span class="r"&gt;when&lt;/span&gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;up&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;
      &lt;span class="i"&gt;38&lt;/span&gt;
    &lt;span class="r"&gt;when&lt;/span&gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;down&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;
      &lt;span class="i"&gt;40&lt;/span&gt;
    &lt;span class="r"&gt;else&lt;/span&gt;
      &lt;span class="i"&gt;0&lt;/span&gt;
    &lt;span class="r"&gt;end&lt;/span&gt;
  &lt;span class="gv"&gt;$browser&lt;/span&gt;.execute_script(&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;event = document.createEvent(&amp;quot;KeyboardEvent&amp;quot;);&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;)
  &lt;span class="gv"&gt;$browser&lt;/span&gt;.execute_script(&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;event.initKeyEvent(&amp;quot;keydown&amp;quot;, true, false, document.window, false, false, false, false, &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; + key_code.to_s + &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;, 0)&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;)
  &lt;span class="gv"&gt;$browser&lt;/span&gt;.execute_script(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;document.getElementById('&lt;/span&gt;&lt;span class="il"&gt;&lt;span class="idl"&gt;#{&lt;/span&gt;id&lt;span class="idl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt;').dispatchEvent(event)&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)
  &lt;span class="co"&gt;When&lt;/span&gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;I wait for the AJAX call to finish&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="r"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Note that this is meant to work for Firefox only. For IE you can do a similar thing with createEventObject, &lt;a href="http://help.dottoro.com/ljhlvomw.php"&gt;see here how&lt;/a&gt;.&lt;/p&gt;
&lt;hr /&gt;&lt;p&gt;&lt;small&gt;Original article written by Lena and published on &lt;a href='http://lenaherrmann.net'&gt;validates_presence_of :purpose&lt;/a&gt; | &lt;a href='http://lenaherrmann.net/2009/11/22/testing-key-events-with-culerity'&gt;direct link to this article&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;</description>
      <pubDate>Sun, 22 Nov 2009 20:43:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:0bb79202-702f-46ab-a4c1-4a9aecaf11b8</guid>
      <comments>http://lenaherrmann.net/2009/11/22/testing-key-events-with-culerity#comments</comments>
      <category>cucumber</category>
      <category>culerity</category>
      <category>celerity</category>
      <category>tdd</category>
      <category>javascript</category>
      <trackback:ping>http://lenaherrmann.net/trackbacks?article_id=7</trackback:ping>
      <link>http://lenaherrmann.net/2009/11/22/testing-key-events-with-culerity</link>
    </item>
    <item>
      <title>Couchapp / Culerity glitches, part 1</title>
      <description>&lt;p&gt;Do you know what's behind these buzzwords: &lt;a href="http://couchdb.apache.org"&gt;CouchDB&lt;/a&gt; / &lt;a href="http://github.com/couchapp/couchapp"&gt;Couchapp&lt;/a&gt; / &lt;a href="http://code.quirkey.com/sammy/"&gt;Sammy.js&lt;/a&gt;? Not really? Then please look at this article now: &lt;a href="http://www.quirkey.com/blog/2009/09/15/sammy-js-couchdb-and-the-new-web-architecture"&gt;Sammy.js, CouchDB, and the new web architecture&lt;/a&gt;. The title says it all.&lt;/p&gt;


&lt;p&gt;This setup happens to be the field of my diploma thesis, friendly sponsored and supported by &lt;a href="http://upstream-berlin.com"&gt;Upstream&lt;/a&gt;. During the next months I'll develop a super duper thing with these technologies, and then I'll write 80 scientific pages about it. Yees, I'm not that much looking forward to the second part! Until then, I'm planning to semi-regularly blog about my findings.&lt;/p&gt;


&lt;p&gt;I'm not allowed to share the code before I have the diploma in my hands. But, because my workmate &lt;a href="http://twitter.com/bionadeholunder"&gt;Frank Proessdorf&lt;/a&gt; is so jealous of what I do, he and I started working on an app with a similar setup on our Upstream Research Fridays, to try things out. &lt;a href="http://github.com/lenalena/jsdoodle"&gt;Here it is&lt;/a&gt;. Don't expect anything yet.&lt;/p&gt;


&lt;p&gt;Today I'm going to tell you about some details of my testing setup. My *cough* supervising tutor &lt;a href="http://twitter.com/langalex"&gt;Alexander Lang&lt;/a&gt; already wrote down &lt;a href="http://upstream-berlin.com/2009/10/25/testing-couchapps-with-cucumber-and-culerity"&gt;all there is to know yet&lt;/a&gt; about Test-Driven Development with Cucumber-Culerity-Celerity and Couchapps.&lt;/p&gt;


&lt;p&gt;But there are a few things that will make your life hard, when the almost perfect Rails testing world has spoiled you as much as me. One thing is that we have to deal with a lot of asynchrony. Sammy renders the page, loads the data from the couch, and whenever the data is there it gets rendered into the page. The best way to do this is via callbacks. I'm going to write another blog post about that soon.&lt;/p&gt;


&lt;p&gt;In the integration test the problem is that celerity doesn't behave as it claims it does:&lt;/p&gt;

&lt;div class="CodeRay"&gt;&lt;pre&gt;&lt;span class="CodeRay"&gt;&lt;span class="gv"&gt;$browser&lt;/span&gt;.wait&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;is &lt;em&gt;supposed&lt;/em&gt; to make the test wait until everything is rendered completely. But for whatever reason it doesn't. The result is that your test fails because it searches for your expressions in an unfinished page.&lt;/p&gt;

&lt;p&gt;Because of that, in culerity we need something like:&lt;/p&gt;

&lt;div class="CodeRay"&gt;&lt;pre&gt;&lt;span class="CodeRay"&gt;sleep &lt;span class="fl"&gt;0.4&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;after every follow, press and go-to-path step. When using culerity in a Rails environment, this usually is enough. Sammy behaves a bit more unpredictable - it sometimes takes more than a whole second until everything is loaded.&lt;/p&gt;

&lt;p&gt;Solution? We can either increase the sleep time a lot, but that's not very nice, the features need long enough to run as it is. Fortunately we can use another method that's build into celerity: wait_while.&lt;/p&gt;

&lt;p&gt;I created a div "spinner" somewhere in index.html:
&lt;div class="CodeRay"&gt;&lt;pre&gt;&lt;span class="CodeRay"&gt; &lt;span class="ta"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="an"&gt;id&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;spinner&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class="ta"&gt;&amp;gt;&lt;/span&gt;&lt;span class="ta"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;You can also add an actual spinner gif here. Just take care to place the div outside of your sammy element selector ("#main" by default), because this div gets replaced all the time.&lt;/p&gt;

&lt;p&gt;We need to show that div before every route that gets run. In application.js:
&lt;div class="CodeRay"&gt;&lt;pre&gt;&lt;span class="CodeRay"&gt;before(&lt;span class="kw"&gt;function&lt;/span&gt;() {
  &lt;span class="pd"&gt;$&lt;/span&gt;(&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;#spinner&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;).show();
});&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;And we need to hide it after your rendering is completed. I haven't found an ideal solution where to do that, it depends on the application you are writing. As a quick and dirty fix, you can add it as a last line in sammy's partial function, in sammy.js:&lt;/p&gt;

&lt;div class="CodeRay"&gt;&lt;pre&gt;&lt;span class="CodeRay"&gt;partial: &lt;span class="kw"&gt;function&lt;/span&gt;(path, data, callback) {
  &lt;span class="c"&gt;//...&lt;/span&gt;
  &lt;span class="pd"&gt;$&lt;/span&gt;(&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;#spinner&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;).hide();
},&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;I prefer to have more control about when I hide it, as my partial calls sometimes have nested callbacks. So I put it in application.js, resp. in my controllers, after each render call or in the partial callbacks. I admit this still sucks a bit.&lt;/p&gt;

&lt;p&gt;Finally, amend the cucumber step:&lt;/p&gt;

&lt;div class="CodeRay"&gt;&lt;pre&gt;&lt;span class="CodeRay"&gt;&lt;span class="co"&gt;When&lt;/span&gt; &lt;span class="rx"&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;span class="k"&gt;I wait for the AJAX call to finish&lt;/span&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;
  sleep &lt;span class="fl"&gt;0.2&lt;/span&gt;
  puts &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;Waiting for page to load ...&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;if&lt;/span&gt; &lt;span class="gv"&gt;$browser&lt;/span&gt;.div(&lt;span class="sy"&gt;:id&lt;/span&gt;, &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;spinner&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;).visible?
  &lt;span class="gv"&gt;$browser&lt;/span&gt;.wait_while { &lt;span class="gv"&gt;$browser&lt;/span&gt;.div(&lt;span class="sy"&gt;:id&lt;/span&gt;, &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;spinner&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;).visible?} 
&lt;span class="r"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The browser still needs to sleep a bit before it actually finds the spinner div. But with this step in my common_culerity_steps.rb, the features finally run smoothly.&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;small&gt;Original article written by Lena and published on &lt;a href='http://lenaherrmann.net'&gt;validates_presence_of :purpose&lt;/a&gt; | &lt;a href='http://lenaherrmann.net/2009/11/04/couchapp-culerity-glitches-part-1'&gt;direct link to this article&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;</description>
      <pubDate>Wed, 04 Nov 2009 10:07:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:3e495ea7-1021-404e-b3ba-18267d409146</guid>
      <comments>http://lenaherrmann.net/2009/11/04/couchapp-culerity-glitches-part-1#comments</comments>
      <category>cucumber</category>
      <category>culerity</category>
      <category>celerity</category>
      <category>tdd</category>
      <category>couchapp</category>
      <category>couchdb</category>
      <category>sammy.js</category>
      <category>javascript</category>
      <category>bug</category>
      <trackback:ping>http://lenaherrmann.net/trackbacks?article_id=6</trackback:ping>
      <link>http://lenaherrmann.net/2009/11/04/couchapp-culerity-glitches-part-1</link>
    </item>
    <item>
      <title>Comatose bug when creating pages in migrations</title>
      <description>&lt;p&gt;&lt;a href="http://comatose.rubyforge.org/"&gt;Comatose&lt;/a&gt; is a micro CMS, easy to embed in your Rails app, ideal when the customer wants to update her FAQ once in a while. I work on a few projects where comatose is integrated, and it's been the second time now that one specific problem has given headaches to me and my colleagues. Time to document the solution.&lt;/p&gt;


&lt;p&gt;Comatose has a hierarchical structure. All the pages are children of the comatose root page, which is usually not in use. This root page is created by the migration AddComatoseSupport. When we add comatose to a project, we usually create another migration, where some child pages are created and populated (because the customer usually already knows what pages she wants). This can look like this:&lt;/p&gt;


&lt;div class="CodeRay"&gt;&lt;pre&gt;&lt;span class="CodeRay"&gt;root = &lt;span class="co"&gt;ComatosePage&lt;/span&gt;.find_by_title(&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;Home Page&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;)
faq = &lt;span class="co"&gt;ComatosePage&lt;/span&gt;.create(&lt;span class="sy"&gt;:title&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;FAQ&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="sy"&gt;:author&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;System&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="sy"&gt;:body&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Text goes here.&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="sy"&gt;:parent_id&lt;/span&gt; =&amp;gt; root.id&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;All will be fine if you run the AddComatoseSupport migration first, and then the other one. If you run both of them in one go, all will look correctly first, too. But then - try to access the application and you get "a nil object when you didn't expect it!" A look in the database will tell you that your root page and your FAQ page are both there - but the slugs (needed to access the pages) are nil. Why is that?&lt;/p&gt;

&lt;p&gt;The answer: The class ComatosePage gets overwritten in the AddComatoseSupport migration, to make sure the comatose root page can be created (they are invalid without parent_id). But if you have another migration following this one, where you create a couple of comatose pages, they still are instances of that overwritten class. Especially the before/after filters from the original ComatosePage aren't evaluated. In those filters the slug fields are meant to be populated, so they are nil.&lt;/p&gt;

&lt;p&gt;First soluton: Define a class ComatoseRootPage instead, so you won't override anything.&lt;/p&gt;

&lt;p&gt;Second and much easier solution: Remove the class redefinition altogether, for the root page just do
&lt;div class="CodeRay"&gt;&lt;pre&gt;&lt;span class="CodeRay"&gt;&lt;span class="co"&gt;ComatosePage&lt;/span&gt;.new(...).save(&lt;span class="pc"&gt;false&lt;/span&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
 &lt;a href="http://github.com/lenalena/comatose/commit/4005cf44f11165393b18b3fed2837a9afb57814a"&gt;See on github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Unfortunately the comatose project is not updated very often, so this bug is still unsolved in the generated migrations.&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;small&gt;Original article written by Lena and published on &lt;a href='http://lenaherrmann.net'&gt;validates_presence_of :purpose&lt;/a&gt; | &lt;a href='http://lenaherrmann.net/2009/10/27/comatose-bug-when-creating-pages-in-migrations'&gt;direct link to this article&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;</description>
      <pubDate>Tue, 27 Oct 2009 22:27:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:0f740e51-8617-4048-a94b-90528f912f58</guid>
      <comments>http://lenaherrmann.net/2009/10/27/comatose-bug-when-creating-pages-in-migrations#comments</comments>
      <category>rails</category>
      <category>comatose</category>
      <category>bug</category>
      <trackback:ping>http://lenaherrmann.net/trackbacks?article_id=4</trackback:ping>
      <link>http://lenaherrmann.net/2009/10/27/comatose-bug-when-creating-pages-in-migrations</link>
    </item>
    <item>
      <title>Snippets for cucumber</title>
      <description>&lt;p&gt;In every project I use cucumber (that means, always) there are a few things that I keep reinventing, or I spend a lot of time searching for them in other projects. Here are some of them. They aren't all written by me, but maybe my coworkers like to use this as a reference, too?&lt;/p&gt;


&lt;p&gt;When you upgrade to the current cucumber (0.4.2) from an older version some steps will fail, because cucumber doesn't examine the whole html anymore. You can still check the raw html with these steps:&lt;/p&gt;


&lt;div class="CodeRay"&gt;&lt;pre&gt;&lt;span class="CodeRay"&gt;&lt;span class="co"&gt;Then&lt;/span&gt; &lt;span class="rx"&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;span class="k"&gt;^I should see &amp;quot;([^&lt;/span&gt;&lt;span class="ch"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;]*)&amp;quot; in the source$&lt;/span&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt; |text|
  response.body.should match(&lt;span class="rx"&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;span class="il"&gt;&lt;span class="idl"&gt;#{&lt;/span&gt;text&lt;span class="idl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;/span&gt;)
&lt;span class="r"&gt;end&lt;/span&gt;

&lt;span class="co"&gt;Then&lt;/span&gt; &lt;span class="rx"&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;span class="k"&gt;^I should not see &amp;quot;([^&lt;/span&gt;&lt;span class="ch"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;]*)&amp;quot; in the source$&lt;/span&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt; |text|
  response.body.should_not match(&lt;span class="rx"&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;span class="il"&gt;&lt;span class="idl"&gt;#{&lt;/span&gt;text&lt;span class="idl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;/span&gt;)
&lt;span class="r"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Want to test sorting in one step?&lt;/p&gt;


&lt;div class="CodeRay"&gt;&lt;pre&gt;&lt;span class="CodeRay"&gt;&lt;span class="co"&gt;Then&lt;/span&gt; &lt;span class="rx"&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;span class="k"&gt;^I should see &amp;quot;([^&lt;/span&gt;&lt;span class="ch"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;]*)&amp;quot; before &amp;quot;([^&lt;/span&gt;&lt;span class="ch"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;]*)&amp;quot;$&lt;/span&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt; |first, second|
  response.body.should match(&lt;span class="rx"&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;span class="il"&gt;&lt;span class="idl"&gt;#{&lt;/span&gt;first&lt;span class="idl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt;.*&lt;/span&gt;&lt;span class="il"&gt;&lt;span class="idl"&gt;#{&lt;/span&gt;second&lt;span class="idl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;span class="mod"&gt;im&lt;/span&gt;&lt;/span&gt;)
&lt;span class="r"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Sometimes you want to click a link in a specific div:&lt;/p&gt;

&lt;div class="CodeRay"&gt;&lt;pre&gt;&lt;span class="CodeRay"&gt;&lt;span class="co"&gt;When&lt;/span&gt; &lt;span class="rx"&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;span class="k"&gt;^I buy &amp;quot;([^&lt;/span&gt;&lt;span class="ch"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;]*)&amp;quot;$&lt;/span&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt; |title|
  product = &lt;span class="co"&gt;Product&lt;/span&gt;.find_by_title(title)
  field_by_xpath(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;//div[@id='buy_product_dialog_product_&lt;/span&gt;&lt;span class="il"&gt;&lt;span class="idl"&gt;#{&lt;/span&gt;product.id&lt;span class="idl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt;']//input&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;).click
&lt;span class="r"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Or you want to test what happens when you delete a specific object:&lt;/p&gt;

&lt;div class="CodeRay"&gt;&lt;pre&gt;&lt;span class="CodeRay"&gt;&lt;span class="co"&gt;When&lt;/span&gt; &lt;span class="rx"&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;span class="k"&gt;^I press &amp;quot;Delete&amp;quot; for comment &amp;quot;([^&lt;/span&gt;&lt;span class="ch"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;]*)&amp;quot;$&lt;/span&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt; |comment|
  tag = &lt;span class="co"&gt;Comment&lt;/span&gt;.find_by_title(comment)
  field_by_xpath(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;//form[@id='delete_comment_&lt;/span&gt;&lt;span class="il"&gt;&lt;span class="idl"&gt;#{&lt;/span&gt;comment.id&lt;span class="idl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt;']//input[@type='submit']&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;).click
&lt;span class="r"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;With this you can check for a string that's within a tag with a specific id:&lt;/p&gt;

&lt;div class="CodeRay"&gt;&lt;pre&gt;&lt;span class="CodeRay"&gt;&lt;span class="co"&gt;Then&lt;/span&gt; &lt;span class="rx"&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;span class="k"&gt;^I should see &amp;quot;([^&lt;/span&gt;&lt;span class="ch"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;]+)&amp;quot; in &amp;quot;([^&lt;/span&gt;&lt;span class="ch"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;]+)&amp;quot;$&lt;/span&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt; |content, css_id|
  response.body.should have_tag(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;#&lt;/span&gt;&lt;span class="il"&gt;&lt;span class="idl"&gt;#{&lt;/span&gt;css_id&lt;span class="idl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, content)
&lt;span class="r"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Use this regex to check for something within a given tag:&lt;/p&gt;

&lt;div class="CodeRay"&gt;&lt;pre&gt;&lt;span class="CodeRay"&gt;&lt;span class="co"&gt;Then&lt;/span&gt; &lt;span class="rx"&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;span class="k"&gt;^I should see &amp;quot;([^&lt;/span&gt;&lt;span class="ch"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;]*)&amp;quot; within a (&lt;/span&gt;&lt;span class="ch"&gt;\w&lt;/span&gt;&lt;span class="k"&gt;+) tag$&lt;/span&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt; |text, tag|
  response.body.should match(&lt;span class="rx"&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;span class="k"&gt;&amp;lt;&lt;/span&gt;&lt;span class="il"&gt;&lt;span class="idl"&gt;#{&lt;/span&gt;tag&lt;span class="idl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt;[^&amp;gt;]*&amp;gt;[^&amp;lt;]*&lt;/span&gt;&lt;span class="il"&gt;&lt;span class="idl"&gt;#{&lt;/span&gt;text&lt;span class="idl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt;[^&amp;lt;]*&amp;lt;&lt;/span&gt;&lt;span class="ch"&gt;\/&lt;/span&gt;&lt;span class="il"&gt;&lt;span class="idl"&gt;#{&lt;/span&gt;tag&lt;span class="idl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt;&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;/span&gt;)
&lt;span class="r"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Cucumber 0.4.2 auto-generates webrat_steps.rb including a step to save the current page and open it in the browser. Just in case not everyone knows this step by now:&lt;/p&gt;

&lt;div class="CodeRay"&gt;&lt;pre&gt;&lt;span class="CodeRay"&gt;&lt;span class="co"&gt;Then&lt;/span&gt; &lt;span class="rx"&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;span class="k"&gt;^show me the page$&lt;/span&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;
  save_and_open_page
&lt;span class="r"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr /&gt;&lt;p&gt;&lt;small&gt;Original article written by Lena and published on &lt;a href='http://lenaherrmann.net'&gt;validates_presence_of :purpose&lt;/a&gt; | &lt;a href='http://lenaherrmann.net/2009/10/25/snippets-for-cucumber'&gt;direct link to this article&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;</description>
      <pubDate>Sun, 25 Oct 2009 21:53:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:f0a52106-3a2f-4e60-b2cf-94b3ac484f5e</guid>
      <comments>http://lenaherrmann.net/2009/10/25/snippets-for-cucumber#comments</comments>
      <category>rails</category>
      <category>xpath</category>
      <category>cucumber</category>
      <category>tdd</category>
      <trackback:ping>http://lenaherrmann.net/trackbacks?article_id=3</trackback:ping>
      <link>http://lenaherrmann.net/2009/10/25/snippets-for-cucumber</link>
    </item>
    <item>
      <title>Things I learned recently</title>
      <description>&lt;p&gt;Doing client work for &lt;a href="http://upstream-agile.com"&gt;Upstream&lt;/a&gt;, I recently had the pleasure of pair programming with fabulous &lt;a href="http://freelancing-gods.com"&gt;Pat Allan&lt;/a&gt; for a month. Here are a few of the things I learned.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    Pair Programming is a good thing (not that I haven't known that before). Here is &lt;a href="http://www.pathf.com/blogs/2009/09/pair-programming-york-times/"&gt;yet another good article about pairing&lt;/a&gt; if you aren't convinced yet. Next to improved concentration, keeping each other from getting stuck in stuff, I like the sharing of best practices, Textmate short cuts, syntax tricks etc.
  &lt;/li&gt;
  
  &lt;li&gt;
    Instead of writing "puts" in, after and before blocks that don't act as expected, use ruby-debug. It's really easy, and gives you so much more information about your situation.
    Just do:
&lt;div class="CodeRay"&gt;&lt;pre&gt;&lt;notextile&gt;&lt;span class="CodeRay"&gt;sudo gem install ruby-debug&lt;/span&gt;&lt;/notextile&gt;&lt;/pre&gt;&lt;/div&gt;      
And in your code, at the place you want to examine:
&lt;div class="CodeRay"&gt;&lt;pre&gt;&lt;notextile&gt;&lt;span class="CodeRay"&gt;require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;ruby-debug&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;
debugger&lt;/span&gt;&lt;/notextile&gt;&lt;/pre&gt;&lt;/div&gt;
    Then restart script/server with the --debug option. It stops when the line where you put 'debugger' is reached. You can directly call variables to explore their values. The basic commands are:
    &lt;ul class="second-level"&gt;
      &lt;li&gt;n - next&lt;/li&gt;
      &lt;li&gt;s - step into method&lt;/li&gt;
      &lt;li&gt;c - continue to breakpoint&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  


  &lt;li&gt;
    Read the source code of the gems you're using. If you are not sure how to do something with the gem, the actual code is often more informative than documentation. Lachie Cox &lt;a href="http://smartbomb.com.au/2008/02/i-love-me-some-source"&gt;describes in his blog&lt;/a&gt; how to set up a Textmate shortcut with which you can access all your gems without any typing. 
  &lt;/li&gt;

  &lt;li&gt;
    &lt;a href="http://www.rubular.com"&gt;Rubular&lt;/a&gt; is a nice app to test regular expressions in your browser.
  &lt;/li&gt;

  &lt;li&gt; 
    I have never used RCov before. Of course it doesn't mean too much, but having a test coverage of 97,7% feels good, I can tell you. A Code to Test Ratio of 1:2.7 is not bad either.
    &lt;br/&gt;
    The RCov gem has moved to &lt;a href="http://github.com/relevance/rcov"&gt;Relevance&lt;/a&gt;, &lt;a href="http://www.claytonlz.com/index.php/2009/04/how-to-setup-rspec-cucumber-webrat-rcov-and-autotest-on-leopard"&gt;read here&lt;/a&gt; how to set it up for an RSpec/Cucumber environment. 
  &lt;/li&gt;

  &lt;li&gt;
    And finally, I got convinced that it's good to have a blog ...
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here we are!&lt;/p&gt;

&lt;hr /&gt;&lt;p&gt;&lt;small&gt;Original article written by Lena and published on &lt;a href='http://lenaherrmann.net'&gt;validates_presence_of :purpose&lt;/a&gt; | &lt;a href='http://lenaherrmann.net/2009/10/24/things-i-learned-recently'&gt;direct link to this article&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;</description>
      <pubDate>Sat, 24 Oct 2009 21:12:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:0934e5ce-393c-4b62-96f3-e14fe762114f</guid>
      <comments>http://lenaherrmann.net/2009/10/24/things-i-learned-recently#comments</comments>
      <category>ruby</category>
      <category>rails</category>
      <category>debugging</category>
      <category>pairing</category>
      <category>textmate</category>
      <trackback:ping>http://lenaherrmann.net/trackbacks?article_id=1</trackback:ping>
      <link>http://lenaherrmann.net/2009/10/24/things-i-learned-recently</link>
    </item>
  </channel>
</rss>
