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

  <title>Jo Liss - Opinionated Programmer</title>
  <link href="https://www.solitr.com/blog/"/>
  <updated>2020-06-18T18:24:15+00:00</updated>
  <id>https://www.solitr.com/blog/</id>
  <author>
    <name><![CDATA[Jo Liss]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
    
      <entry>
        <title type="html"><![CDATA[Technical causes of today's OpenSSL vulnerabilities]]></title>
        <link href="https://www.solitr.com/blog/2015/03/openssl-vulnerability-breakdown/"/>
        <updated>2015-03-19T00:00:00+00:00</updated>
        <published>2015-03-19T00:00:00+00:00</published>
        <id>https://www.solitr.com/blog/2015/03/openssl-vulnerability-breakdown/</id>
        <content type="html"><![CDATA[<p>I like to study vulnerabilities to help me write more secure code. Here are the vulnerabilities listed in the March 19th OpenSSL advisory (<a href="https://www.openssl.org/news/secadv_20150319.txt">secadv_20150319.txt</a>), ordered by underlying cause.</p>

<h2>Segfaults, enabling DoS (maybe worse)</h2>

<p>NULL pointer dereference:</p>

<ul>
<li><em>OpenSSL 1.0.2 ClientHello sigalgs DoS (CVE-2015-0291):</em> <a href="https://github.com/openssl/openssl/commit/34e3edbf3a10953cb407288101fd56a629af22f9">34e3edb</a></li>
<li><em>Multiblock corrupted pointer (CVE-2015-0290):</em> <a href="https://github.com/openssl/openssl/commit/1d2a18dc5a3b3363e17db5af8b6b0273856ac077">1d2a18d</a></li>
<li><em>Segmentation fault for invalid PSS parameters (CVE-2015-0208):</em> <a href="https://github.com/openssl/openssl/commit/09f06923e636019c39c807cb59c481375e720556">09f0692</a></li>
<li><em>PKCS7 NULL pointer dereferences (CVE-2015-0289):</em> <a href="https://github.com/openssl/openssl/commit/c225c3cf9bd67297fb0c297768d69cbc03fbdab7">c225c3c</a></li>
<li><em>X509_to_X509_REQ NULL pointer deref (CVE-2015-0288):</em> <a href="https://github.com/openssl/openssl/commit/28a00bcd8e318da18031b2ac8778c64147cd54f9">28a00bc</a></li>
</ul>


<p>State reuse:</p>

<ul>
<li><em>Segmentation fault in DTLSv1_listen (CVE-2015-0207)</em>: <a href="https://github.com/openssl/openssl/commit/e83ee04bb7de800cdb71d522fa562e99328003a3">e83ee04</a></li>
<li><em>ASN.1 structure reuse memory corruption (CVE-2015-0287):</em> <a href="https://github.com/openssl/openssl/commit/8106d61c354430d6bbbd7f8e7840a39efc0f5829">8106d61</a></li>
</ul>


<p>Underflow:</p>

<ul>
<li><em>Base64 decode (CVE-2015-0292):</em> <a href="https://github.com/openssl/openssl/commit/d0666f289ac013094bbbf547bfbcd616199b7d2d">d0666f2</a></li>
</ul>


<p>Double free / use after free:</p>

<ul>
<li><em>Use After Free following d2i_ECPrivatekey error (CVE-2015-0209):</em> <a href="https://github.com/openssl/openssl/commit/9e442d485008046933cdc7da65080f436a4af089">9e442d4</a>, <a href="https://github.com/openssl/openssl/commit/5e5d53d341fd9a9b9cc0a58eb3690832ca7a511f">5e5d53d</a></li>
</ul>


<p>Unhandled dynamic type:</p>

<ul>
<li><em>Segmentation fault in ASN1_TYPE_cmp (CVE-2015-0286):</em> <a href="https://github.com/openssl/openssl/commit/e677e8d13595f7b3287f8feef7676feb301b0e8a">e677e8d</a></li>
</ul>


<p>Unclear:</p>

<ul>
<li><em>Empty CKE with client auth and DHE (CVE-2015-1787):</em> <a href="https://github.com/openssl/openssl/commit/d3cc5e610d1719a35cda52c9152134b490a8c944">d3cc5e6</a></li>
</ul>


<h2>Failed assert, enabling DoS</h2>

<ul>
<li><em>DoS via reachable assert in SSLv2 servers (CVE-2015-0293):</em> <a href="https://github.com/openssl/openssl/commit/86f8fb0e344d62454f8daf3e15236b2b59210756">86f8fb0</a></li>
</ul>


<h2>Cryptographic vulnerabilities, enabling MITM</h2>

<p>Cipher downgrade:</p>

<ul>
<li><em>Reclassified: RSA silently downgrades to EXPORT_RSA [Client] (CVE-2015-0204)</em>: <a href="https://github.com/openssl/openssl/commit/ce325c60c74b0fa784f5872404b722e120e5cab0">ce325c6</a></li>
</ul>


<p>Bad randomness:</p>

<ul>
<li><em>Handshake with unseeded PRNG (CVE-2015-0285):</em> <a href="https://github.com/openssl/openssl/commit/e1b568dd2462f7cacf98f3d117936c34e2849a6b">e1b568d</a></li>
</ul>

]]></content>
      </entry>
    
  
    
      <entry>
        <title type="html"><![CDATA[What's Next for Me (As of April 2014)]]></title>
        <link href="https://www.solitr.com/blog/2014/04/whats-next/"/>
        <updated>2014-04-08T00:00:00+00:00</updated>
        <published>2014-04-08T00:00:00+00:00</published>
        <id>https://www.solitr.com/blog/2014/04/whats-next/</id>
        <content type="html"><![CDATA[<p>On a personal note, I just wanted to update everyone on what I&#8217;ve been up to:</p>

<h2>Open Source</h2>

<p>The past four months have been dedicated to working full time on
<a href="https://github.com/joliss/broccoli">Broccoli</a> (<a href="https://www.solitr.com/blog/2014/02/broccoli-first-release/">blog
post</a>), thanks to
some savings from my previous consulting gigs, combined with moderate living
expenses.</p>

<p>In retrospect, taking time off to write Broccoli was clearly worth it. I went
one month over my original budget of three months, but people&#8217;s enthusiastic
reactions at EmberConf have convinced me that I solved a worthwhile problem,
and that writing Broccoli will pay off in productivity increases across the
community. Personally, having Broccoli will help me with the upcoming work on
my business, and writing it has helped me become a better developer.</p>

<p>Starting a week from now, I will scale my open-source work back to part time,
to about 1–2 hours per day. There is still work to be done on Broccoli as well
as related projects like ember-cli, but it doesn&#8217;t require full-time
commitment from me anymore.</p>

<p>Building better community is another thing I&#8217;m planning to dedicate some time
to. I will blog about this soon.</p>

<p>My vague expectation is that in a year or so, I will find another worthwhile
problem to solve, and take some time off in a similar fashion. In the
meantime, it is time for me to work on my business.</p>

<h2>Business: Solitr</h2>

<h3>SEO</h3>

<p><a href="https://www.solitr.com/">Solitr</a> started off as a weekend project, but then I
noticed it started getting actual traffic. I knew that the highest-ranked site
for &#8220;solitaire&#8221; gets <a href="http://cosmicrealms.com/blog/2011/10/30/time-analysis-by-server/">over 100k daily
visits</a>, so
I figured that with ad-monetization alone, there&#8217;s probably a business there.</p>

<p>Since then, traffic to Solitr has risen to 4000 daily visits (mostly through
ranking for niche keywords), even though I haven&#8217;t been able to work much on
it so far. Some testing with AdSense indicates that I can start paying the
rent with it. That&#8217;s not much, but it feels quite liberating. It also makes me
confident that once the search ranking improves, I can have a viable business.</p>

<p>My plan is to hit 100k daily visitors by the end of 2015. Getting there will
require some SEO work, both on the main keyword (&#8220;solitaire&#8221;) and long tail
for niche keywords and i18n.</p>

<h3>A/B Testing</h3>

<p>I also want to learn A/B testing, in parallel to the SEO work. A/B testing
requires many data points to yield statistically significant results. Running
a free-to-play game presents a unique opportunity to get my hands dirty, as I
get a ludicrous number of data points very early in my business &#8211; the kind of
data that with a SaaS business you would only get at significant scale.</p>

<p>My role model for this is <a href="http://www.kalzumeus.com/blog/">Patrick McKenzie</a>
&#8211; my Solitr is approximately equivalent to his Bingo Card Creator &#8211; and his
extensive blogging has been of immeasurable value to me. I hope to pay it
forward by being open about Solitr and blogging about my adventures with A/B
testing in a similar vein.</p>

<p>I view the A/B testing work mostly as paid-for education. Perhaps I can
monetize it a bit by selling boutique consulting like Patrick. But more
importantly, I&#8217;ll have a valuable tool for scaling businesses in my
professional skill set. If I start a business in the future (say a B2B SaaS)
and it gets traction, I&#8217;m hoping that data-driven tools like A/B testing will
allow me to scale it and realize returns much faster than I&#8217;d be able to
otherwise.</p>

<p>That&#8217;s all for now. See you all soon, on Twitter and GitHub!</p>
]]></content>
      </entry>
    
  
    
      <entry>
        <title type="html"><![CDATA[Broccoli: First Beta Release]]></title>
        <link href="https://www.solitr.com/blog/2014/02/broccoli-first-release/"/>
        <updated>2014-02-17T00:00:00+00:00</updated>
        <published>2014-02-17T00:00:00+00:00</published>
        <id>https://www.solitr.com/blog/2014/02/broccoli-first-release/</id>
        <content type="html"><![CDATA[<p><a href="https://github.com/joliss/broccoli">Broccoli</a> is a new build tool. It&#8217;s
comparable to the Rails asset pipeline in scope, though it runs on Node and is
backend-agnostic.</p>

<p>After a long slew of 0.0.x alpha releases, I just pushed out the first beta
version, Broccoli 0.1.0.</p>

<p><strong>Update March 2015:</strong> This post is still up-to-date with regard to
architectural considerations, but the syntax used in the examples is
outdated.</p>

<p>Table of Contents:</p>

<ol>
<li>Quick Example</li>
<li>Motivation / Features</li>
<li>Architecture</li>
<li>Background / Larger Vision</li>
<li>Comparison With Other Build Tools</li>
<li>What&#8217;s Next</li>
</ol>


<h2>1. Quick Example</h2>

<p>Here is a sample build definition file (<code>Brocfile.js</code>), presented without
commentary just to illustrate the syntax:</p>

<figure class='code'><figcaption><span>Brocfile.js</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>
</pre></td><td class='code'><pre><code class='js'><span class='line'><span class="nx">module</span><span class="p">.</span><span class="nx">exports</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">broccoli</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="kd">var</span> <span class="nx">filterCoffeeScript</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;broccoli-coffee&#39;</span><span class="p">);</span>
</span><span class='line'>  <span class="kd">var</span> <span class="nx">compileES6</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;broccoli-es6-concatenator&#39;</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>  <span class="kd">var</span> <span class="nx">sourceTree</span> <span class="o">=</span> <span class="nx">broccoli</span><span class="p">.</span><span class="nx">makeTree</span><span class="p">(</span><span class="s1">&#39;lib&#39;</span><span class="p">);</span>
</span><span class='line'>  <span class="nx">sourceTree</span> <span class="o">=</span> <span class="nx">filterCoffeeScript</span><span class="p">(</span><span class="nx">sourceTree</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>  <span class="kd">var</span> <span class="nx">appJs</span> <span class="o">=</span> <span class="nx">compileES6</span><span class="p">(</span><span class="nx">sourceTree</span><span class="p">,</span> <span class="p">{</span>
</span><span class='line'>    <span class="p">...</span>
</span><span class='line'>    <span class="nx">outputFile</span><span class="o">:</span> <span class="s1">&#39;/assets/app.js&#39;</span>
</span><span class='line'>  <span class="p">});</span>
</span><span class='line'>
</span><span class='line'>  <span class="kd">var</span> <span class="nx">publicFiles</span> <span class="o">=</span> <span class="nx">broccoli</span><span class="p">.</span><span class="nx">makeTree</span><span class="p">(</span><span class="s1">&#39;public&#39;</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">return</span> <span class="p">[</span><span class="nx">appJs</span><span class="p">,</span> <span class="nx">publicFiles</span><span class="p">];</span>
</span><span class='line'><span class="p">};</span>
</span></code></pre></td></tr></table></div></figure>


<p>Run <code>broccoli serve</code> to watch the source files and continuously serve the
build output on localhost. Broccoli is optimized to make <code>broccoli serve</code> as
fast as possible, so you should never experience rebuild pauses.</p>

<p>Run <code>broccoli build dist</code> to run a one-off build and place the build output in
the <code>dist</code> directory.</p>

<p>For a longer example, see the
<a href="https://github.com/joliss/broccoli-sample-app">broccoli-sample-app</a>.</p>

<h2>2. Motivation / Features</h2>

<h3>2.1. Fast Rebuilds</h3>

<p>The most important concern when designing Broccoli was enabling fast
incremental rebuilds. Here&#8217;s why:</p>

<p>Let&#8217;s say you&#8217;re using Grunt to build an application written with
CoffeeScript, Sass, and a few more such compilers. As you develop, you want to
edit files and reload the browser, without having to manually rebuild each
time. So you use <code>grunt watch</code>, to rebuild automatically. But as your
application grows, the build gets slower. Within a few months of development
time, your edit-reload cycle has turned into an edit-<em>wait-10-seconds</em>-reload
cycle.</p>

<p>So to speed up your build, you try rebuilding only the files that have
changed. This is difficult, because sometimes one output file depends on
multiple input files. You manually configure some dependency rules, to rebuild
the right files depending on which files were modified. But Grunt was never
designed to do this well, and your custom rule set won&#8217;t reliably rebuild the
right files. Sometimes it rebuilds files when it doesn&#8217;t have to (making your
build slow). Worse, sometimes it doesn&#8217;t rebuild files when it should (making
your build unreliable).</p>

<p>With Broccoli, once you fire up <code>broccoli serve</code>, it will figure out by itself
which files to watch, and only rebuild those that need rebuilding.</p>

<p>In effect, this means that rebuilds tend to be O(1) constant-time with the
number of files in your application, as you generally only rebuild one file.
I&#8217;m aiming for under 200 ms per rebuild with a typical build stack, since that
type of delay feels near-instantaneous to the human brain, though anything up
to half a second is acceptable in my book.</p>

<h3>2.2. Chainable Plugins</h3>

<p>Another concern was making plugins composable. Let me show you how easy it
is to compile CoffeeScript and then minify the output with Broccoli.</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>
</pre></td><td class='code'><pre><code class='js'><span class='line'><span class="kd">var</span> <span class="nx">tree</span> <span class="o">=</span> <span class="nx">broccoli</span><span class="p">.</span><span class="nx">makeTree</span><span class="p">(</span><span class="s1">&#39;lib&#39;</span><span class="p">)</span>
</span><span class='line'><span class="nx">tree</span> <span class="o">=</span> <span class="nx">compileCoffeeScript</span><span class="p">(</span><span class="nx">tree</span><span class="p">)</span>
</span><span class='line'><span class="nx">tree</span> <span class="o">=</span> <span class="nx">uglifyJS</span><span class="p">(</span><span class="nx">tree</span><span class="p">)</span>
</span><span class='line'><span class="k">return</span> <span class="nx">tree</span>
</span></code></pre></td></tr></table></div></figure>


<p>With Grunt, we&#8217;d have to create a temporary directory to store the
CoffeeScript output, as well as an output directory. As a result of all this
bookkeeping, Gruntfiles tend to grow rather lengthy. With Broccoli, all this
is handled automatically.</p>

<h2>3. Architecture</h2>

<p>For those who are curious, let me tell you about Broccoli&#8217;s architecture.</p>

<h3>3.1. Trees, Not Files</h3>

<p>Broccoli&#8217;s unit of abstraction to describe sources and build products is not a
file, but rather a tree &#8211; that is, a directory with files and subdirectories.
So it&#8217;s not <em>file-goes-in-file-goes-out</em>, it&#8217;s <em>tree-goes-in-tree-goes-out</em>.</p>

<p>If we designed Broccoli around individual files, we&#8217;d be able to compile
CoffeeScript just fine (as it compiles 1 input file into 1 output file), but
the API would be unnatural for compilers like Sass (which needs to read more
files as it encounters <code>@import</code> statements, and thus compiles <em>n</em> input files
into 1 output file).</p>

<p>On the other hand, with Broccoli&#8217;s design around trees, <em>n</em>:1 compilers like
Sass are no problem, while 1:1 compilers like CoffeeScript are an easily
expressible sub-case. In fact, we have a <code>Filter</code> base class for such 1:1
compilers to make them very easy to implement.</p>

<h3>3.2. Plugins Just Return New Trees</h3>

<p>This one is slightly more subtle: At first, I had designed Broccoli with two
primitives: a &#8220;tree&#8221;, which represents a directory with files, and a chainable
&#8220;transform&#8221;, which takes an input tree and returns a new compiled tree.</p>

<p>This implies that transforms map trees 1:1. Surprisingly, this is not a good
abstraction for all compilers. For instance, the Sass compiler has a notion of
&#8220;load paths&#8221; that it searches when it encounters an <code>@import</code> directive.
Similarly, JavaScript concatenators like r.js have a &#8220;paths&#8221; option to search
for imported modules. These load paths are ideally represented as a set of
&#8220;tree&#8221; objects.</p>

<p>As you can see, many real-world compilers actually map <em>n</em> trees into 1 tree.
The easiest way to support this is to let plugins deal with their input trees
themselves, thereby allowing them to take 0, 1, or <em>n</em> input trees.</p>

<p>But now that we let plugins handle their input trees, we don&#8217;t need to know
about compilers as first-class objects in Broccoli land anymore. Plugins
simply export functions that take zero or more input trees (and perhaps some
options), and return an object representing a new tree. For instance:</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>
</pre></td><td class='code'><pre><code class='js'><span class='line'><span class="nx">broccoli</span><span class="p">.</span><span class="nx">makeTree</span><span class="p">(</span><span class="s1">&#39;lib&#39;</span><span class="p">)</span> <span class="c1">// =&gt; a tree</span>
</span><span class='line'><span class="nx">compileCoffeeScript</span><span class="p">(</span><span class="nx">tree</span><span class="p">)</span> <span class="c1">// =&gt; a tree</span>
</span><span class='line'><span class="nx">compileSass</span><span class="p">(</span><span class="nx">tree</span><span class="p">,</span> <span class="p">{</span>
</span><span class='line'>  <span class="nx">loadPaths</span><span class="o">:</span> <span class="p">[</span><span class="nx">moreTrees</span><span class="p">,</span> <span class="p">...]</span>
</span><span class='line'><span class="p">})</span> <span class="c1">// =&gt; a tree</span>
</span></code></pre></td></tr></table></div></figure>


<h3>3.3. The File System Is The API</h3>

<p>Remember that because Grunt doesn&#8217;t support chaining of plugins, we end up
having to manage temporary directories for intermediate build products in our
Grunt configurations, making them overly verbose and hard to maintain.</p>

<p>To avoid all this, our first intuition might be to abstract the file system
away into an in-memory API, representing trees as collections of streams. Gulp
for instance does this. I tried this in an early version of Broccoli, but it
turns out to make the code quite complicated: With streams, plugins now have
to worry about race conditions and deadlocks. Also, in addition to having a
notion of streams and paths, we need file attributes like last-modified time
and size in our API. And if we ever need the ability to re-read a file, or
seek, or memory-map, or if we need to pass an input tree to another process
we&#8217;re shelling out to, the stream API fails us and we have to write out the
entire tree to the file system first. So much complexity!</p>

<p>But wait. If we&#8217;re going to replicate just about every feature of the file
system, and in some cases we have to fall back to turning our in-memory
representation into an actual tree on the file system and back again, then &#8230;
why don&#8217;t we use the actual file system instead?</p>

<p>Node&#8217;s <code>fs</code> module already provides as compact an API to the file system as we
could wish for.</p>

<p>The only disadvantage is that we have to manage temporary directories behind
the scenes, and clean them up. But that&#8217;s easy to do in practice.</p>

<p>People sometimes worry that writing to disk is slower. But even if you hit the
actual disk drive (which thanks to paging is rare), the bandwidth of modern
SSDs has become so high compared to CPU speed that the overhead tends to be
negligible.</p>

<h3>3.4. Caching, Not Partial Rebuilding</h3>

<p>When I originally tried to solve the problem of incremental rebuilds, I tried
to devise a way to check whether each existing output file is stale, so that
Broccoli could trigger the rebuild for a subset of its input files. But this
&#8220;partial rebuild&#8221; approach requires that we are able to trace which files an
output file depends on, all the way back to the source files, and it also
makes file deletion tricky. &#8220;Partial rebuilds&#8221; is the classical approach of
Make, as well as the Rails asset pipeline, Rake::Pipeline, and Brunch, but
I&#8217;ve come to believe that it&#8217;s unnecessarily complicated.</p>

<p>Broccoli&#8217;s approach is much simpler: Ask each plugin to cache its build output
as appropriate. When we rebuild, start with a blank slate, and re-run the
entire build process. Plugins will be able to provide most of their output
from their caches, which takes near-zero time.</p>

<p>Broccoli started off providing some caching primitives, but it turned out
unnecessary to have this in the core API. Now we just make sure that the
general architecture doesn&#8217;t stand in the way of caching.</p>

<p>For plugins that map files 1:1, like the CoffeeScript compiler, we can
use common caching code (provided by the
<a href="https://github.com/joliss/broccoli-filter">broccoli-filter</a> package), leaving
the plugin code looking
<a href="https://github.com/joliss/broccoli-coffee/blob/af08e5d0284c12eb4eb16c23f05a1333d5043594/index.js">very simple</a>.
Plugins that map files <em>n</em>:1, like Sass, need to be more careful about
invalidating their caches, so they need to provide custom caching logic. I
assume that we&#8217;ll still be able to extract some common caching logic in the
future.</p>

<h3>3.5. No Parallelism</h3>

<p>If we all suffer from slow builds, should we try to parallelize builds,
compiling multiple files in parallel?</p>

<p>My answer is <em>no</em>: The reason is that parallelism makes it possible to have
race conditions in plugins, which you might not notice until deploy time.
These are the worst kinds of bugs, and avoiding parallel execution eliminates
this entire class of bugs.</p>

<p>On the other hand, <a href="https://en.wikipedia.org/wiki/Amdahl's_law">Amdahl&#8217;s law</a>
stops us from gaining much performance through parallelizing. For a simplified
example, say our build process takes 16 seconds in total. Let&#8217;s say 50% of it
can be parallelized, and the rest needs to run in sequence (e.g.
CoffeeScript-then-concatenate-then-UglifyJS). If we run this on a 4-core
machine, the build would take 8 seconds for the sequential part plus 8 / 4 = 2
seconds for the parallel part, still totaling 10 seconds, less than a 40%
performance gain.</p>

<p>For incremental rebuilds, which constitute the hot path that we <em>really</em> care
about, caching tends to eliminate most of the parallelizable parts of the
build process anyway, so we are left with little to no performance gain.</p>

<p>Because of that, in general I believe that parallelizing the build process is
not a good trade. In principle you could write a Broccoli plugin that performs
some work in a parallel fashion. However, Broccoli&#8217;s primitives, as well as
the helper code that I&#8217;ve published on GitHub, actively encourage
deterministic sequential code patterns.</p>

<h2>4. Background / Larger Vision</h2>

<p>There are two main motivators that made me tackle writing a good build tool.</p>

<p>The first motivator is better productivity, through fast incremental rebuilds.</p>

<p>I generally believe that developer productivity is largely determined by the
quality of the libraries and tools we use. The &#8220;edit file, reload browser&#8221;
cycle that we perform hundreds of times a day is probably the core feedback
loop when we program. A great way to improve our tooling is getting this
edit-reload feedback loop to be as fast as humanly possible.</p>

<p>The second motivator is encouraging an ecosystem of front-end packages.</p>

<p>I believe that Bower and the ES6 module system will help us build a great
ecosystem, but Bower by itself is useless unless you have a build tool running
on top. This is because Bower is a content-agnostic transport tool that only
dumps all your dependencies (and their dependencies, recursively) into the
file system—it&#8217;s up to you what to do with them. Broccoli aims to become the
missing build tool sitting on top.</p>

<p>Note that Broccoli itself is angnostic about Bower or ES6 modules—you can use
it for whatever you like. (I am aware there are other stacks, like npm +
browserify, or npm + r.js.) I will discuss all of this in more detail in a
future blog post.</p>

<h2>5. Comparison With Other Build Tools</h2>

<p>If you are almost convinced but also wondering how other build tools stack up
against Broccoli, let me tell you why I wrote Broccoli instead of using any of
the following:</p>

<p><strong>Grunt</strong> is a task runner, and it never set out to be a build tool. If you
try to (ab)use it as a build tool, you quickly find that because it doesn&#8217;t
attempt to handle chaining (composition), you end up having to manage
temporary directories for intermediate build products yourself, adding a lot
of complexity to your Grunt configuration. It also does not support reliable
incremental rebuilds, so your rebuilds will tend to be slow and/or unreliable;
see section &#8220;Fast Rebuilds&#8221; above.</p>

<p>That said, Grunt&#8217;s utility as a task runner is in providing a cross-platform
way to run shell-script type functionality, such as deploying your app or
generating scaffolding. Broccoli will be able to act as a Grunt plugin in the
future, so that you can call it from your Gruntfile.</p>

<p><strong>Gulp</strong> tries to solve the problem of chaining plugins,
but in my view it gets the architecture wrong: Rather than passing around
trees, it passes around sequences (= event streams) of files (= streams or
buffers).
This works fine for cases where one input file maps into one output
file. But when a plugin needs to follow <code>import</code> statements, and thus needs to
access input files out of order, things get complicated.
For now, plugins that follow <code>import</code> statements tend to just just bypass the
build tool and read <a href="https://github.com/plus3network/gulp-less/blob/7d5ca85033d902d19ddb73929c00720d8fe7fc30/index.js#L32-L33">directly from the
file system</a>.
In the future, I hear that there will be helper libraries to turn all the
streams into a (virtual) file system and pass that to the compiler. I would
claim though that all this complexity is a symptom of an impedance mismatch
between the build tool and the compiler. See &#8220;Trees, Not Files&#8221; above for more
on this. I&#8217;m also not convinced that abstracting away files behind a stream or
buffer API is helpful at all; see &#8220;The File System Is The API&#8221; above.</p>

<p><strong>Brunch</strong>, like Gulp, uses a file-based (not tree-based) in-memory API (see
<a href="https://github.com/brunch/sass-brunch/blob/ddd1b8f23ff180cd4fd391e6d49ca6b3b3ff8e1e/index.js#L147">this method
signature</a>).
Like with Gulp, plugins end up falling back to <a href="https://github.com/brunch/sass-brunch/blob/ddd1b8f23ff180cd4fd391e6d49ca6b3b3ff8e1e/index.js#L105-L106">bypassing the build
tool</a>
when they need to read more than one file.
Brunch also tries to do partial rebuilding rather than caching; see section
&#8220;Caching, Not Partial Rebuilding&#8221; above.</p>

<p><strong>Rake::Pipeline</strong> is written in Ruby, which is less ubiquitous than Node in
front-end land. It tries to do partial rebuilds as well. Yehuda says it&#8217;s not
heavily maintained anymore, and that he&#8217;s betting on Broccoli.</p>

<p>The <strong>Rails asset pipeline</strong> uses partial rebuilds as well, and uses very
different code paths for development mode and production (precompilation)
mode, causing people to have unexpected issues when they deploy. More
importantly it&#8217;s tied to Rails as a backend.</p>

<h2>6. What&#8217;s Next</h2>

<p>The <a href="https://github.com/joliss/broccoli#plugins">list of plugins</a> is still
small. If they are enough for you, I cautiously recommend giving Broccoli a
try right now: <a href="https://github.com/joliss/broccoli#installation">https://github.com/joliss/broccoli#installation</a></p>

<p>I would like to see other people get involved in writing plugins. Wrapping
compilers is easy, but the hard and important part is getting caching and
performance right. We&#8217;ll also want to work on generalizing more caching
patterns in addition to
<a href="https://github.com/joliss/broccoli-filter">broccoli-filter</a>, so that plugins
don&#8217;t suffer from excessive boilerplate.</p>

<p>Over the next week or two, my plan is to improve the documentation and clean
up the code base of Broccoli core and the plugins. We will also have to add a
test suite to Broccoli core, and figure out an elegant way to integration-test
Broccoli plugins against Broccoli core.
Another thing that&#8217;s missing with the existing plugins is source map support.
This is slightly complicated by performance considerations, as well as the
fact that chained plugins need to consume other plugins&#8217; source maps and
interoperate properly, so I haven&#8217;t found the time to tackle this yet.</p>

<p>Broccoli will see active use in the Ember ecosystem, powering the default
stack emitted by <a href="https://github.com/stefanpenner/ember-cli">ember-cli</a> (an
upcoming tool similar in functionality to the <code>rails</code> command). We are also
hoping to move the build process used for generating the Ember core and
ember-data distributions from Rake::Pipeline and Grunt to Broccoli.</p>

<p>That said, I would love to see Broccoli adopted outside the Ember community as
well. JS MVC applications written with frameworks like Angular or Backbone, as
well as JavaScript and CSS libraries that require build steps, are all prime
candidates for being built by Broccoli.</p>

<p>I don&#8217;t currently see any major roadblocks on the path to Broccoli becoming
stable. By using it for real-world build scenarios, we should gain confidence
in its API, and I&#8217;m hoping that we can bump the version to 1.0.0 within a few
months&#8217; time.</p>

<p>This blog post is the first comprehensive explanation of Broccoli&#8217;s
architecture, and the documentation is still somewhat sparse. I&#8217;m happy to
help you get started, and fix any bugs you encounter. Come find me on
#broccolijs on Freenode, or at
<a href="mailto:joliss42@gmail.com">joliss42@gmail.com</a> on Google Talk. I&#8217;ll also
respond to any issues you post on GitHub.</p>

<p><em>Thanks to Jonas Nicklas, Josef Brandl, Paul Miller, Erik Bryn, Yehuda Katz,
Jeff Felchner, Chris Willard, Joe Fiorini, Luke Melia, Andrew Davey, and Alex
Matchneer for reading and critiquing drafts of this post.</em></p>

<p><a href="https://twitter.com/jo_liss/status/435436442332839936"><em>Discuss on Twitter</em></a></p>
]]></content>
      </entry>
    
  
    
      <entry>
        <title type="html"><![CDATA[The State of Libsass (versus Ruby Sass)]]></title>
        <link href="https://www.solitr.com/blog/2014/01/state-of-libsass/"/>
        <updated>2014-01-29T00:00:00+00:00</updated>
        <published>2014-01-29T00:00:00+00:00</published>
        <id>https://www.solitr.com/blog/2014/01/state-of-libsass/</id>
        <content type="html"><![CDATA[<p><a href="https://github.com/hcatlin/libsass">Libsass</a> is a C++ re-implementation of
the Ruby-based Sass compiler. It&#8217;s an <a href="https://www.solitr.com/blog/2014/01/css-preprocessor-benchmark/">order of
magnitude</a>
faster than Ruby Sass, but hasn&#8217;t seen as much adoption yet.</p>

<p>I recently asked <a href="https://twitter.com/akhleung">Aaron Leung</a>, the current
maintainer, about the state of libsass. He kindly agreed to let me publish his
response, rendered below. Shout-out to his employer
<a href="http://www.moovweb.com/aboutus/careers/">Moovweb</a>, who, Aaron lets me know,
have been paying him to work on libsass.</p>

<blockquote><p>Hi Jo,</p><p>I appreciate your interest in LibSass! It&#8217;s been very stable &#8211; the company I work for uses it internally in our SDK and build server, and it&#8217;s been running fine. Unfortunately, in terms of features, it hasn&#8217;t fully caught up with the Ruby implementation yet. The biggest deficiency right now is that @extend isn&#8217;t fully functional &#8211; LibSass works correctly for more basic uses of @extend, but a full implementation is still 2-3 months out (it&#8217;s a very complex feature).</p><p>Off the top of my head, other incompatibilities include:<br/>* no 3.3 features yet<br/>* full UTF-8 support is in the works (hopefully will be done in a week or two)<br/>* @media blocks are following the scoping rules of pre-3.2 Sass<br/>* limited support for the new CSS filter functions<br/>* not properly handling namespaced selectors</p><p>In addition to those, there are miscellaneous little bugs that cause LibSass to generate incorrect output, mostly in obscure edge-casey stuff. However, thanks to a recent spike in community interest, I&#8217;ve been working harder to get all these things sorted out, and my employer is also interested in seeing LibSass become every bit as good as the Ruby version. Thanks to all that, as well as taking a closer look at the Ruby code, I&#8217;m hoping to get completely caught up with the Ruby version by mid-summer.</p><p>Hope this helps, and let me know if you have any more questions!</p><p>Aaron</p></blockquote>


<p>He adds:</p>

<blockquote><p>I should also let you know that we&#8217;re working on a more detailed feature/compatibility grid. More generally, we&#8217;re trying to be better about staying in touch with the community this year (via blog posts, talks at conferences & meetups, etc), so I&#8217;ll try to keep you apprised of any LibSass progress.</p></blockquote>


<p>P.S. Keep in mind that the &#8220;mid-summer 2014&#8221; estimate above was given in
private email to me, and is not an official commitment on anyone&#8217;s part. ;-)</p>

<p><a href="https://twitter.com/jo_liss/status/428602506545881088"><em>Discuss on Twitter</em></a></p>
]]></content>
      </entry>
    
  
    
      <entry>
        <title type="html"><![CDATA[CSS Preprocessor Benchmark]]></title>
        <link href="https://www.solitr.com/blog/2014/01/css-preprocessor-benchmark/"/>
        <updated>2014-01-27T00:00:00+00:00</updated>
        <published>2014-01-27T00:00:00+00:00</published>
        <id>https://www.solitr.com/blog/2014/01/css-preprocessor-benchmark/</id>
        <content type="html"><![CDATA[<h2>Results</h2>

<p>The timings for processing a 200 KB file of plain CSS (lower is better):</p>

<ul>
<li><a href="https://github.com/nex3/sass">Sass</a>: 4.9 sec</li>
<li>Sass: 2.5 sec (with warm <code>.sass-cache</code>)</li>
<li><a href="https://github.com/hcatlin/libsass">libsass</a>: 0.2 sec</li>
<li><a href="https://github.com/learnboost/stylus">Stylus</a>: 1.7 sec</li>
<li><a href="https://github.com/reworkcss/rework">Rework</a>: 0.2 sec</li>
<li><a href="https://github.com/less/less.js">LESS</a>: 0.5 sec</li>
<li><a href="https://github.com/jrburke/r.js">r.js</a>: 0.2 sec</li>
</ul>


<p>Libsass (a C++ implementation of Sass) and Rework turn out to be extremely
fast.</p>

<h2>Background</h2>

<p>The speed of your CSS preprocessor is important for developer/designer
ergonomics. The preprocessing time measured by this benchmark will typically
incur as a delay every time you edit the stylesheet sources and hit <em>reload</em>
in the browser. Delays below 0.2 to 0.5 seconds tend to be perceived by
the human brain as near-instantaneous. The higher the delay, the higher the
mental overhead.</p>

<p>To see how fast preprocessors are, I recently ran an informal benchmark of CSS
preprocessors. The benchmark garnered a lot of
<a href="https://twitter.com/jo_liss/status/427448839063089152">interest</a>, so I&#8217;m
posting this write-up in blog form.</p>

<h2>Methods</h2>

<p>I chose 200 KB of minified ungzipped CSS to simulate a large-ish web
application, because that&#8217;s approximately the amount that the Yahoo homepage
uses.</p>

<p>The file contents were artificially simple:</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>
</pre></td><td class='code'><pre><code class='css'><span class='line'><span class="nc">.x0</span><span class="p">{</span><span class="k">color</span><span class="o">:</span><span class="nb">green</span><span class="p">;}</span>
</span><span class='line'><span class="nc">.x1</span><span class="p">{</span><span class="k">color</span><span class="o">:</span><span class="nb">green</span><span class="p">;}</span>
</span><span class='line'><span class="o">...</span>
</span><span class='line'><span class="nc">.x9999</span><span class="p">{</span><span class="k">color</span><span class="o">:</span><span class="nb">green</span><span class="p">;}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Benchmark script: <a href="https://gist.github.com/joliss/8641182">css-preprocessor-benchmark.sh</a></p>

<p>I used Ruby 2.1.0p0, Node 0.10.24, and the master branches of each library
(Sass 767c53f, libsass 991bc26, Stylus f539ef0, Rework c60edd3, less.js
281a895, r.js 84f325c).</p>

<h2>Discussion</h2>

<p>Libsass, Rework, LESS, and r.js came in below the 0.5 second threshold.</p>

<h3>Ruby Sass and libsass</h3>

<p>Libsass, a re-implementation of Sass in C++, provides a massive (>10x) speed
improvement over the original Sass written in Ruby, dropping processing time
from 2.5 seconds to 0.2 seconds. It is not quite a drop-in replacement for
Sass yet, but it&#8217;s getting a lot of development love from <a href="https://twitter.com/akhleung">Aaron
Leung</a>. It might be worth considering for new
applications.</p>

<p>People&#8217;s biggest worry about libsass seems to be losing the Ruby-based
<a href="https://github.com/chriseppstein/compass">Compass</a>. Perhaps there will be an
alternative/re-implementation of Compass that is not Ruby-based. But even
without that, we might think about whether the massive speed increase of
libsass might justify going without Compass completely.</p>

<p>Given the speed difference, I&#8217;d like to suggest that the move from Ruby Sass
to libsass is inevitable, and I hope that it will see copious contributions
from the community to bring it up to par.</p>

<p><em>Update:</em> Read Aaron&#8217;s notes on the <a href="https://www.solitr.com/blog/2014/01/state-of-libsass/">state of libsass</a>.</p>

<h3>Others</h3>

<p>A surprising contender is the newer Rework coming in at only 0.2 seconds,
written in JavaScript but nearly as fast as libsass. LESS.js also did fairly
well at 0.5 seconds, while the third JavaScript-based preprocessor, Stylus,
fell on the slow side with 1.7 seconds. Perhaps it can be improved though.</p>

<p>I also included r.js, which was the fastest of all. While it&#8217;s not strictly a
preprocessor, it can inline <code>@import</code> statements, and so it can be used to
concatenate your project&#8217;s plain CSS files (if you are the minimalist type).</p>

<p><a href="https://twitter.com/jo_liss/status/427811467480424449"><em>Discuss on Twitter</em></a></p>
]]></content>
      </entry>
    
  
    
      <entry>
        <title type="html"><![CDATA[Ember.js: Implementing text fields with save buttons]]></title>
        <link href="https://www.solitr.com/blog/2012/06/ember-input-field-with-save-button/"/>
        <updated>2012-06-11T00:00:00+00:00</updated>
        <published>2012-06-11T00:00:00+00:00</published>
        <id>https://www.solitr.com/blog/2012/06/ember-input-field-with-save-button/</id>
        <content type="html"><![CDATA[<p><em>[Note: This post uses Ember master syntax. On 0.9.8.1, you may have to remove
<code>view.</code> in the *Binding attributes.]</em></p>

<h2>Live Updating</h2>

<p><a href="http://docs.emberjs.com/symbols/Ember.TextField.html">Ember.TextField</a> and
friends live-update their <code>value</code> property as the user enters text. You can use
<code>valueBinding</code> to bind to some model property, like so:</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'>{{view Ember.TextField valueBinding="firstName"}}</span></code></pre></td></tr></table></div></figure>


<p>Now <code>firstName</code> will be updated immediately as the user enters text.</p>

<h2>With Save button</h2>

<p>Oftentimes, live updating is not what you want. Instead, you want to update the
model data only when the user clicks a <em>Save</em> button.</p>

<h3>Plain input field</h3>

<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='js'><span class='line'><span class="nx">App</span><span class="p">.</span><span class="nx">LazyTextField</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
</span><span class='line'>  <span class="nx">attributeBindings</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;value&#39;</span><span class="p">,</span> <span class="s1">&#39;type&#39;</span><span class="p">,</span> <span class="s1">&#39;size&#39;</span><span class="p">,</span> <span class="s1">&#39;name&#39;</span><span class="p">,</span> <span class="s1">&#39;placeholder&#39;</span><span class="p">,</span> <span class="s1">&#39;disabled&#39;</span><span class="p">,</span> <span class="s1">&#39;maxlength&#39;</span><span class="p">],</span>
</span><span class='line'>  <span class="nx">tagName</span><span class="o">:</span> <span class="s1">&#39;input&#39;</span><span class="p">,</span>
</span><span class='line'>  <span class="nx">type</span><span class="o">:</span> <span class="s1">&#39;text&#39;</span><span class="p">,</span>
</span><span class='line'>  <span class="nx">getCurrentValue</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">$</span><span class="p">().</span><span class="nx">val</span><span class="p">();</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>


<p>This is a lazy-updating text field. Whenever you set or update its <code>value</code>
property, the contents get updated, but when the user changes the contents,
they are not written back into <code>value</code>.</p>

<p>Now we can implement a save button like so:</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>
<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>
</pre></td><td class='code'><pre><code class=''><span class='line'>App.PersonView = Ember.View.extend({
</span><span class='line'>  firstName: 'Jane',
</span><span class='line'>  template: Ember.Handlebars.compile(
</span><span class='line'>    '&lt;form&gt;' +
</span><span class='line'>    '{{view App.LazyTextField valueBinding="view.firstName" viewName="textField"}}' +
</span><span class='line'>    '&lt;input type="submit" value="Save" {{action save}}&gt;' +
</span><span class='line'>    '&lt;/form&gt;'),
</span><span class='line'>  save: function(e) {
</span><span class='line'>    e.preventDefault(); e.stopPropagation();
</span><span class='line'>    this.set('firstName', this.get('textField').getCurrentValue());
</span><span class='line'>  }
</span><span class='line'>});</span></code></pre></td></tr></table></div></figure>


<h2>Another pattern: One-way bindings</h2>

<p>There is another way to achieve this, using the built-in live-updating
<code>Ember.TextField</code> and a one-way binding. It&#8217;s more compact, though slightly
more opaque:</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>
</pre></td><td class='code'><pre><code class='js'><span class='line'><span class="nx">App</span><span class="p">.</span><span class="nx">LazyTextField</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nx">TextField</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
</span><span class='line'>  <span class="nx">valueBinding</span><span class="o">:</span> <span class="nx">Ember</span><span class="p">.</span><span class="nx">Binding</span><span class="p">.</span><span class="nx">oneWay</span><span class="p">(</span><span class="s1">&#39;source&#39;</span><span class="p">)</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>


<p>Now instantiate LazyTextField, and bind your model data to <code>source</code> instead of
<code>value</code>, and property changes will propagate only from <code>source</code> to <code>value</code>, but
not vice versa (unless explicitly copied by the <code>save</code> function).</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>
<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>
</pre></td><td class='code'><pre><code class=''><span class='line'>App.PersonView = Ember.View.extend({
</span><span class='line'>  firstName: 'Jane',
</span><span class='line'>  template: Ember.Handlebars.compile(
</span><span class='line'>    '&lt;form&gt;' +
</span><span class='line'>    '{{view App.LazyTextField sourceBinding="view.firstName" viewName="textField"}}' +
</span><span class='line'>    '&lt;input type="submit" value="Save" {{action save}}&gt;' +
</span><span class='line'>    '&lt;/form&gt;'),
</span><span class='line'>  save: function(e) {
</span><span class='line'>    e.preventDefault(); e.stopPropagation();
</span><span class='line'>    this.set('firstName', this.getPath('textField.value'));
</span><span class='line'>  }
</span><span class='line'>});</span></code></pre></td></tr></table></div></figure>

]]></content>
      </entry>
    
  
    
      <entry>
        <title type="html"><![CDATA[Roll your own drag-and-drop handling, with help from jQuery UI]]></title>
        <link href="https://www.solitr.com/blog/2012/05/roll-your-own-drag-and-drop-handling-with-jquery-ui/"/>
        <updated>2012-05-08T00:00:00+00:00</updated>
        <published>2012-05-08T00:00:00+00:00</published>
        <id>https://www.solitr.com/blog/2012/05/roll-your-own-drag-and-drop-handling-with-jquery-ui/</id>
        <content type="html"><![CDATA[<p>In which I show how to harness jQuery UI&#8217;s Mouse plugin to roll your own
drag-and-drop handling, when Draggable is not flexible enough for you.</p>

<h2>Overview</h2>

<p>Sometimes you need tighter control over drag-and-drop logic than jQuery UI&#8217;s
<a href="http://jqueryui.com/demos/draggable/">Draggable</a> and
<a href="http://jqueryui.com/demos/droppable/">Droppable</a> plugins afford. For instance,
when I wrote up the <a href="https://www.solitr.com/">Solitr</a> game, I initially used
Draggable, but I ended up with an unmaintainable mess of auxiliary &#8220;drop-zone&#8221;
divs, and I also didn&#8217;t find the drop logic to be flexible enough for a game.</p>

<p>But simply binding to mousedown and mousemove events yourself will cause a
headache because you&#8217;d have to work around subtle cross-browser compatibility
issues.</p>

<p>Luckily, jQuery UI comes with a
<a href="https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.mouse.js">Mouse</a>
plugin. (Incidentally, Draggable derives from this.) We can use this
to handle mouseStart, mouseDrag, and mouseStop events in a way that works
consistently across browsers.</p>

<h2>Setup</h2>

<p>It&#8217;s not possible/useful to instantiate the <code>mouse</code> widget directly, but we can
easily subclass it to make it usable with our own custom event handlers. Simply
copy and paste the following code, which registers a <code>custommouse</code> plugin, to
get started:</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>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">$</span><span class="p">.</span><span class="nx">widget</span><span class="p">(</span><span class="s1">&#39;ui.custommouse&#39;</span><span class="p">,</span> <span class="nx">$</span><span class="p">.</span><span class="nx">ui</span><span class="p">.</span><span class="nx">mouse</span><span class="p">,</span> <span class="p">{</span>
</span><span class='line'>  <span class="nx">options</span><span class="o">:</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">mouseStart</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{},</span>
</span><span class='line'>    <span class="nx">mouseDrag</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{},</span>
</span><span class='line'>    <span class="nx">mouseStop</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{},</span>
</span><span class='line'>    <span class="nx">mouseCapture</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="kc">true</span><span class="p">;</span> <span class="p">}</span>
</span><span class='line'>  <span class="p">},</span>
</span><span class='line'>  <span class="c1">// Forward events to custom handlers</span>
</span><span class='line'>  <span class="nx">_mouseStart</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">options</span><span class="p">.</span><span class="nx">mouseStart</span><span class="p">(</span><span class="nx">e</span><span class="p">);</span> <span class="p">},</span>
</span><span class='line'>  <span class="nx">_mouseDrag</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">options</span><span class="p">.</span><span class="nx">mouseDrag</span><span class="p">(</span><span class="nx">e</span><span class="p">);</span> <span class="p">},</span>
</span><span class='line'>  <span class="nx">_mouseStop</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">options</span><span class="p">.</span><span class="nx">mouseStop</span><span class="p">(</span><span class="nx">e</span><span class="p">);</span> <span class="p">},</span>
</span><span class='line'>  <span class="nx">_mouseCapture</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">options</span><span class="p">.</span><span class="nx">mouseCapture</span><span class="p">(</span><span class="nx">e</span><span class="p">);</span> <span class="p">}</span>
</span><span class='line'>  <span class="c1">// Bookkeeping, inspired by Draggable</span>
</span><span class='line'>  <span class="nx">widgetEventPrefix</span><span class="o">:</span> <span class="s1">&#39;custommouse&#39;</span><span class="p">,</span>
</span><span class='line'>  <span class="nx">_init</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_mouseInit</span><span class="p">();</span>
</span><span class='line'>  <span class="p">},</span>
</span><span class='line'>  <span class="nx">_create</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">element</span><span class="p">.</span><span class="nx">addClass</span><span class="p">(</span><span class="s1">&#39;ui-custommouse&#39;</span><span class="p">);</span>
</span><span class='line'>  <span class="p">},</span>
</span><span class='line'>  <span class="nx">_destroy</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">this</span><span class="p">.</span><span class="nx">_mouseDestroy</span><span class="p">();</span>
</span><span class='line'>    <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">element</span><span class="p">.</span><span class="nx">removeClass</span><span class="p">(</span><span class="s1">&#39;ui-custommouse&#39;</span><span class="p">);</span>
</span><span class='line'>  <span class="p">},</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>


<p>Now instantiate the <code>custommouse</code> plugin we just defined, and pass your own
event handlers:</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>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">$</span><span class="p">(</span><span class="s1">&#39;#containerElement&#39;</span><span class="p">).</span><span class="nx">custommouse</span><span class="p">({</span>
</span><span class='line'>  <span class="nx">mouseStart</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="c1">// Handle the start of a drag-and-drop sequence here ...</span>
</span><span class='line'>  <span class="p">},</span>
</span><span class='line'>  <span class="nx">mouseDrag</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="c1">// Handle the dragging ...</span>
</span><span class='line'>  <span class="p">},</span>
</span><span class='line'>  <span class="nx">mouseStop</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="c1">// Handle the drop ...</span>
</span><span class='line'>  <span class="p">},</span>
</span><span class='line'>  <span class="nx">mouseCapture</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="c1">// Optional event handler: Return false here when you want to ignore a</span>
</span><span class='line'>    <span class="c1">// drag-and-drop sequence, so the start/drag/stop events don&#39;t fire ...</span>
</span><span class='line'>    <span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1">// Goodies from the Mouse plugin:</span>
</span><span class='line'>  <span class="c1">// Minimum distance in pixels before dragging is triggered</span>
</span><span class='line'>  <span class="c1">//distance: 1</span>
</span><span class='line'>  <span class="c1">// Minimum time in milliseconds before dragging is triggered</span>
</span><span class='line'>  <span class="c1">//delay: 0</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>


<h2>Event Sequence</h2>

<p>Say the user starts dragging horizontally at point <code>50, 50</code>, with <code>distance</code>
set to <code>10</code>. Then the event sequence is guaranteed to be as follows.</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>
<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>
</pre></td><td class='code'><pre><code class=''><span class='line'>Event         e.pageX, e.pageY  Notes
</span><span class='line'>============= ================= =======================================
</span><span class='line'>mouseCapture  50, 50            Subsequent events only trigger if true
</span><span class='line'>
</span><span class='line'>    ... user drags until they reach 60, 50 ...
</span><span class='line'>
</span><span class='line'>mouseStart    50, 50            Mouse cursor is already at 60, 50, but
</span><span class='line'>                                this triggers "late" at the original
</span><span class='line'>                                position, once minimum distance and
</span><span class='line'>                                delay are exceeded
</span><span class='line'>
</span><span class='line'>mouseDrag     60, 50            First mouseDrag fires event immediately
</span><span class='line'>                                after mouseStart, at real cursor
</span><span class='line'>                                position
</span><span class='line'>
</span><span class='line'>    ... user keeps dragging ...
</span><span class='line'>
</span><span class='line'>mouseDrag     63, 50
</span><span class='line'>
</span><span class='line'>    ... and dragging ...
</span><span class='line'>
</span><span class='line'>mouseDrag     68, 50
</span><span class='line'>
</span><span class='line'>    ... and releases the mouse ...
</span><span class='line'>
</span><span class='line'>mouseStop     68, 50            Perhaps this is not guaranteed to be in
</span><span class='line'>                                the same position as the last mouseDrag</span></code></pre></td></tr></table></div></figure>


<p>So much for the theory. Let me give you some practical hints on how to
implement this:</p>

<h2>Practical Hints</h2>

<p>There are many coordinate properties on the event object, but you should use
<code>e.pageX</code> and <code>e.pageY</code>, which <a href="http://www.bennadel.com/blog/1869-jQuery-Mouse-Events-PageX-Y-vs-ClientX-Y.htm">are
standardized</a>
by jQuery to return the coordinates relative to the top left corner of the
entire document.</p>

<p>The only exception is the
<a href="https://developer.mozilla.org/en/DOM/document.elementFromPoint">elementFromPoint</a>
method, which <a href="http://www.quirksmode.org/dom/w3c_cssom.html#documentview">on modern
browsers</a> takes
<code>e.clientX</code> and <code>e.clientY</code> and returns the element under that point.</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>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">mouseStart</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">this</span><span class="p">.</span><span class="nx">element</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">elementFromPoint</span><span class="p">(</span><span class="nx">e</span><span class="p">.</span><span class="nx">clientX</span><span class="p">,</span> <span class="nx">e</span><span class="p">.</span><span class="nx">clientY</span><span class="p">);</span>
</span><span class='line'>  <span class="k">this</span><span class="p">.</span><span class="nx">originalElementPosition</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">element</span><span class="p">).</span><span class="nx">position</span><span class="p">();</span>
</span><span class='line'>  <span class="k">this</span><span class="p">.</span><span class="nx">dragStart</span> <span class="o">=</span> <span class="p">{</span> <span class="nx">left</span><span class="o">:</span> <span class="nx">e</span><span class="p">.</span><span class="nx">pageX</span><span class="p">,</span> <span class="nx">top</span><span class="o">:</span> <span class="nx">e</span><span class="p">.</span><span class="nx">pageY</span> <span class="p">};</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Then in the <code>mouseDrag</code> handler, calculate the offset:</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>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">mouseDrag</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="kd">var</span> <span class="nx">dragOffset</span> <span class="o">=</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">left</span><span class="o">:</span> <span class="nx">e</span><span class="p">.</span><span class="nx">pageX</span> <span class="o">-</span> <span class="k">this</span><span class="p">.</span><span class="nx">dragStart</span><span class="p">.</span><span class="nx">left</span><span class="p">,</span>
</span><span class='line'>    <span class="nx">top</span><span class="o">:</span> <span class="nx">e</span><span class="p">.</span><span class="nx">pageY</span> <span class="o">-</span> <span class="k">this</span><span class="p">.</span><span class="nx">dragStart</span><span class="p">.</span><span class="nx">top</span>
</span><span class='line'>  <span class="p">};</span>
</span><span class='line'>  <span class="c1">// Assuming the element is absolutely positioned already</span>
</span><span class='line'>  <span class="nx">$</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">element</span><span class="p">).</span><span class="nx">css</span><span class="p">({</span>
</span><span class='line'>    <span class="nx">left</span><span class="o">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">originalElementPosition</span><span class="p">.</span><span class="nx">left</span> <span class="o">+</span> <span class="nx">dragOffset</span><span class="p">.</span><span class="nx">left</span><span class="p">,</span>
</span><span class='line'>    <span class="nx">top</span><span class="o">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">originalElementPosition</span><span class="p">.</span><span class="nx">top</span> <span class="o">+</span> <span class="nx">dragOffset</span><span class="p">.</span><span class="nx">top</span>
</span><span class='line'>  <span class="p">});</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Finally, in <code>mouseStop</code>, snap the element to the nearest drop point (or
<a href="https://github.com/joliss/solitr/blob/e8fa7760e2/app/assets/javascripts/controllers.js.coffee#L405">whatever
logic</a>
you want to implement), and update the application state if necessary.</p>

<h2>Finally</h2>

<p>It would be sweet to handle touch events to make this work on mobile devices.
Unfortunately, the Mouse plugin doesn&#8217;t support touch handling yet. I have a
feeling that there will a lot of issues with inconsistent browser behavior if I
try to do this myself, so I&#8217;m leaving it for now.</p>

<p>In any case, I hope that this post was helpful to you. If you have practical
insights or alternative techniques to share (perhaps even without using
jquery.ui.mouse), please leave a comment!</p>
]]></content>
      </entry>
    
  
    
      <entry>
        <title type="html"><![CDATA[Getting Started With Konacha: JavaScript Testing on Rails]]></title>
        <link href="https://www.solitr.com/blog/2012/04/konacha-tutorial-javascript-testing-with-rails/"/>
        <updated>2012-04-03T00:00:00+00:00</updated>
        <published>2012-04-03T00:00:00+00:00</published>
        <id>https://www.solitr.com/blog/2012/04/konacha-tutorial-javascript-testing-with-rails/</id>
        <content type="html"><![CDATA[<p><a href="https://github.com/jfirebaugh/konacha">Konacha</a> is a testing tool for JavaScript applications running on Rails.</p>

<h2>Why Konacha?</h2>

<ul>
<li>It&#8217;s very fast.</li>
<li>It treats JavaScript like a first-class citizen: Your tests are written in
JavaScript, call into JavaScript code, and inspect JavaScript objects. You can
still trigger events, e.g. with jQuery, if you need to simulate user actions.</li>
<li>It comes with support for the Rails asset pipeline. [1]</li>
<li>It supports CoffeeScript.</li>
<li>You can use the in-browser runner (good for development), or run your test
suite from the command line through Selenium (good for build servers).</li>
</ul>


<p>What it <em>cannot</em> do is talk to the server. In particular:</p>

<ul>
<li>It cannot use the database.</li>
<li>It cannot access your Rails (server-side) views. Any DOM nodes you are
testing need to be created on the client side (for instance with JST
templates), not served out by views.</li>
</ul>


<p>When you need either of these two, write integration tests with Capybara
instead.</p>

<h2>Tutorial: Overview</h2>

<h3>Testing Plain JavaScript</h3>

<p>Let&#8217;s start by testing some pure JavaScript (without DOM manipulation). Say you
want to test the following function in a Rails 3.1+ app:</p>

<figure class='code'><figcaption><span>app/assets/javascripts/prime_numbers.js</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='javascript'><span class='line'><span class="nx">isPrime</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">n</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">n</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="p">(</span><span class="nx">n</span> <span class="o">%</span> <span class="nx">i</span><span class="p">))</span> <span class="p">{</span>
</span><span class='line'>      <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>  <span class="k">return</span> <span class="kc">true</span><span class="p">;</span> <span class="c1">// intentionally wrong for 0 and 1</span>
</span><span class='line'><span class="p">};</span>
</span></code></pre></td></tr></table></div></figure>


<p>To test this, first add Konacha to your Gemfile:</p>

<figure class='code'><figcaption><span>Gemfile</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>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">group</span> <span class="ss">:test</span><span class="p">,</span> <span class="ss">:development</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">gem</span> <span class="s1">&#39;konacha&#39;</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>Now <code>mkdir -p spec/javascripts</code>, and create a spec file:</p>

<figure class='code'><figcaption><span>spec/javascripts/prime_numbers_spec.js</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>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="c1">//= require prime_numbers</span>
</span><span class='line'>
</span><span class='line'><span class="nx">describe</span><span class="p">(</span><span class="s1">&#39;isPrime&#39;</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>  <span class="nx">it</span><span class="p">(</span><span class="s1">&#39;should be true for prime numbers&#39;</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">isPrime</span><span class="p">(</span><span class="mi">2</span><span class="p">).</span><span class="nx">should</span><span class="p">.</span><span class="nx">be</span><span class="p">.</span><span class="kc">true</span><span class="p">;</span>
</span><span class='line'>    <span class="nx">isPrime</span><span class="p">(</span><span class="mi">3</span><span class="p">).</span><span class="nx">should</span><span class="p">.</span><span class="nx">be</span><span class="p">.</span><span class="kc">true</span><span class="p">;</span>
</span><span class='line'>  <span class="p">});</span>
</span><span class='line'>  <span class="nx">it</span><span class="p">(</span><span class="s1">&#39;should be false for numbers with non-trivial divisors&#39;</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">isPrime</span><span class="p">(</span><span class="mi">4</span><span class="p">).</span><span class="nx">should</span><span class="p">.</span><span class="nx">be</span><span class="p">.</span><span class="kc">false</span><span class="p">;</span>
</span><span class='line'>    <span class="nx">isPrime</span><span class="p">(</span><span class="mi">6</span><span class="p">).</span><span class="nx">should</span><span class="p">.</span><span class="nx">be</span><span class="p">.</span><span class="kc">false</span><span class="p">;</span>
</span><span class='line'>  <span class="p">});</span>
</span><span class='line'>  <span class="nx">it</span><span class="p">(</span><span class="s1">&#39;should be false for 0 and 1&#39;</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">isPrime</span><span class="p">(</span><span class="mi">0</span><span class="p">).</span><span class="nx">should</span><span class="p">.</span><span class="nx">be</span><span class="p">.</span><span class="kc">false</span><span class="p">;</span>
</span><span class='line'>    <span class="nx">isPrime</span><span class="p">(</span><span class="mi">1</span><span class="p">).</span><span class="nx">should</span><span class="p">.</span><span class="nx">be</span><span class="p">.</span><span class="kc">false</span><span class="p">;</span>
</span><span class='line'>  <span class="p">});</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>


<p>We&#8217;ll get to the details of the syntax in a minute.</p>

<p>If you prefer CoffeeScript, you can also use <code>.js.coffee</code> spec files. For spec
files in particular, I find CoffeeScript much more readable than plain
JavaScript.</p>

<p>Run <code>bundle exec rake konacha:serve</code>, and point your browser at
<a href="http://localhost:3500/">localhost:3500</a>.</p>

<p>If everything loaded alright, you should now see two tests passing, and the
third one failing:</p>

<p><img alt="Konacha isPrime test screenshot" src="https://www.solitr.com/blog/post-img/konacha-isprime.png" class="screenshot"></p>

<p>If that&#8217;s not what you are getting, make sure you have a JavaScript console
open in the Konacha browser window, so you can see errors. If there are any
issues with loading your tests (such as syntax errors in your test
declarations), Konacha will <em>not</em> catch it and display an error. You just get a
blank test page, or worse, parts of your test suite are silently dropped. For
that reason, I always run my tests with a JavaScript console open.</p>

<h3>Testing the DOM</h3>

<p>Let&#8217;s write up a minimal three-line app:</p>

<figure class='code'><figcaption><span>app/assets/javascripts/views.js</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>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="c1">//= require jquery</span>
</span><span class='line'>
</span><span class='line'><span class="nx">appendTo</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">applicationRoot</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">return</span> <span class="nx">$</span><span class="p">(</span><span class="nx">applicationRoot</span><span class="p">).</span><span class="nx">append</span><span class="p">(</span><span class="s1">&#39;&lt;div class=&quot;hello-world&quot;&gt;Hello, world!&lt;/div&gt;&#39;</span><span class="p">);</span>
</span><span class='line'><span class="p">};</span>
</span></code></pre></td></tr></table></div></figure>


<p>Here, <code>appendTo</code> shall be the method used to initialize our app and render it
into the DOM &#8211; normally into an empty root div provided by the view. To test
it with Konacha, we render it into the special <code>#konacha</code> div, which is
automatically cleared between test cases.</p>

<figure class='code'><figcaption><span>spec/javascripts/view_spec.js</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>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="c1">//= require views</span>
</span><span class='line'><span class="c1">//= require jquery</span>
</span><span class='line'>
</span><span class='line'><span class="nx">describe</span><span class="p">(</span><span class="s1">&#39;application view&#39;</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>  <span class="nx">it</span><span class="p">(</span><span class="s1">&#39;should render&#39;</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="c1">// Call the production code</span>
</span><span class='line'>    <span class="nx">appendTo</span><span class="p">(</span><span class="s1">&#39;#konacha&#39;</span><span class="p">);</span>
</span><span class='line'>    <span class="c1">// Test that &quot;Hello World&quot; was rendered (by testing that the</span>
</span><span class='line'>    <span class="c1">// number of .hello-world divs is truthy)</span>
</span><span class='line'>    <span class="nx">assert</span><span class="p">.</span><span class="nx">ok</span><span class="p">(</span><span class="nx">$</span><span class="p">(</span><span class="s1">&#39;#konacha&#39;</span><span class="p">).</span><span class="nx">find</span><span class="p">(</span><span class="s1">&#39;div.hello-world&#39;</span><span class="p">).</span><span class="nx">length</span><span class="p">);</span>
</span><span class='line'>  <span class="p">});</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>


<p>Open <a href="http://localhost:3500/">localhost:3500</a>, or
<a href="http://localhost:3500/view_spec">localhost:3500/view_spec</a> to run the test in
isolation.</p>

<h2>Writing Tests</h2>

<h3>Assertions</h3>

<p>The assertions you saw in the test code above &#8211; <code>.should.be.false</code> and
<code>assert.ok(...)</code> &#8211; are provided through the <a href="http://chaijs.com/">Chai</a> testing library. Chai comes
with two assertion styles, which you can mix and match freely in your tests:
<a href="http://chaijs.com/api/bdd/">should/expect</a> (&#8220;BDD-style&#8221;) and
<a href="http://chaijs.com/api/assert/">assert</a> (&#8220;TDD-style&#8221;).</p>

<p>I generally find the <code>should</code> style more readable, but I recommend you still
acquaint yourself with both styles, as they are not one-to-one equivalents.</p>

<p>If you are coming from RSpec, you will be disappointed to find that Chai&#8217;s
<code>should</code> interface is much less powerful than RSpec&#8217;s. For example, it does not
allow you to call arbitrary
<a href="https://www.relishapp.com/rspec/rspec-expectations/v/2-8/docs/built-in-matchers/operator-matchers">operators</a>
or <a href="https://www.relishapp.com/rspec/rspec-expectations/v/2-8/docs/built-in-matchers/predicate-matchers">predicate
methods</a>.
So whereas in Ruby I would write <code>a.should be_open</code>, in JavaScript I write
<code>assert.ok(a.open())</code> or <code>a.open().should.be.ok</code>.</p>

<h3>Structure</h3>

<p>Konacha uses the <a href="http://visionmedia.github.com/mocha/">Mocha</a> framework with the <a href="http://visionmedia.github.com/mocha/#bdd-interface">BDD
interface</a> style to
structure your tests into suites and test cases. The <code>describe</code>/<code>it</code> syntax
should look familiar to most:</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='javascript'><span class='line'><span class="nx">describe</span><span class="p">(</span><span class="s1">&#39;Widget&#39;</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>  <span class="nx">beforeEach</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="c1">// ... setup code here ...</span>
</span><span class='line'>  <span class="p">});</span>
</span><span class='line'>  <span class="nx">it</span><span class="p">(</span><span class="s1">&#39;should do things&#39;</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="c1">// ... test code here ...</span>
</span><span class='line'>  <span class="p">});</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>


<h2>Practical Hints</h2>

<ul>
<li><p>Extract common code into a <code>spec/javascripts/spec_helper.js</code> file, and <code>//=
require spec_helper</code> at the top of each spec file.</p></li>
<li><p>Group your tests into subdirectories as you see fit.</p></li>
<li><p>It&#8217;s happened to me several times that I wrote assertions that cannot fail.
Examples include <code>.should.be.thisIsATypo</code> (does nothing) and
<code>$('.foo').should.not.be.empty</code> (<code>empty</code> does not play with jQuery).
For that reason, I recommend practicing test-first development, so you&#8217;ve
seen each of your tests fail at least once.</p></li>
<li><p>Writing DOM tests with jQuery turns out to be rather awkward. Try adding
<a href="https://github.com/jfirebaugh/chai-jquery">chai-jquery</a> to your project
for some jQuery-specific Chai assertions. For instance:</p></li>
</ul>


<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>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">assert</span><span class="p">.</span><span class="nx">ok</span><span class="p">(</span><span class="nx">$</span><span class="p">(</span><span class="s1">&#39;.hello-world&#39;</span><span class="p">).</span><span class="nx">length</span><span class="p">);</span> <span class="c1">// without chai-jquery</span>
</span><span class='line'><span class="nx">$</span><span class="p">(</span><span class="s1">&#39;.hello-world&#39;</span><span class="p">).</span><span class="nx">should</span><span class="p">.</span><span class="nx">exist</span><span class="p">;</span>      <span class="c1">// with chai-jquery</span>
</span></code></pre></td></tr></table></div></figure>


<ul>
<li>Always keep a JavaScript console open while running tests, so you&#8217;ll see load
errors.</li>
</ul>


<h2>Further Reading</h2>

<ul>
<li><a href="https://github.com/jfirebaugh/konacha">Konacha documentation</a></li>
<li><a href="http://visionmedia.github.com/mocha/">Mocha documentation</a></li>
<li><a href="http://chaijs.com/api/assert/">Chai documentation: assert</a></li>
<li><a href="http://chaijs.com/api/bdd/">Chai documentation: should</a></li>
</ul>


<h4>Footnotes</h4>

<p>[1] Without asset pipeline support, you would either have to enumerate all your
dependencies manually, or include the generated <code>application.js</code> file and live
with stack-traces like <code>application.js:54029</code>.</p>

<p><strong>Thanks</strong> to John Firebaugh, Yuri Gadow, and Joel Parker Henderson for reading
drafts of this.</p>
]]></content>
      </entry>
    
  
    
      <entry>
        <title type="html"><![CDATA[Bundling JavaScript With Your Gem? Make It Contributor-Friendly!]]></title>
        <link href="https://www.solitr.com/blog/2012/04/contributor-friendly-gems/"/>
        <updated>2012-04-02T00:00:00+00:00</updated>
        <published>2012-04-02T00:00:00+00:00</published>
        <id>https://www.solitr.com/blog/2012/04/contributor-friendly-gems/</id>
        <content type="html"><![CDATA[<p>Many Rails gems these days bundle third-party assets, JavaScript assets in
particular.</p>

<p>Oftentimes gem authors simply dump .js files into their repository, sometimes
even concatenated build products. It&#8217;s a simple solution, and with tools like
<a href="https://github.com/grosser/vendorer">Vendorer</a> it doesn&#8217;t have to turn into a
maintenance headache.</p>

<p>But this makes it hard for users of your gem to contribute to your asset
upstream (that is, to the third-party code that you include). Imagine I am a
user of your gem: If I want to fix a bug in <em>your gem code</em>, it&#8217;s easy: I can
clone your repository, point the gem in my Gemfile at my checkout or fork
(with <code>:path</code> or <code>:git</code>), hack away at your code, and send you pull requests,
while all my changes are instantly live in my app. But I cannot do the same to
fix a bug in <em>the third-party code</em> you are shipping, since the version you
ship is almost never up-to-date with the upstream master. And if I cloned the
upstream, I would have trouble getting my fix back into your gem so I can use
it in my app immediately. By losing that instant gratification, I&#8217;m much less
likely to contribute to the upstream.</p>

<p>Luckily, this is easy to fix: <strong>Include the upstream using a Git submodule.</strong>
Then add a Rake task that copies or builds the files into <code>vendor/assets</code>.</p>

<p>Now it&#8217;s easy to contribute: I simply clone your repository and set <code>:path</code> as
before, and then check out the master branch on the submodule. I can hack away
and send pull requests to the upstream straight from the submodule, while at
the same time my changes to the upstream will be live in my app through your
gem.</p>

<p>I call this quality <strong>contributor-friendliness</strong>. It&#8217;s not so much a service to
your users &#8211; most won&#8217;t even care &#8211; as it is to the upstream project. By
making it easy to contribute through your gem, you have expanded the upstream&#8217;s
base of potential contributors with your users.</p>

<p>I think making open source work better is worth the overhead of using
submodules, even if dumping vendor files might be easier sometimes. Our
upstream maintainers provide all this awesome code. Let&#8217;s be nice to them and
make our gems contributor-friendly.</p>

<hr />

<p><strong>Update June 2012:</strong></p>

<p>This has been used in practice in
<a href="https://github.com/jfirebaugh/konacha">Konacha</a> and
<a href="https://github.com/joliss/jquery-ui-rails">jquery-ui-rails</a>. It seems to be
working well so far.</p>

<p>To see a working Rake task, check the <code>:assets</code> task in <a href="https://github.com/jfirebaugh/konacha/blob/master/Rakefile">Konacha&#8217;s
Rakefile</a>.</p>

<p>One insight we&#8217;ve had is to always check in the generated asset files. This is
necessary so your library can be used in Bundler like so:</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='ruby'><span class='line'><span class="n">gem</span> <span class="s1">&#39;foo&#39;</span><span class="p">,</span> <span class="ss">:git</span> <span class="o">=&gt;</span> <span class="s1">&#39;...&#39;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Bundler obviously won&#8217;t run your build step, so everything needs to be checked
in.</p>
]]></content>
      </entry>
    
  
    
      <entry>
        <title type="html"><![CDATA[markdown-rails: Markdown for your views and partials]]></title>
        <link href="https://www.solitr.com/blog/2012/02/markdown-rails-for-static-views/"/>
        <updated>2012-02-23T00:00:00+00:00</updated>
        <published>2012-02-23T00:00:00+00:00</published>
        <id>https://www.solitr.com/blog/2012/02/markdown-rails-for-static-views/</id>
        <content type="html"><![CDATA[<p>In my Rails apps, I have a lot of static prose, and that prose tends to be
written in HTML. As a result, it&#8217;s cumbersome to edit.</p>

<p>Markdown would be much better suited for prose. However, Rails does not support
<code>.html.md</code> views out of the box.</p>

<p>As <a href="http://stackoverflow.com/a/4418389/525872">described</a> by @tjwallace, there
is a simple workaround &#8211; use HAML&#8217;s
<code>:markdown</code>
<a href="http://haml-lang.com/docs/yardoc/file.HAML_REFERENCE.html#markdown-filter">filter</a>:</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>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>:markdown
</span><span class='line'>  **Markdown** goes here.
</span><span class='line'>
</span><span class='line'>  The time is #{Time.now}.</span></code></pre></td></tr></table></div></figure>


<p>Still, this leaves your Markdown files indented. I thought there is no reason
why Rails shouldn&#8217;t support plain <code>.html.md</code> files.</p>

<p>So I wrote up a simple markdown-rails gem. Check it out:</p>

<p><a href="https://github.com/joliss/markdown-rails">https://github.com/joliss/markdown-rails</a></p>

<p>One shortcoming is, it doesn&#8217;t support embedded Ruby code (like HAML&#8217;s
<code>:markdown</code> filter with <code>#{exp}</code>). I&#8217;d love to add this at some point, but I&#8217;m
not sure about the best approach. See the comments and the Limitations section
in the README.</p>
]]></content>
      </entry>
    
  
    
      <entry>
        <title type="html"><![CDATA[Announcing the jquery-ui-rails Gem: jQuery UI for the Asset Pipeline]]></title>
        <link href="https://www.solitr.com/blog/2012/02/jquery-ui-rails-gem-for-the-asset-pipeline/"/>
        <updated>2012-02-20T00:00:00+00:00</updated>
        <published>2012-02-20T00:00:00+00:00</published>
        <id>https://www.solitr.com/blog/2012/02/jquery-ui-rails-gem-for-the-asset-pipeline/</id>
        <content type="html"><![CDATA[<p>Have you ever headed to the <a href="http://jqueryui.com/download">jQuery UI download
page</a>, selected some components, downloaded a
custom jQuery UI package, and dumped the files in your Rails app? Then you
probably felt as undignified as I did. This is not how we should have to
configure our libraries.</p>

<p>The only alternative right now is the
<a href="https://github.com/rails/jquery-rails">jquery-rails</a> gem, which (in
addition to packaging jQuery) is nice enough to ship a <code>jquery-ui.js</code> asset
file for your convenience. However, this gives you <em>all</em> of jQuery UI&#8217;s
components (an extra 51KB gzipped) when you might need only one or two, and it
also does not give you the CSS and image files.</p>

<p>To put an end to this situation, I wrote up the
<a href="https://github.com/joliss/jquery-ui-rails"><strong>jquery-ui-rails</strong></a> gem, which
packages all the JavaScript, stylesheet and image files for the Rails 3.1+
asset pipeline.</p>

<p>It comes with individual jQuery UI modules, and it resolves dependencies
between the jQuery UI modules through the asset pipeline, so you can <code>require</code>
the component(s) you need and things will just work.</p>

<p>Also, the image references in the CSS files now point at images in the asset
pipeline. No more dumping PNGs in your <code>public</code> folder.</p>

<p>If you are using jQuery UI in your app right now, please give it a spin, and
let me know if it works for you!</p>

<p>Link: <a href="https://github.com/joliss/jquery-ui-rails">https://github.com/joliss/jquery-ui-rails</a></p>

<hr />

<p>P.S. Right now it only bundles the default theme (&#8220;Smoothness&#8221; I think), but
once it is possible to <a href="https://forum.jquery.com/topic/downloading-bundling-all-themes">regenerate the theme
files</a>, it
should be easy to ship all the themes in the
<a href="http://jqueryui.com/themeroller/">ThemeRoller</a> gallery.</p>

<p>P.P.S. I haven&#8217;t tested it, but I see that CodeOfficer has made a
<a href="https://github.com/CodeOfficer/jquery-ui-rails-helpers">jquery-ui-rails-helpers</a>
gem (and perhaps there are more helper gems that I don&#8217;t know about). See also
<em><a href="http://stackoverflow.com/questions/3825836/modifying-rails-helpers-to-add-html-classes">jquery ui - Modifying Rails helpers to add HTML
classes</a></em>
on Stack Overflow. I&#8217;m not looking to add helpers to the jquery-ui-rails gem,
since I think it&#8217;s best to do one thing well, but if you have used helpers for
jQuery UI (or written your own), please share your experiences so other people
can benefit.</p>
]]></content>
      </entry>
    
  
    
      <entry>
        <title type="html"><![CDATA[How I Hand-Rolled MVC for a JavaScript Game (and It Was Awesome)]]></title>
        <link href="https://www.solitr.com/blog/2012/02/mvc-design/"/>
        <updated>2012-02-13T00:00:00+00:00</updated>
        <published>2012-02-13T00:00:00+00:00</published>
        <id>https://www.solitr.com/blog/2012/02/mvc-design</id>
        <content type="html"><![CDATA[<p><em>In which</em></p>

<ul>
<li><em>I sing the praises of frameworks like Ember.js,</em></li>
<li><em>explain why they don&#8217;t work so well for games, and</em></li>
<li><em>demonstrate how to structure any JavaScript app (game or not, framework or
not) around MVC for cleaner code.</em></li>
</ul>


<p>I recently decided to improve the <a href="https://www.solitr.com/">Solitr</a> game
(<a href="https://github.com/joliss/solitr">GitHub</a>) I had hacked together in a
one-day hackathon (<a href="https://www.solitr.com/blog/2011/11/18-hour-hackathon-making-a-coffeescript-solitaire/">blogged about
here</a>).
The code had turned out rather messy, so I went for a rewrite with better
design, only copying bits and pieces from the first implementation.</p>

<p>A plethora of JavaScript MVC frameworks have cropped up since 2011 &#8211;
<a href="http://documentcloud.github.com/backbone/">Backbone</a>,
<a href="http://spinejs.com/">Spine</a>, <a href="http://knockoutjs.com/">Knockout</a>,
<a href="http://emberjs.com/">Ember</a>, <a
href="http://batmanjs.org/">Batman</a>, and
<a href="https://github.com/elabs/serenade.js">Serenade</a> come to mind. I had used Backbone
before, but I had heard interesting things about Ember, so I decided to give
that a spin. I am rather enthused:</p>

<h2>Why Ember.js Rocks</h2>

<p>Probably the most important feature in Ember is <strong>attribute binding</strong>. It
allows attribute changes to automatically propagate through all layers of your
application. For example, say you change <code>firstName</code> on your model, then the
<code>firstName</code> attributes on your controller and view class are updated (because
they are &#8220;bound&#8221; to <code>model.firstName</code>), and the <code>fullName</code> helper attribute on
your view class gets recalculated as well, because it in turn is &#8220;bound&#8221; to
<code>view.firstName</code>.</p>

<p>This is the awesomest thing since sliced bread. It means that when your
controller responds to an event, it only needs to update the model and every
piece of your app that (directly on indirectly) depends on it is notified.</p>

<p>Ember&#8217;s <strong>in-place template updating</strong> deserves special attention too, and
coming from server-side templating languages, the significance of this feature
wasn&#8217;t obvious to me at first: When the <code>fullName</code> attribute in the previous
example is updated, Ember&#8217;s template engine will change the attribute inside
the template live in the DOM, and not just re-render the entire template.
That&#8217;s important because otherwise you lose all GUI state (such as collapsible
elements, or cursors in text fields) whenever a single attribute inside a
template changes. I learned this the hard way with a Backbone application I
worked on: Having to re-render views just because a counter increases is
bothersome for small page elements, but once you get to reloading an entire
pane, it becomes a usability issue, and one that&#8217;s rather hard to fix.</p>

<p>In other words, unlike on the server side, it&#8217;s useful for JavaScript
templating engines to be more intelligent than just spitting out a chunk of
HTML.</p>

<p>So attribute binding and template updating are the two things I recommend you
pay attention to when choosing an MVC framework.</p>

<h2>Enter Games: On States and State Transitions</h2>

<p>So I started to rewrite Solitr with Ember.js. A day or so into the rewrite
however, I was beginning to question whether Ember&#8217;s attribute-binding approach
was right for a game. Let me explain why.</p>

<p>When a card moves to a new place, it needs to be animated. So you can&#8217;t just
update the <code>left</code> and <code>top</code> CSS properties when the game state (and hence the
location of a card) changes. My first instict was to simply slide the
cards into place whenever the position changes, either by catching the
changes to the position attribute and wrapping it in a call to
jQuery&#8217;s <a href="http://api.jquery.com/animate/">.animate()</a>, or using the CSS
<a href="https://developer.mozilla.org/en/CSS/transition">transition</a> property.
However, this doesn&#8217;t <em>quite</em> work: The type of animation you need depends on
the last action: For instance, turning over three cards on the stock, playing a
card you double-clicked, or snapping a card into place after it has been
drag-and-dropped, all require different sliding speeds and easing functions.</p>

<p>Of course you can hack the animation code so that it infers the right type of
animation from the difference between the current and the previous game state.
This might works most of the time, but besides being ugly, there are cases
where it&#8217;s not possible to know whether a given state change came about
through, say, double-click, drag-and-drop, or undo (all of which are animated
differently).</p>

<p>In this situation, compromising on the quality of the animations is a
no-brainer for a regular web application. But for a game, <strong>animations should
be first-class citizens.</strong> Since they are so ubiquitous in a game (even a
simple one like solitaire), treating them as less than first-class citizen will
yield hundreds of lines of unmaintainable animation spaghetti code.</p>

<p>So how do you make animations first-class citizens? Easy enough: You do not
update the game state and then ask the controller to update the GUI according
to the new state. Instead, you send a Command object (<a href="http://www.ece.ubc.ca/~matei/EECE417/command-pattern.pdf">as described in
GoF&#8217;s Design Patterns</a>) to the game
state so that it can update itself, and then send the same Command object to
the animation method so it can update the GUI <em>based on the type of command</em>.</p>

<p>In other words, the application is now fundamentally structured around <strong>state
transitions</strong> (commands, that is) rather than <strong>states</strong>.</p>

<p>This approach is probably untypical for &#8220;regular&#8221; web apps, and frameworks like
Ember.js discourage it by exposing state and hiding state transitions behind
the auto-updating mechanism for object attributes. Besides animations, the only use case I can
think of is when you absolutely need to build an undo stack: With your code
structured around state transitions, you can easily use Command objects for the
undo stack, rather than ad-hoc closures (or clones of the model object). Other
than that, I am not sure if for a non-game app that doesn&#8217;t require
sophisticated animations, this is worth the effort.</p>

<p>However, for game code, I have found that this pattern works very well, and it
has turned out to be very maintainable so far.</p>

<h2>Hand-Rolling MVC</h2>

<p>As I structured my app around Commands, my reliance on Ember&#8217;s features
started to disappear, and eventually I was left with Ember&#8217;s slightly
cumbersome attribute accessor syntax (<code>card.get('rank')</code> instead of
<code>card.rank</code>) with no benefit from it, as all my attributes had become
independent, and no auto-updating between objects (&#8220;binding&#8221; in Ember
parlance) was going on anymore.</p>

<p>The only thing Ember was doing for me was templating with Handlebars, but since
all I render are cards (essentially <code>&lt;div class="card" id="..."&gt;&lt;/div&gt;</code>), I
felt safe pulling these one-liners into the JavaScript code without sacrificing
maintainability.</p>

<p>So I removed the dependence on the Ember.js library. What was left was an
application handsomely structured around the MVC pattern, and compared to the
initial version I hacked together, the logical separation into model and
presentation code is the biggest single design improvement.</p>

<h2>A Look at the Code</h2>

<p>The application essentially consists of two files,
<a href="https://github.com/joliss/solitr/blob/master/app/assets/javascripts/models.js.coffee">models.js.coffee</a>
and
<a href="https://github.com/joliss/solitr/blob/master/app/assets/javascripts/controllers.js.coffee">controllers.js.coffee</a>
(written in CoffeeScript).</p>

<p>I haven&#8217;t found it necessary to derive either models or controllers from a
common base class.</p>

<h3>Models</h3>

<p>The models hold the game state and implement the game (domain) logic. I
deliberatedly kept the models isolated from the rest of the application, so the
code doesn&#8217;t know about the controllers or views, and also doesn&#8217;t need a DOM.
This has made the code much more maintainable. I&#8217;m also hoping that it will
help me when I write tests, perhaps with Mocha. <!-- XXX
https://github.com/jfirebaugh/matcha ? --></p>

<h4>Card Model</h4>

<p>The Card model is very simple. It only holds three attributes &#8211; <code>rank</code>,
<code>suit</code>, and <code>id</code> &#8211; and no logic at all. Whether it is face-up or face-down is
inferable from its place in the game (stock cards are always face-down, waste
cards are always face-up, etc.), so that is something that is determined by the
controller that renders it, not stored by the model.</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>
</pre></td><td class='code'><pre><code class='coffeescript'><span class='line'><span class="nv">_nextId = </span><span class="mi">0</span>
</span><span class='line'>
</span><span class='line'><span class="k">class</span> <span class="nx">App</span><span class="p">.</span><span class="nx">Models</span><span class="p">.</span><span class="nx">Card</span>
</span><span class='line'>  <span class="nv">constructor: </span><span class="nf">(@rank, @suit) -&gt;</span>
</span><span class='line'>    <span class="vi">@id = </span><span class="s">&quot;id</span><span class="si">#{</span><span class="nx">_nextId</span><span class="o">++</span><span class="si">}</span><span class="s">&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<h4>Game State Model</h4>

<p>The game state model, on the other hand, is rather more complicated. It holds
several arrays of cards (stock, waste, tableau piles, foundations), and encodes
the rules of the game (the domain logic, that is). Here is a slightly
simplified version:</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>
</pre></td><td class='code'><pre><code class='coffeescript'><span class='line'><span class="k">class</span> <span class="nx">App</span><span class="p">.</span><span class="nx">Models</span><span class="p">.</span><span class="nx">KlondikeTurnThree</span>
</span><span class='line'>  <span class="nv">cardsToTurn: </span><span class="mi">3</span>
</span><span class='line'>  <span class="nv">numberOfFoundations: </span><span class="mi">4</span>
</span><span class='line'>  <span class="nv">numberOfTableaux: </span><span class="mi">7</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1"># Initialization</span>
</span><span class='line'>  <span class="nv">constructor: </span><span class="nf">-&gt;</span> <span class="c1"># initialize deck and arrays</span>
</span><span class='line'>  <span class="nv">createDeck: </span><span class="nf">-&gt;</span> <span class="c1"># create all the cards for the deck</span>
</span><span class='line'>  <span class="nv">deal: </span><span class="nf">-&gt;</span> <span class="c1"># set up initial layout</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1"># Rules</span>
</span><span class='line'>  <span class="nv">foundationAccepts: </span><span class="nf">(foundationIndex, cards) -&gt;</span>
</span><span class='line'>  <span class="nv">tableauPileAccepts: </span><span class="nf">(tableauPileIndex, cards) -&gt;</span>
</span><span class='line'>  <span class="nv">isMovable: </span><span class="nf">(card) -&gt;</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1"># Commands</span>
</span><span class='line'>  <span class="nv">executeCommand: </span><span class="nf">(cmd) -&gt;</span>
</span><span class='line'>    <span class="c1"># The Big Method that parses and executes commands,</span>
</span><span class='line'>    <span class="c1"># thereby managing all state transitions</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1"># Helpers</span>
</span><span class='line'>  <span class="nv">nextAutoCommand: </span><span class="nf">-&gt;</span>
</span><span class='line'>    <span class="c1"># Return command to auto-play and auto-flip</span>
</span><span class='line'>    <span class="c1"># cards in some situations</span>
</span><span class='line'>  <span class="p">...</span> <span class="nx">other</span> <span class="nx">helpers</span> <span class="p">...</span>
</span></code></pre></td></tr></table></div></figure>


<p>While the model implements rule logic (with methods like <code>foundationAccepts</code>),
it does not enforce it. The controller has to check whether a given action is
legal in order to give proper user feedback. It then seemed redundant to
implement another such check in the game state model.</p>

<p>For simplicity&#8217;s sake, I decided not to let model classes proliferate: The piles
that make up the game state model (stock, waste, etc.) are dumb arrays, not
models on their own. Any logic that might conceivably be attached to those
piles is moved up into the all-knowing game state model.</p>

<h3>Controllers</h3>

<p>Paralleling the models, there is a simple Card controller performing basic rendering
duties, and a game controller (App.Controllers.KlondikeTurnThree) ordering the
cards around.</p>

<h4>Card Controller</h4>

<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>
</pre></td><td class='code'><pre><code class='coffeescript'><span class='line'><span class="k">class</span> <span class="nx">App</span><span class="p">.</span><span class="nx">Controllers</span><span class="p">.</span><span class="nx">Card</span>
</span><span class='line'>  <span class="nv">size: </span><span class="p">{</span><span class="nv">width: </span><span class="mi">79</span><span class="p">,</span> <span class="nv">height: </span><span class="mi">123</span><span class="p">}</span>
</span><span class='line'>  <span class="nv">element: </span><span class="kc">null</span>
</span><span class='line'>
</span><span class='line'>  <span class="nv">constructor: </span><span class="nf">(@model) -&gt;</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1"># Insert / remove from DOM</span>
</span><span class='line'>  <span class="nv">appendTo: </span><span class="nf">(rootElement) -&gt;</span>
</span><span class='line'>  <span class="nv">destroy: </span><span class="nf">-&gt;</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1"># Move around</span>
</span><span class='line'>  <span class="nv">setRestingPosition: </span><span class="nf">(position) -&gt;</span>
</span><span class='line'>  <span class="nv">jumpToRestingPosition: </span><span class="nf">-&gt;</span>
</span><span class='line'>  <span class="nv">animateToRestingPosition: </span><span class="nf">(animationOptions) -&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<h4>Game Controller</h4>

<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>
</pre></td><td class='code'><pre><code class='coffeescript'><span class='line'><span class="k">class</span> <span class="nx">App</span><span class="p">.</span><span class="nx">Controllers</span><span class="p">.</span><span class="nx">KlondikeTurnThree</span>
</span><span class='line'>  <span class="nv">model: </span><span class="kc">null</span>
</span><span class='line'>
</span><span class='line'>  <span class="nv">constructor: </span><span class="nf">-&gt;</span>
</span><span class='line'>
</span><span class='line'>  <span class="nv">newGame: </span><span class="nf">-&gt;</span>
</span><span class='line'>
</span><span class='line'>  <span class="nv">processCommand: </span><span class="nf">(cmd) -&gt;</span>
</span><span class='line'>    <span class="c1"># Call @model.executeCommand and @animateCards</span>
</span><span class='line'>  <span class="nv">animateCards: </span><span class="nf">(cmd) -&gt;</span>
</span><span class='line'>    <span class="c1"># Paralleling executeCommand in the model, this method</span>
</span><span class='line'>    <span class="c1"># animates the GUI</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1"># Housekeeping</span>
</span><span class='line'>  <span class="nv">calculateGeometry: </span><span class="p">()</span> <span class="nf">-&gt;</span>
</span><span class='line'>  <span class="nv">appendBaseElements: </span><span class="p">()</span> <span class="nf">-&gt;</span>
</span><span class='line'>  <span class="nv">registerEventHandlers: </span><span class="nf">-&gt;</span>
</span><span class='line'>  <span class="nv">removeEventHandlers: </span><span class="nf">-&gt;</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1"># The actual event handlers</span>
</span><span class='line'>  <span class="nv">turnStock: </span><span class="o">=&gt;</span>
</span><span class='line'>  <span class="nv">redeal: </span><span class="o">=&gt;</span>
</span><span class='line'>  <span class="p">...</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1"># And tons of helper functions dealing with minutiae like</span>
</span><span class='line'>  <span class="c1"># drop zone geometry for drag&#39;n&#39;drop ...</span>
</span><span class='line'>  <span class="p">...</span>
</span></code></pre></td></tr></table></div></figure>


<p>To be honest, I&#8217;m finding that my game controller is becoming a sprawling
assortment of semi-related methods. I think this in part due to GUIs being
messy business, and in part due to suboptimal design.  Eventually I will have
to split it into more classes, but for now it actually works quite well.</p>

<h3>Views and Templates</h3>

<p>The view classes and templates that most frameworks expect you to create have
been folded into the Controller classes.  There is the occasional <code>$('&lt;div
class="button"&gt;...&lt;/div&gt;')</code>, and the cards are rendered by programmatically
by creating DOM nodes:</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="k">class</span> <span class="nx">App</span><span class="p">.</span><span class="nx">Controllers</span><span class="p">.</span><span class="nx">Card</span>
</span><span class='line'>  <span class="nv">appendTo: </span><span class="nf">(rootElement) -&gt;</span>
</span><span class='line'>    <span class="vi">@element = </span><span class="nb">document</span><span class="p">.</span><span class="nx">createElement</span><span class="p">(</span><span class="s">&#39;div&#39;</span><span class="p">)</span>
</span><span class='line'>    <span class="vi">@element.className = </span><span class="s">&#39;card&#39;</span>
</span><span class='line'>    <span class="vi">@element.id = </span><span class="nx">@model</span><span class="p">.</span><span class="nx">id</span>
</span><span class='line'>    <span class="nx">$</span><span class="p">(</span><span class="nx">@element</span><span class="p">).</span><span class="nx">css</span><span class="p">(</span><span class="nx">@size</span><span class="p">)</span>
</span><span class='line'>    <span class="nx">$</span><span class="p">(</span><span class="nx">rootElement</span><span class="p">).</span><span class="nx">append</span><span class="p">(</span><span class="nx">@element</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>So far I haven&#8217;t needed to separate these from the controllers because they are
so miniscule. (I am sure that this will not scale though, and if you are using
an MVC framework that comes with templating functionality, you should
definitely use it from the get-go.)</p>

<h2>Conclusions</h2>

<ul>
<li><p>Ember.js rocks because it can propagate (bind) attributes between objects,
and it auto-updates templates live without rerendering.</p></li>
<li><p>But attribute propagation is suboptimal for games, since animation requires
that you know about state transitions, not just state.</p></li>
<li><p>For any app, it greatly helps the design to follow MVC:</p>

<ol>
<li>Create isolated model classes storing application state and implementing
domain logic.</li>
<li>Create controller classes that talk to the models and the DOM,
implementing the GUI logic.</li>
<li>Factor templates out of the controllers.</li>
<li>Factor helper methods for the templates into view classes.</li>
</ol>
</li>
</ul>

]]></content>
      </entry>
    
  
    
      <entry>
        <title type="html"><![CDATA[Screenshots with Capybara]]></title>
        <link href="http://www.opinionatedprogrammer.com/2012/01/screenshots-with-capybara-selenium/"/>
        <updated>2012-01-06T00:00:00+00:00</updated>
        <published>2012-01-06T00:00:00+00:00</published>
        <id>http://opinionatedprogrammer.com/?p=1130</id>
        <content type="html"><![CDATA[<p>Just so I&#8217;ll never have to google this again, here is how to save and open a
screenshot with Capybara when you are using the <code>:selenium</code> driver:</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>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">page</span><span class="o">.</span><span class="n">driver</span><span class="o">.</span><span class="n">browser</span><span class="o">.</span><span class="n">save_screenshot</span> <span class="s1">&#39;screenshot.png&#39;</span>
</span><span class='line'><span class="no">Launchy</span><span class="o">.</span><span class="n">open</span> <span class="s1">&#39;screenshot.png&#39;</span> <span class="c1"># or open manually</span>
</span></code></pre></td></tr></table></div></figure>


<p><strong>Update:</strong> In Capybara 2.0.0.beta2, screenshotting has become part of the API
and can be done like this:</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>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">page</span><span class="o">.</span><span class="n">save_screenshot</span> <span class="s1">&#39;screenshot.png&#39;</span>
</span><span class='line'><span class="no">Launchy</span><span class="o">.</span><span class="n">open</span> <span class="s1">&#39;screenshot.png&#39;</span> <span class="c1"># or open manually</span>
</span></code></pre></td></tr></table></div></figure>

]]></content>
      </entry>
    
  
    
      <entry>
        <title type="html"><![CDATA[Adding Twitter's Bootstrap CSS to your Rails app]]></title>
        <link href="http://www.opinionatedprogrammer.com/2011/11/twitter-bootstrap-on-rails/"/>
        <updated>2011-11-10T00:00:00+00:00</updated>
        <published>2011-11-10T00:00:00+00:00</published>
        <id>http://opinionatedprogrammer.com/?p=952</id>
        <content type="html"><![CDATA[<figure class="float-right" style="max-width: 320px">
<a href="https://www.solitr.com/blog/post-img/bootstrap-demo.png"><img class="size-medium wp-image-1060" title="Bootstrap demo" src="https://www.solitr.com/blog/post-img/bootstrap-demo-300x222.png" alt="" width="300" height="222" /></a>
<figcaption>Bootstrap in action, as demoed in <a href='http://lucapette.com/rails/twitter-bootstrap-on-rails/'>Luca Pette&#39;s article</a></figcaption>
</figure>


<p><em>Updated Feb 2012 for Bootstrap 2.</em></p>

<p>Twitter&#8217;s new CSS toolkit, <a href="http://twitter.github.com/bootstrap/">Bootstrap</a>, is all the rage these days. I explain how to get the CSS, and optionally the mixins and the JavaScript, into your Rails app.</p>

<h2>&#8220;How do I serve Bootstrap through Rails 3.1&#8217;s asset pipeline?&#8221;</h2>

<p>Just add Ken Collins&#8217;s (<a href="https://twitter.com/metaskills">@metaskill</a>&#8217;s) <a href="https://github.com/metaskills/less-rails-bootstrap">less-rails-bootstrap</a> gem (<a href="http://metaskills.net/2011/09/26/less-is-more-using-twitter-bootstrap-in-the-rails-3-1-asset-pipeline/">announced recently</a> on his blog) to your Gemfile:</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='ruby'><span class='line'><span class="n">gem</span> <span class="s1">&#39;less-rails-bootstrap&#39;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Require it in your <code>app/assets/stylesheets/application.css</code>:</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'> *= require twitter/bootstrap</span></code></pre></td></tr></table></div></figure>


<p>Done. You now have Bootstrap 2 working in your Rails app. :-)</p>

<p>By the way: Did you know that Bootstrap is written in <a
href="http://lesscss.org/">LESS</a>, a stylesheet language like SCSS?</p>

<h2>&#8220;Ugh, I hate LESS. Can I get Bootstrap as plain CSS please?&#8221;</h2>

<p>That&#8217;s OK, not everybody likes LESS. Behind the scenes, less-rails-bootstrap
transparently compiles the Bootstrap LESS files into CSS through Rails&#8217;s asset
pipeline (using the <a
href="https://github.com/metaskills/less-rails">less-rails</a> gem). This means
that there is no scary client-side compilation with less.js (like the LESS
website advertises). And on the Rails side, you can just carry on using SCSS.
In other words, Bootstrap by default acts like any regular CSS library &#8211; all
the LESS stuff is hidden from you.</p>

<h2>&#8220;I love LESS. Can I use the <a href="http://twitter.github.com/bootstrap/less.html">Bootstrap mixins</a> in my LESS code?&#8221;</h2>

<p>Sure you can. Just import the mixins and variables in any stylesheet file
ending in <code>.less</code> (like <code>posts.css.less</code>):</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='css'><span class='line'><span class="k">@import</span> <span class="s2">&quot;twitter/bootstrap/variables&quot;</span><span class="p">;</span>
</span><span class='line'><span class="k">@import</span> <span class="s2">&quot;twitter/bootstrap/mixins&quot;</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="nt">div</span><span class="nc">.post</span> <span class="p">{</span>
</span><span class='line'>   <span class="k">color</span><span class="o">:</span> <span class="o">@</span><span class="nb">yellow</span><span class="p">;</span>  <span class="o">//</span> <span class="o">&lt;--</span> <span class="n">using</span> <span class="n">variables</span>
</span><span class='line'>   <span class="m">#gradie</span><span class="n">nt</span><span class="o">.</span><span class="n">vertical</span><span class="p">(</span><span class="o">@</span><span class="nb">black</span><span class="o">,</span> <span class="o">@</span><span class="nb">blue</span><span class="p">);</span>  <span class="o">//</span> <span class="o">&lt;--</span> <span class="n">using</span> <span class="n">mixins</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p><b>Warning:</b> Do not get confused about requiring vs importing:</p>

<ul>
<li><p>Use <code>= require twitter/bootstrap</code> at least once (typically in
application.css) to get all the CSS rules that come with Bootstrap. The files
will be processed through Sprockets (Rails&#8217;s asset handler), which guards
against duplicate inclusion. If you tried to <code>require</code> the mixins or
variables, it would have no effect, since Sprockets compiles them separately
from your stylesheets.</p></li>
<li><p>Add the two <code>@import</code> lines above to <em>every</em> LESS file in which
you want to use Bootstrap mixins or variables. As you can verify by
inspecting the CSS output, importing them has no effect (i.e. no CSS rules
are generated) until you actually use the mixins and variables in your own
CSS rules. If you tried to <code>@import</code> the entire &#8220;twitter/bootstrap&#8221;
library, it would show up multiple times in your compiled CSS assets, because
Sprockets can&#8217;t guard against duplicate inclusion when you use
<code>@import</code>.</p></li>
</ul>


<p>To summarize, <code>require</code> the entire toolkit, and <code>@import</code> the
mixins and variables.</p>

<h2>&#8220;Can I use Bootstrap&#8217;s <a href="http://twitter.github.com/bootstrap/javascript.html">JavaScript plugins</a>?&#8221;</h2>

<p>Easy enough. Add this to your <code>application.js</code>:</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='javascript'><span class='line'><span class="c1">//= require twitter/bootstrap</span>
</span></code></pre></td></tr></table></div></figure>


<p>The plugins load through jQuery&#8217;s <code><a
href="http://api.jquery.com/ready/">.ready</a></code>, so be sure to wrap your
own code as well:</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>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">$</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>  <span class="c1">// ...</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>


<h2>&#8220;Now how do I get started using Bootstrap in my layouts and views?&#8221;</h2>

<p>Try adding a button in any view file &#8211; it should be rendered pretty:</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='xml'><span class='line'><span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">&quot;button&quot;</span> <span class="na">value=</span><span class="s">&quot;Click me&quot;</span> <span class="na">class=</span><span class="s">&quot;btn primary&quot;</span><span class="nt">&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Or try adding a <a
href="http://twitter.github.com/bootstrap/components.html#navbar">black
navigation bar</a> to your layout:</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>
</pre></td><td class='code'><pre><code class='xml'><span class='line'><span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">&quot;navbar navbar-fixed-top&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>  <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">&quot;navbar-inner&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>    <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">&quot;container&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>      <span class="nt">&lt;a</span> <span class="na">class=</span><span class="s">&quot;brand&quot;</span> <span class="na">href=</span><span class="s">&quot;/&quot;</span><span class="nt">&gt;</span>Whizboo App<span class="nt">&lt;/a&gt;</span>
</span><span class='line'>      <span class="nt">&lt;ul</span> <span class="na">class=</span><span class="s">&quot;nav&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>        <span class="nt">&lt;li</span> <span class="na">class=</span><span class="s">&quot;active&quot;</span><span class="nt">&gt;&lt;a</span> <span class="na">href=</span><span class="s">&quot;/&quot;</span><span class="nt">&gt;</span>Home<span class="nt">&lt;/a&gt;&lt;/li&gt;</span>
</span><span class='line'>        <span class="nt">&lt;li&gt;&lt;a</span> <span class="na">href=</span><span class="s">&quot;/about&quot;</span><span class="nt">&gt;</span>About<span class="nt">&lt;/a&gt;&lt;/li&gt;</span>
</span><span class='line'>      <span class="nt">&lt;/ul&gt;</span>
</span><span class='line'>      <span class="nt">&lt;ul</span> <span class="na">class=</span><span class="s">&quot;nav pull-right&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>        <span class="nt">&lt;li&gt;&lt;a</span> <span class="na">href=</span><span class="s">&quot;/sign_in&quot;</span><span class="nt">&gt;</span>Sign In<span class="nt">&lt;/a&gt;&lt;/li&gt;</span>
</span><span class='line'>      <span class="nt">&lt;/ul&gt;</span>
</span><span class='line'>    <span class="nt">&lt;/div&gt;</span>
</span><span class='line'>  <span class="nt">&lt;/div&gt;</span>
</span><span class='line'><span class="nt">&lt;/div&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Fore more inspiration, check out Luca&#8217;s <a
href="http://lucapette.com/rails/twitter-bootstrap-on-rails/">article about
using Bootstrap with Rails</a>.</p>

<h2>&#8220;I want more explanation. / I heard there is a Sass version of Bootstrap.&#8221;</h2>

<p>Check out &#8221;<a
href="http://rubysource.com/twitter-bootstrap-less-and-sass-understanding-your-options-for-rails-3-1/">Twitter
Bootstrap, Less, and Sass: Understanding Your Options for Rails 3.1</a>&#8221; on
RubySource!</p>
]]></content>
      </entry>
    
  
    
      <entry>
        <title type="html"><![CDATA[18-Hour Hackathon: Making a CoffeeScript Solitaire]]></title>
        <link href="https://www.solitr.com/blog/2011/11/hackathon-making-solitr-a-coffeescript-solitaire/"/>
        <updated>2011-11-07T00:00:00+00:00</updated>
        <published>2011-11-07T00:00:00+00:00</published>
        <id>http://opinionated-programmer.com/?p=930</id>
        <content type="html"><![CDATA[<p>The making of <a href="https://www.solitr.com/">solitr.com</a> (source at <a href="https://github.com/joliss/solitr">github.com/joliss/solitr</a>), a
CoffeeScript solitaire, in one 18-hour hackathon:</p>

<h2>Hackathon Diary</h2>

<p>9:15 am: <em>Shreeeek-shreeek-shreeeeeeeek!</em>
<em>Get-up-get-dressed-have-breakfast-coffee-go-go-go.</em></p>

<p>9:50 am: Sit down at laptop. What do I name my project? What CSS syntax
do I use? What CSS libraries?</p>

<p>10:45 am: Too much reading, let’s just decide and keep moving! “rails
new solitaire” (it’s 100% static, but I need Rails’s asset handling with
Sprockets), drop in yui-reset. Make controller, route root to
play#index.</p>

<p>11:10 am: Alright, let’s code up a data model (no ORM, just JS classes).
Cards first. Then a GameState class to hold the card positions. Lots of
googling for CoffeeScript and JavaScript basics in the process.</p>

<p>12:15 pm:
<em>Microwave-yesterday’s-food-have-lunch-coffee-go-go-go-keep-moving!</em></p>

<p>12:35 pm: Finish up data model. Make presentation layer. Code up CSS for
makeshift card rendering. Drop in <a href="http://documentcloud.github.com/underscore/">Underscore.js</a> for more coding
sanity.</p>

<p>4:00 pm: Work-in-progress (completely static): <strong><a href="http://demo.solitr.com/1db973871d8bf7e3c0ddbab2950543df5b1ca296/">1db97387</a></strong>. Next up
is event-handling. Read up on jQuery’s <a href="http://api.jquery.com/on/">.on</a>. Figure out how to drop
in jQuery 1.7 without making frickin jquery-rails unhappy with its
outdated jQuery. Code up some easy events.</p>

<p>6:30 pm:
<em>Put-pizza-in-the-oven-go-jogging-yes-it’s-cold-but-you-gotta-keep-running-for-30-minutes-or-your-brain-will-be-fried-by-midnight.
Get-back-exhausted-</em>pizza-ready-<em>house-not-burnt-down-very-good-let’s-eat-eat-eat.
Coffee. Back-to-coding-no-time-to-waste!</em></p>

<p>7:40 pm: Brain in reasonable condition. 7.5 hours to go, still on
schedule I think. Time to start reading about <a href="http://jqueryui.com/demos/draggable/">dragging</a> and
<a href="http://jqueryui.com/demos/droppable/">dropping</a>. Painful stuff as expected.</p>

<p>10:35 pm: Houston! Problem! The way I set up the DOM structure is not
looking to work out with drag’n’drop. Check in work-in-progress and
revert to 7:40 pm instantly. Three hours lost, I think I’m off schedule
now. Let’s try again, using HTML/CSS only as a dumb rendering canvas,
with less DOM structure.</p>

<p>11:05 pm: Yup, looking better. Now for dragging and dropping, fingers
crossed. Time’s tight.</p>

<p>2:25 am: First working version: <strong><a href="http://demo.solitr.com/c475ae9e78f8f75ed64a06df19cc53b9ff473647/">c475ae9e</a></strong>. Tired, but brain’s
still producing reasonable code. Time to drop in a pretty card deck with
CSS sprite handling, test, fix undo handling, add double-clicking, “you
win” message, “new game” buttons, make production environment work, test
some more.</p>

<p>5:35 am: It got late, but I’m done: <strong><a href="http://demo.solitr.com/18961aa1cf7be72176c5ba1ad4d3174fbca49eff/">18961aa1</a></strong>. More than 2h over
budget, my 18h hackathon has become a 20h hackathon. And dragging of
multiple cards has a rendering issue. Still, I’m very happy with the
result. Brain is fried, off to bed.</p>

<p>(And the next day I set up <a href="https://www.solitr.com/">solitr.com</a> and pushed the code to
<a href="https://github.com/joliss/solitr">github.com/joliss/solitr</a>. But I’ll blog about the whole
domain/DNS/deployment thing some other time in detail.)</p>

<h2>Hackathon Retrospective</h2>

<p>Oh my gosh. This was <em>so</em> much fun. I’ll definitely do hackathons again.
Being able to whip up a webapp on a whim is such a good feeling. Also, I
picked up a lot of CoffeeScript and jQuery that I wouldn’t have been
exposed to otherwise.</p>

<p>I’ve found that by doing a hackathon, I’m forced to just keep working,
so I’m producing code all day. I’ve rarely gotten so much output from my
brain in one day.</p>

<p>Pulling 18 hour work-days, of course, is rather not sustainable, let alone the
20 real hours that it turned into. But when you’re writing an app from scratch,
it’s only satisfying if at the end you have it actually working, so
compromising on scope is not really an option. I think the better alternative
is trying to get faster at creating new apps. Now that I know my way around the
basics of CoffeeScript and jQuery, I think I might be able to do the same thing
in 16 hours, which seems much more reasonable.</p>

<p>Next time I’ll try to get started faster at the beginning (less agonizing about
things like the name or the CSS library — it’s all trivial to change later),
and I’ll also try to be more disciplined in the last 2 hours to not let
non-essential features creep in.</p>

<p><em>Update Feb 2012: <a href="https://www.solitr.com/blog/2012/02/mvc-design/">Read up on how I rewrote Solitr around
MVC.</a></em></p>
]]></content>
      </entry>
    
  
    
      <entry>
        <title type="html"><![CDATA[EC2 CPU benchmark: Fastest instance type (serial performance)]]></title>
        <link href="http://www.opinionatedprogrammer.com/2011/07/ec2-cpu-benchmark-fastest-instance-type-for-build-servers/"/>
        <updated>2011-07-25T00:00:00+00:00</updated>
        <published>2011-07-25T00:00:00+00:00</published>
        <id>http://opinionated-programmer.com/?p=807</id>
        <content type="html"><![CDATA[<p><b>Update:</b> This post is still relevant for build servers, but it turns out that at the moment EC2 does not give you a serial speed advantage over most modern laptops. Run the loop below on your laptop if you don&#8217;t believe me.</p>

<p>I sometimes use EC2 spot instances to run my test suite. To figure out which
<a href="http://aws.amazon.com/ec2/instance-types/">instance type</a> to use, I ran a
quick benchmark. I mostly care about <b>serial performance</b>, not the number
of cores, which left me with the following contenders (prices are hourly for
spot instances):</p>

<ul>
<li><b>m1.large</b> / $0.12 / &#8220;Large&#8221;<br>2 x 2 EC2 Compute Units; <i>here:</i> 2 cores of Intel Xeon E5507 @ 2.27GHz</li>
<li><b>m2.xlarge</b> / $0.17 / &#8220;High-Memory Extra Large&#8221;<br>2 x 3.25 EC2 Compute Units; <i>here:</i> 2 cores of Intel Xeon           X5550  @ 2.67GHz</li>
<li><b>c1.medium</b> / $0.06 / &#8220;High-CPU Medium&#8221; [32-bit]<br>2 x 2.5 EC2 Compute Units; <i>here:</i> 2 cores of Intel Xeon           E5410  @ 2.33GHz</li>
<li><b>c1.xlarge</b> / $0.24 / &#8220;High-CPU Extra Large&#8221;<br>8 x 2.5 EC2 Computer Units; <i>here:</i> 2 cores of Intel Xeon E5506  @ 2.13GHz</li>
<li><b>cc1.4xlarge</b> / $0.56 / &#8220;Cluster Compute Quadruple Extra Large&#8221;<br>total 33.5 (I assume 16 x 2.1) EC2 Compute Units on two Intel Xeon X5570 @ 2.93GHz</li>
</ul>


<p>I ran two benchmarks. First, the following loop:</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='bash'><span class='line'><span class="nb">time </span><span class="k">for </span>i in <span class="o">{</span>0..10000<span class="o">}</span>; <span class="k">do for </span>j in <span class="o">{</span>0..1000<span class="o">}</span>; <span class="k">do</span> :; <span class="k">done</span>; <span class="k">done</span>
</span></code></pre></td></tr></table></div></figure>


<p>Second, my Rails app&#8217;s test suite, with Selenium on a headless X server,
unparallelized.</p>

<p>Here are the timings:</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>
<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=''><span class='line'>Instance Type   Loop (sec)   Test suite (sec)
</span><span class='line'>m1.large        47           79
</span><span class='line'>m2.xlarge       28           51
</span><span class='line'>c1.medium       45           67
</span><span class='line'>c1.xlarge       37           63
</span><span class='line'>cc1.4xlarge     27           64</span></code></pre></td></tr></table></div></figure>


<h2>Conclusion</h2>

<p>The result seems pretty clear: For serial computation, the high-memory
instances (m2.xlarge and above) are the fastest.</p>

<p>(This of course is not because of the RAM, but because their CPUs happen to
have the highest serial computation power, as you might expect from the EC2
Compute Unit count provided by Amazon.)</p>

<h2>Notes</h2>

<ul>
<li>The timings came back with +/- 1 on the loop, and +/- 2 on the test suite, so
at this point I am reasonably confident in the results.</li>
<li>Just to make sure, I launched an m2.4xlarge instance, and as expected, it has
the same CPU model and the same timings as m2.xlarge. The only difference is
that it comes with 8 cores instead of 2.</li>
<li>I&#8217;m not sure why the cluster-compute instance (cc1.4xlarge) is so slow on my
test suite, compared to the loop. I launched two different instances, in case
I had a &#8220;bad apple&#8221;, and both came out the same. Perhaps it&#8217;s some weird
timing issue in my test. But I think more likely, the CPUs in the
cluster-compute instances just happen to be very good at this particular
loop. (Unlike the loop timings, the slower test suite timing is in line with
what you might expect from Amazon&#8217;s EC2 Compute Unit count.)</li>
<li>All benchmarks were run on the official <a
href="http://uec-images.ubuntu.com/releases/11.04/release/">Ubuntu 11.04
AMIs</a>, 32-bit for c1.medium, 64-bit for the rest, with EBS for the
cc1.4xlarge instance and instance storage for the rest.</li>
</ul>

]]></content>
      </entry>
    
  
    
      <entry>
        <title type="html"><![CDATA[Creating a swap file with Chef]]></title>
        <link href="http://www.opinionatedprogrammer.com/2011/07/creating-a-swap-file-with-chef/"/>
        <updated>2011-07-01T00:00:00+00:00</updated>
        <published>2011-07-01T00:00:00+00:00</published>
        <id>http://opinionated-programmer.com/?p=780</id>
        <content type="html"><![CDATA[<p>In case anyone else needs this, here is my Chef snippet to create a swap file:</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="n">script</span> <span class="s1">&#39;create swapfile&#39;</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">interpreter</span> <span class="s1">&#39;bash&#39;</span>
</span><span class='line'>  <span class="n">not_if</span> <span class="p">{</span> <span class="no">File</span><span class="o">.</span><span class="n">exists?</span><span class="p">(</span><span class="s1">&#39;/var/swapfile&#39;</span><span class="p">)</span> <span class="p">}</span>
</span><span class='line'>  <span class="n">code</span> <span class="o">&lt;&lt;-</span><span class="no">eof</span>
</span><span class='line'><span class="sh">    dd if=/dev/zero of=/var/swapfile bs=1M count=2048 &amp;&amp;</span>
</span><span class='line'><span class="sh">    chmod 600 /var/swapfile &amp;&amp;</span>
</span><span class='line'><span class="sh">    mkswap /var/swapfile</span>
</span><span class='line'><span class="no">  eof</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="n">mount</span> <span class="s1">&#39;/dev/null&#39;</span> <span class="k">do</span>  <span class="c1"># swap file entry for fstab</span>
</span><span class='line'>  <span class="n">action</span> <span class="ss">:enable</span>  <span class="c1"># cannot mount; only add to fstab</span>
</span><span class='line'>  <span class="n">device</span> <span class="s1">&#39;/var/swapfile&#39;</span>
</span><span class='line'>  <span class="n">fstype</span> <span class="s1">&#39;swap&#39;</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="n">script</span> <span class="s1">&#39;activate swap&#39;</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">interpreter</span> <span class="s1">&#39;bash&#39;</span>
</span><span class='line'>  <span class="n">code</span> <span class="s1">&#39;swapon -a&#39;</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>Normally I would use &#8220;none&#8221; as the mount point for a swap file, but Chef <a
href="http://tickets.opscode.com/browse/CHEF-1967">requires the mount point to
exist</a>, so we use /dev/null instead. Chef cannot mount the fstab entry it
just created (because it only calls <code>mount</code>), so we use <code>swapon</code>.</p>

<p>Depending on how fast your disk is (I&#8217;m looking at you, Amazon!), <code>dd</code>
can take a while, so I recommend you put this at the end of your recipe (or
recipe list).</p>

<p>P.S. In case you were wondering where to put the swap file: Apparently
/var/swapfile is <a
href="http://serverfault.com/questions/279248/linux-where-to-put-the-swap-file">as
good a place as any</a>.</p>

<p>P.P.S. No proselytizing in the comments about how swap partitions are faster
please, unless you show me a benchmark. ;-)</p>
]]></content>
      </entry>
    
  
    
      <entry>
        <title type="html"><![CDATA[Chef Solo tutorial: Managing a single server with Chef]]></title>
        <link href="http://www.opinionatedprogrammer.com/2011/06/chef-solo-tutorial-managing-a-single-server-with-chef/"/>
        <updated>2011-06-27T00:00:00+00:00</updated>
        <published>2011-06-27T00:00:00+00:00</published>
        <id>http://opinionated-programmer.com/?p=613</id>
        <content type="html"><![CDATA[<p>The <a href="http://wiki.opscode.com/display/chef/Documentation">Chef documentation</a>
assumes you have an entire server farm to manage, so it hits you with a lot of
complexity. If all you want is to set up and maintain a single VM, this
tutorial will help.</p>

<div style="width: 45%;" class="float-right light-border">

<h2>This is the cloud</h2>

<p>We will be creating &#8220;throwaway&#8221; VMs that we can recreate with a single call. If you need to have a single server system persist for years across all changes, you should perhaps check out <a href="http://puppetlabs.com/">Puppet</a> for a less cloudy solution.</p>

<h2>Using Amazon EC2?</h2>

<p>Any fresh instance of an <a href="https://help.ubuntu.com/community/EC2StartersGuide#Official_Ubuntu_Cloud_Guest_Amazon_Machine_Images_.28AMIs.29">Ubuntu AMI</a> will do, for example <code>ami-06ad526f</code> (11.04, 32-bit EBS in us-east-1).</p>

<p><i>Hint:</i> The EC2 API tools are (by nature) complex and error-prone, so I recommend you stay with the point-and-click <a href="https://console.aws.amazon.com/ec2/">web interface</a> for as long as possible, instead of trying to automate launching new instances.</p>
<p><i>Hint 2:</i> Create a separate EBS volume as a data partition to hold your databases, etc.</p>
<p><i>Hint 3:</i> Use Elastic IPs for all your instances.</p></div>


<p>All you need is</p>

<ul>
<li>a laptop with Bash and SSH (no need to even install Chef), and</li>
<li>any <i>vanilla</i> Linux server that you can SSH into.</li>
</ul>


<p>Why do we run against vanilla servers? In my opinion, the system your
deployment scripts run against should be as minimal possible, essentially
straight from the vendor. So instead of manually installing packages like Chef
and then creating a snapshot to instantiate our VMs from, we will use a freshly
installed system and make the entire process scripted. On the downside, we need
some bootstrapping code (~30 LOC), but on the upside we get more repeatability
and less maintenance overhead, and we stay independent from any specific cloud
or virtualization provider.</p>

<h2>Overview</h2>

<p>Since we only have one server to manage, using Chef Server and Chef Clients is
clearly overkill. We will use Chef Solo instead. In a newly created directory
on our laptop, we will have the following files (all under version control if
you like):</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>
<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=''><span class='line'>deploy.sh     &lt;--- run "./deploy.sh" on your laptop to deploy
</span><span class='line'>install.sh    &lt;--- this is run on the server to bootstrap and call chef-solo
</span><span class='line'>solo.json     &lt;--- chef configuration
</span><span class='line'>solo.rb       &lt;--- chef configuration
</span><span class='line'>cookbooks/op/recipes/default.rb   &lt;--- the most important file -- your
</span><span class='line'>                                       server recipe goes here</span></code></pre></td></tr></table></div></figure>


<p>That&#8217;s all we need to turn any bare-bones Linux system into a fully equipped
server. Let&#8217;s now take a look at the contents of each file. You can copy and
paste freely (everything was written by me, and it&#8217;s in the public domain).
Some of it assumes Ubuntu &#8211; adjust accordingly.</p>

<h2>deploy.sh</h2>

<p>The <code>deploy.sh</code> script is the one you run on your laptop every time you
want to (re-)apply your Chef recipe to your server. It only copies the tree to
the server and runs <code>install.sh</code>:</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>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="c">#!/bin/bash</span>
</span><span class='line'>
</span><span class='line'><span class="c"># Usage: ./deploy.sh [host]</span>
</span><span class='line'>
</span><span class='line'><span class="nv">host</span><span class="o">=</span><span class="s2">&quot;${1:-ubuntu@opinionatedprogrammer.com}&quot;</span>
</span><span class='line'>
</span><span class='line'><span class="c"># The host key might change when we instantiate a new VM, so</span>
</span><span class='line'><span class="c"># we remove (-R) the old host key from known_hosts</span>
</span><span class='line'>ssh-keygen -R <span class="s2">&quot;${host#*@}&quot;</span> 2&gt; /dev/null
</span><span class='line'>
</span><span class='line'>tar cj . | ssh -o <span class="s1">&#39;StrictHostKeyChecking no&#39;</span> <span class="s2">&quot;$host&quot;</span> <span class="s1">&#39;</span>
</span><span class='line'><span class="s1">sudo rm -rf ~/chef &amp;&amp;</span>
</span><span class='line'><span class="s1">mkdir ~/chef &amp;&amp;</span>
</span><span class='line'><span class="s1">cd ~/chef &amp;&amp;</span>
</span><span class='line'><span class="s1">tar xj &amp;&amp;</span>
</span><span class='line'><span class="s1">sudo bash install.sh&#39;</span>
</span></code></pre></td></tr></table></div></figure>


<p>(Remember to change the default host name to match yours.)</p>

<h2>install.sh</h2>

<p><code>install.sh</code> is responsible for bootstrapping the system if necessary
(installing Chef), and then calling the <code>chef-solo</code> binary. (You don&#8217;t
ever need to run it manually. Keep it mode 644 as a precaution against wrecking
your development machine.)</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>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="c">#!/bin/bash</span>
</span><span class='line'>
</span><span class='line'><span class="c"># This runs as root on the server</span>
</span><span class='line'>
</span><span class='line'><span class="nv">chef_binary</span><span class="o">=</span>/var/lib/gems/1.9.1/bin/chef-solo
</span><span class='line'>
</span><span class='line'><span class="c"># Are we on a vanilla system?</span>
</span><span class='line'><span class="k">if</span> ! <span class="nb">test</span> -f <span class="s2">&quot;$chef_binary&quot;</span>; <span class="k">then</span>
</span><span class='line'><span class="k">    </span><span class="nb">export </span><span class="nv">DEBIAN_FRONTEND</span><span class="o">=</span>noninteractive
</span><span class='line'>    <span class="c"># Upgrade headlessly (this is only safe-ish on vanilla systems)</span>
</span><span class='line'>    aptitude update <span class="o">&amp;&amp;</span>
</span><span class='line'>    apt-get -o Dpkg::Options::<span class="o">=</span><span class="s2">&quot;--force-confnew&quot;</span> <span class="se">\</span>
</span><span class='line'>        --force-yes -fuy dist-upgrade <span class="o">&amp;&amp;</span>
</span><span class='line'>    <span class="c"># Install Ruby and Chef</span>
</span><span class='line'>    aptitude install -y ruby1.9.1 ruby1.9.1-dev make <span class="o">&amp;&amp;</span>
</span><span class='line'>    sudo gem1.9.1 install --no-rdoc --no-ri chef --version 0.10.0
</span><span class='line'><span class="k">fi</span> <span class="o">&amp;&amp;</span>
</span><span class='line'>
</span><span class='line'><span class="s2">&quot;$chef_binary&quot;</span> -c solo.rb -j solo.json
</span></code></pre></td></tr></table></div></figure>


<h2>solo.rb</h2>

<p><code>solo.rb</code> only sets two paths for Chef Solo. You should go with this:</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>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">root</span> <span class="o">=</span> <span class="no">File</span><span class="o">.</span><span class="n">absolute_path</span><span class="p">(</span><span class="no">File</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="bp">__FILE__</span><span class="p">))</span>
</span><span class='line'>
</span><span class='line'><span class="n">file_cache_path</span> <span class="n">root</span>
</span><span class='line'><span class="n">cookbook_path</span> <span class="n">root</span> <span class="o">+</span> <span class="s1">&#39;/cookbooks&#39;</span>
</span></code></pre></td></tr></table></div></figure>


<h2>solo.json</h2>

<p><code>solo.json</code> holds a pointer to the recipe(s) we want to run (that&#8217;s only
one recipe for now). My cookbook is called &#8220;op&#8221; (for <i>Opinionated
Programmer</i>) &#8211; you should name yours after your server or your site.</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>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="s2">&quot;run_list&quot;</span><span class="o">:</span> <span class="p">[</span> <span class="s2">&quot;recipe[op::default]&quot;</span> <span class="p">]</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<h2>cookbooks/op/recipes/default.rb</h2>

<p>I like to just have a single &#8220;default&#8221; recipe that holds all the server
configuration. If it gets out of hand, you can always split it up, but for
small sites, a single recipe file should be easiest to deal with.</p>

<p>A recipe is simply a list of resources. The <a
href="http://wiki.opscode.com/display/chef/Resources"><strong>Resources</strong></a>
page on the Chef wiki is probably the one piece of documentation you will be
consulting a lot.</p>

<p>I will give you a few examples of things you might want to do in your recipe:</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>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="c1"># --- Install packages we need ---</span>
</span><span class='line'><span class="n">package</span> <span class="s1">&#39;ntp&#39;</span>
</span><span class='line'><span class="n">package</span> <span class="s1">&#39;sysstat&#39;</span>
</span><span class='line'><span class="n">package</span> <span class="s1">&#39;apache2&#39;</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># --- Add the data partition ---</span>
</span><span class='line'><span class="n">directory</span> <span class="s1">&#39;/mnt/data_joliss&#39;</span>
</span><span class='line'>
</span><span class='line'><span class="n">mount</span> <span class="s1">&#39;/mnt/data_joliss&#39;</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">action</span> <span class="o">[</span><span class="ss">:mount</span><span class="p">,</span> <span class="ss">:enable</span><span class="o">]</span>  <span class="c1"># mount and add to fstab</span>
</span><span class='line'>  <span class="n">device</span> <span class="s1">&#39;data_joliss&#39;</span>
</span><span class='line'>  <span class="n">device_type</span> <span class="ss">:label</span>
</span><span class='line'>  <span class="n">options</span> <span class="s1">&#39;noatime,errors=remount-ro&#39;</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># --- Set host name ---</span>
</span><span class='line'><span class="c1"># Note how this is plain Ruby code, so we can define variables to</span>
</span><span class='line'><span class="c1"># DRY up our code:</span>
</span><span class='line'><span class="n">hostname</span> <span class="o">=</span> <span class="s1">&#39;opinionatedprogrammer.com&#39;</span>
</span><span class='line'>
</span><span class='line'><span class="n">file</span> <span class="s1">&#39;/etc/hostname&#39;</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">content</span> <span class="s2">&quot;</span><span class="si">#{</span><span class="n">hostname</span><span class="si">}</span><span class="se">\n</span><span class="s2">&quot;</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="n">service</span> <span class="s1">&#39;hostname&#39;</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">action</span> <span class="ss">:restart</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="n">file</span> <span class="s1">&#39;/etc/hosts&#39;</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">content</span> <span class="s2">&quot;127.0.0.1 localhost </span><span class="si">#{</span><span class="n">hostname</span><span class="si">}</span><span class="se">\n</span><span class="s2">&quot;</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># --- Deploy a configuration file ---</span>
</span><span class='line'><span class="c1"># For longer files, when using &#39;content &quot;...&quot;&#39; becomes too</span>
</span><span class='line'><span class="c1"># cumbersome, we can resort to deploying separate files:</span>
</span><span class='line'><span class="n">cookbook_file</span> <span class="s1">&#39;/etc/apache2/apache2.conf&#39;</span>
</span><span class='line'><span class="c1"># This will copy cookbooks/op/files/default/apache2.conf (which</span>
</span><span class='line'><span class="c1"># you&#39;ll have to create yourself) into place. Whenever you edit</span>
</span><span class='line'><span class="c1"># that file, simply run &quot;./deploy.sh&quot; to copy it to the server.</span>
</span><span class='line'>
</span><span class='line'><span class="n">service</span> <span class="s1">&#39;apache2&#39;</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">action</span> <span class="ss">:restart</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>Note that all dependencies are implicitly given by the ordering of the
resources.</p>

<p>This should be enough examples to get you going. Again, all of these resources
(and many more) are documented on the <a
href="http://wiki.opscode.com/display/chef/Resources"><strong>Resources</strong></a>
page.</p>

<h2>Hints</h2>

<ul>
<li>As you write your recipe, re-run <code>./deploy.sh</code> frequently, like you would recompile a piece of software.</li>
<li>When you are done, tear down your VM and redeploy on a fresh system, just to make sure everything is working OK. Sometimes subtle dependency/ordering issues creep in that are only revealed by applying the entire recipe on a vanilla system. You don&#8217;t want to be left with a non-working recipe when your server goes down and you need to re-deploy afresh.</li>
</ul>


<p><i>All code was written by me and is licensed under <a href="http://creativecommons.org/publicdomain/zero/1.0/">CC0</a> (public domain).</i></p>
]]></content>
      </entry>
    
  
    
      <entry>
        <title type="html"><![CDATA[Parsing YAML 1.1 with Ruby]]></title>
        <link href="http://www.opinionatedprogrammer.com/2011/04/parsing-yaml-1-1-with-ruby/"/>
        <updated>2011-04-12T00:00:00+00:00</updated>
        <published>2011-04-12T00:00:00+00:00</published>
        <id>http://opinionated-programmer.com/?p=581</id>
        <content type="html"><![CDATA[<p>To parse YAML with Ruby, do not use the <code>YAML</code> module, use
<code>Psych</code> (which <a href="http://www.ruby-lang.org/en/news/2010/08/18/ruby-1-9.2-released/">ships with Ruby
1.9.2</a>,
though there is also a <a href="https://rubygems.org/gems/psych">gem</a>).</p>

<p>The reason is that <code>YAML</code> uses the unmaintained <a
href="https://rubyforge.org/projects/syck/">Syck</a> library, whereas
<code>Psych</code> uses the modern <a
href="http://pyyaml.org/wiki/LibYAML">LibYAML</a>:</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='ruby'><span class='line'><span class="o">&gt;&gt;</span> <span class="nb">require</span> <span class="s1">&#39;yaml&#39;</span>
</span><span class='line'><span class="o">&gt;&gt;</span> <span class="no">YAML</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="s2">&quot;%YAML 1.1</span><span class="se">\n</span><span class="s2">---</span><span class="se">\n</span><span class="s2">&#39;test&#39;&quot;</span><span class="p">)</span>  <span class="c1"># %YAML directive not supported</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="s2">&quot;%YAML 1.1 --- &#39;test&#39;&quot;</span>
</span><span class='line'>
</span><span class='line'><span class="o">&gt;&gt;</span> <span class="nb">require</span> <span class="s1">&#39;psych&#39;</span>
</span><span class='line'><span class="o">&gt;&gt;</span> <span class="no">Psych</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="s2">&quot;%YAML 1.1</span><span class="se">\n</span><span class="s2">---</span><span class="se">\n</span><span class="s2">&#39;test&#39;&quot;</span><span class="p">)</span>  <span class="c1"># all good</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="s2">&quot;test&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<p>P.S. Even if the YAML you are parsing is very simple, <code>YAML</code> silently runs into problems with escaped whitespace (&#8220;foo\ bar&#8221;), erroneously leaving the backslashes in the output.  <code>Psych</code> handles this just fine.</p>

<p>P.P.S. <code>YAML</code> will use Psych instead of Syck as its engine if you have <code>require 'psych'</code> before <code>require 'yaml'</code> &#8211; thanks to Benoit Daloze for pointing this out. If this implicit behavior is causing pains for you, especially with Rails or Bundler, I recommend you read <a href="http://pivotallabs.com/users/mkocher/blog/articles/1692-yaml-psych-and-ruby-1-9-2-p180-here-there-be-dragons">Matthew Kocher&#8217;s post about YAML, Psych, and Syck</a> (and the discussion in the comments there).</p>
]]></content>
      </entry>
    
  
    
      <entry>
        <title type="html"><![CDATA[Capybara roundup]]></title>
        <link href="http://www.opinionatedprogrammer.com/2011/03/capybara-roundup/"/>
        <updated>2011-03-14T00:00:00+00:00</updated>
        <published>2011-03-14T00:00:00+00:00</published>
        <id>http://opinionated-programmer.com/?p=505</id>
        <content type="html"><![CDATA[<p>Here is a roundup of recent changes in and around
<a href="https://github.com/jnicklas/capybara">Capybara</a>. Where they apply to the
Capybara source, they are not included in any release yet, so make sure you are
using the edge version from GitHub (and be prepared for things to break here
and there <code>^_^</code>).</p>

<ul>
<li>The Celerity and Culerity drivers have been extracted into the <a href="https://github.com/sobrinho/capybara-celerity">capybara-celerity</a> and <a href="https://github.com/sobrinho/capybara-culerity">capybara-culerity</a> gems (5c4f28, by Gabriel Sobrinho).  They will be officially supported until (at least) Capybara 1.0, but Jonas <a href="https://groups.google.com/d/msg/ruby-capybara/0ziQ8pJtJnA/2dveetHEScMJ">recommends</a> using <a href="https://github.com/bernerdschaefer/akephalos">Akephalos</a> as your HtmlUnit driver.</li>
<li>For RSpec, Capybara now supports <code>:type =&gt; :request</code> example groups, as suggested by the rspec-rails gem (558e7b, by yours truly).  See <a href="https://github.com/jnicklas/capybara">the README</a>, section &#8220;Using Capybara with RSpec&#8221;.</li>
<li>There is now an (optional) acceptance test DSL for RSpec (f4897f, by Jonas Nicklas and Nicklas Ramhöj).  See <a href="https://github.com/jnicklas/capybara">the README</a> (section &#8220;Using Capybara with RSpec&#8221;) or Jeff Kreeftmeijer&#8217;s <a href="http://jeffkreeftmeijer.com/2011/acceptance-testing-using-capybaras-new-rspec-dsl/">blog post</a>.</li>
<li>The Selenium driver now waits for Ajax requests (021b87, by Maurizio Giambalvo, Jonas, and Nicklas).  Search <a href="https://github.com/jnicklas/capybara">the README</a> for <code>:resynchronize</code> for more info.</li>
<li>Capybara now prefers visible over hidden elements (408423, by Jonas and Nicklas, configurable with <code>Capybara.prefer_visible_elements</code>).</li>
<li>The RSpec matchers, which are responsible for giving you nice error messages (and allow you to write <code>should_not have_css</code> without breaking asynchronous JavaScript, though that&#8217;s not documented yet), have been improved and are now used in Cucumber as well.  Jonas says they might still change a bit, so don&#8217;t rely on them too much.</li>
<li>John Firebaugh wrote a <a href="https://github.com/jfirebaugh/capybara-firebug">capybara-firebug gem</a> to run Capybara with Firebug enabled.</li>
</ul>


<p>Miscellaneous tips and tricks from around the web:</p>

<ul>
<li>Hugo Baraúna of Plataforma suggests that you <a href="http://blog.plataformatec.com.br/2011/02/improving-your-tests-with-capybara-custom-selectors/">improve your tests by using Capybara&#8217;s custom selectors</a>.</li>
<li>Carlos Antônio of Plataforma demonstrates how to <a href="http://blog.plataformatec.com.br/2011/03/configuring-user-agents-with-capybara-selenium-webdriver/">configure the User-Agent header with Capybara and Selenium</a>.</li>
<li>Sara Trice shows <a href="http://saratrice.com/2011/03/09/testing-ckeditor-in-ruby-on-rails-with-cucumbercapybara/">how to test CKEditor</a> in your pages.</li>
<li>Jason Neylon has some example code for <a href="http://jasonneylon.wordpress.com/2011/02/16/selecting-from-a-dropdown-generically-with-capybara/">selecting from a dropdown when you don&#8217;t care about its contents</a>.</li>
<li>Hiroshi Saito suggests a <a href="https://groups.google.com/d/topic/ruby-capybara/H4LsbkXvNBM/discussion">hack to use transactional fixtures with the Akephalos driver</a>.</li>
<li>Jari Bakken shows <a href="https://groups.google.com/d/msg/ruby-capybara/WsTXmDFjzu4/KOAEZEv0OAEJ">how to take screenshots with the Selenium driver</a>.</li>
<li>Leonid Shevtsov started a discussion on <a href="https://github.com/jnicklas/capybara/pull/295">preloading the browser in Spork</a> for Selenium, but we were not able to iron out all the kinks to make it usable.  It would be most awesome to get this working, so if anyone has an idea, please post it!</li>
</ul>


<p>Anything else?  Leave a comment!</p>

<p>P.S. Thanks to <a href="http://elabs.se/">Elabs</a> for continuing to put
company resources into Capybara!  Did you know you can hire them to do agile
web development for you?  (Full disclosure: I&#8217;m not affiliated.)</p>
]]></content>
      </entry>
    
  
</feed>
