<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Jean-Hadrien Chabran]]></title>
  <link href="http://jhchabran.github.com/atom.xml" rel="self"/>
  <link href="http://jhchabran.github.com/"/>
  <updated>2012-01-05T17:56:22+01:00</updated>
  <id>http://jhchabran.github.com/</id>
  <author>
    <name><![CDATA[jhchabran]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Build a chrome extension with Coffee Script]]></title>
    <link href="http://jhchabran.github.com/blog/2011/12/17/build-a-chrome-extension-with-coffee-script/"/>
    <updated>2011-12-17T12:30:00+01:00</updated>
    <id>http://jhchabran.github.com/blog/2011/12/17/build-a-chrome-extension-with-coffee-script</id>
    <content type="html"><![CDATA[<p>Ever had an idea for a great Chrome Extension ? Did you know that a
chrome extension is just javascript ? And where there&#8217;s Javascript, we
can write some CoffeeScript !</p>

<p>This post aims to give you an overview of building a chrome extension
wrote in CoffeeScript. While being familiar with the latest is mandatory to understand
what&#8217;s going on there, no previous experience with Google Chrome is needed.</p>

<p>Our chrome extension will be a fully fonctional tab switcher that mimics
Command-T feature of Textmate (also known as fuzzy finding).</p>

<p><img class="center" src="http://jhchabran.github.com/images/chrome-extension-screenshot.png" title="Screenshot" ></p>

<p><strong><a href="http://github.com/jhchabran/tabswitcher">Code on Github</a></strong> and <strong><a href="https://chrome.google.com/webstore/detail/gkdkligmcadfbagoeggeohelmgalchcn">Extension on Chrome store</a></strong></p>

<h2>Why doing it in CoffeeScript ?</h2>

<p><a href="http://jashkenas.github.com/coffee-script/">Coffee Script</a> is a thin and elegant syntaxic layer on top of Javascript, allowing
you to write cleaner and concise code and still outputting almost
readable javascript. Why should we avoid a such nice tool to write a
chrome extension ! Plus it&#8217;s fun to write, it will remind you Ruby and
Python, while still letting you do Javascript wizardry.</p>

<p>For french readers, I gave a talk at a recent <a href="http://www.meetup.com/parisrb/">Paris.rb</a> event, you can
read my
<a href="http://www.slideshare.net/jhchabran/introduction-coffeescript-pour-parisrb">slides</a> until we get the video online.</p>

<h2>Our goal</h2>

<p>Command-T is a battle-tested quick-file-access method that proved to be
efficient. It should be useful to have it available in Chrome, especially if you
often have more than 20 tabs opened, where they all look like pinned ones.
Typing a few letter of the URL is clearly faster than hammering like a
monkey the next tab hotkey !</p>

<p>Couldn&#8217;t we port that great feature in Chrome ?</p>

<h2>Dissecting an extension</h2>

<p>Chrome being a popular browser, it is as expected from a modern browser, pretty easy to extend.
<a href="http://code.google.com/chrome/extensions/getstarted.html">Google&#8217;s starter
guide</a> is a
good resource and gives you a quick intro.</p>

<p>Skipping implementation details, it&#8217;s basically the following :</p>

<ul>
<li>A <em>content script</em> is executed in the context of the current page,
having access to the DOM</li>
<li>An <em>extension script</em> is executed in what you could call chrome
context, meaning it can manipulate chrome objects like tabs, windows</li>
<li>The <em>background page</em> include the <em>extension script</em></li>
<li>These two contexts are <em>sandboxed</em>, meaning you can&#8217;t collide with
the scripts running on the page</li>
<li>Communication between them are made through <em>message passing</em></li>
</ul>


<h2>Get confortable</h2>

<p>The absolute minimum is the following structure :</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>tabswitcher               # Repository root 
</span><span class='line'>      /background.html    # Extension's 'main view'
</span><span class='line'>      /manifest.json      # Extension settings </span></code></pre></td></tr></table></div></figure>


<p>Coffee Script need to be compiled in the first place, automating it
brings two benefits : it&#8217;s comfortable to develop with, a contributor
can just check out your sources and run your command to build the whole
thing. This lower the entry barrier for contributing to our extension
=).</p>

<p>The simplest way to handle compilation easily is to build a <em>Cakefile</em>
(a <em>Rakefile</em> or <em>Makefile</em> in CoffeeScript).</p>

<p>We&#8217;ll write it to take *.coffee input from <em>/src</em> and output javascript
in  <em>/build</em> using this command. Our goal is to do the following to
build our extension :</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>  $ cake build</span></code></pre></td></tr></table></div></figure>


<p></p>

<p>But while in development, it&#8217;s easier to have our files monitored to
reflect changes as we save them. So To watch the <em>src/</em> folder and reflect any
changes made there, there&#8217;s the <em>watch</em> command :</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>  $ cake watch</span></code></pre></td></tr></table></div></figure>


<p></p>

<p><em>coffee -h</em> tells us these commands are directly available :</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>  $ coffee --output build/ --watch src/</span></code></pre></td></tr></table></div></figure>


<p>Good. It&#8217;s time to bake this into a <em>Cakefile</em>. Below are the interesting parts
of it :</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='coffeescript'><span class='line'><span class="nx">task</span> <span class="s1">&#39;build&#39;</span><span class="p">,</span> <span class="s1">&#39;Build extension code into build/&#39;</span><span class="p">,</span> <span class="o">-&gt;</span>
</span><span class='line'>  <span class="nx">if_coffee</span> <span class="o">-&gt;</span>
</span><span class='line'>    <span class="nv">ps = </span><span class="nx">spawn</span><span class="p">(</span><span class="s2">&quot;coffee&quot;</span><span class="p">,</span> <span class="p">[</span><span class="s2">&quot;--output&quot;</span><span class="p">,</span> <span class="nx">JAVASCRIPTS_PATH</span><span class="p">,</span><span class="s2">&quot;--compile&quot;</span><span class="p">,</span><span class="nx">COFFEESCRIPTS_PATH</span><span class="p">])</span>
</span><span class='line'>    <span class="nx">ps</span><span class="p">.</span><span class="nx">stdout</span><span class="p">.</span><span class="kc">on</span><span class="p">(</span><span class="s1">&#39;data&#39;</span><span class="p">,</span> <span class="nx">log</span><span class="p">)</span>
</span><span class='line'>    <span class="nx">ps</span><span class="p">.</span><span class="nx">stderr</span><span class="p">.</span><span class="kc">on</span><span class="p">(</span><span class="s1">&#39;data&#39;</span><span class="p">,</span> <span class="nx">log</span><span class="p">)</span>
</span><span class='line'>    <span class="nx">ps</span><span class="p">.</span><span class="kc">on</span> <span class="s1">&#39;exit&#39;</span><span class="p">,</span> <span class="nf">(code)-&gt;</span>
</span><span class='line'>      <span class="k">if</span> <span class="nx">code</span> <span class="o">!=</span> <span class="mi">0</span>
</span><span class='line'>        <span class="nx">console</span><span class="p">.</span><span class="nx">log</span> <span class="s1">&#39;failed&#39;</span>
</span></code></pre></td></tr></table></div></figure>


<p>If you&#8217;ve alreay wrote any Rakefile, it&#8217;s quite similar. If not, we
basically declare the command <em>build</em> to be invokable through <em>cake
build</em>. We handle if the coffee binary is available or not in the $PATH
and finally execute our coffee command as expected.</p>

<h2>A small overview</h2>

<p>Manipulating the DOM through the standard API bores me to death, so
let&#8217;s grab <a href="http://zeptojs.com/">Zepto</a> to do the big work for us. We could have used JQuery
but we don&#8217;t need all the browser compatibility stuff, so Zepto with its
minimal features set is a perfect match. Let&#8217;s store it in <em>/libs</em>.</p>

<p>Our final structure is the following :</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='coffeescript'><span class='line'><span class="nx">tabswitcher</span>               <span class="c1"># Repository root </span>
</span><span class='line'>      <span class="err">/build              # Generated Javascripts end there</span>
</span><span class='line'>      <span class="o">/</span><span class="nx">libs</span>               <span class="c1"># Dependencies</span>
</span><span class='line'>      <span class="err">/src                # Our code</span>
</span><span class='line'>      <span class="o">/</span><span class="nx">background</span><span class="p">.</span><span class="nx">html</span>    <span class="c1"># Extension&#39;s &#39;main view&#39;</span>
</span><span class='line'>      <span class="err">/manifest.json      # Extension settings </span>
</span><span class='line'>      <span class="o">/</span><span class="nx">Cakefile</span>           <span class="c1"># Starts build task</span>
</span></code></pre></td></tr></table></div></figure>


<p>Ok, we&#8217;re now ready to spill some coffee into Chrome :</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='coffeescript'><span class='line'>  <span class="nx">$</span> <span class="nx">cake</span> <span class="nx">watch</span>
</span></code></pre></td></tr></table></div></figure>


<h2>The extension itself</h2>

<p>Our extension is quite simple in its behavior :</p>

<ul>
<li>listen for keyboard events if  <em>ctrl-\</em> was pressed instead of
<em>command-t</em> <del>because we can&#8217;t bind to <em>command</em> in Chrome and it&#8217;s
not portable</del> <strong>edit : cmd sends meta under osx</strong></li>
<li>if pressed, insert some html in the page containing our UI</li>
<li>display opened tabs</li>
<li>wait for user input</li>
<li>on enter in the input, go to that tab</li>
</ul>


<p>So in these steps, those two are calls to <em>chrome api</em> :</p>

<ul>
<li>list all opened tabs, we&#8217;ll name it  <em>getTabs</em></li>
<li>go to a tag, as <em>switchTab</em></li>
</ul>


<p>Our <em>content script</em> that run in the current page, it will send these two messages to
the <em>background script</em>, which is the only one that can make these calls.</p>

<p>We end with the following process :</p>

<p><img src="http://jhchabran.github.com/images/schema-chrome-plugin.png" title="Schema" ></p>

<p>The red arrows are message passed from the content script to the
background page ( <a href="http://code.google.com/chrome/extensions/messaging.html">message
passing</a> ).
It&#8217;s similar to firing custom events with JQuery and listening for them,
but with a particular API.</p>

<h2>Implementation</h2>

<p>The <em>content script</em> is <em>src/content.coffee</em> and <em>background script</em>
lives in <em>src/background.coffee</em></p>

<p>First things first : a tab. It&#8217;s simpler than what you may have expected</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='coffeescript'><span class='line'>  <span class="nv">tab = </span>
</span><span class='line'>    <span class="nv">id : </span><span class="mi">43</span>
</span><span class='line'>    <span class="nv">windowId : </span><span class="mi">4</span>
</span><span class='line'>    <span class="nv">url: </span><span class="s2">&quot;http://google.com&quot;</span>
</span><span class='line'>    <span class="nv">title: </span><span class="s2">&quot;Google&quot;</span>
</span><span class='line'>    <span class="p">...</span>
</span></code></pre></td></tr></table></div></figure>


<p>We don&#8217;t need to handle them directly as the Chrome API will do the job
for us, but it&#8217;s a starting point.</p>

<p>Let&#8217;s examine the <em>content script</em>, which is where all the work happens.</p>

<p>An <em>Application</em> class encapsulates the main logic. It setups the UI, binds the
callbacks and pass messages to the <em>background page</em>.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
<span class='line-number'>56</span>
<span class='line-number'>57</span>
<span class='line-number'>58</span>
<span class='line-number'>59</span>
<span class='line-number'>60</span>
<span class='line-number'>61</span>
<span class='line-number'>62</span>
<span class='line-number'>63</span>
</pre></td><td class='code'><pre><code class='coffeescript'><span class='line'><span class="k">class</span> <span class="nx">Application</span>
</span><span class='line'>  <span class="nv">constructor: </span><span class="o">-&gt;</span>
</span><span class='line'>    <span class="c1"># Inject our html into the view</span>
</span><span class='line'>    <span class="nx">@injectView</span><span class="p">()</span>
</span><span class='line'>
</span><span class='line'>    <span class="c1"># Install a listener for our input </span>
</span><span class='line'>    <span class="nx">@element</span><span class="p">().</span><span class="nx">find</span><span class="p">(</span><span class="s1">&#39;input&#39;</span><span class="p">).</span><span class="nx">keyup</span> <span class="p">(</span><span class="nx">event</span><span class="p">)</span><span class="o">=&gt;</span>
</span><span class='line'>      <span class="nx">@onInput</span><span class="p">(</span><span class="nx">event</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'>    <span class="c1"># Spawn a view that handle results display</span>
</span><span class='line'>    <span class="vi">@tabListView = </span><span class="k">new</span> <span class="nx">TabListView</span> <span class="nx">@element</span><span class="p">().</span><span class="nx">find</span><span class="p">(</span><span class="s1">&#39;ul&#39;</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'>  <span class="nv">element: </span><span class="o">-&gt;</span>
</span><span class='line'>    <span class="c1"># Return our base div</span>
</span><span class='line'>    <span class="nx">@element_</span> <span class="o">||=</span> <span class="nx">$</span><span class="p">(</span><span class="s1">&#39;#tabswitcher-overlay&#39;</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'>  <span class="nv">onInput: </span><span class="nf">(event)-&gt;</span>
</span><span class='line'>    <span class="c1"># When something is entered is the input, filter tabs !</span>
</span><span class='line'>    <span class="nv">candidates = </span><span class="nx">fuzzy</span><span class="p">(</span><span class="nx">@tabs</span><span class="p">(),</span> <span class="nx">event</span><span class="p">.</span><span class="nx">target</span><span class="p">.</span><span class="nx">value</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'>    <span class="c1"># Update tabs that match</span>
</span><span class='line'>    <span class="nx">@tabListView</span><span class="p">.</span><span class="nx">update</span> <span class="nx">candidates</span>
</span><span class='line'>
</span><span class='line'>    <span class="c1"># If enter</span>
</span><span class='line'>    <span class="k">if</span> <span class="nx">event</span><span class="p">.</span><span class="nx">keyCode</span> <span class="o">==</span> <span class="mi">13</span>
</span><span class='line'>      <span class="c1"># Go to that tab</span>
</span><span class='line'>      <span class="nx">@switchTab</span> <span class="nx">candidates</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">tab</span> <span class="k">if</span> <span class="nx">candidates</span><span class="o">?</span>
</span><span class='line'>
</span><span class='line'>  <span class="nv">hide: </span><span class="o">-&gt;</span>
</span><span class='line'>    <span class="c1"># ...</span>
</span><span class='line'>  <span class="nv">show: </span><span class="o">-&gt;</span>
</span><span class='line'>    <span class="c1"># ...</span>
</span><span class='line'>
</span><span class='line'>  <span class="nv">switchTab: </span><span class="nf">(tab)-&gt;</span>
</span><span class='line'>    <span class="c1"># We&#39;re switching tab, hide the UI before leaving</span>
</span><span class='line'>    <span class="nx">@hide</span><span class="p">()</span>
</span><span class='line'>
</span><span class='line'>    <span class="c1"># Send message to the background script</span>
</span><span class='line'>    <span class="nx">chrome</span><span class="p">.</span><span class="nx">extension</span><span class="p">.</span><span class="nx">sendRequest</span><span class="p">(</span><span class="nx">message</span><span class="o">:</span><span class="s2">&quot;switchTab&quot;</span><span class="p">,</span> <span class="nx">target</span><span class="o">:</span><span class="nx">tab</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'>  <span class="nv">hotKeyListener: </span><span class="nf">(event)-&gt;</span>
</span><span class='line'>    <span class="c1"># Listen for ctrl-\</span>
</span><span class='line'>    <span class="k">if</span> <span class="nx">event</span><span class="p">.</span><span class="nx">keyCode</span>
</span><span class='line'>      <span class="k">if</span> <span class="nx">event</span><span class="p">.</span><span class="nx">ctrlKey</span> <span class="o">&amp;&amp;</span> <span class="nx">event</span><span class="p">.</span><span class="nx">keyCode</span> <span class="o">==</span> <span class="mi">220</span> <span class="c1"># Ctrl + \</span>
</span><span class='line'>        <span class="c1"># Send message to background script, ask for list of tabs</span>
</span><span class='line'>        <span class="nx">chrome</span><span class="p">.</span><span class="nx">extension</span><span class="p">.</span><span class="nx">sendRequest</span> <span class="p">{</span><span class="nv">message: </span><span class="s2">&quot;getTabs&quot;</span><span class="p">},</span>
</span><span class='line'>          <span class="p">(</span><span class="nx">response</span><span class="p">)</span><span class="o">=&gt;</span>
</span><span class='line'>            <span class="vi">@tabs_ = </span><span class="nx">response</span><span class="p">.</span><span class="nx">tabs</span>
</span><span class='line'>            <span class="nx">@show</span><span class="p">()</span>
</span><span class='line'>
</span><span class='line'>      <span class="k">else</span> <span class="k">if</span> <span class="nx">event</span><span class="p">.</span><span class="nx">keyCode</span> <span class="o">==</span> <span class="mi">27</span> <span class="c1"># ESC</span>
</span><span class='line'>        <span class="nx">@hide</span><span class="p">()</span>
</span><span class='line'>
</span><span class='line'>  <span class="nv">injectView: </span><span class="o">-&gt;</span>
</span><span class='line'>    <span class="c1"># Inject our UI in the DOM</span>
</span><span class='line'>    <span class="nx">$</span><span class="p">(</span><span class="s1">&#39;body&#39;</span><span class="p">).</span><span class="nx">append</span> <span class="p">...</span>
</span><span class='line'>
</span><span class='line'><span class="nv">app = </span><span class="k">new</span> <span class="nx">Application</span><span class="p">()</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># Attach our handler</span>
</span><span class='line'><span class="nb">window</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span><span class="s2">&quot;keyup&quot;</span><span class="p">,</span> <span class="nf">(e)-&gt;</span>
</span><span class='line'>  <span class="nx">app</span><span class="p">.</span><span class="nx">hotKeyListener</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span>
</span><span class='line'><span class="p">,</span><span class="kc">false</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>After defining Application we just instanciate it and bind our
listener, to grab keyboard events. For the sake of readability, I&#8217;ve
skipped the <a href="https://github.com/jhchabran/tabswitcher/blob/master/src/hook.coffee#L4">fuzzy filter implementation</a>, which is kind of naive but do
the job as expected. Bold stuff as you can see in the screenshot in the
beginning of the post is handled in another class named <em>TabView</em>.</p>

<p>Let&#8217;s now see the script running on the <em>background page</em> that respond
to calls made from the <em>content script</em> :</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
</pre></td><td class='code'><pre><code class='coffeescript'><span class='line'><span class="c1"># Install the message listener</span>
</span><span class='line'><span class="nx">chrome</span><span class="p">.</span><span class="nx">extension</span><span class="p">.</span><span class="nx">onRequest</span><span class="p">.</span><span class="nx">addListener</span> <span class="nf">(request, sender, sendResponse)-&gt;</span>
</span><span class='line'>  <span class="c1"># Select the right response given the message</span>
</span><span class='line'>  <span class="k">switch</span> <span class="nx">request</span><span class="p">.</span><span class="nx">message</span>
</span><span class='line'>    <span class="c1"># Grab all tabs</span>
</span><span class='line'>    <span class="k">when</span> <span class="s2">&quot;getTabs&quot;</span>
</span><span class='line'>      <span class="nx">chrome</span><span class="p">.</span><span class="nx">windows</span><span class="p">.</span><span class="nx">getCurrent</span> <span class="nf">(window)-&gt;</span>
</span><span class='line'>        <span class="nx">chrome</span><span class="p">.</span><span class="nx">tabs</span><span class="p">.</span><span class="nx">getAllInWindow</span> <span class="nb">window</span><span class="p">.</span><span class="nx">id</span><span class="p">,</span> <span class="nf">(tabs)-&gt;</span>
</span><span class='line'>          <span class="c1"># We&#39;ve collected all tabs, let&#39;s send them back</span>
</span><span class='line'>          <span class="nx">sendResponse</span><span class="p">(</span><span class="nx">tabs</span><span class="o">:</span><span class="nx">tabs</span><span class="p">)</span>
</span><span class='line'>      <span class="k">break</span>
</span><span class='line'>    <span class="k">when</span> <span class="s2">&quot;switchTab&quot;</span>
</span><span class='line'>      <span class="nx">chrome</span><span class="p">.</span><span class="nx">tabs</span><span class="p">.</span><span class="nx">update</span><span class="p">(</span><span class="nx">request</span><span class="p">.</span><span class="nx">target</span><span class="p">.</span><span class="nx">id</span><span class="p">,</span> <span class="nx">selected</span><span class="o">:</span><span class="kc">true</span><span class="p">)</span>
</span><span class='line'>      <span class="nx">sendResponse</span><span class="p">({})</span>
</span><span class='line'>      <span class="k">break</span>
</span><span class='line'>    <span class="k">else</span>
</span><span class='line'>      <span class="nx">sendResponse</span><span class="p">({})</span>
</span></code></pre></td></tr></table></div></figure>


<p>Pretty straight-forward, we just take incoming message and handle them.
Only the message &#8216;getTabs&#8217; sends back a response : an array of tabs returned by
Chrome.</p>

<h2>What now ?</h2>

<p>Well, beside some crappy HTML to render tabs, there&#8217;s nothing left. The complete code of this extension is available on
<a href="http://github.com/jhchabran/tabswitcher">GitHub</a> where you can explore
it, fork it as you want !</p>

<p>Remember that you need to enable developer&#8217;s mode in chrome extensions
to install it directly from the sources.</p>

<p>You can also install the <a href="https://chrome.google.com/webstore/detail/gkdkligmcadfbagoeggeohelmgalchcn">released
version</a>. It doesn&#8217;t have all original features, you can&#8217;t select the second result for example, but it&#8217;s usable.</p>

<p>Coffee Script is available everywhere you can use javascript, with some
tooling to kick in compilation ! Set up two tasks,
adjust .gitignore and there it works.</p>

<p>Chrome extensions are way simpler to write than I thought ! Next, understanding how Chrome
handles security and isolation through sandboxing and still sharing DOM access is
pretty impressive.</p>

<p>Once you grasped the big picture, it&#8217;s finally just like building any
web app interactive UI !</p>

<ul>
<li><a href="https://chrome.google.com/webstore/detail/gkdkligmcadfbagoeggeohelmgalchcn">Install it directly on your Chrome</a>.</li>
<li><a href="http://github.com/jhchabran/tabswitcher">Source code</a></li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Writing readable model specs]]></title>
    <link href="http://jhchabran.github.com/blog/2011/11/18/writing-readable-models-specs/"/>
    <updated>2011-11-18T19:08:00+01:00</updated>
    <id>http://jhchabran.github.com/blog/2011/11/18/writing-readable-models-specs</id>
    <content type="html"><![CDATA[<p>Writing Rails specs with <a href="https://www.relishapp.com/rspec">RSpec</a> and
<a href="https://github.com/thoughtbot/factory_girl">FactoryGirl</a> is easy to do when you
got a basic understanding of testing principles but you may have noticed
how these specs tends to get cluttered over time. Even to the point you
don&#8217;t get what&#8217;s going on at all and call your co-worker who wrote them
and ask him to handle your task!</p>

<p>The following points are basic principles to keep in mind while writing
specs to avoid being stuck with an unreadable spec.</p>

<p>We deal with four models : User, Cart, Order and Item.
Their relationships are obviously as simplified as possible to keep
ourselves focused on their tests.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">class</span> <span class="nc">User</span>
</span><span class='line'>  <span class="n">has_one</span> <span class="ss">:cart</span>
</span><span class='line'>  <span class="n">has_many</span> <span class="ss">:orders</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="k">class</span> <span class="nc">Cart</span>
</span><span class='line'>  <span class="n">belongs_to</span> <span class="ss">:user</span>
</span><span class='line'>  <span class="n">has_many</span> <span class="ss">:items</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="k">class</span> <span class="nc">Order</span>
</span><span class='line'>  <span class="n">has_many</span> <span class="ss">:items</span>
</span><span class='line'>  <span class="n">belongs_to</span> <span class="ss">:user</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="k">class</span> <span class="nc">Item</span>
</span><span class='line'>  <span class="n">belongs_to</span> <span class="ss">:cart</span>
</span><span class='line'>  <span class="n">belongs_to</span> <span class="ss">:order</span>
</span><span class='line'>  <span class="n">belongs_to</span> <span class="ss">:product</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<h2>Don&#8217;t Repeat Yourself</h2>

<p>As usual, the DRY principle. Consider the following code :</p>

<figure class='code'><figcaption><span>user_spec.rb</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">describe</span> <span class="no">User</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">before</span> <span class="ss">:each</span> <span class="k">do</span>
</span><span class='line'>    <span class="vi">@user</span> <span class="o">=</span> <span class="no">Factory</span><span class="o">.</span><span class="n">create</span> <span class="ss">:user</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">it</span> <span class="s2">&quot;should order the cart with one item&quot;</span> <span class="k">do</span>
</span><span class='line'>    <span class="vi">@cart</span> <span class="o">=</span> <span class="no">Factory</span><span class="o">.</span><span class="n">create</span> <span class="ss">:cart</span><span class="p">,</span> <span class="ss">:user</span> <span class="o">=&gt;</span> <span class="vi">@user</span>
</span><span class='line'>    <span class="vi">@item</span> <span class="o">=</span> <span class="no">Factory</span><span class="o">.</span><span class="n">create</span> <span class="ss">:item</span><span class="p">,</span> <span class="ss">:cart</span> <span class="o">=&gt;</span> <span class="vi">@cart</span>
</span><span class='line'>
</span><span class='line'>    <span class="vi">@user</span><span class="o">.</span><span class="n">order!</span> <span class="vi">@cart</span>
</span><span class='line'>    <span class="vi">@cart</span><span class="o">.</span><span class="n">should</span> <span class="n">be_ordered</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">it</span> <span class="s2">&quot;should discard the cart&quot;</span> <span class="k">do</span>
</span><span class='line'>    <span class="vi">@cart</span> <span class="o">=</span> <span class="no">Factory</span><span class="o">.</span><span class="n">create</span> <span class="ss">:cart</span><span class="p">,</span> <span class="ss">:user</span> <span class="o">=&gt;</span> <span class="vi">@user</span>
</span><span class='line'>    <span class="vi">@item</span> <span class="o">=</span> <span class="no">Factory</span><span class="o">.</span><span class="n">create</span> <span class="ss">:item</span><span class="p">,</span> <span class="ss">:cart</span> <span class="o">=&gt;</span> <span class="vi">@cart</span>
</span><span class='line'>
</span><span class='line'>    <span class="vi">@user</span><span class="o">.</span><span class="n">discard_cart</span>
</span><span class='line'>    <span class="vi">@cart</span><span class="o">.</span><span class="n">items</span><span class="o">.</span><span class="n">should</span> <span class="n">be_empty</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>Quite clean by itself, we create a user for each test, as expected for a
spec about the user model. Yet you can easily notice we&#8217;re building other models
in our two tests.</p>

<p>We can factorize these factories instanciation to stay DRY :</p>

<figure class='code'><figcaption><span>user_spec.rb</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">describe</span> <span class="no">User</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">before</span> <span class="ss">:each</span> <span class="k">do</span>
</span><span class='line'>    <span class="vi">@user</span>    <span class="o">=</span> <span class="no">Factory</span><span class="o">.</span><span class="n">create</span> <span class="ss">:user</span>
</span><span class='line'>    <span class="vi">@cart</span>    <span class="o">=</span> <span class="no">Factory</span><span class="o">.</span><span class="n">create</span> <span class="ss">:cart</span><span class="p">,</span> <span class="ss">:user</span> <span class="o">=&gt;</span> <span class="vi">@user</span>
</span><span class='line'>    <span class="vi">@item</span>    <span class="o">=</span> <span class="no">Factory</span><span class="o">.</span><span class="n">create</span> <span class="ss">:item</span><span class="p">,</span> <span class="ss">:cart</span> <span class="o">=&gt;</span> <span class="vi">@cart</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">it</span> <span class="s2">&quot;should order the cart with one item&quot;</span> <span class="k">do</span>
</span><span class='line'>    <span class="vi">@user</span><span class="o">.</span><span class="n">order!</span> <span class="vi">@cart</span>
</span><span class='line'>    <span class="vi">@cart</span><span class="o">.</span><span class="n">should</span> <span class="n">be_ordered</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">it</span> <span class="s2">&quot;should discard the cart&quot;</span> <span class="k">do</span>
</span><span class='line'>    <span class="vi">@user</span><span class="o">.</span><span class="n">discard_cart</span>
</span><span class='line'>    <span class="vi">@cart</span><span class="o">.</span><span class="n">items</span><span class="o">.</span><span class="n">should</span> <span class="n">be_empty</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>Now we got two tests and this example rise the following principle :</p>

<p><strong>Test code should be almost a direct translation of its name</strong></p>

<p>Any context initialization, should be done in a before block to avoid
polluting the test code itself.</p>

<h2>Enhance readability</h2>

<p>As we avoid to pollute code to enhance readability, we can also
emphasize on what&#8217;s important. It allows the reader to grasp with ease
what&#8217;s going on.</p>

<figure class='code'><figcaption><span>user_spec.rb</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">describe</span> <span class="no">User</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">before</span> <span class="ss">:each</span> <span class="k">do</span>
</span><span class='line'>    <span class="vi">@user</span>    <span class="o">=</span> <span class="no">Factory</span><span class="o">.</span><span class="n">create</span> <span class="ss">:user</span>
</span><span class='line'>    <span class="vi">@cart</span>    <span class="o">=</span> <span class="no">Factory</span><span class="o">.</span><span class="n">create</span> <span class="ss">:cart</span><span class="p">,</span> <span class="ss">:user</span> <span class="o">=&gt;</span> <span class="vi">@user</span>
</span><span class='line'>    <span class="vi">@item</span>    <span class="o">=</span> <span class="no">Factory</span><span class="o">.</span><span class="n">create</span> <span class="ss">:item</span>
</span><span class='line'>
</span><span class='line'>    <span class="vi">@cart</span><span class="o">.</span><span class="n">items</span> <span class="o">&lt;&lt;</span> <span class="vi">@item</span> <span class="c1"># focus on adding an item</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1"># ...</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>The main point of this before block is to craft a cart with an item
within. As factories are cool, it doesn&#8217;t mean we have to use their
features all the time.</p>

<p>Using the &lt;&lt; operator on line 7, on the items association
emphasize on adding our item to the cart instead of diluting it
through the factories. This line of is the most important
considering we&#8217;re testing how a user interacts with items.</p>

<p>So while writing your test code, be sure to <strong>avoid embedding your
intentions in the basic plumbing</strong>.</p>

<h2>One expectation per test please</h2>

<p>To pursue in our readability quest, you may have noticed that the
example used in the previous points was really simple. But what makes
theses so simple ? Those two tests got only one expectation at a time.</p>

<p>Consider the following code :</p>

<figure class='code'><figcaption><span>user_spec.rb</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">describe</span> <span class="no">User</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">before</span> <span class="ss">:each</span> <span class="k">do</span>
</span><span class='line'>    <span class="vi">@user</span> <span class="o">=</span> <span class="no">Factory</span><span class="o">.</span><span class="n">create</span> <span class="ss">:user</span>
</span><span class='line'>    <span class="vi">@cart</span> <span class="o">=</span> <span class="no">Factory</span><span class="o">.</span><span class="n">create</span> <span class="ss">:cart</span><span class="p">,</span> <span class="ss">:user</span> <span class="o">=&gt;</span> <span class="vi">@user</span>
</span><span class='line'>    <span class="vi">@item</span> <span class="o">=</span> <span class="no">Factory</span><span class="o">.</span><span class="n">create</span> <span class="ss">:item</span><span class="p">,</span> <span class="ss">:cart</span> <span class="o">=&gt;</span> <span class="vi">@cart</span>
</span><span class='line'>
</span><span class='line'>    <span class="vi">@order</span> <span class="o">=</span> <span class="vi">@user</span><span class="o">.</span><span class="n">order!</span> <span class="vi">@cart</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">it</span> <span class="s2">&quot;should finalize the order&quot;</span> <span class="k">do</span>
</span><span class='line'>    <span class="vi">@order</span><span class="o">.</span><span class="n">finalize!</span>
</span><span class='line'>    <span class="vi">@user</span><span class="o">.</span><span class="n">should</span> <span class="n">have</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span><span class="o">.</span><span class="n">finalized_orders</span>
</span><span class='line'>    <span class="vi">@order</span><span class="o">.</span><span class="n">should</span> <span class="n">be_finalized</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>We&#8217;ve got two <em>should</em> call there. Even if it&#8217;s just slightly more
complicated than before, you can separate concerns. We wrote <em>describe
User</em> meaning we talk about user here. We do not want to mix
expectations about orders and users.</p>

<p>Accordingly expectation on line 12 , even if being really similar to line 11 has
nothing to do here. So we can rewrite this test in two separated tests :</p>

<figure class='code'><figcaption><span>order_spec.rb</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">describe</span> <span class="no">Order</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">before</span> <span class="ss">:each</span> <span class="k">do</span>
</span><span class='line'>    <span class="vi">@cart</span>  <span class="o">=</span> <span class="no">Factory</span><span class="o">.</span><span class="n">create</span> <span class="ss">:cart</span>
</span><span class='line'>    <span class="vi">@user</span>  <span class="o">=</span> <span class="vi">@cart</span><span class="o">.</span><span class="n">user</span>
</span><span class='line'>    <span class="vi">@cart</span><span class="o">.</span><span class="n">items</span> <span class="o">&lt;&lt;</span> <span class="no">Factory</span><span class="o">.</span><span class="n">create_list</span> <span class="ss">:item</span><span class="p">,</span> <span class="mi">3</span>
</span><span class='line'>
</span><span class='line'>    <span class="vi">@order</span> <span class="o">=</span> <span class="vi">@user</span><span class="o">.</span><span class="n">order!</span> <span class="vi">@cart</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">it</span> <span class="s2">&quot;should finalize the order&quot;</span> <span class="k">do</span>
</span><span class='line'>    <span class="vi">@order</span><span class="o">.</span><span class="n">finalize</span>
</span><span class='line'>    <span class="vi">@order</span><span class="o">.</span><span class="n">should</span> <span class="n">be_finalized</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>




<figure class='code'><figcaption><span>user_spec.rb</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">describe</span> <span class="no">User</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">before</span> <span class="ss">:each</span> <span class="k">do</span>
</span><span class='line'>    <span class="vi">@user</span> <span class="o">=</span> <span class="no">Factory</span><span class="o">.</span><span class="n">create</span> <span class="ss">:user</span>
</span><span class='line'>    <span class="vi">@cart</span> <span class="o">=</span> <span class="no">Factory</span><span class="o">.</span><span class="n">create</span> <span class="ss">:cart</span><span class="p">,</span> <span class="ss">:user</span> <span class="o">=&gt;</span> <span class="vi">@user</span>
</span><span class='line'>    <span class="vi">@item</span> <span class="o">=</span> <span class="no">Factory</span><span class="o">.</span><span class="n">create</span> <span class="ss">:item</span><span class="p">,</span> <span class="ss">:cart</span> <span class="o">=&gt;</span> <span class="vi">@cart</span>
</span><span class='line'>
</span><span class='line'>    <span class="vi">@order</span> <span class="o">=</span> <span class="vi">@user</span><span class="o">.</span><span class="n">order!</span> <span class="vi">@cart</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">it</span> <span class="s2">&quot;should finalize the order&quot;</span> <span class="k">do</span>
</span><span class='line'>    <span class="vi">@order</span><span class="o">.</span><span class="n">finalize!</span>
</span><span class='line'>    <span class="vi">@user</span><span class="o">.</span><span class="n">should</span> <span class="n">have</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span><span class="o">.</span><span class="n">finalized_orders</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>Plain simple, just <strong>formulate expectations about your current subject while writing test
and ignore the rest</strong>. Why ? Because if you don&#8217;t you&#8217;re leaving the coast
of unit tests to head around integration testing land.</p>

<h2>Slice your specs with different contexts</h2>

<p>When it comes to models, there&#8217;s a lot to handle. Business logic,
mass-assignements, validation sanity.( Remember <a href="http://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model"><em>fat models for skinny controllers</em></a> eh ? It&#8217;s for a reason ! )</p>

<p>While you can argue if you should test validations and assignments or not, which is out
of the topic here, we still have to test for a wide range of business
logic cases.</p>

<p>All of these case can easily be sliced by concerns, for example a user
can be edited and can order items through a cart. An easy way to
name contexts is to use the ing form of the verb describing the action :</p>

<figure class='code'><figcaption><span>user_spec.rb</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">describe</span> <span class="no">User</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">context</span> <span class="s2">&quot;editing informations&quot;</span> <span class="k">do</span>
</span><span class='line'>    <span class="c1"># ...</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">context</span> <span class="s2">&quot;ordering items&quot;</span> <span class="k">do</span>
</span><span class='line'>    <span class="c1"># ...</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">context</span> <span class="s2">&quot;canceling cart&quot;</span> <span class="k">do</span>
</span><span class='line'>    <span class="c1"># ...</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>Writing &#8220;while editing &#8230;&#8221; or &#8220;when editing &#8230;&#8221; is a matter of taste,
while I personally tend to prefer a concise description.</p>

<p>And if we add validations and assignments ? (helpers are provided by
<a href="https://github.com/thoughtbot/shoulda-matchers">should-matchers</a>)</p>

<figure class='code'><figcaption><span>user_spec.rb </span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">describe</span> <span class="no">User</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">describe</span> <span class="s2">&quot;validations&quot;</span> <span class="k">do</span>
</span><span class='line'>    <span class="n">it</span> <span class="p">{</span> <span class="n">should</span> <span class="n">validate_presence_of</span><span class="p">(</span><span class="ss">:email</span><span class="p">)</span> <span class="p">}</span>
</span><span class='line'>    <span class="n">it</span> <span class="p">{</span> <span class="n">should</span> <span class="n">validate_presence_of</span><span class="p">(</span><span class="ss">:name</span><span class="p">)</span> <span class="p">}</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">describe</span> <span class="s2">&quot;assignments&quot;</span> <span class="k">do</span>
</span><span class='line'>    <span class="n">it</span> <span class="p">{</span> <span class="n">should</span> <span class="n">allow_mass_assignment_of</span><span class="p">(</span><span class="ss">:email</span><span class="p">)</span> <span class="p">}</span>
</span><span class='line'>    <span class="n">it</span> <span class="p">{</span> <span class="n">should</span> <span class="n">allow_mass_assignment_of</span><span class="p">(</span><span class="ss">:name</span><span class="p">)</span> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">it</span> <span class="p">{</span> <span class="n">should_not</span> <span class="n">allow_mass_assignment_of</span><span class="p">(</span><span class="ss">:administrator</span><span class="p">)</span> <span class="p">}</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">context</span> <span class="s2">&quot;editing informations&quot;</span> <span class="k">do</span>
</span><span class='line'>    <span class="c1"># ...</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">context</span> <span class="s2">&quot;ordering items&quot;</span> <span class="k">do</span>
</span><span class='line'>    <span class="c1"># ...</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">context</span> <span class="s2">&quot;canceling cart&quot;</span> <span class="k">do</span>
</span><span class='line'>    <span class="c1"># ...</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>That makes a readable skeleton for our tests.</p>

<p>The point of writing specs is to keep them enjoyable and litteraly act
as documentation for everyone. Those four advices are just basics but at
least ensure you&#8217;re heading in the right direction with your specs.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Notes on migrating to Lion]]></title>
    <link href="http://jhchabran.github.com/blog/2011/07/30/migrating-to-lion/"/>
    <updated>2011-07-30T20:30:00+02:00</updated>
    <id>http://jhchabran.github.com/blog/2011/07/30/migrating-to-lion</id>
    <content type="html"><![CDATA[<p>I bought Lion yesterday ! People have already tested it against tools I
use
for work : Homebrew, RVM, MacVim so installing it on a friday night
shouldn&#8217;t
be too painful. Plus I got backups everywhere (local server + dropbox +
github + tarsnap).</p>

<h2>What went well</h2>

<ul>
<li>Downloading it, I got a stable and fast ADSL connection ( thanks
Free.fr )</li>
<li>Installing it right after the download</li>
<li>Installing Xcode and <a href="http://mxcl.github.com/homebrew/">Homebrew</a>.</li>
</ul>


<h2>FAIL : Uninstalling MacFuse</h2>

<ul>
<li>Uninstalling <a href="http://code.google.com/p/macfuse/">MacFuse</a> after the
install. I forgot to remove it before
intalling Lion, since it&#8217;s quite unmaintained, you can guess it&#8217;s
going be boring to remove it correctly.</li>
<li>The uninstall script will fail with various errors.

<ul>
<li><a href="http://www.mail-archive.com/macfuse@googlegroups.com/msg01094.html">Mailing list thread that sum up what&#8217;s going
on</a></li>
</ul>
</li>
<li>Removing it manually, <em>but wait that&#8217;s my fault !</em> I inspected the
uninstall shell script
and decided to do some quick shell script surgery.

<ul>
<li>Looks like I messed up there. Even if I manually unplugged the Kext
before starting it, I got a weird freeze where no more application
could be launched, they were bouncing endlessly.</li>
<li>Forced reboot.</li>
<li>Lion detects a broken os and decided to re-install itself.</li>
</ul>
</li>
</ul>


<h2>FAIL : Admin privileges</h2>

<ul>
<li>Second install, Lion did not set any admin rights to my main user.
This
means :

<ul>
<li>I can&#8217;t touch anything in system preferences.</li>
<li>I can&#8217;t sudo.</li>
</ul>
</li>
<li>Fixed it by booting in single user mode and adding myself manually to
admin group :

<ul>
<li>Reboot and hold cmd+s</li>
<li>Remount your partition to have it writable

<ul>
<li><em>/sbin/fsck -fy</em></li>
<li><em>/sbin/mount -uw /</em></li>
</ul>
</li>
<li>Add myself to admin group

<ul>
<li><em>dseeditgroup -o edit -a myusername -t user admin</em></li>
</ul>
</li>
<li>Reboot</li>
</ul>
</li>
</ul>


<h2>FAIL : SSH encoding issues</h2>

<ul>
<li>SSH&#8217;ing into any box messed up completely my encoding settings.</li>
<li>Comment <em>SendEnv LANG LC_</em> * in <em>/etc/ssh_config</em> to get back to the
pre-Lion behavior.</li>
<li>Lion does not set its locale to <em>en_us.utf8</em> by default,
appending it to your <em>~/.profile</em> with <em>export LC_ALL=en_US.UTF-8</em>
corrects this issue if you want to adapt to the new
default.</li>
</ul>


<h2>FAIL : Rvm and Ruby Entreprise edition ( Ree )</h2>

<ul>
<li>Segfault !</li>
</ul>


<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>ld: warning: directory not found for option '-L/opt/local/lib'
</span><span class='line'>./ext/purelib.rb:2: [BUG] Segmentation fault
</span><span class='line'>ruby 1.8.7 (2011-02-18 patchlevel 334) [i686-darwin11.0.0],
</span><span class='line'>MBARI 0x6770, Ruby Enterprise Edition 2011.03</span></code></pre></td></tr></table></div></figure>


<p>  <a href="https://gist.github.com/1115457">fulls logs</a></p>

<ul>
<li>Fixed by using gcc instead of llvm</li>
</ul>


<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>rvm remove ree
</span><span class='line'>export CC=/usr/bin/gcc-4.2
</span><span class='line'>rvm install --force ree</span></code></pre></td></tr></table></div></figure>


<p>  <a href="http://stackoverflow.com/questions/6804195/cant-install-ruby-enterprise-edition-with-rvm-on-osx-lion">StackOverflow thread</a></p>

<h2>FAIL : Rvm and Postgresql with Homebrew</h2>

<ul>
<li>Fail to exec the <em>Postgresql</em> recipe :</li>
</ul>


<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Error: undefined method `strip' for #&lt;KegOnlyReason:0x10ac404b8&gt;</span></code></pre></td></tr></table></div></figure>


<ul>
<li>I updated and relaunched <em>brew install postgresql</em> which ran smoothly
thanks to <a href="https://github.com/mxcl/homebrew/commit/20d2edf18deefb6d6439d415625f506c662dcba2">this fix</a></li>
</ul>


<h2>FAIL : Fullscreen :</h2>

<ul>
<li>Can&#8217;t use cmd+` to alternate windows while in fullscreen, this isn&#8217;t
vital but it&#8217;s quite annoying.</li>
</ul>


<h2>Finally</h2>

<p>As I wasn&#8217;t expecting everything to work for the first time, those small
issues did not upset me and weren&#8217;t hard to fix. I laughed hard at
myself for the macfuse failed surgery where I
can only blame myself.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Code-editors or how to lock yourself]]></title>
    <link href="http://jhchabran.github.com/blog/2010/03/11/code-editors-or-how-to-lock-yourself/"/>
    <updated>2010-03-11T20:29:00+01:00</updated>
    <id>http://jhchabran.github.com/blog/2010/03/11/code-editors-or-how-to-lock-yourself</id>
    <content type="html"><![CDATA[<p>I tried every code editor out there, every IDE I could find. Six or
seven years ago, I came to the conclusion that I do prefer simple
editors to them, mostly because I prefer a sharp tool than a clumsy
thing that tries to solve every problem. Oh sure, stuff like NetBeans or
Eclipse perform really well on Java, but I don’t code with this
language, so let’s skip directly to code editors.</p>

<p>I spent something like two years with Emacs, it was great since I really
enjoy Lisp but I never really liked the way the you input the shortcuts,
making you holding Ctrl every couple of seconds to do something.
Moreover, the way you have to setup it, installing loads of libraries,
byte-compiling everything to have something still going fast was fun,
but those shitloads of stuff to install can drive you crazy when
something goes wrong with your install.</p>

<p>Vim had been my favorite code-editor for most of the time, maybe like
five years. It’s clearly an awesome piece of software and was convinced
it would be my daily companion until something better come-out. Great
plugins, blazing fast editing, tons of colorschemes (yeah I like
changing those  two or three times per week, mostly to visually break
routine).</p>

<p>And two years ago I got a MacBook, switched from daily C++ development
to Rails. Textmate always tickled me, and I finally gave it a try. I
loved it. The feeling of having something modern, clean and simple,
focusing on just what you need, providing new features like snippets,
that cmd -T shortcut to jump to any file, it was just so cool.</p>

<p>But recently, things felt wrong. I’m using it daily for two years now
and some details made me realize it’s going nowhere, which is the point
in this blog post.</p>

<p>No window splitting at all
Scripting it with your favorite language basically means writing a
script which will be called by your TM script
You can crash it just by opening any log file
Colorschemes are so damn cool nobody tries to create new ones !
But those are minor problems, except for the splitting issue which I
really miss. The main problem is :</p>

<p>Textmate 1 is abandoned.
We’re all waiting for Textmate 2 to came out. But it’s taking ages, and
sincerely like its author said, it just another Duke Nukem Forever
incarnation. I even doubt it will be released, maybe because if it’s not
perfect, its author will be flamed to oblivion by everyone, encouraging
him to continue until its perfect. Well, it may not be the case, but
currently we have no clue of a potential release date.</p>

<p>To me, Textmate is like a modern vim (ok, it’s not open-source, it
sucks, but I can accept that if the tool is really awesome, which is
almost the case). No need to look at your keyboard and asking yourself
why the fuck it’s ctrl-] to jump on a help subject, it’s just simple.
Another cool one : moving around in Vim with jk keys is really nice, but
as I still have to use arrows to browse in my cmd history, I can’t get
my fingers escaping from those arrows. For sure another shortcut must
exist to do that, there are many reasons to excuse this behavior, but
it’s still not “great”, it’s just cool.</p>

<p>You’ll probably think by reading this that I’m an unsatisfied programmer
who can’t find its editor (which is true) but the point isn’t exactly
that. I found my editor of choice. I’m raging against it because :</p>

<p>Even if they won tons of money while selling Textmate, there’s only one
developer. Come on, it’s a code editor, it’s serious business.
Communication around Textmate 2 is a nice example of worst practices.
Its author is trapped in that Babylon tower thingy, if he don’t release
it, he’ll be smashed by everyone (which is already the case)
Its author have to release something great or everyone will flame him,
write awful frustrated blog posts, Scotty will beam him up to pluto, …
Learning an editor is an investment, we all know that, and feeling stuck
because you can’t help its author to make it great, you can’t do
anything at all ’cause its closed-source.
It feels like I bet and lost.
I’m not blaming its author for its license choices, I’m okay with that,
people have to eat, but that implies Macromates have duties too. A big
one, update our fucking editor for god’s sake. Writing good stuff then
disappearing is the best fucking way to frustrate everyone. Moreover,
I’m stucked. Emacs or Vim don’t satisfy me anymore, 20 years old
software rocks for stability, but there’s some evolutions we had since
I’d like to have in my editor.</p>

<p>Conclusion: there must be a law against selling closed-source editors, I
killed thousands of kittens with the troll potential of this blog post.</p>

<p><strong>Addendum</strong></p>

<p><em>I finally threw away my never ending thirst of perfection. I&#8217;m happily
sticking to Vim
as it is and it does the job really well. Feel free to browse and fork
my <a href="https://github.com/jhchabran/vimfiles">vimrc</a></em>.j</p>
]]></content>
  </entry>
  
</feed>

