<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>The Carbon Emitter</title>
	<atom:link href="http://blog.carbonfive.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.carbonfive.com</link>
	<description>The blog of Carbon Five</description>
	<lastBuildDate>Thu, 19 Apr 2012 16:48:46 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Project/Technology Showcase, April 25th</title>
		<link>http://blog.carbonfive.com/2012/04/17/project-technology-showcase/</link>
		<comments>http://blog.carbonfive.com/2012/04/17/project-technology-showcase/#comments</comments>
		<pubDate>Wed, 18 Apr 2012 00:16:31 +0000</pubDate>
		<dc:creator>Christian Nelson</dc:creator>
				<category><![CDATA[Process]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[fibrous]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[mongo]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://blog.carbonfive.com/?p=6227</guid>
		<description><![CDATA[Carbon Five and Good Eggs are joining up to show off some of the projects they&#8217;ve recently worked with an emphasis on the technology that made them possible. We want to share what we think is interesting and what we&#8217;ve &#8230; <a href="http://blog.carbonfive.com/2012/04/17/project-technology-showcase/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Carbon Five and Good Eggs are joining up to show off some of the projects they&#8217;ve recently worked with an emphasis on the technology that made them possible. We want to share what we think is interesting and what we&#8217;ve learned along the way.</p>

<p><strong>Genetic Symphony</strong> &#8211; A Genentech, IDEO, and Carbon Five collaboration for TED2012. Participants provide a genetic sample via a cheek swab, which is processed overnight and used to generate a unique song and visualization. Tech includes: Backbone, CoffeeScript, Audia, PhoneGap, SoX, RMagick, Rails, Jasmine and Sinon.</p>

<p>Presenters: David Hendee and Sean Durham, Carbon Five</p>

<p><strong>ChatOS</strong> &#8211; A collaborative UX/programming experiment that allows participants to build a shared real-time web experience. It provides the basic plumbing that makes collaborative programming possible and leaves it up to the participants to build the tools and design the interactions. The talk will provide a live, interactive demonstration, and will briefly cover the technology behind the application including Node.js, Mocha.js, HTML 5, Web Sockets, and Mongo DB.</p>

<p>Presenter: Alex Cruikshank, Carbon Five</p>

<p><strong>Escape from the Pyramid of Doom</strong> &#8211; If you set out to build real, reliable apps using Node.js you will need to tame the callback-based asynchronous jungle you find yourself in. For the last several months at Good Eggs we have explored solutions that include a combination of third party libraries, homegrown libraries, and convention. For this talk, we use our journey to provide a survey of different techniques for writing asynchronous code in Node.js including fibrous, the library solution that we currently use to support our established conventions.</p>

<p>Presenters: Alon Salant and Randy Puro, Good Eggs</p>

<p><strong>Q &amp; A</strong> &#8211; We want to continue discussing anything already mentioned, or go over other topics that might be interesting (e.g. js testing, tech stacks, hosting, project management, etc).</p>

<p>Wednesday April 25th. Doors at 6 and talks start around 6:30. Food and drinks will be provided. Huge thanks to CBSi for the venue and sponsoring food/drinks!</p>

<p><strong>Please RSVP on the <a href="http://www.meetup.com/jsmeetup/events/60203352">SF JS meetup event page</a>!</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2012/04/17/project-technology-showcase/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tech Talk: Seth Ladd on Dart</title>
		<link>http://blog.carbonfive.com/2012/04/13/tech-talk-seth-ladd-on-dart/</link>
		<comments>http://blog.carbonfive.com/2012/04/13/tech-talk-seth-ladd-on-dart/#comments</comments>
		<pubDate>Fri, 13 Apr 2012 15:21:32 +0000</pubDate>
		<dc:creator>Christian Nelson</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[dart]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://blog.carbonfive.com/?p=6218</guid>
		<description><![CDATA[Seth Ladd (Google, @sethladd) joined us last week and presented An Introduction to Dart: The structured web development platform. You should check it out, the folks over at Google are doing some interesting things. Dart is young and has potential. &#8230; <a href="http://blog.carbonfive.com/2012/04/13/tech-talk-seth-ladd-on-dart/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Seth Ladd (Google, <a href="https://twitter.com/#!/sethladd">@sethladd</a>) joined us last week and presented <strong>An Introduction to Dart: The structured web development platform</strong>. You should check it out, the folks over at Google are doing some interesting things. Dart is young and has potential.</p>

<iframe src="http://player.vimeo.com/video/40236121" width="500" height="281" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>

<p>Learn more about Dart at <a href="http://dartlang.org" title="dartlang.org" target="_blank">http://dartlang.org</a>.</p>

<p>Thanks Seth! Looking forward to the next one.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2012/04/13/tech-talk-seth-ladd-on-dart/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>UX Recipe: Developer Wireframe Walkthrough</title>
		<link>http://blog.carbonfive.com/2012/03/21/wireframe-walkthrough/</link>
		<comments>http://blog.carbonfive.com/2012/03/21/wireframe-walkthrough/#comments</comments>
		<pubDate>Wed, 21 Mar 2012 23:13:44 +0000</pubDate>
		<dc:creator>David Hendee</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[Process]]></category>
		<category><![CDATA[agile design]]></category>
		<category><![CDATA[collaboration]]></category>
		<category><![CDATA[lean startups]]></category>
		<category><![CDATA[lean ux]]></category>
		<category><![CDATA[recipe]]></category>
		<category><![CDATA[user experience]]></category>

		<guid isPermaLink="false">http://blog.carbonfive.com/?p=6122</guid>
		<description><![CDATA[This is the first in a series of posts highlighting Lean UX practices at Carbon Five. They are presented as &#8216;recipes&#8217; for you try out for yourself, then alter them to make them your own. While more and more of &#8230; <a href="http://blog.carbonfive.com/2012/03/21/wireframe-walkthrough/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><em>This is the first in a series of posts highlighting Lean UX practices at Carbon Five. They are presented as &#8216;recipes&#8217; for you try out for yourself, then alter them to make them your own.</em></p>

<p><img src="http://blog.carbonfive.com/wp-content/uploads/2012/03/wireframe-walkthrough.jpg" alt="Wireframe Walkthrough" title="wireframe-walkthrough" width="440" class="aligncenter size-full wp-image-6127" /></p>

<p>While more and more of our clients are engaging us in full-service design/build projects, we still enjoy working with outside or on-staff designers. And even when we are providing design services, we always want to maximize the collaboration between the designers, engineers and business owners on our projects.</p>

<p>Last year, Janice Fraser of <a href="http://luxr.co/">LUXr</a> introduced us to an activity called the &#8220;Wireframe Walkthrough.&#8221; It&#8217;s probably something you&#8217;re already doing on projects without quite putting a formal name or process around it. We&#8217;ve taken the activity and deconstructed it a bit, added our insights, and put a fancy title on it in the hopes that others will try it out and add their experience and wisdom.</p>

<span id="more-6122"></span>

<h2>What is it?</h2>

<p>A collaborative design critique from a technical perspective to identify hard features and suggest alternatives.</p>

<h2>Why do it?</h2>

<p>By engaging designers and engineers in a constructive discussion of tradeoffs you stand to get more bang for your development buck. Posting wireframes on walls also helps externalize ideas and define the project&#8217;s collaborative space.</p>

<h2>When to do it?</h2>

<p>It’s typically done weekly during the planning session as the designers generate wireframes for the next iteration or two; but it can be done any time and should definitely be done during kickoff.</p>

<h2>How to do it?</h2>

<ol>
<li><em>(Designer)</em> <strong>Print out and post the latest wireframes on a wall at gallery height.</strong> Find a developer and put them at arms length from the drawings.</li>
<li><em>(Developer)</em> <strong>Ask about the current state of the designs and what kind of feedback they&#8217;re looking for.</strong> Find out if the designer is more interested in generative or evaluative feedback. Try asking &#8220;Where are you at?&#8221;</li>
<li><em>(Designer)</em> <strong>Let the developer know about your goals for the walkthrough.</strong> For instance, say &#8220;I&#8217;m really interested in hearing your thoughts on&#8230;&#8221;</li>
<li><em>(Developer)</em> <strong>Acknowledge the challenge.</strong> Good design is as hard as writing good code. Share some enthusiasm. Then walk through the flow, pointing where your mouse would be. Narrate what you are thinking and doing as a user. Say things like &#8220;I&#8217;m trying to find the contact us page.&#8221;</li>
<li><em>(Designer)</em> <strong>Take notes on stickies.</strong> Place the stickies directly on the wireframes to mark the location of the comment or observation. This is essentially a free usability test!</li>
<li><em>(Developer)</em> <strong>Note missing functionality or difficult technical challenges.</strong> Ask questions about the user rather than making statements. For instance: &#8220;How would I find a forgotten password?&#8221; rather than &#8220;You forgot the forgot your password screen.&#8221; Keep in mind that this is a cooperative discussion about the design, not a judgement on the designer.</li>
<li><em>(Designer)</em> <strong>Take notes and offer insights into the current design solution.</strong> Listen, breathe, and try not to get defensive (or think of elephants). Postpone deep or off-topic discussions. For instance, say &#8220;That&#8217;s something we&#8217;ve been really struggling with. We should schedule a meeting to talk about that after.&#8221;</li>
<li><em>(Developer)</em> <strong>Suggest alternatives to any particularly challenging engineering implications.</strong> Try engaging the designer with phrases like &#8220;What user need are we trying to address here?&#8221; or &#8220;We could try&#8230; and get a similar result with less effort.&#8221; Challenge yourself and throw the designer a bone by saying something like &#8220;This is the main feature so it makes sense that we spend extra time on it.&#8221;</li>
<li><em>(Designer)</em> <strong>Thank the developer.</strong> Incorporate feedback as appropriate. Rinse and repeat. It&#8217;s better to do this a little bit all the time.</li>
</ol>

<p>That&#8217;s it! Please let us know if you have any tricks or tips to add, or if you have a suggestion for our next  Lean UX &#8216;recipe.&#8217;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2012/03/21/wireframe-walkthrough/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>How to Test External APIs</title>
		<link>http://blog.carbonfive.com/2012/03/18/how-to-test-external-apis/</link>
		<comments>http://blog.carbonfive.com/2012/03/18/how-to-test-external-apis/#comments</comments>
		<pubDate>Sun, 18 Mar 2012 19:24:34 +0000</pubDate>
		<dc:creator>Jared Carroll</dc:creator>
				<category><![CDATA[Process]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[rspec]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[vcr]]></category>

		<guid isPermaLink="false">http://blog.carbonfive.com/?p=6081</guid>
		<description><![CDATA[Integrating with an external API is almost a guarantee in any modern web app. To effectively test such integration, you need to stub it out. A good stub should be easy to create and consistently up-to-date with actual, current API &#8230; <a href="http://blog.carbonfive.com/2012/03/18/how-to-test-external-apis/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>
Integrating with an external API is almost a guarantee in any modern web app. To effectively test such integration, you need to stub it out. A good stub should be easy to create and consistently up-to-date with actual, current API responses. In this post, we&#8217;ll outline a testing strategy using stubs for an external API.
</p>

<span id="more-6081"></span>

<h2>Integrating with an External API</h2>

<p>
Our example app is a stock Rails 3.2 app. Let&#8217;s imagine that we&#8217;re assigned the following story:
</p>

<div id="gist-2048534" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'>In order to find interesting links for the intellectually curious</div><div class='line' id='LC2'>As a user</div><div class='line' id='LC3'>I want to see the latest Hacker News posts on the homepage</div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/2048534/b6706893cd830a57da29258b5748928198e87950/9.txt" style="float:right;">view raw</a>
            <a href="https://gist.github.com/2048534#file_9.txt" style="float:right;margin-right:10px;color:#666">9.txt</a>
            <a href="https://gist.github.com/2048534">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>


<p>
This story involves integrating content from an external site.  Hacker News doesn&#8217;t have an API, but they do have an <a href="http://news.ycombinator.com/rss">RSS feed</a> that we can use instead.
</p>

<h2>The Testing Strategy</h2>

<p>
A typical implementation of our story will look something like this:
</p>

<ol>
  <li>
    A request for the homepage is routed by Rails to a controller.
  </li>
  <li>
    The controller asks a <code>Post</code> model for recent posts.
  </li>
  <li>
    The <code>Post</code> model asks a Hacker News library for recent posts.
  </li>
  <li>
    The Hacker News library gets the latest posts from the Hacker News RSS feed.
  </li>
</ol>

<p>
To test this we&#8217;ll:
</p>

<ol>
  <li>
    Start with an end-to-end integration test. I like to use RSpec, so we&#8217;ll use RSpec Rails&#8217; <a href="https://www.relishapp.com/rspec/rspec-rails/docs/request-specs/request-spec">request specs</a>. <a href="http://rubygems.org/gems/vcr">vcr</a> will be used to record the actual Hacker News HTTP request and response.
  </li>
  <li>
    Skip controller specs. Directly specifying the controller won&#8217;t gain us much, because it will be thin and completely exercised by the request spec. 
  </li>
  <li>
    Mock out the Hacker News library in the <code>Post</code> model&#8217;s specs. Since we already have an integration test, there&#8217;s no need to perform another mini-integration test between our domain model and its collaborator.
  </li>
  <li>
    Specify the Hacker News library directly. Instead of mocking, we&#8217;ll again use <code>vcr</code> to record the actual Hacker News HTTP request and response. This will give us the ability in the future to change our HTTP client without breaking our specs.
  </li>
</ol>

<h2>Starting at the Outside with a Request Spec</h2>

<p>
Our request spec uses <a href="http://rubygems.org/gems/capybara">capybara</a> to simulate a homepage request.  We tell <code>vcr</code> to record any HTTP requests by using its <a href="https://www.relishapp.com/myronmarston/vcr/v/2-0-0/docs/test-frameworks/usage-with-rspec-metadata">RSpec metadata</a> support.
</p>

<p><em>spec/requests/homepage_spec.rb</em></p>

<div id="gist-2048534" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="nb">require</span> <span class="s1">&#39;spec_helper&#39;</span></div><div class='line' id='LC2'><br/></div><div class='line' id='LC3'><span class="n">describe</span> <span class="s1">&#39;The homepage&#39;</span><span class="p">,</span> <span class="ss">:vcr</span> <span class="k">do</span></div><div class='line' id='LC4'>&nbsp;&nbsp;<span class="n">before</span> <span class="k">do</span></div><div class='line' id='LC5'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">visit</span> <span class="s1">&#39;/&#39;</span></div><div class='line' id='LC6'>&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC7'><br/></div><div class='line' id='LC8'>&nbsp;&nbsp;<span class="n">it</span> <span class="s1">&#39;displays recent posts from Hacker News&#39;</span> <span class="k">do</span></div><div class='line' id='LC9'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">hacker_news_links</span> <span class="o">=</span> <span class="n">all</span> <span class="s1">&#39;#hn .post a&#39;</span></div><div class='line' id='LC10'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">hacker_news_links</span><span class="o">.</span><span class="n">should_not</span> <span class="n">be_empty</span></div><div class='line' id='LC11'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">hacker_news_links</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">link</span><span class="o">|</span></div><div class='line' id='LC12'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">link</span><span class="o">[</span><span class="ss">:href</span><span class="o">].</span><span class="n">should</span> <span class="n">match</span><span class="p">(</span><span class="sr">%r{http://news\.ycombinator\.com}</span><span class="p">)</span></div><div class='line' id='LC13'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC14'>&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC15'><span class="k">end</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/2048534/8f5c2626c75058846664393564eb853add9b6379/0.rb" style="float:right;">view raw</a>
            <a href="https://gist.github.com/2048534#file_0.rb" style="float:right;margin-right:10px;color:#666">0.rb</a>
            <a href="https://gist.github.com/2048534">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>


<p>
The first time this spec is run, <code>vcr</code> will record the actual Hacker News HTTP request and response and save it to the filesystem. Future spec runs will then reuse this recorded HTTP interaction. Since we don&#8217;t know the latest posts on Hacker News at the time this spec is first run, we only specify an expected DOM structure.
</p>

<div id="gist-2048534" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'>$ rspec spec/requests/homepage_spec.rb                                                                                                                                  </div><div class='line' id='LC2'>F</div><div class='line' id='LC3'><br/></div><div class='line' id='LC4'>Failures:</div><div class='line' id='LC5'><br/></div><div class='line' id='LC6'>&nbsp;&nbsp;1) The homepage displays recent posts from Hacker News</div><div class='line' id='LC7'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Failure/Error: visit &#39;/&#39;</div><div class='line' id='LC8'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ActionController::RoutingError:</div><div class='line' id='LC9'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;No route matches [GET] &quot;/&quot;</div><div class='line' id='LC10'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# ./spec/requests/homepage_spec.rb:5:in `block (2 levels) in &lt;top (required)&gt;&#39;</div><div class='line' id='LC11'><br/></div><div class='line' id='LC12'>Finished in 0.05392 seconds</div><div class='line' id='LC13'>1 example, 1 failure</div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/2048534/3ffdf37575526e0d1f516afa0450754afe4514ed/1.txt" style="float:right;">view raw</a>
            <a href="https://gist.github.com/2048534#file_1.txt" style="float:right;margin-right:10px;color:#666">1.txt</a>
            <a href="https://gist.github.com/2048534">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>


<p>
This failing spec guides us to the following controller and view implementation.
</p>

<p><em>config/routes.rb</em></p>

<div id="gist-2048534" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="no">Sample</span><span class="o">::</span><span class="no">Application</span><span class="o">.</span><span class="n">routes</span><span class="o">.</span><span class="n">draw</span> <span class="k">do</span></div><div class='line' id='LC2'>&nbsp;&nbsp;<span class="n">root</span> <span class="n">to</span><span class="p">:</span> <span class="s1">&#39;posts#index&#39;</span></div><div class='line' id='LC3'><span class="k">end</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/2048534/4333a29b655706cea6b45c0269c69f41981bb6fe/2.rb" style="float:right;">view raw</a>
            <a href="https://gist.github.com/2048534#file_2.rb" style="float:right;margin-right:10px;color:#666">2.rb</a>
            <a href="https://gist.github.com/2048534">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>


<p><em>app/views/posts/index.html.haml</em></p>

<div id="gist-2048534" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="nf">#hn</span></div><div class='line' id='LC2'>&nbsp;&nbsp;<span class="p">-</span> <span class="vi">@recent_posts</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">post</span><span class="o">|</span></div><div class='line' id='LC3'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nc">.post</span></div><div class='line' id='LC4'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">=</span> <span class="n">link_to</span> <span class="n">post</span><span class="o">.</span><span class="n">title</span><span class="p">,</span> <span class="n">post</span><span class="o">.</span><span class="n">url</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/2048534/91814ad4a7646b7400be40a9c19b5d6befff85f5/3.html.haml" style="float:right;">view raw</a>
            <a href="https://gist.github.com/2048534#file_3.html.haml" style="float:right;margin-right:10px;color:#666">3.html.haml</a>
            <a href="https://gist.github.com/2048534">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>


<p><em>app/controllers/posts_controller.rb</em></p>

<div id="gist-2048534" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="k">class</span> <span class="nc">PostsController</span> <span class="o">&lt;</span> <span class="no">ApplicationController</span></div><div class='line' id='LC2'>&nbsp;&nbsp;<span class="k">def</span> <span class="nf">index</span></div><div class='line' id='LC3'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="vi">@recent_posts</span> <span class="o">=</span> <span class="no">Post</span><span class="o">.</span><span class="n">recent</span></div><div class='line' id='LC4'>&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC5'><span class="k">end</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/2048534/1c6955dc21e5466fbe114ff6f00498b931b1793a/4.rb" style="float:right;">view raw</a>
            <a href="https://gist.github.com/2048534#file_4.rb" style="float:right;margin-right:10px;color:#666">4.rb</a>
            <a href="https://gist.github.com/2048534">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>


<p>
The second run of the request spec goes further than the first, moving us to the domain model.
</p>

<div id="gist-2048534" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'>$ rspec spec/requests/homepage_spec.rb                                                                                                                                  F</div><div class='line' id='LC2'><br/></div><div class='line' id='LC3'>Failures:</div><div class='line' id='LC4'><br/></div><div class='line' id='LC5'>&nbsp;&nbsp;1) The homepage displays recent posts from Hacker News</div><div class='line' id='LC6'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Failure/Error: visit &#39;/&#39;</div><div class='line' id='LC7'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NameError:</div><div class='line' id='LC8'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uninitialized constant PostsController::Post</div><div class='line' id='LC9'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# ./app/controllers/posts_controller.rb:3:in `index&#39;</div><div class='line' id='LC10'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# ./spec/requests/homepage_spec.rb:5:in `block (2 levels) in &lt;top (required)&gt;&#39;</div><div class='line' id='LC11'><br/></div><div class='line' id='LC12'>Finished in 0.07371 seconds</div><div class='line' id='LC13'>1 example, 1 failure</div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/2048534/376fc12df8f433540e383bf6a8e8c8f7eab65c43/5.txt" style="float:right;">view raw</a>
            <a href="https://gist.github.com/2048534#file_5.txt" style="float:right;margin-right:10px;color:#666">5.txt</a>
            <a href="https://gist.github.com/2048534">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>


<h2>Mocking Collaborators in the Domain Model Spec</h2>

<p>
Instead of programming our controllers and views to the interface of our Hacker News library, we&#8217;ll introduce a domain model. The domain model is where we&#8217;ll consolidate our app&#8217;s business logic. It also gives us another level of indirection, allowing us in the future to change how we get Hacker News content without having to change our controllers and views.
</p>

<p>
Our domain model won&#8217;t directly make any HTTP requests. Instead, it will collaborate with a separate Hacker News library that will be responsible for making HTTP requests and parsing RSS.  This library acts as an <a href="http://c2.com/cgi/wiki?PortsAndAdaptersArchitecture">adapter layer</a>, allowing our domain model to define its relationship to the outside world in its own terms.  With an integration test already in place, we can use mocking to test our domain model in isolation.
</p>

<p><em>spec/models/post_spec.rb</em></p>

<div id="gist-2048534" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="nb">require</span> <span class="s1">&#39;spec_helper&#39;</span></div><div class='line' id='LC2'><br/></div><div class='line' id='LC3'><span class="n">describe</span> <span class="no">Post</span> <span class="k">do</span></div><div class='line' id='LC4'>&nbsp;&nbsp;<span class="n">describe</span> <span class="s1">&#39;.recent&#39;</span> <span class="k">do</span></div><div class='line' id='LC5'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">before</span> <span class="k">do</span></div><div class='line' id='LC6'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">posts</span> <span class="o">=</span> <span class="o">[</span></div><div class='line' id='LC7'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">{</span> <span class="n">title</span><span class="p">:</span> <span class="s1">&#39;Post #1&#39;</span><span class="p">,</span> <span class="n">url</span><span class="p">:</span> <span class="s1">&#39;http://example.com/1&#39;</span> <span class="p">},</span></div><div class='line' id='LC8'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">{</span> <span class="n">title</span><span class="p">:</span> <span class="s1">&#39;Post #2&#39;</span><span class="p">,</span> <span class="n">url</span><span class="p">:</span> <span class="s1">&#39;http://example.com/2&#39;</span> <span class="p">},</span></div><div class='line' id='LC9'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">{</span> <span class="n">title</span><span class="p">:</span> <span class="s1">&#39;Post #3&#39;</span><span class="p">,</span> <span class="n">url</span><span class="p">:</span> <span class="s1">&#39;http://example.com/3&#39;</span> <span class="p">}</span></div><div class='line' id='LC10'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">]</span></div><div class='line' id='LC11'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="no">HN</span><span class="o">::</span><span class="no">Post</span></div><div class='line' id='LC12'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">.</span><span class="n">should_receive</span><span class="p">(</span><span class="ss">:recent</span><span class="p">)</span></div><div class='line' id='LC13'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">.</span><span class="n">and_return</span><span class="p">(</span><span class="n">posts</span><span class="p">)</span></div><div class='line' id='LC14'><br/></div><div class='line' id='LC15'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="vi">@recent_posts</span> <span class="o">=</span> <span class="no">Post</span><span class="o">.</span><span class="n">recent</span></div><div class='line' id='LC16'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC17'><br/></div><div class='line' id='LC18'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">it</span> <span class="s1">&#39;returns recent posts&#39;</span> <span class="k">do</span></div><div class='line' id='LC19'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="vi">@recent_posts</span><span class="o">.</span><span class="n">should</span> <span class="n">have</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span><span class="o">.</span><span class="n">posts</span></div><div class='line' id='LC20'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC21'><br/></div><div class='line' id='LC22'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">it</span> <span class="s1">&#39;sets their title&#39;</span> <span class="k">do</span></div><div class='line' id='LC23'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="vi">@recent_posts</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">post</span><span class="o">|</span></div><div class='line' id='LC24'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">post</span><span class="o">.</span><span class="n">title</span><span class="o">.</span><span class="n">should</span> <span class="n">be</span></div><div class='line' id='LC25'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC26'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC27'><br/></div><div class='line' id='LC28'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">it</span> <span class="s1">&#39;sets their url&#39;</span> <span class="k">do</span></div><div class='line' id='LC29'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="vi">@recent_posts</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">post</span><span class="o">|</span></div><div class='line' id='LC30'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">post</span><span class="o">.</span><span class="n">url</span><span class="o">.</span><span class="n">should</span> <span class="n">be</span></div><div class='line' id='LC31'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC32'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC33'>&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC34'><span class="k">end</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/2048534/1cdf44bf2a96281f7b401d8e35d7a2e5358af72f/6.rb" style="float:right;">view raw</a>
            <a href="https://gist.github.com/2048534#file_6.rb" style="float:right;margin-right:10px;color:#666">6.rb</a>
            <a href="https://gist.github.com/2048534">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>


<p><em>lib/hn/post.rb</em></p>

<div id="gist-2048534" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="k">module</span> <span class="nn">HN</span></div><div class='line' id='LC2'>&nbsp;&nbsp;<span class="k">class</span> <span class="nc">Post</span></div><div class='line' id='LC3'>&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC4'><span class="k">end</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/2048534/ade3d07ef597436799945c73a73532186b7af280/7.rb" style="float:right;">view raw</a>
            <a href="https://gist.github.com/2048534#file_7.rb" style="float:right;margin-right:10px;color:#666">7.rb</a>
            <a href="https://gist.github.com/2048534">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>


<p><em>app/models/post.rb</em></p>

<div id="gist-2048534" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="k">class</span> <span class="nc">Post</span></div><div class='line' id='LC2'>&nbsp;&nbsp;<span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">recent</span></div><div class='line' id='LC3'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">posts</span> <span class="o">=</span> <span class="no">HN</span><span class="o">::</span><span class="no">Post</span><span class="o">.</span><span class="n">recent</span></div><div class='line' id='LC4'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">posts</span><span class="o">.</span><span class="n">collect</span> <span class="k">do</span> <span class="o">|</span><span class="n">post</span><span class="o">|</span></div><div class='line' id='LC5'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="kp">new</span> <span class="n">post</span></div><div class='line' id='LC6'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC7'>&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC8'><br/></div><div class='line' id='LC9'>&nbsp;&nbsp;<span class="kp">attr_accessor</span> <span class="ss">:title</span><span class="p">,</span></div><div class='line' id='LC10'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="ss">:url</span></div><div class='line' id='LC11'><br/></div><div class='line' id='LC12'>&nbsp;&nbsp;<span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">attributes</span><span class="p">)</span></div><div class='line' id='LC13'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nb">self</span><span class="o">.</span><span class="n">title</span> <span class="o">=</span> <span class="n">attributes</span><span class="o">[</span><span class="ss">:title</span><span class="o">]</span></div><div class='line' id='LC14'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nb">self</span><span class="o">.</span><span class="n">url</span> <span class="o">=</span> <span class="n">attributes</span><span class="o">[</span><span class="ss">:url</span><span class="o">]</span></div><div class='line' id='LC15'>&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC16'><span class="k">end</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/2048534/5514de8b079b50e9f4bc2b28469b4ab6b126882a/8.rb" style="float:right;">view raw</a>
            <a href="https://gist.github.com/2048534#file_8.rb" style="float:right;margin-right:10px;color:#666">8.rb</a>
            <a href="https://gist.github.com/2048534">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>


<p>
Our domain model is now specified but a re-run of our request spec reminds us we still have work to do. Mocking allowed us to implement our domain model by faking its collaborator, but we still have to implement that collaborator. Whenever you mock, you must have a higher-level test that actually tests the full integration between all your objects.
</p>

<div id="gist-2048540" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'>$ rspec spec/requests/homepage_spec.rb</div><div class='line' id='LC2'>F</div><div class='line' id='LC3'><br/></div><div class='line' id='LC4'>Failures:</div><div class='line' id='LC5'><br/></div><div class='line' id='LC6'>&nbsp;&nbsp;1) The homepage displays recent posts from Hacker News</div><div class='line' id='LC7'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Failure/Error: visit &#39;/&#39;</div><div class='line' id='LC8'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NoMethodError:</div><div class='line' id='LC9'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;undefined method `recent&#39; for HN::Post:Class</div><div class='line' id='LC10'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# ./app/models/post.rb:3:in `recent&#39;</div><div class='line' id='LC11'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# ./app/controllers/posts_controller.rb:3:in `index&#39;</div><div class='line' id='LC12'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# ./spec/requests/homepage_spec.rb:5:in `block (2 levels) in &lt;top (required)&gt;&#39;</div><div class='line' id='LC13'><br/></div><div class='line' id='LC14'>Finished in 0.066 seconds</div><div class='line' id='LC15'>1 example, 1 failure</div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/2048540/33bd1af1e083fa601c9cf28dcd325e4d3adb493e/0.txt" style="float:right;">view raw</a>
            <a href="https://gist.github.com/2048540#file_0.txt" style="float:right;margin-right:10px;color:#666">0.txt</a>
            <a href="https://gist.github.com/2048540">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>


<p>
We can now drop back down and spec out the Hacker News library.
</p>

<h2>Black-Box Testing the Library</h2>

<p>
Our Hacker News library will be responsible for getting the latest posts from Hacker News.  Like in our request spec, we&#8217;ll use <code>vcr</code> to record the actual HTTP request and response to Hacker News. This keeps our spec accurate. Future runs of this spec will then reuse the recorded HTTP interaction.  This keeps our spec fast. Stubbing at the HTTP level instead of mocking out our HTTP client, gives us the ability to change our HTTP client later (granted it&#8217;s one of <code>vcr</code>&#8216;s <a href="https://github.com/myronmarston/vcr">supported HTTP clients</a>).
</p>

<p><em>spec/lib/hn/post_spec.rb</em></p>

<div id="gist-2048540" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="nb">require</span> <span class="s1">&#39;spec_helper&#39;</span></div><div class='line' id='LC2'><br/></div><div class='line' id='LC3'><span class="n">describe</span> <span class="no">HN</span><span class="o">::</span><span class="no">Post</span> <span class="k">do</span></div><div class='line' id='LC4'>&nbsp;&nbsp;<span class="n">describe</span> <span class="s1">&#39;.recent&#39;</span><span class="p">,</span> <span class="ss">:vcr</span> <span class="k">do</span></div><div class='line' id='LC5'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">before</span> <span class="k">do</span></div><div class='line' id='LC6'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="vi">@posts</span> <span class="o">=</span> <span class="no">HN</span><span class="o">::</span><span class="no">Post</span><span class="o">.</span><span class="n">recent</span></div><div class='line' id='LC7'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC8'><br/></div><div class='line' id='LC9'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">it</span> <span class="s1">&#39;returns recently submitted posts from Hacker News&#39;</span> <span class="k">do</span></div><div class='line' id='LC10'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="vi">@posts</span><span class="o">.</span><span class="n">should_not</span> <span class="n">be_empty</span></div><div class='line' id='LC11'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="vi">@posts</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">post</span><span class="o">|</span></div><div class='line' id='LC12'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">post</span><span class="o">.</span><span class="n">should</span> <span class="n">have_key</span><span class="p">(</span><span class="ss">:title</span><span class="p">)</span></div><div class='line' id='LC13'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">post</span><span class="o">.</span><span class="n">should</span> <span class="n">have_key</span><span class="p">(</span><span class="ss">:url</span><span class="p">)</span></div><div class='line' id='LC14'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">post</span><span class="o">[</span><span class="ss">:url</span><span class="o">].</span><span class="n">should</span> <span class="n">match</span><span class="p">(</span><span class="sr">%r{http://news\.ycombinator\.com}</span><span class="p">)</span></div><div class='line' id='LC15'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC16'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC17'>&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC18'><span class="k">end</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/2048540/52bd635c47ac4f52e07e3aca89d1355747c0e6ee/1.rb" style="float:right;">view raw</a>
            <a href="https://gist.github.com/2048540#file_1.rb" style="float:right;margin-right:10px;color:#666">1.rb</a>
            <a href="https://gist.github.com/2048540">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>


<p>
<a href="http://rubygems.org/gems/typhoeus">typhoeus</a> and Ruby 1.9.3&#8242;s <a href="http://www.ruby-doc.org/stdlib-1.9.3/libdoc/rss/rdoc/RSS.html">RSS library</a> work together to request and parse the Hacker News RSS feed.
</p>

<p><em>lib/hn/post.rb</em></p>

<div id="gist-2048540" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="nb">require</span> <span class="s1">&#39;rss&#39;</span></div><div class='line' id='LC2'><br/></div><div class='line' id='LC3'><span class="k">module</span> <span class="nn">HN</span></div><div class='line' id='LC4'>&nbsp;&nbsp;<span class="k">class</span> <span class="nc">Post</span></div><div class='line' id='LC5'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">recent</span></div><div class='line' id='LC6'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">response</span> <span class="o">=</span> <span class="no">Typhoeus</span><span class="o">::</span><span class="no">Request</span><span class="o">.</span><span class="n">get</span> <span class="s1">&#39;http://news.ycombinator.com/rss&#39;</span></div><div class='line' id='LC7'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">feed</span> <span class="o">=</span> <span class="no">RSS</span><span class="o">::</span><span class="no">Parser</span><span class="o">.</span><span class="n">parse</span> <span class="n">response</span><span class="o">.</span><span class="n">body</span></div><div class='line' id='LC8'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">feed</span><span class="o">.</span><span class="n">items</span><span class="o">.</span><span class="n">collect</span> <span class="k">do</span> <span class="o">|</span><span class="n">item</span><span class="o">|</span></div><div class='line' id='LC9'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">{</span> <span class="n">title</span><span class="p">:</span> <span class="n">item</span><span class="o">.</span><span class="n">title</span><span class="p">,</span></div><div class='line' id='LC10'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">url</span><span class="p">:</span> <span class="n">item</span><span class="o">.</span><span class="n">comments</span> <span class="p">}</span></div><div class='line' id='LC11'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC12'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC13'>&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC14'><span class="k">end</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/2048540/9cd50a7bf6ae059eed8b67103da9d7b8e86fa99e/2.rb" style="float:right;">view raw</a>
            <a href="https://gist.github.com/2048540#file_2.rb" style="float:right;margin-right:10px;color:#666">2.rb</a>
            <a href="https://gist.github.com/2048540">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>


<p>
With our library specified, we can move back up to our request spec, which should now be passing.
</p>

<div id="gist-2048540" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'>$ rspec spec/requests/homepage_spec.rb</div><div class='line' id='LC2'>.</div><div class='line' id='LC3'><br/></div><div class='line' id='LC4'>Finished in 0.1785 seconds</div><div class='line' id='LC5'>1 example, 0 failures</div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/2048540/9d872fa660b2ab7073ccc8bcef00e663ba3f87b3/4.txt" style="float:right;">view raw</a>
            <a href="https://gist.github.com/2048540#file_4.txt" style="float:right;margin-right:10px;color:#666">4.txt</a>
            <a href="https://gist.github.com/2048540">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>


<h2>Staying in Sync with External APIs</h2>

<p>
In our request and library specs, we used <code>vcr</code> to record an actual HTTP request to Hacker News and then in future spec runs reused that recorded HTTP interaction. The specs were accurate and fast but, if the Hacker News RSS feed changes, our specs still continue to pass. We need to keep our stubs up-to-date.
</p>

<p>
Fortunately <code>vcr</code> can be configured to automatically re-record &#8220;out-of-date&#8221; HTTP interactions.
</p>

<p><em>spec/support/vcr.rb</em></p>

<div id="gist-2048540" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="no">VCR</span><span class="o">.</span><span class="n">configure</span> <span class="k">do</span> <span class="o">|</span><span class="n">config</span><span class="o">|</span></div><div class='line' id='LC2'>&nbsp;&nbsp;<span class="n">config</span><span class="o">.</span><span class="n">hook_into</span> <span class="ss">:webmock</span></div><div class='line' id='LC3'>&nbsp;&nbsp;<span class="n">config</span><span class="o">.</span><span class="n">cassette_library_dir</span> <span class="o">=</span> <span class="s1">&#39;spec/fixtures/vcr_cassettes&#39;</span></div><div class='line' id='LC4'>&nbsp;&nbsp;<span class="n">config</span><span class="o">.</span><span class="n">configure_rspec_metadata!</span></div><div class='line' id='LC5'>&nbsp;&nbsp;<span class="n">config</span><span class="o">.</span><span class="n">preserve_exact_body_bytes</span> <span class="p">{</span> <span class="kp">true</span> <span class="p">}</span></div><div class='line' id='LC6'>&nbsp;&nbsp;<span class="n">config</span><span class="o">.</span><span class="n">default_cassette_options</span> <span class="o">=</span> <span class="p">{</span></div><div class='line' id='LC7'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">re_record_interval</span><span class="p">:</span> <span class="mi">1</span><span class="o">.</span><span class="n">week</span></div><div class='line' id='LC8'>&nbsp;&nbsp;<span class="p">}</span></div><div class='line' id='LC9'><span class="k">end</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/2048540/ffdd7178c084a6a64cd41ae6fff58a750f34c9c9/5.rb" style="float:right;">view raw</a>
            <a href="https://gist.github.com/2048540#file_5.rb" style="float:right;margin-right:10px;color:#666">5.rb</a>
            <a href="https://gist.github.com/2048540">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>


<p>
<code>vcr</code> stores a timestamp alongside every recorded HTTP interaction. The above <code>default_cassette_options</code> configuration tells <code>vcr</code> to re-record all HTTP interactions that are older than 1 week.
</p>

<h2>Summary</h2>

<p>
Depending on an external API in your test suite can easily lead to tests that sometimes pass and sometimes fail. To make your tests run consistently, stub out external APIs. Ensure your stubs are accurate by creating them from actual API responses. And finally, remember to routinely verify that your stubs are up-to-date with the current state of the external API.
</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2012/03/18/how-to-test-external-apis/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Customizing the iOS keyboard</title>
		<link>http://blog.carbonfive.com/2012/03/12/customizing-the-ios-keyboard/</link>
		<comments>http://blog.carbonfive.com/2012/03/12/customizing-the-ios-keyboard/#comments</comments>
		<pubDate>Tue, 13 Mar 2012 06:20:29 +0000</pubDate>
		<dc:creator>Jonah Williams</dc:creator>
				<category><![CDATA[Mobile]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[objective-c]]></category>

		<guid isPermaLink="false">http://blog.carbonfive.com/?p=6068</guid>
		<description><![CDATA[Our applications need input and the default iOS keyboards are often not optimally suited to providing the sort of data we want. When we find that we really wish the keyboard had some extra controls or want to help our &#8230; <a href="http://blog.carbonfive.com/2012/03/12/customizing-the-ios-keyboard/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Our applications need input and the default iOS keyboards are often not optimally suited to providing the sort of data we want. When we find that we really wish the keyboard had some extra controls or want to help our users enter a specific set of symbols it is time to customize our apps&#8217; keyboards.</p>

<span id="more-6068"></span>

<p><strong>What controls the keyboard anyway?</strong></p>

<p>Our first exposure to different keyboard types probably comes from <code>UITextField</code> and <code>UITextView</code>. Both provide conform to the <code>UITextInputTraits</code> protocol which gives us options to set the keyboard type, return key type, keyboard appearance, and other behaviors. Those options cover many of the types of text input we might want to support; plain text, passwords, email addresses, urls, and so on. That&#8217;s a good place to start customizing our keyboard options but <code>UITextInputTraits</code> itself doesn&#8217;t present the keyboard so when we need behavior the protocol doesn&#8217;t provide we will have to keep looking.</p>

<p>Traversing up the class hierarchy we see that <code>UITextField</code>, <code>UITextView</code>, and indeed all <code>UIView</code> objects inherit from <code>UIResponer</code>. All of the responder objects in our views form a responder chain, a sequence of objects which will be given a chance to respond to non-touch input events. (If this isn&#8217;t a familiar topic then take a look at &#8220;Responder Objects and the Responder Chain&#8221; in the &#8220;Event Handling Guide for iOS&#8221; for a full discussion of how the system works.)  Whenever a responder becomes the first responder (see <code>-becomeFirstResponer</code>) it determines what, if any, keyboard needs to be shown.
<code>UIResponder</code> gives us two read-only properties for controlling the keyboard&#8217;s appearance; <code>inputView</code> which provides the keyboard itself and <code>inputAccessoryView</code> which controls the accessory view attached to the top of the keyboard (containing the &#8220;next&#8221; and &#8220;previous&#8221; buttons when editing a form in Mobile Safari for example). By returning our own views from these properties we can replace the system keyboards with any custom <code>UIView</code> we care to construct.</p>

<p><strong>Start simple: customizing UITextView</strong></p>

<p><code>UITextField</code> (and <code>UITextView</code>) redefine their <code>inputView</code> and <code>inputAccessoryView</code> properties to be <code>readwrite</code> instead of <code>readonly</code>. When working with these view classes we can therefore set their keyboard easily from some other class, like our view controller.</p>

<p>Suppose we were want to support editing <a href="http://daringfireball.net/projects/markdown/">markdown</a> formatted text in our app. The system keyboards work well for this but it takes three taps to enter a # or * and &#92; doesn&#8217;t appear on the keyboard at all. That&#8217;s going to make it difficult for our users to emphasize text or insert code blocks. Let&#8217;s add an input accessory view to give them &#8220;emphasize&#8221;, &#8220;strong&#8221;, and &#8220;code&#8221; formatting controls.</p>

<p>Given a simple view controller with <code>UITextView *textView</code> and <code>UIView *accessoryView</code> outlets we can set the text view&#8217;s <code>inputAccessoryView</code> in our <code>-viewDidLoad</code>.</p>

<pre><code><pre class="brush: objc; title: ; notranslate">@interface MarkdownViewController : UIViewController

@property (nonatomic, strong) IBOutlet UITextView *textView;
@property (nonatomic, strong) IBOutlet UIView *accessoryView;

@end

@implementation MarkdownViewController

@synthesize textView;
@synthesize accessoryView;

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.textView.inputAccessoryView = self.accessoryView;
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    self.textView = nil;
    self.accessoryView = nil;
}

@end</pre>
</code></pre>

<p>Now when the text view becomes the first responder we see our accessory view added to the top of the keyboard.</p>

<p><a href="http://blog.carbonfive.com/2012/03/12/customizing-the-ios-keyboard/screen-shot-2012-03-12-at-11-16-31-pm/" rel="attachment wp-att-6071"><img src="http://blog.carbonfive.com/wp-content/uploads/2012/03/Screen-Shot-2012-03-12-at-11.16.31-PM.png" alt="" title="Screen Shot 2012-03-12 at 11.16.31 PM" width="396" height="744" class="alignright size-full wp-image-6071" /></a></p>

<p><strong>Responding to input</strong></p>

<p>Showing our accessory view is only half of the solution. We also want to make changes to our text view&#8217;s content when a user taps one of the accessory view&#8217;s buttons. Let&#8217;s create a custom view class for our accessory view and give it a reference to the text field.</p>

<pre><code><pre class="brush: objc; title: ; notranslate">@interface MarkdownInputAccessoryView : UIView

@property(nonatomic, weak) id &amp;lt;UITextInput&amp;gt; delegate;

- (IBAction)toggleStrong:(id)sender;
- (IBAction)toggleEmphasis:(id)sender;
- (IBAction)toggleCode:(id)sender;

@end

@implementation MarkdownInputAccessoryView

@synthesize delegate;

- (IBAction)toggleStrong:(id)sender {
    UITextRange *selectedText = [delegate selectedTextRange];
    if (selectedText == nil) {
        //no selection or insertion point
        //...
    }
    else if (selectedText.empty) {
        //inserting text at an insertion point
        [delegate replaceRange:selectedText withText:@&amp;quot;*&amp;quot;];
        //...
    }
    else {
        //updated a selected range
        //...
    }
}

- (IBAction)toggleEmphasis:(id)sender {
    //...
}

- (IBAction)toggleCode:(id)sender {
    //...
}

@end</pre>
</code></pre>

<p>Our controller can then set the delegate property and the accessory view will be able to update the text field.</p>

<pre><code><pre class="brush: objc; title: ; notranslate">//...
@property (nonatomic, strong) IBOutlet UIView *accessoryView;
//...
- (void)viewDidLoad
{
    [super viewDidLoad];
    self.accessoryView.delegate = self.textView;
    self.textView.inputAccessoryView = self.accessoryView;
}</pre>
</code></pre>

<p><strong>Adding complexity: keyboards for a custom UIView</strong></p>

<p>Adding a custom input view is much the same as adding a custom input accessory view. When we&#8217;re working with a <code>UITextField</code> or <code>UITextView</code> we can create the custom view and pass it to the appropriate property&#8217;s setter.If however we have built a custom <code>UIView</code> subclass then we have to do a little more work.</p>

<p>If it still makes sense for a view controller or other class to provide the view with its input views then we can redeclare <code>inputView</code> and <code>inputAccessoryView</code> as <code>readwrite</code> properties, exposing setters so that the view can be given references to the input views it should use. Alternately we can override the <code>inputView</code> and <code>inputAccessoryView</code> getter methods to return appropriate views. I tend to prefer the latter option because it allows a view to how its own input controls should be presented but if selecting an appropriate input view depends on factors like the current interface idiom or language then it may make more sense for an external service to provide an input view for the current view.</p>

<p>If we wanted to build a view for displaying a score of sheet music we might build something like the following.</p>

<pre><code><pre class="brush: objc; title: ; notranslate">@class MusicScoreView;

@interface MusicScoreInputView : UIView

@property (nonatomic, weak) IBOutlet MusicScoreView *delegate;

@end

@interface MusicScoreView ()

@property(nonatomic, readwrite, strong) IBOutlet UIView *inputView;

- (void) loadInputView;

@end

@implementation MusicScoreView

@synthesize inputView;

- (id)initWithFrame:(CGRect)frame {
    self = [super init];
    if (self) {
        [self loadInputView];
    }
    return self;    
}

- (id)initWithCoder:(NSCoder *)coder
{
    self = [super initWithCoder:coder];
    if (self) {
        [self loadInputView];
    }
    return self;
}

- (void)loadInputView {
    UINib *inputViewNib = [UINib nibWithNibName:@&amp;quot;MusicScoreInputView&amp;quot; bundle:nil];
    [inputViewNib instantiateWithOwner:self options:nil];
}

@end

@interface MusicScoreInputView : UIView

@property (nonatomic, weak) IBOutlet MusicScoreView *delegate;

@end

@implementation MusicScoreInputView

@synthesize delegate;

@end</pre>
</code></pre>

<p><a href="http://blog.carbonfive.com/2012/03/12/customizing-the-ios-keyboard/screen-shot-2012-03-12-at-11-16-15-pm/" rel="attachment wp-att-6074"><img src="http://blog.carbonfive.com/wp-content/uploads/2012/03/Screen-Shot-2012-03-12-at-11.16.15-PM.png" alt="" title="Screen Shot 2012-03-12 at 11.16.15 PM" width="396" height="744" class="alignright size-full wp-image-6074" /></a></p>

<p><strong>Visual styling: reacting to the keyboard</strong></p>

<p>Now that we can display a custom keyboard we still need to make sure to adjust our views when it appears. Since the actual presentation of our input view is handled by UIKit we need to observe and react to the notifications the framework sends to announce changes in the input view&#8217;s position. Apple provides a set of <code>NSNotification</code>s we can observe:</p>

<ul>
    <li><code>UIKeyboardWillShowNotification</code></li>
    <li><code>UIKeyboardDidShowNotification</code></li>
    <li><code>UIKeyboardWillHideNotification</code></li>
    <li><code>UIKeyboardDidHideNotification</code></li>
</ul>

<p>Each of these notifications includes a user info dictionary which describes the frame of the keyboard before and after its transition and the timing of the animation which will be used to show or hide it. When we rotate a device the keyboard may be resized to better support the new orientation. In that case we&#8217;ll need to update the insets or positions of our other views as well to reflect these new dimensions. Again UIKit provides a set of notifications we can observe to determine the changing bounds of the keyboard and react accordingly.</p>

<ul>
    <li><code>UIKeyboardWillChangeFrameNotification</code></li>
    <li><code>UIKeyboardDidChangeFrameNotification</code></li>
</ul>

<p>Given these we can respond to the appearance or disappearance of the keyboard as needed.</p>

<pre><code><pre class="brush: objc; title: ; notranslate">- (void)viewWillAppear:(BOOL)animated {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateScrollInsets:) name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateScrollInsets:) name:UIKeyboardWillChangeFrameNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resetScrollInsets:) name:UIKeyboardWillHideNotification object:nil];
}

- (void)viewDidDisappear:(BOOL)animated {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}</pre>
</code></pre>

<p>In most cases we will want to respond by adjusting the <code>contentInset</code> and <code>scrollIndicatorInsets</code> of a <code>UIScrollView</code> to add enough padding to the bottom of our scroll view&#8217;s content view that all of its content can scroll to a position above the top of the keyboard. Alternately we might adjust the frames of some of our views directly but this is less desirable because it might leave a blank region on the screen (rather than showing the scroll view&#8217;s background color), especially on an iPad where the user can choose to split the keyboard.</p>

<p>To calculate the appropriate insets we need to be aware that the keyboard is presented anchored to the bottom of the window, which is not necessarily flush with the bottom of the current view controller&#8217;s view (for example we might have a tab bar or tool bar visible). We should only add insets equal to the height of the portion of our view which is being hidden by the keyboard.</p>

<pre><code><pre class="brush: objc; title: ; notranslate">- (void) updateScrollInsets:(NSNotification *)notification {
    //determine what portion of the view will be hidden by the keyboard
    CGRect keyboardEndFrameInScreenCoordinates;
    [[notification.userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&amp;amp;keyboardEndFrameInScreenCoordinates];
    CGRect keyboardEndFrameInWindowCoordinates = [self.view.window convertRect:keyboardEndFrameInScreenCoordinates fromWindow:nil];
    CGRect keyboardEndFrameInViewCoordinates = [self.view convertRect:keyboardEndFrameInWindowCoordinates fromView:nil];
    CGRect windowFrameInViewCoords = [self.view convertRect:self.view.window.frame fromView:nil];
    CGFloat heightBelowViewInWindow = windowFrameInViewCoords.origin.y + windowFrameInViewCoords.size.height - (self.view.frame.origin.y + self.view.frame.size.height);
    CGFloat heightCoveredByKeyboard = keyboardEndFrameInViewCoordinates.size.height - heightBelowViewInWindow;

    //build an inset to add padding to the content view equal to the height of the portion of the view hidden by the keyboard
    UIEdgeInsets insets = UIEdgeInsetsMake(0, 0, heightCoveredByKeyboard, 0);
    [self setInsets:insets givenUserInfo:notification.userInfo];
}

- (void) resetScrollInsets:(NSNotification *)notification {
    UIEdgeInsets insets = UIEdgeInsetsMake(0, 0, 0, 0);
    [self setInsets:insets givenUserInfo:notification.userInfo];
}

- (void) setInsets:(UIEdgeInsets)insets givenUserInfo:(NSDictionary *)userInfo {
    //match the keyboard's animation
    double duration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
    UIViewAnimationCurve animationCurve = [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue];
    UIViewAnimationOptions animationOptions = animationCurve;
    [UIView animateWithDuration:duration delay:0 options:animationOptions animations:^{
        self.textView.contentInset = insets;
        self.textView.scrollIndicatorInsets = insets;
    } completion:nil];
}</pre>
</code></pre>

<p><a href="http://blog.carbonfive.com/2012/03/12/customizing-the-ios-keyboard/screen-shot-2012-03-12-at-11-16-04-pm/" rel="attachment wp-att-6075"><img src="http://blog.carbonfive.com/wp-content/uploads/2012/03/Screen-Shot-2012-03-12-at-11.16.04-PM.png" alt="" title="Screen Shot 2012-03-12 at 11.16.04 PM" width="396" height="744" class="alignleft size-full wp-image-6075" /></a></p>

<p><a href="http://blog.carbonfive.com/2012/03/12/customizing-the-ios-keyboard/screen-shot-2012-03-12-at-11-16-08-pm/" rel="attachment wp-att-6076"><img src="http://blog.carbonfive.com/wp-content/uploads/2012/03/Screen-Shot-2012-03-12-at-11.16.08-PM.png" alt="" title="Screen Shot 2012-03-12 at 11.16.08 PM" width="744" height="396" class="alignright size-full wp-image-6076" /></a></p>

<p><strong>Summary</strong></p>

<p>We&#8217;ve seen how to define custom input and input accessory views to enhance or replace the system keyboard. How to add those input views to existing text fields, text views, and to our own custom view classes. When an input view does appear we can also now appropriately adjust the rest of our content to accommodate it. With these tools we should now be ready to build custom input views tailored to the type of data we need and the context in which it will be gathered.</p>

<p>The examples given above are also available at <a href="https://jonah-carbonfive@github.com/jonah-carbonfive/CustomInputViewDemo.git">https://jonah-carbonfive@github.com/jonah-carbonfive/CustomInputViewDemo.git</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2012/03/12/customizing-the-ios-keyboard/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Supporting Cross-Domain AJAX in Rails using JSONP and CORS</title>
		<link>http://blog.carbonfive.com/2012/02/27/supporting-cross-domain-ajax-in-rails-using-jsonp-and-cors/</link>
		<comments>http://blog.carbonfive.com/2012/02/27/supporting-cross-domain-ajax-in-rails-using-jsonp-and-cors/#comments</comments>
		<pubDate>Tue, 28 Feb 2012 04:26:27 +0000</pubDate>
		<dc:creator>Jared Carroll</dc:creator>
				<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[cors]]></category>
		<category><![CDATA[cross domain ajax]]></category>
		<category><![CDATA[jsonp]]></category>
		<category><![CDATA[rack]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://blog.carbonfive.com/?p=5989</guid>
		<description><![CDATA[The recent rise in popularity of client-side JavaScript MVC frameworks has led to a revival of web apps with thick clients. As more logic is moved to the client-side, the need to communicate with servers in different domains becomes more &#8230; <a href="http://blog.carbonfive.com/2012/02/27/supporting-cross-domain-ajax-in-rails-using-jsonp-and-cors/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>
The recent rise in popularity of client-side JavaScript MVC frameworks has led to a revival of web apps with thick clients. As more logic is moved to the client-side, the need to communicate with servers in different domains becomes more common. Unfortunately, JavaScript&#8217;s <strong>same origin policy</strong> prohibits you from making a request to a server in another domain.  Two ways to circumvent this restriction are JSONP and CORS. In this article, we&#8217;ll take a look at supporting both of these in a Rails app.
</p>

<span id="more-5989"></span>

<h2>JSONP</h2>

<p> 
<strong>JSONP</strong> or &#8220;JSON with padding&#8221; is a technique that can be used to load JavaScript from a server in a <em>different</em> domain. JSONP takes advantage of the fact that JavaScript&#8217;s same origin policy doesn&#8217;t apply to the HTML &lt;script&gt; element. When using JSONP, the &lt;script&gt; element&#8217;s <code>src</code> attribute is set to a resource in another domain. This URL includes a callback parameter corresponding to a local JavaScript function. The server responds with JavaScript that calls this function, passing JSON as an argument.  The client then evaluates this JavaScript, giving it access to the server&#8217;s data
</p>

<p>
In the following example, HTML from <em>http://server1.example.com/</em> includes a &lt;script&gt; element to load JavaScript from a server in another domain, <em>http://server2.example.com</em>. The entire domain, including all subdomains, as well as the port number, are all used by JavaScript to determine if the server is in another domain. Here we have two apps at different subdomains within the same domain. The callback parameter is set to a local function defined in a previous &lt;script&gt; element.
</p>

<p><em>http://server1.example.com/</em></p>

<script src="https://gist.github.com/1921504.js?file=0.html"></script>

<p>
The JavaScript returned from the server consists of a function call to <code>parseUser</code>, passing user #1 as JSON. Implementing this server-side logic in a Rails app is straightforward. <code>ActionController::Base#render</code> accepts a <code>:callback</code> option to specify the function to pass the resulting JSON to.
</p>

<p><em>app/controllers/users_controller.rb</em></p>

<script src="https://gist.github.com/1921504.js?file=3.rb"> </script>

<p>
Let&#8217;s try this out (by running the Rails app locally) on the command line using <code>curl</code>.
</p>

<script src="https://gist.github.com/1921504.js?file=4.sh"> </script>

<h3>DRYing up JSONP with <code>Rack::JSONP</code></h3>

<p>
Repeating the same <code>:callback</code> option for multiple actions supporting JSONP quickly becomes tedious. <a href="http://rubygems.org/gems/rack-jsonp-middleware">rack-jsonp-middleware</a> is a Ruby gem that includes a piece of Rack middleware that can take care of this repetition for us. For any JSONP request, <code>rack-jsonp-middleware</code> will strip the callback parameter value, forward the request on to Rails as if it were a JSON request, and then respond with JavaScript containing a function call to the callback parameter, passing it the returned JSON.
</p>

<p>
Using <code>rack-jsonp-middleware</code> will require a few changes to our client and server. Let&#8217;s first add the gem to our app&#8217;s <em>Gemfile</em>.
</p>

<p><em>Gemfile</em></p>

<script src="https://gist.github.com/1921504.js?file=5.rb"> </script>

<p>
Then add it to the Rails middleware stack.
</p>

<p><em>config/application.rb</em></p>

<script src="https://gist.github.com/1921504.js?file=6.rb"> </script>

<p>
<code>rack-jsonp-middleware</code> considers a request a JSONP request <em>if</em> the url ends in <em>.jsonp</em>. We&#8217;ll need to change the ending of our client url from <em>.js</em> to <em>.jsonp</em>.
</p>

<p><em>http://server1.example.com/</em></p>

<script src="https://gist.github.com/1921504.js?file=7.html"> </script>

<p>
<code>rack-jsonp-middleware</code> expects our server-side action to return JSON. Instead of handling JavaScript requests, let&#8217;s rewrite our action to return JSON. We can use <a href="http://apidock.com/rails/ActionController/MimeResponds/respond_with"><code>ActionController::MimeResponds#respond_with</code></a> and <a href="http://apidock.com/rails/ActionController/MimeResponds/respond_to"><code>ActionController::MimeResponds.respond_to</code></a> in our controller to simplify the implementation.
</p>

<p><em>app/controllers/users_controller.rb</em></p>

<script src="https://gist.github.com/1921504.js?file=8.rb"> </script>

<p>
Testing this refactored version from the command line returns the same response as our previous implementation.
</p>

<script src="https://gist.github.com/1921504.js?file=9.sh"> </script>

<p>
JSONP is a nice, simple solution for reading data from a server in another domain. But what if you want to write data? For that, there&#8217;s CORS.
</p>

<h2>CORS (Cross-Origin Resource Sharing)</h2>

<p>
<strong>CORS</strong> is a <a href="http://www.w3.org/TR/cors/">W3C standard</a>, that specifies a way for a client to determine if a particular request can be made to a server in a different domain. With JSONP you&#8217;re limited to HTTP GET requests. CORS on the other hand, allows any type of request. It requires <em>you</em> to define who can do what to a given resource.
</p>

<p>
In CORS, the client first makes a &#8220;preflight&#8221; request to a server in another domain. This is an HTTP OPTIONS request, asking the server if the client can make a particular request. The &#8220;preflight&#8221; request includes CORS-specific headers specifying the client&#8217;s domain, the type of request they want to make (POST, GET, etc.), and any HTTP headers they want to send.  The server response answers the request using CORS-specific headers. If the request is allowed, the client can then issue the cross-domain request.
</p>

<p>
Adding CORS support to a Rails app is easy with the <a href="http://rubygems.org/gems/rack-cors">rack-cors</a> Ruby gem.
</p>

<h3>Supporting CORS in Rails with <code>Rack::Cors</code></h3>

<p>
<code>rack-cors</code> handles CORS&#8217;s &#8220;preflight&#8221; requests by adding support for HTTP OPTIONS requests. It also includes a DSL for specifying on a per-resource basis, the allowable requesting domains, the types of requests, and the supported HTTP headers.
</p>

<p>
Let&#8217;s take a look at adding CORS support for updating and deleting users in our Rails app.  The first step is to add <code>rack-cors</code> to our app&#8217;s <em>Gemfile</em>.
</p>

<p><em>Gemfile</em></p>

<script src="https://gist.github.com/1921504.js?file=1.rb"> </script>

<p>
Then we&#8217;ll add it to the Rails middleware stack. This is where you configure your resources for CORS.
</p>

<p><em>config/application.rb</em></p>

<script src="https://gist.github.com/1921504.js?file=2.rb"> </script>

<p>
Our configuration allows HTTP PUT and DELETE requests from <em>http://server1.example.com</em> to <code>/users/\d+.json</code> (we used a regular expression to match the user id in the URL). The allowable headers in such requests are:
</p>

<ul>
  <li>
    <code>Origin</code> &#8211; the domain from where the request will be made (this is required by CORS).
  </li>
  <li>
    <code>Accept</code> &#8211; the acceptable response media type.
  </li>
  <li>
    <code>Content-Type</code> &#8211; the media type of the body of the request.
  </li>
</ul>

<p>
Let&#8217;s try this out from the command line using <code>curl</code> (this is the exact same CORS &#8220;preflight&#8221; request that jQuery will make when sending a cross-domain AJAX request in a browser).
</p>

<script src="https://gist.github.com/1921513.js?file=10.sh"></script>

<p>
This &#8220;preflight&#8221; request uses several CORS-specific headers:
</p>

<ul>
  <li>  
    <code>Origin</code> &#8211; the domain from where the request will be made.
  </li>
  <li>
   <code>Access-Control-Request-Headers</code> &#8211;  a list of headers we want to send with our request.
   </li>
  <li>
   <code>Access-Control-Request-Method</code> &#8211; the type of request we want to make.
  </li>
</ul>

<p>
Essentially, this &#8220;preflight&#8221; request is asking the server at <code>http://localhost:3000</code> if we can send an update from 
<code>http://server1.example.com</code> to one of its users.
</p>

<p>
The server response also includes several CORS-specific headers:
</p>

<ul>
  <li>
    <code>Access-Control-Allow-Origin</code> &#8211; the domains that are allowed to make a request to this resource (a value of &#8220;*&#8221; is a wildcard that matches any domain).
  </li>
  <li>
    <code>Access-Control-Allow-Methods</code> &#8211; the types of requests that are allowed (both PUT and DELETE in the above response).
  </li>
  <li>
    <code>Access-Control-Allow-Headers</code> &#8211; the allowable request headers.
  </li>
</ul>

<p>
<code>rack-cors</code> has also added some additional CORS-specific headers with default values:
</p>

<ul>
  <li>
    <code>Access-Control-Expose-Headers</code> &#8211; a list of additional response headers the client can access. By default, the client can only access simple response headers such as <code>Content-Type</code> and <code>Last-Modified</code>. <code>rack-cors</code> defaults this header to an empty list.  
  </li>
  <li>
    <code>Access-Control-Max-Age</code> &#8211; how long (in seconds) the client can cache this &#8220;preflight&#8221; response. <code>rack-cors</code> defaults this to 20 days. 
  </li>
  <li>
    <code>Access-Control-Allow-Credentials</code> &#8211; tells the client whether it should send cookies in CORS requests. <code>rack-cors</code> defaults this to true.
  </li>
</ul>

<h3>Browser Support for CORS</h3>

<p>
According to Wikipedia, CORS is currently supported <a href="http://en.wikipedia.org/wiki/Cross-Origin_Resource_Sharing#Browser_support">by all major browsers (IE 8+) except Opera</a>.
</p>

<p>
I recently used CORS to support an internal app. This meant only supporting Chrome, Firefox, and Safari. So far, I&#8217;ve had no problems using CORS in any of these browsers.
</p>

<h3>Fine-grained Access Control</h3>

<p>
The <code>Access-Control-Allow-Origin</code> header in CORS, gives us more flexibility and security than JSONP. Instead of opening up a resource to any domain using JSONP, we can create a whitelist of allowable domains, HTTP methods, and headers.
</p>

<h2>The Rise of Thick Clients</h2>

<p>
As client-side JavaScript MVC frameworks continue to rise in popularity, the same origin request policy becomes far too limiting. JSONP offers a simple workaround for reading data from servers in other domains. CORS is more complex, but it provides the ability to not only read but also write data.
</p>

<p>
JSON APIs are already trivial to implement in Rails. And thanks to Ruby gems, such as <code>rack-jsonp-middleware</code> and <code>rack-cors</code>, opening them up to thick client apps running on other domains is just as easy.
</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2012/02/27/supporting-cross-domain-ajax-in-rails-using-jsonp-and-cors/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Lunchtime Tech Talk: Tom Dale and Yehuda Katz on Ember.js</title>
		<link>http://blog.carbonfive.com/2012/02/17/lunchtime-tech-talk-tom-dale-and-yehuda-katz-on-ember-js/</link>
		<comments>http://blog.carbonfive.com/2012/02/17/lunchtime-tech-talk-tom-dale-and-yehuda-katz-on-ember-js/#comments</comments>
		<pubDate>Sat, 18 Feb 2012 00:39:53 +0000</pubDate>
		<dc:creator>Christian Nelson</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[emberjs]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://blog.carbonfive.com/?p=5972</guid>
		<description><![CDATA[On Wednesday, Tom Dale and Yehuda Katz joined us for a lunchtime tech talk. Tom gave a great overview of ember.js, a new JavaScript MVC born out of the work done on SproutCore 2.0. Here&#8217;s the video of the presentation &#8230; <a href="http://blog.carbonfive.com/2012/02/17/lunchtime-tech-talk-tom-dale-and-yehuda-katz-on-ember-js/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>On Wednesday, Tom Dale and Yehuda Katz joined us for a lunchtime tech talk. Tom gave a great overview of <a href="http://emberjs.com/">ember.js</a>, a new JavaScript MVC born out of the work done on SproutCore 2.0. Here&#8217;s the video of the presentation and Q&amp;A that followed:</p>

<iframe src="http://player.vimeo.com/video/36992934" width="500" height="281" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>

<p>Happy JS hacking!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2012/02/17/lunchtime-tech-talk-tom-dale-and-yehuda-katz-on-ember-js/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Beginning Outside-In Rails Development with Cucumber and RSpec</title>
		<link>http://blog.carbonfive.com/2012/02/14/beginning-outside-in-rails-development-with-cucumber-and-rspec/</link>
		<comments>http://blog.carbonfive.com/2012/02/14/beginning-outside-in-rails-development-with-cucumber-and-rspec/#comments</comments>
		<pubDate>Wed, 15 Feb 2012 05:18:38 +0000</pubDate>
		<dc:creator>Jared Carroll</dc:creator>
				<category><![CDATA[Process]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[bdd]]></category>
		<category><![CDATA[cucumber]]></category>
		<category><![CDATA[outside-in development]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[rspec]]></category>

		<guid isPermaLink="false">http://blog.carbonfive.com/?p=5935</guid>
		<description><![CDATA[The RSpec Book defines outside-in Rails development as starting with views and working your way in toward the models. By developing from the outside in, you are always taking a client perspective at each layer of the application. The end &#8230; <a href="http://blog.carbonfive.com/2012/02/14/beginning-outside-in-rails-development-with-cucumber-and-rspec/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>
<a href="http://pragprog.com/book/achbd/the-rspec-book">The RSpec Book</a> defines outside-in Rails development as <strong>starting with views and working your way in toward the models</strong>. By developing from the outside in, you are always taking a client perspective at each layer of the application. The end result is an absolute minimum implementation, consisting of simple, expressive interfaces.
</p>
<p>
Outside-in development doesn&#8217;t require any specific tool or language. This article will demonstrate it in Rails, using two popular testing tools: <a href="http://cukes.info/">Cucumber</a> and <a href="http://rspec.info/">RSpec</a>.
</p>
<p><span id="more-5935"></span></p>
<h2>Start with a High-level Specification</h2>
<p>
Starting with a high-level specification requires you to have a clear understanding about what you want to achieve. If it&#8217;s still unclear, now is the time to have a conversation with the client. After establishing a clear goal, we can use Cucumber to turn a plaintext story into executable code.
</p>
<p>
Our sample story will be from a news site. The feature is a JSON API endpoint for news articles.
</p>
<p><div id="gist-1824236" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'>In order to reference published articles in other applications</div><div class='line' id='LC2'>As an API client</div><div class='line' id='LC3'>I want to be able to request articles via a JSON API</div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1824236/d48e23dfa1ac1e564c28b13bec53a741202ba5e1/gistfile1.txt" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1824236#file_gistfile1.txt" style="float:right;margin-right:10px;color:#666">gistfile1.txt</a>
            <a href="https://gist.github.com/1824236">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</p>
<p>
This story can be copied directly into a Cucumber feature.
</p>
<p><em>features/api/v1/articles.feature</em></p>
<p><div id="gist-1824148" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="k">Feature:</span><span class="nf"> Articles API </span></div><div class='line' id='LC2'><span class="nf">  In order to reference published articles in other applications</span></div><div class='line' id='LC3'><span class="nf">  As an API client</span></div><div class='line' id='LC4'><span class="nf">  I want to be able to request articles via a JSON API </span></div><div class='line' id='LC5'><br/></div><div class='line' id='LC6'><span class="nf">  </span><span class="k">Scenario:</span><span class="nf"> Get articles</span></div><div class='line' id='LC7'><span class="k">    Given </span><span class="nf">some published articles</span></div><div class='line' id='LC8'><span class="nf">      </span><span class="k">And </span><span class="nf">some unpublished articles</span></div><div class='line' id='LC9'><span class="nf">    </span><span class="k">When </span><span class="nf">I ask for articles from the API </span></div><div class='line' id='LC10'><span class="nf">    </span><span class="k">Then </span><span class="nf">I should only receive published articles as JSON</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1824148/a0f3deb9a2430b7bd41820a2d205e3c2af7b6fd9/gistfile1.feature" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1824148#file_gistfile1.feature" style="float:right;margin-right:10px;color:#666">gistfile1.feature</a>
            <a href="https://gist.github.com/1824148">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</p>
<p>
Let&#8217;s run this feature to figure out what to do next.
</p>
<p><div id="gist-1824155" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="nv">$ </span>cucumber features/api/v1/articles.feature</div><div class='line' id='LC2'>Using the default profile...</div><div class='line' id='LC3'>UUUU</div><div class='line' id='LC4'><br/></div><div class='line' id='LC5'>1 scenario <span class="o">(</span>1 undefined<span class="o">)</span></div><div class='line' id='LC6'>4 steps <span class="o">(</span>4 undefined<span class="o">)</span></div><div class='line' id='LC7'>0m0.002s</div><div class='line' id='LC8'><br/></div><div class='line' id='LC9'>You can implement step definitions <span class="k">for </span>undefined steps with these</div><div class='line' id='LC10'>snippets:</div><div class='line' id='LC11'><br/></div><div class='line' id='LC12'>Given /^some published articles<span class="nv">$/</span> <span class="k">do</span></div><div class='line' id='LC13'><span class="k">  </span>pending <span class="c"># express the regexp above with the code you wish you had</span></div><div class='line' id='LC14'>end</div><div class='line' id='LC15'><br/></div><div class='line' id='LC16'>Given /^some unpublished articles<span class="nv">$/</span> <span class="k">do</span></div><div class='line' id='LC17'><span class="k">  </span>pending <span class="c"># express the regexp above with the code you wish you had</span></div><div class='line' id='LC18'>end</div><div class='line' id='LC19'><br/></div><div class='line' id='LC20'>When /^I ask <span class="k">for </span>articles from the API<span class="nv">$/</span> <span class="k">do</span></div><div class='line' id='LC21'><span class="k">  </span>pending <span class="c"># express the regexp above with the code you wish you had</span></div><div class='line' id='LC22'>end</div><div class='line' id='LC23'><br/></div><div class='line' id='LC24'>Then /^I should only receive published articles as JSON<span class="nv">$/</span> <span class="k">do</span></div><div class='line' id='LC25'><span class="k">  </span>pending <span class="c"># express the regexp above with the code you wish you had</span></div><div class='line' id='LC26'>end</div><div class='line' id='LC27'><br/></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1824155/dcd586c02cc0d3bd0ec171641d92a6faf0775823/gistfile1.sh" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1824155#file_gistfile1.sh" style="float:right;margin-right:10px;color:#666">gistfile1.sh</a>
            <a href="https://gist.github.com/1824155">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</p>
<h2>Fantasy Coding</h2>
<p>
Cucumber successfully parsed our feature but it needs definitions for all of our steps. Let&#8217;s implement these steps writing code that we wish already existed.
</p>
<p><em>features/step_definitions/api/v1/articles_steps.rb</em></p>
<p><div id="gist-1824157" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="no">Given</span> <span class="sr">/^some published articles$/</span> <span class="k">do</span></div><div class='line' id='LC2'>&nbsp;&nbsp;<span class="no">FactoryGirl</span><span class="o">.</span><span class="n">create_list</span> <span class="ss">:published_article</span><span class="p">,</span> <span class="mi">3</span></div><div class='line' id='LC3'><span class="k">end</span></div><div class='line' id='LC4'><br/></div><div class='line' id='LC5'><span class="no">Given</span> <span class="sr">/^some unpublished articles$/</span> <span class="k">do</span></div><div class='line' id='LC6'>&nbsp;&nbsp;<span class="no">FactoryGirl</span><span class="o">.</span><span class="n">create_list</span> <span class="ss">:unpublished_article</span><span class="p">,</span> <span class="mi">3</span></div><div class='line' id='LC7'><span class="k">end</span></div><div class='line' id='LC8'><br/></div><div class='line' id='LC9'><span class="no">When</span> <span class="sr">/^I ask for articles from the API$/</span> <span class="k">do</span></div><div class='line' id='LC10'>&nbsp;&nbsp;<span class="n">header</span> <span class="s1">&#39;Accept&#39;</span><span class="p">,</span> <span class="s1">&#39;application/json&#39;</span></div><div class='line' id='LC11'>&nbsp;&nbsp;<span class="n">get</span> <span class="s1">&#39;/api/v1/articles&#39;</span></div><div class='line' id='LC12'><span class="k">end</span></div><div class='line' id='LC13'><br/></div><div class='line' id='LC14'><span class="no">Then</span> <span class="sr">/^I should only receive published articles as JSON$/</span> <span class="k">do</span></div><div class='line' id='LC15'>&nbsp;&nbsp;<span class="n">articles_json</span> <span class="o">=</span> <span class="no">JSON</span> <span class="n">last_response</span><span class="o">.</span><span class="n">body</span></div><div class='line' id='LC16'>&nbsp;&nbsp;<span class="n">articles_json</span><span class="o">.</span><span class="n">should</span> <span class="n">have</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span><span class="o">.</span><span class="n">published_articles</span></div><div class='line' id='LC17'><br/></div><div class='line' id='LC18'>&nbsp;&nbsp;<span class="n">published_articles</span> <span class="o">=</span> <span class="no">Article</span><span class="o">.</span><span class="n">all</span><span class="o">.</span><span class="n">select</span> <span class="p">{</span><span class="o">|</span><span class="n">article</span><span class="o">|</span> <span class="n">article</span><span class="o">.</span><span class="n">published?</span><span class="p">}</span></div><div class='line' id='LC19'>&nbsp;&nbsp;<span class="n">published_articles</span><span class="o">.</span><span class="n">should_not</span> <span class="n">be_empty</span></div><div class='line' id='LC20'>&nbsp;&nbsp;<span class="n">published_articles</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">published_article</span><span class="o">|</span></div><div class='line' id='LC21'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">article_json</span> <span class="o">=</span> <span class="n">articles_json</span><span class="o">.</span><span class="n">detect</span> <span class="k">do</span> <span class="o">|</span><span class="n">article_json</span><span class="o">|</span></div><div class='line' id='LC22'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">article_json</span><span class="o">[</span><span class="s1">&#39;title&#39;</span><span class="o">]</span> <span class="o">==</span> <span class="n">published_article</span><span class="o">.</span><span class="n">title</span></div><div class='line' id='LC23'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC24'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">article_json</span><span class="o">.</span><span class="n">should</span> <span class="n">be</span></div><div class='line' id='LC25'>&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC26'><span class="k">end</span></div><div class='line' id='LC27'><br/></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1824157/32ee766ec202f466c75fd57d6531eafc97736ca3/gistfile1.rb" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1824157#file_gistfile1.rb" style="float:right;margin-right:10px;color:#666">gistfile1.rb</a>
            <a href="https://gist.github.com/1824157">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</p>
<p>
In our two <code>Given</code> steps, we establish a context consisting of published and unpublished articles. These two factories don&#8217;t exist yet; we just wrote the code we wish we had. This is a major benefit of developing from the outside in. By writing code that doesn&#8217;t even exist, you&#8217;ll end up creating ideal objects and interfaces.
</p>
<p>
In our <code>When</code> step, we exercise our application by first setting a proper HTTP header and then making an HTTP GET request to a non-existent URL. Again, this URL doesn&#8217;t exist, it&#8217;s just where we would expect the articles to be.
</p>
<p>
Finally in our <code>Then</code> step, we verify the response. Here we begin to discover our domain model; imagining an <code>Article</code> class with a <code>#published?</code> instance method.
</p>
<h2>Let Cucumber Guide the Way</h2>
<p>
With our steps defined, a rerun of Cucumber fails in our <code>Given</code> step because our factories don&#8217;t exist yet.
</p>
<p><div id="gist-1824158" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="nv">$ </span>cucumber features/api/v1/articles.feature</div><div class='line' id='LC2'>Using the default profile...</div><div class='line' id='LC3'>F---</div><div class='line' id='LC4'><br/></div><div class='line' id='LC5'><span class="o">(</span>::<span class="o">)</span> failed steps <span class="o">(</span>::<span class="o">)</span></div><div class='line' id='LC6'><br/></div><div class='line' id='LC7'>Factory not registered: published_article <span class="o">(</span>ArgumentError<span class="o">)</span></div><div class='line' id='LC8'>./features/step_definitions/api/v1/articles_steps.rb:2:in <span class="sb">`</span>/^some</div><div class='line' id='LC9'>published articles<span class="nv">$/</span><span class="s1">&#39;</span></div><div class='line' id='LC10'><span class="s1">features/api/v1/articles.feature:7:in `Given some published articles&#39;</span></div><div class='line' id='LC11'><br/></div><div class='line' id='LC12'>Failing Scenarios:</div><div class='line' id='LC13'>cucumber features/api/v1/articles.feature:6 <span class="c"># Scenario: Get articles</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1824158/ab4a48a0d34c8d88539927e43451ed8b75d44933/gistfile1.sh" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1824158#file_gistfile1.sh" style="float:right;margin-right:10px;color:#666">gistfile1.sh</a>
            <a href="https://gist.github.com/1824158">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</p>
<p>
Let&#8217;s define these two factories.
</p>
<p><em>spec/factories/articles.rb</em></p>
<p><div id="gist-1824163" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="no">FactoryGirl</span><span class="o">.</span><span class="n">define</span> <span class="k">do</span></div><div class='line' id='LC2'>&nbsp;&nbsp;<span class="n">factory</span> <span class="ss">:article</span> <span class="k">do</span></div><div class='line' id='LC3'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">sequence</span><span class="p">(</span><span class="ss">:title</span><span class="p">)</span> <span class="p">{</span><span class="o">|</span><span class="n">n</span><span class="o">|</span> <span class="s2">&quot;title-</span><span class="si">#{</span><span class="n">n</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">}</span></div><div class='line' id='LC4'><br/></div><div class='line' id='LC5'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">factory</span> <span class="ss">:published_article</span> <span class="k">do</span></div><div class='line' id='LC6'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">published</span> <span class="kp">true</span></div><div class='line' id='LC7'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC8'><br/></div><div class='line' id='LC9'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">factory</span> <span class="ss">:unpublished_article</span> <span class="k">do</span></div><div class='line' id='LC10'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">published</span> <span class="kp">false</span></div><div class='line' id='LC11'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC12'>&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC13'><span class="k">end</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1824163/33c94471745a732e192e8f9b2ce49adf2db5e2de/gistfile1.rb" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1824163#file_gistfile1.rb" style="float:right;margin-right:10px;color:#666">gistfile1.rb</a>
            <a href="https://gist.github.com/1824163">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</p>
<p>
Cucumber guides us toward our next step.
</p>
<p><div id="gist-1824165" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="nv">$ </span>cucumber features/api/v1/articles.feature</div><div class='line' id='LC2'>Using the default profile...</div><div class='line' id='LC3'>F---</div><div class='line' id='LC4'><br/></div><div class='line' id='LC5'><span class="o">(</span>::<span class="o">)</span> failed steps <span class="o">(</span>::<span class="o">)</span></div><div class='line' id='LC6'><br/></div><div class='line' id='LC7'>uninitialized constant Article <span class="o">(</span>NameError<span class="o">)</span></div><div class='line' id='LC8'>./features/step_definitions/api/v1/articles_steps.rb:2:in <span class="sb">`</span>/^some</div><div class='line' id='LC9'>published articles<span class="nv">$/</span><span class="s1">&#39;</span></div><div class='line' id='LC10'><span class="s1">features/api/v1/articles.feature:7:in `Given some published articles&#39;</span></div><div class='line' id='LC11'><br/></div><div class='line' id='LC12'>Failing Scenarios:</div><div class='line' id='LC13'>cucumber features/api/v1/articles.feature:6 <span class="c"># Scenario: Get articles</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1824165/910268bc1aed28dda4e21cd4a1cc8e8b48e79cfb/gistfile1.sh" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1824165#file_gistfile1.sh" style="float:right;margin-right:10px;color:#666">gistfile1.sh</a>
            <a href="https://gist.github.com/1824165">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</p>
<p>
Our factories are being automatically mapped to a non-existent <code>Article</code> class. We can use the Rails model generator to create this class. We&#8217;ll also specify the <code>title</code> and <code>published</code> attributes we referenced in our <code>Then</code> step.
</p>
<p><div id="gist-1824169" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="nv">$ </span>rails g model article title published:boolean</div><div class='line' id='LC2'>&nbsp;&nbsp;&nbsp;&nbsp;invoke  active_record</div><div class='line' id='LC3'>&nbsp;&nbsp;&nbsp;&nbsp;create    db/migrate/20120213050147_create_articles.rb</div><div class='line' id='LC4'>&nbsp;&nbsp;&nbsp;&nbsp;create    app/models/article.rb</div><div class='line' id='LC5'>&nbsp;&nbsp;&nbsp;&nbsp;invoke    rspec</div><div class='line' id='LC6'>&nbsp;&nbsp;&nbsp;&nbsp;create      spec/models/article_spec.rb</div><div class='line' id='LC7'><span class="nv">$ </span>rake db:migrate db:test:prepare</div><div class='line' id='LC8'><span class="o">==</span>  CreateArticles: <span class="nv">migrating</span></div><div class='line' id='LC9'><span class="o">=================================================</span></div><div class='line' id='LC10'>-- create_table<span class="o">(</span>:articles<span class="o">)</span></div><div class='line' id='LC11'>&nbsp;&nbsp;&nbsp;-&gt; 0.0497s</div><div class='line' id='LC12'><span class="o">==</span>  CreateArticles: migrated <span class="o">(</span>0.0498s<span class="o">)</span></div><div class='line' id='LC13'><span class="o">========================================</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1824169/4cfdc16d3f1ef84530f25595834fcf9b3cd9d71d/gistfile1.sh" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1824169#file_gistfile1.sh" style="float:right;margin-right:10px;color:#666">gistfile1.sh</a>
            <a href="https://gist.github.com/1824169">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</p>
<p>
With our setup passing, Cucumber now fails at our API request.
</p>
<p><div id="gist-1824172" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="nv">$ </span>cucumber features/api/v1/articles.feature</div><div class='line' id='LC2'>Using the default profile...</div><div class='line' id='LC3'>..F-</div><div class='line' id='LC4'><br/></div><div class='line' id='LC5'><span class="o">(</span>::<span class="o">)</span> failed steps <span class="o">(</span>::<span class="o">)</span></div><div class='line' id='LC6'><br/></div><div class='line' id='LC7'>No route matches <span class="o">[</span>GET<span class="o">]</span> <span class="s2">&quot;/api/v1/articles&quot;</span></div><div class='line' id='LC8'><span class="o">(</span>ActionController::RoutingError<span class="o">)</span></div><div class='line' id='LC9'>./features/step_definitions/api/v1/articles_steps.rb:11:in <span class="sb">`</span>/^I ask <span class="k">for</span></div><div class='line' id='LC10'>articles from the API<span class="nv">$/</span><span class="s1">&#39;</span></div><div class='line' id='LC11'><span class="s1">features/api/v1/articles.feature:9:in `When I ask for articles from the</span></div><div class='line' id='LC12'><span class="s1">API&#39;</span></div><div class='line' id='LC13'><br/></div><div class='line' id='LC14'>Failing Scenarios:</div><div class='line' id='LC15'>cucumber features/api/v1/articles.feature:6 <span class="c"># Scenario: Get articles</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1824172/1e8ee09cf82f51273a6a78567ed7ee2ada46ba30/gistfile1.sh" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1824172#file_gistfile1.sh" style="float:right;margin-right:10px;color:#666">gistfile1.sh</a>
            <a href="https://gist.github.com/1824172">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</p>
<h2>Drill Down to the Controller</h2>
<p>
We need to add a route for our API endpoint.
</p>
<p><em>config/routes.rb</em></p>
<p><div id="gist-1824174" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="no">Sample</span><span class="o">::</span><span class="no">Application</span><span class="o">.</span><span class="n">routes</span><span class="o">.</span><span class="n">draw</span> <span class="k">do</span></div><div class='line' id='LC2'>&nbsp;&nbsp;<span class="n">namespace</span> <span class="ss">:api</span> <span class="k">do</span></div><div class='line' id='LC3'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">namespace</span> <span class="ss">:v1</span> <span class="k">do</span></div><div class='line' id='LC4'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">resources</span> <span class="ss">:articles</span></div><div class='line' id='LC5'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC6'>&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC7'><span class="k">end</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1824174/d2857a1aeebd14c436d8aadbf499748da1c92b9f/gistfile1.rb" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1824174#file_gistfile1.rb" style="float:right;margin-right:10px;color:#666">gistfile1.rb</a>
            <a href="https://gist.github.com/1824174">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</p>
<p><div id="gist-1824177" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="nv">$ </span>cucumber features/api/v1/articles.feature</div><div class='line' id='LC2'>Using the default profile...</div><div class='line' id='LC3'>..F-</div><div class='line' id='LC4'><br/></div><div class='line' id='LC5'><span class="o">(</span>::<span class="o">)</span> failed steps <span class="o">(</span>::<span class="o">)</span></div><div class='line' id='LC6'><br/></div><div class='line' id='LC7'>uninitialized constant Api <span class="o">(</span>ActionController::RoutingError<span class="o">)</span></div><div class='line' id='LC8'>./features/step_definitions/api/v1/articles_steps.rb:11:in <span class="sb">`</span>/^I ask <span class="k">for</span></div><div class='line' id='LC9'>articles from the API<span class="nv">$/</span><span class="s1">&#39;</span></div><div class='line' id='LC10'><span class="s1">features/api/v1/articles.feature:9:in `When I ask for articles from the</span></div><div class='line' id='LC11'><span class="s1">API&#39;</span></div><div class='line' id='LC12'><br/></div><div class='line' id='LC13'>Failing Scenarios:</div><div class='line' id='LC14'>cucumber features/api/v1/articles.feature:6 <span class="c"># Scenario: Get articles</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1824177/39186806e58f25e24852b8e5992f1fb6690f6bef/gistfile1.sh" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1824177#file_gistfile1.sh" style="float:right;margin-right:10px;color:#666">gistfile1.sh</a>
            <a href="https://gist.github.com/1824177">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</p>
<p>
With the routes in place, Cucumber tells us we&#8217;re missing a constant. This particular error message is from the Rails <code>#namespace</code> method we used in our routes file. Namespacing our controller will fix this issue. We can use the Rails controller generator to create a namespaced controller class.
</p>
<p><div id="gist-1824182" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="nv">$ </span>rails g controller api::v1::articles</div><div class='line' id='LC2'>&nbsp;&nbsp;&nbsp;&nbsp;create  app/controllers/api/v1/articles_controller.rb</div><div class='line' id='LC3'>&nbsp;&nbsp;&nbsp;&nbsp;invoke  erb</div><div class='line' id='LC4'>&nbsp;&nbsp;&nbsp;&nbsp;create    app/views/api/v1/articles</div><div class='line' id='LC5'>&nbsp;&nbsp;&nbsp;&nbsp;invoke  rspec</div><div class='line' id='LC6'>&nbsp;&nbsp;&nbsp;&nbsp;create    spec/controllers/api/v1/articles_controller_spec.rb</div><div class='line' id='LC7'>&nbsp;&nbsp;&nbsp;&nbsp;invoke  helper</div><div class='line' id='LC8'>&nbsp;&nbsp;&nbsp;&nbsp;create    app/helpers/api/v1/articles_helper.rb</div><div class='line' id='LC9'>&nbsp;&nbsp;&nbsp;&nbsp;invoke    rspec</div><div class='line' id='LC10'>&nbsp;&nbsp;&nbsp;&nbsp;create      spec/helpers/api/v1/articles_helper_spec.rb</div><div class='line' id='LC11'>&nbsp;&nbsp;&nbsp;&nbsp;invoke  assets</div><div class='line' id='LC12'>&nbsp;&nbsp;&nbsp;&nbsp;invoke    coffee</div><div class='line' id='LC13'>&nbsp;&nbsp;&nbsp;&nbsp;create      app/assets/javascripts/api/v1/articles.js.coffee</div><div class='line' id='LC14'>&nbsp;&nbsp;&nbsp;&nbsp;invoke    scss</div><div class='line' id='LC15'>&nbsp;&nbsp;&nbsp;&nbsp;create      app/assets/stylesheets/api/v1/articles.css.scss</div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1824182/3e9a18248dd74fba5022fba5210f1e4835c02acb/gistfile1.sh" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1824182#file_gistfile1.sh" style="float:right;margin-right:10px;color:#666">gistfile1.sh</a>
            <a href="https://gist.github.com/1824182">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</p>
<p>
Cucumber fails again, this time looking for an <code>#index</code> action in our controller.
</p>
<p><div id="gist-1824183" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="nv">$ </span>cucumber features/api/v1/articles.feature</div><div class='line' id='LC2'>Using the default profile...</div><div class='line' id='LC3'>..F-</div><div class='line' id='LC4'><br/></div><div class='line' id='LC5'><span class="o">(</span>::<span class="o">)</span> failed steps <span class="o">(</span>::<span class="o">)</span></div><div class='line' id='LC6'><br/></div><div class='line' id='LC7'>The action <span class="s1">&#39;index&#39;</span> could not be found <span class="k">for </span>Api::V1::ArticlesController</div><div class='line' id='LC8'><span class="o">(</span>AbstractController::ActionNotFound<span class="o">)</span></div><div class='line' id='LC9'>./features/step_definitions/api/v1/articles_steps.rb:11:in <span class="sb">`</span>/^I ask <span class="k">for</span></div><div class='line' id='LC10'>articles from the API<span class="nv">$/</span><span class="s1">&#39;</span></div><div class='line' id='LC11'><span class="s1">features/api/v1/articles.feature:9:in `When I ask for articles from the</span></div><div class='line' id='LC12'><span class="s1">API&#39;</span></div><div class='line' id='LC13'><br/></div><div class='line' id='LC14'>Failing Scenarios:</div><div class='line' id='LC15'>cucumber features/api/v1/articles.feature:6 <span class="c"># Scenario: Get articles</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1824183/472857541e659e99ef9b36608e8eec678f68a524/gistfile1.sh" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1824183#file_gistfile1.sh" style="float:right;margin-right:10px;color:#666">gistfile1.sh</a>
            <a href="https://gist.github.com/1824183">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</p>
<p>
At this point, some outside-in practitioners will also drop down a level with respect to testing and use RSpec to spec out the controller. Since we&#8217;re new to outside-in development, I&#8217;m going to skip this step and go straight to the implementation. We&#8217;ll look at the value of controller specs and when it makes sense to write them later on.
</p>
<p><em>app/controllers/api/v1/articles_controller.rb</em></p>
<p><div id="gist-1824184" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="k">class</span> <span class="nc">Api</span><span class="o">::</span><span class="no">V1</span><span class="o">::</span><span class="no">ArticlesController</span> <span class="o">&lt;</span> <span class="no">ApplicationController</span></div><div class='line' id='LC2'>&nbsp;&nbsp;<span class="k">def</span> <span class="nf">index</span></div><div class='line' id='LC3'>&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC4'><span class="k">end</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1824184/a3a46a94ba9bf90b203e8255f995eaf7c7086e54/gistfile1.rb" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1824184#file_gistfile1.rb" style="float:right;margin-right:10px;color:#666">gistfile1.rb</a>
            <a href="https://gist.github.com/1824184">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</p>
<p><div id="gist-1824186" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="nv">$ </span>cucumber features/api/v1/articles.feature</div><div class='line' id='LC2'>Using the default profile...</div><div class='line' id='LC3'>..F-</div><div class='line' id='LC4'><br/></div><div class='line' id='LC5'><span class="o">(</span>::<span class="o">)</span> failed steps <span class="o">(</span>::<span class="o">)</span></div><div class='line' id='LC6'><br/></div><div class='line' id='LC7'>Missing template api/v1/articles/index, application/index with</div><div class='line' id='LC8'><span class="o">{</span>:locale<span class="o">=</span>&gt;<span class="o">[</span>:en<span class="o">]</span>, :formats<span class="o">=</span>&gt;<span class="o">[</span>:json<span class="o">]</span>, :handlers<span class="o">=</span>&gt;<span class="o">[</span>:erb, :builder,</div><div class='line' id='LC9'>:jbuilder, :coffee<span class="o">]}</span>. Searched in:</div><div class='line' id='LC10'>&nbsp;&nbsp;* <span class="s2">&quot;/Users/jared/Projects/sample/app/views&quot;</span></div><div class='line' id='LC11'>&nbsp;<span class="o">(</span>ActionView::MissingTemplate<span class="o">)</span></div><div class='line' id='LC12'>/Users/jared/.rbenv/versions/1.9.2-p290/lib/ruby/1.9.1/benchmark.rb:310:in</div><div class='line' id='LC13'><span class="sb">`</span>realtime<span class="s1">&#39;</span></div><div class='line' id='LC14'><span class="s1">./features/step_definitions/api/v1/articles_steps.rb:11:in `/^I ask for</span></div><div class='line' id='LC15'><span class="s1">articles from the API$/&#39;</span></div><div class='line' id='LC16'>features/api/v1/articles.feature:9:in <span class="sb">`</span>When I ask <span class="k">for </span>articles from the</div><div class='line' id='LC17'>API<span class="err">&#39;</span></div><div class='line' id='LC18'><br/></div><div class='line' id='LC19'>Failing Scenarios:</div><div class='line' id='LC20'>cucumber features/api/v1/articles.feature:6 <span class="c"># Scenario: Get articles</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1824186/e9fec42d14d16bf8e6cb8150015af8ed739e28e1/gistfile1.sh" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1824186#file_gistfile1.sh" style="float:right;margin-right:10px;color:#666">gistfile1.sh</a>
            <a href="https://gist.github.com/1824186">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</p>
<p>
Now we fail because our <code>#index</code> action needs a template.  Let&#8217;s create an empty template just so we can finally get a non-infrastructure related failure, i.e., a logic error, from Cucumber.
</p>
<p><div id="gist-1824191" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="nv">$ </span>touch app/views/api/v1/articles/index.json.jbuilder</div><div class='line' id='LC2'><span class="nv">$ </span>cucumber features/api/v1/articles.feature</div><div class='line' id='LC3'>Using the default profile...</div><div class='line' id='LC4'>...F</div><div class='line' id='LC5'><br/></div><div class='line' id='LC6'><span class="o">(</span>::<span class="o">)</span> failed steps <span class="o">(</span>::<span class="o">)</span></div><div class='line' id='LC7'><br/></div><div class='line' id='LC8'>expected 3 published_articles, got 0</div><div class='line' id='LC9'><span class="o">(</span>RSpec::Expectations::ExpectationNotMetError<span class="o">)</span></div><div class='line' id='LC10'>./features/step_definitions/api/v1/articles_steps.rb:16:in <span class="sb">`</span>/^I should</div><div class='line' id='LC11'>only receive published articles as JSON<span class="nv">$/</span><span class="s1">&#39;</span></div><div class='line' id='LC12'><span class="s1">features/api/v1/articles.feature:10:in `Then I should only receive</span></div><div class='line' id='LC13'><span class="s1">published articles as JSON&#39;</span></div><div class='line' id='LC14'><br/></div><div class='line' id='LC15'>Failing Scenarios:</div><div class='line' id='LC16'>cucumber features/api/v1/articles.feature:6 <span class="c"># Scenario: Get articles</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1824191/a2108da9f52c0ed6419aee482f986205342b6b2f/gistfile1.sh" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1824191#file_gistfile1.sh" style="float:right;margin-right:10px;color:#666">gistfile1.sh</a>
            <a href="https://gist.github.com/1824191">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</p>
<h2>Drill Down to the View</h2>
<p>
With the routing and request handling boilerplate out of the way, we finally get a &#8220;legitimate&#8221; failure from Cucumber. At this point, some outside-in practitioners will drop down a level with respect to testing and use RSpec to spec out the view. Like controller specs, I&#8217;m going to skip this step for simplicity. We&#8217;ll discuss when a view spec makes sense later on. For now, let&#8217;s update our blank view to actually render some JSON (we&#8217;ll use the <a href="https://github.com/rails/jbuilder">jbuilder</a> Gem to construct the JSON).
</p>
<p><em>app/views/api/v1/articles/index.json.jbuilder</em></p>
<p><div id="gist-1824193" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="n">json</span><span class="o">.</span><span class="n">array!</span> <span class="vi">@articles</span> <span class="k">do</span> <span class="o">|</span><span class="n">json</span><span class="p">,</span> <span class="n">article</span><span class="o">|</span></div><div class='line' id='LC2'>&nbsp;&nbsp;<span class="n">json</span><span class="o">.</span><span class="n">title</span> <span class="n">article</span><span class="o">.</span><span class="n">title</span></div><div class='line' id='LC3'><span class="k">end</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1824193/8fe2513bbc92ad8eca9b0b4d85d68557cae312cf/gistfile1.rb" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1824193#file_gistfile1.rb" style="float:right;margin-right:10px;color:#666">gistfile1.rb</a>
            <a href="https://gist.github.com/1824193">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</p>
<p>
Again, we write this view imagining an &#8220;articles&#8221; instance variable; ideally, a collection containing our articles. This helps us avoid setting up unnecessary state in our action.
</p>
<p>
Cucumber fails again, this time with a long stacktrace (abbreviated below) originating in <code>jbuilder</code>.
</p>
<p><div id="gist-1824194" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="nv">$ </span>cucumber features/api/v1/articles.feature</div><div class='line' id='LC2'>Using the default profile...</div><div class='line' id='LC3'>..F-</div><div class='line' id='LC4'><br/></div><div class='line' id='LC5'><span class="o">(</span>::<span class="o">)</span> failed steps <span class="o">(</span>::<span class="o">)</span></div><div class='line' id='LC6'><br/></div><div class='line' id='LC7'>undefined method <span class="sb">`</span>empty?<span class="err">&#39;</span> <span class="k">for </span>nil:NilClass <span class="o">(</span>ActionView::Template::Error<span class="o">)</span></div><div class='line' id='LC8'><br/></div><div class='line' id='LC9'>Failing Scenarios:</div><div class='line' id='LC10'>cucumber features/api/v1/articles.feature:6 <span class="c"># Scenario: Get articles</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1824194/5ab77afd28e64261043599df3e70a21b396b840a/gistfile1.sh" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1824194#file_gistfile1.sh" style="float:right;margin-right:10px;color:#666">gistfile1.sh</a>
            <a href="https://gist.github.com/1824194">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</p>
<p>
This failure is because the instance variable doesn&#8217;t exist yet.  Let&#8217;s update our <code>Api::V1::ArticlesController#index</code> action to find all published articles.
</p>
<p><em>app/controllers/api/v1/articles_controller.rb</em></p>
<p><div id="gist-1824196" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="k">class</span> <span class="nc">Api</span><span class="o">::</span><span class="no">V1</span><span class="o">::</span><span class="no">ArticlesController</span> <span class="o">&lt;</span> <span class="no">ApplicationController</span></div><div class='line' id='LC2'>&nbsp;&nbsp;<span class="k">def</span> <span class="nf">index</span></div><div class='line' id='LC3'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="vi">@articles</span> <span class="o">=</span> <span class="no">Article</span><span class="o">.</span><span class="n">published</span></div><div class='line' id='LC4'>&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC5'><span class="k">end</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1824196/ee87637bd1acfc1b1ba41cd1ea5e6991ff1f82d5/gistfile1.rb" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1824196#file_gistfile1.rb" style="float:right;margin-right:10px;color:#666">gistfile1.rb</a>
            <a href="https://gist.github.com/1824196">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</p>
<p>
We&#8217;ve kept our controller thin and decided to not directly test it. By keeping controller logic to a minimum, skipping controller tests isn&#8217;t a significant risk.
</p>
<p>
Cucumber now guides us to our domain model.
</p>
<p><div id="gist-1824199" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="nv">$ </span>cucumber features/api/v1/articles.feature</div><div class='line' id='LC2'>Using the default profile...</div><div class='line' id='LC3'>..F-</div><div class='line' id='LC4'><br/></div><div class='line' id='LC5'><span class="o">(</span>::<span class="o">)</span> failed steps <span class="o">(</span>::<span class="o">)</span></div><div class='line' id='LC6'><br/></div><div class='line' id='LC7'>undefined method <span class="sb">`</span>published<span class="s1">&#39; for #&lt;Class:0x007ff13c529498&gt;</span></div><div class='line' id='LC8'><span class="s1">(NoMethodError)</span></div><div class='line' id='LC9'><span class="s1">./app/controllers/api/v1/articles_controller.rb:3:in `index&#39;</span></div><div class='line' id='LC10'>./features/step_definitions/api/v1/articles_steps.rb:11:in <span class="sb">`</span>/^I ask <span class="k">for</span></div><div class='line' id='LC11'>articles from the API<span class="nv">$/</span><span class="s1">&#39;</span></div><div class='line' id='LC12'><span class="s1">features/api/v1/articles.feature:9:in `When I ask for articles from the</span></div><div class='line' id='LC13'><span class="s1">API&#39;</span></div><div class='line' id='LC14'><br/></div><div class='line' id='LC15'>Failing Scenarios:</div><div class='line' id='LC16'>cucumber features/api/v1/articles.feature:6 <span class="c"># Scenario: Get articles</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1824199/6dee1ddaa3b6fb4b058c050bed0b896fc4bfd1f3/gistfile1.sh" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1824199#file_gistfile1.sh" style="float:right;margin-right:10px;color:#666">gistfile1.sh</a>
            <a href="https://gist.github.com/1824199">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</p>
<h2>Drill Down to the Model</h2>
<p>
Despite skipping controller and view specs, I do feel it&#8217;s beneficial to drill down a layer in our tests and directly test the model. Model tests will shorten our testing feedback loop and allow us to specify at a level closer to the code. Skipping model tests and relying on Cucumber, keeps the feedback loop too large, slowing you down.
</p>
<p><em>spec/models/article_spec.rb</em></p>
<p><div id="gist-1824200" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="nb">require</span> <span class="s1">&#39;spec_helper&#39;</span></div><div class='line' id='LC2'><br/></div><div class='line' id='LC3'><span class="n">describe</span> <span class="no">Article</span> <span class="k">do</span></div><div class='line' id='LC4'>&nbsp;&nbsp;<span class="n">describe</span> <span class="s1">&#39;.published&#39;</span> <span class="k">do</span></div><div class='line' id='LC5'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">before</span> <span class="k">do</span></div><div class='line' id='LC6'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="no">FactoryGirl</span><span class="o">.</span><span class="n">create_list</span><span class="p">(</span><span class="ss">:published_article</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span></div><div class='line' id='LC7'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="no">FactoryGirl</span><span class="o">.</span><span class="n">create_list</span><span class="p">(</span><span class="ss">:unpublished_article</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span></div><div class='line' id='LC8'><br/></div><div class='line' id='LC9'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="vi">@published</span> <span class="o">=</span> <span class="no">Article</span><span class="o">.</span><span class="n">published</span></div><div class='line' id='LC10'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC11'><br/></div><div class='line' id='LC12'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">it</span> <span class="s1">&#39;only returns published articles&#39;</span> <span class="k">do</span></div><div class='line' id='LC13'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="vi">@published</span><span class="o">.</span><span class="n">should_not</span> <span class="n">be_empty</span></div><div class='line' id='LC14'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="vi">@published</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">article</span><span class="o">|</span></div><div class='line' id='LC15'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">article</span><span class="o">.</span><span class="n">should</span> <span class="n">be_published</span></div><div class='line' id='LC16'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC17'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC18'>&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC19'><span class="k">end</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1824200/e984a4bb99679f04f9b4ad06c2c34cb2a0970de6/gistfile1.rb" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1824200#file_gistfile1.rb" style="float:right;margin-right:10px;color:#666">gistfile1.rb</a>
            <a href="https://gist.github.com/1824200">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</p>
<p>
RSpec will now be our guide.
</p>
<p><div id="gist-1824203" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="nv">$ </span>rspec spec/models/article_spec.rb</div><div class='line' id='LC2'>F</div><div class='line' id='LC3'><br/></div><div class='line' id='LC4'>Failures:</div><div class='line' id='LC5'><br/></div><div class='line' id='LC6'>&nbsp;&nbsp;1<span class="o">)</span> Article.published only returns published articles</div><div class='line' id='LC7'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Failure/Error: @published <span class="o">=</span> Article.published</div><div class='line' id='LC8'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NoMethodError:</div><div class='line' id='LC9'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;undefined method <span class="sb">`</span>published<span class="s1">&#39; for #&lt;Class:0x007fee85f72440&gt;</span></div><div class='line' id='LC10'><span class="s1">     # ./spec/models/article_spec.rb:9:in `block (3 levels) in &lt;top</span></div><div class='line' id='LC11'><span class="s1">     # (required)&gt;&#39;</span></div><div class='line' id='LC12'><br/></div><div class='line' id='LC13'>Finished in 0.03521 seconds</div><div class='line' id='LC14'>1 example, 1 failure</div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1824203/7587766fd82ecb90464b0eb3b1be0fa430009a67/gistfile1.sh" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1824203#file_gistfile1.sh" style="float:right;margin-right:10px;color:#666">gistfile1.sh</a>
            <a href="https://gist.github.com/1824203">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</p>
<p><em>app/models/article.rb</em></p>
<p><div id="gist-1824206" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="k">class</span> <span class="nc">Article</span> <span class="o">&lt;</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span></div><div class='line' id='LC2'>&nbsp;&nbsp;<span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">published</span></div><div class='line' id='LC3'>&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC4'><span class="k">end</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1824206/85c080638fecc429cfe5ad1a944062b3870ca1e1/gistfile1.rb" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1824206#file_gistfile1.rb" style="float:right;margin-right:10px;color:#666">gistfile1.rb</a>
            <a href="https://gist.github.com/1824206">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</p>
<p><div id="gist-1824208" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="nv">$ </span>rspec spec/models/article_spec.rb</div><div class='line' id='LC2'>F</div><div class='line' id='LC3'><br/></div><div class='line' id='LC4'>Failures:</div><div class='line' id='LC5'><br/></div><div class='line' id='LC6'>&nbsp;&nbsp;1<span class="o">)</span> Article.published only returns published articles</div><div class='line' id='LC7'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Failure/Error: @published.should_not be_empty</div><div class='line' id='LC8'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NoMethodError:</div><div class='line' id='LC9'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;undefined method <span class="sb">`</span>empty?<span class="s1">&#39; for nil:NilClass</span></div><div class='line' id='LC10'><span class="s1">     # ./spec/models/article_spec.rb:13:in `block (3 levels) in &lt;top</span></div><div class='line' id='LC11'><span class="s1">     # (required)&gt;&#39;</span></div><div class='line' id='LC12'><br/></div><div class='line' id='LC13'>Finished in 0.03338 seconds</div><div class='line' id='LC14'>1 example, 1 failure</div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1824208/741186e4714e6aebab4531f2b181a40b6a4f7095/gistfile1.sh" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1824208#file_gistfile1.sh" style="float:right;margin-right:10px;color:#666">gistfile1.sh</a>
            <a href="https://gist.github.com/1824208">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</p>
<p><em>app/models/article.rb</em></p>
<p><div id="gist-1824210" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="k">class</span> <span class="nc">Article</span> <span class="o">&lt;</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span></div><div class='line' id='LC2'>&nbsp;&nbsp;<span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">published</span></div><div class='line' id='LC3'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">where</span> <span class="ss">:published</span> <span class="o">=&gt;</span> <span class="kp">true</span></div><div class='line' id='LC4'>&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC5'><span class="k">end</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1824210/acb3bbe06028e4003641da1fd77472cf50741bac/gistfile1.rb" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1824210#file_gistfile1.rb" style="float:right;margin-right:10px;color:#666">gistfile1.rb</a>
            <a href="https://gist.github.com/1824210">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</p>
<p><div id="gist-1824212" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="nv">$ </span>rspec spec/models/article_spec.rb</div><div class='line' id='LC2'>.</div><div class='line' id='LC3'><br/></div><div class='line' id='LC4'>Finished in 0.10455 seconds</div><div class='line' id='LC5'>1 example, 0 failures</div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1824212/fd9063ebd5189771131a057839cdadf9879a1a56/gistfile1.sh" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1824212#file_gistfile1.sh" style="float:right;margin-right:10px;color:#666">gistfile1.sh</a>
            <a href="https://gist.github.com/1824212">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</p>
<p>
With <code>Article.published</code> specified, we can return to Cucumber.
</p>
<h2>Jump Back Up to Cucumber</h2>
<p>
Cucumber is now passing and our story is complete.
</p>
<p><div id="gist-1824216" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="nv">$ </span>cucumber features/api/v1/articles.feature</div><div class='line' id='LC2'>Using the default profile...</div><div class='line' id='LC3'>....</div><div class='line' id='LC4'><br/></div><div class='line' id='LC5'>1 scenario <span class="o">(</span>1 passed<span class="o">)</span></div><div class='line' id='LC6'>4 steps <span class="o">(</span>4 passed<span class="o">)</span></div><div class='line' id='LC7'><br/></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1824216/34d632e5aba3417606dfcdabacad0203a255082d/gistfile1.sh" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1824216#file_gistfile1.sh" style="float:right;margin-right:10px;color:#666">gistfile1.sh</a>
            <a href="https://gist.github.com/1824216">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</p>
<p>
The complete code for this example can be found on <a href="https://github.com/carbonfive/beginning-outside-in-rails-development">github</a>.
</p>
<h2>Change Your Perspective</h2>
<p>
I use the above approach on every feature I write.  At each layer, I find myself getting lazier and lazier, delaying the hard work until the very end. At that point, I&#8217;m in the domain model, the heart of the application, and where the majority of logic should be. By taking a client perspective at each layer, the resulting objects remain simple, have expressive interfaces, and logic naturally finds its home.
</p>
<p>
You can begin developing from the outside in at every one of your application&#8217;s interfaces. The example above demonstrated a JSON API. Traditional HTML interfaces can easily be tested using <a href="http://rubygems.org/gems/capybara">capybara</a>. And if you&#8217;re developing a command line interface, perhaps for a Ruby gem, take a look at <a href="http://rubygems.org/gems/aruba">aruba</a>.
</p>
<h2>Do I Need to Test at Every Layer?</h2>
<p>
The RSpec book suggests writing tests at each layer, i.e., view specs, controller specs, helper specs, and model specs. I&#8217;ve tried this approach several times but I usually feel all the lower level specs, except model specs, aren&#8217;t worth it. They do shorten the testing feedback loop, but their reliance on stubbing and mocking to achieve true isolation makes refactoring and maintenance difficult. I also keep the logic to such a minimum in these objects, e.g., controllers, that the additional fine-grained unit tests don&#8217;t provide that much benefit.
</p>
<p>
There is nothing wrong with not unit testing each part of your application. Don&#8217;t dogmatically insist that everything be unit tested. Oftentimes a higher-level integration test will sufficiently exercise (albeit indirectly) a particular piece of code. The tradeoff here is that your testing feedback loop will be large. You&#8217;ll need to execute a full-stack Cucumber test just to see if a change you made, perhaps in a controller or a view, passes your failing test. Occasionally, I&#8217;ll use a lower level view or controller test to handle an edge case but this is a pretty rare occurrence. This is just my personal style. I would recommend trying out testing at every level, especially view and controller tests, to see how it feels and if it&#8217;s beneficial for you and your team.
</p>
<h2>Give It A Try</h2>
<p>
Outside-in development often feels strange to newcomers. Most developers prefer to start with the &#8220;important&#8221; part of an application, i.e., the domain model, and work their way outwards. Thinking like a server and not a client can lead to overengineering by implementing more than you need. Your resulting objects and their interfaces will also be less than optimal, or at least take longer to get quite right.
</p>
<p>
Like most things in Rails, the tools for developing outside-in are easy to setup and configure. If Cucumber or RSpec aren&#8217;t your thing, adapt your favorite tool and give outside-in development a try.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2012/02/14/beginning-outside-in-rails-development-with-cucumber-and-rspec/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>Monkey-Patching iOS with Objective-C Categories Part I: Simple Extensions and Overrides</title>
		<link>http://blog.carbonfive.com/2012/01/23/monkey-patching-ios-with-objective-c-categories-part-1-simple-extensions-and-overrides/</link>
		<comments>http://blog.carbonfive.com/2012/01/23/monkey-patching-ios-with-objective-c-categories-part-1-simple-extensions-and-overrides/#comments</comments>
		<pubDate>Mon, 23 Jan 2012 18:38:45 +0000</pubDate>
		<dc:creator>Rudy Jahchan</dc:creator>
				<category><![CDATA[Mobile]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[monkey-patching]]></category>
		<category><![CDATA[objective-c]]></category>

		<guid isPermaLink="false">http://blog.carbonfive.com/?p=5851</guid>
		<description><![CDATA[Have you ever wanted to introduce new functionality to base classes in the iOS SDK? Or just make them work a little bit differently? In order to do so, you must enter the wild and dangerous world of monkey-patching. Monkey-patching &#8230; <a href="http://blog.carbonfive.com/2012/01/23/monkey-patching-ios-with-objective-c-categories-part-1-simple-extensions-and-overrides/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Have you ever wanted to introduce new functionality to base classes in the iOS SDK? Or just make them work a <strong>little bit</strong> differently? In order to do so, you must enter the wild and dangerous world of monkey-patching.</p>

<p>Monkey-patching is extending or modifying the behavior of code at runtime <strong>without</strong> changing its original source code. You can monkey-patch any code, it doesn&#8217;t matter whether it&#8217;s your own code or not. This is distinctly different than traditional sub-classing because you are not creating a new class, instead, you are reopening an existing class and changing its behavior.</p>

<p>Monkey-patching is possible in Objective-C by using <a href="http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/objectivec/chapters/occategories.html">categories</a>. In fact, the definition of a category practically matches that of monkey-patching:</p>

<p><code>"A category allows you to add methods to an existing class—even to one for which you do not have the source."</code></p>

<p>In this series of posts, we&#8217;ll use categories to add and change methods, to add new instance variables and properties, and introduce swizzling, a technique that allows us to extend and preserve existing functionality.<span id="more-5851"></span> <a href="#tldr"><strong>TL;DR &raquo;</strong></a></p>

<h2>Category Basics</h2>

<p>To modify an existing class specify the category in both its interface and implementation definitions:</p>

<h4>Interface Definition</h4>

<script src="https://gist.github.com/1660134.js?file=AClassACategoryImplementation.h"></script>

<h4>Implementation</h4>

<script src="https://gist.github.com/1660134.js?file=AClassACategoryImplementation.m"></script>

<h2>Adding Simple Methods</h2>

<p>The most basic usage of categories is to add a new method to an existing class.</p>

<p>Suppose in our application we want to output dates relative to the current time, e.g., &#8220;13 minutes ago&#8221;, &#8220;4 hours ago&#8221;, &#8220;just now&#8221;, etc. Traditional object-oriented solutions would have us introducing a new class that either extends <code>NSDate</code> (e.g., creating a <code>RelativeDescriptionDate</code> subclass with a <code>timeAgoInWords</code> instance method) or is a standalone helper/utility class (e.g., <code>[NSDateHelper timeAgoInWordsFromDate:myDate]</code>).</p>

<p>But with categories, we can reopen the <code>NSDate</code> class and simply add a new instance method:</p>

<h4>NSDate+Formatting.h</h4>

<script src="https://gist.github.com/1660134.js?file=NSDateFormatting.h"></script>

<h4>NSDate+Formatting.m</h4>

<script src="https://gist.github.com/1660134.js?file=NSDateFormatting.m"></script>

<p>Now <strong>every</strong> <code>NSDate</code> object will have the new method available to it. The following code:</p>

<script src="https://gist.github.com/1660134.js?file=UsingNSDateFormatting.m"></script>

<p>Will print out the following on the console:</p>

<script src="https://gist.github.com/1660134.js?file=gistfile1.sh"></script>

<h2>The Dangers of Simply Overriding Methods</h2>

<p>We can take this a step further and instead of adding new behavior we&#8217;ll override existing behavior. Continuing with our example, what if we wanted the default description of a <code>NSDate</code> object to include the time ago in words? We could simply do the following:</p>

<script src="https://gist.github.com/1660134.js?file=NSDateFormatting2.m"></script>

<p>However, this is <strong>strongly discouraged</strong> for two reasons.</p>

<ol>
<li>Other frameworks may rely on the expected behavior of the original method. We now have to go through the trouble of re-implementing that behavior, in addition to the new functionality we wanted to introduce, or risk strange side effects and possibly even crashing out. </li>
<li>If multiple categories implement the same method, the last one loaded wins! The load order is consistent within an application, but it&#8217;s arbitrary, out of our hands, and fragile. For all we know, our implementation could itself be overwritten by an internal framework category!</li>
</ol>

<p>Because of these reasons, this blunt approach to overriding methods should only be used for the simplest of cases. Later in this series, we&#8217;ll explore how swizzling allows us to override a method while preserving all implementations.</p>

<h2>Including Your Monkey-Patches</h2>

<p>Categories are not automatically &#8220;picked up&#8221; in a project. Any code that relies on the behavior will need to <code>#import</code> the necessary header files:</p>

<script src="https://gist.github.com/1660134.js?file=EntryCell.m"></script>

<p>However, including the same set of headers over and over again is redundant. We should first create a single header file that imports all of our most frequently used categories:</p>

<script src="https://gist.github.com/1660134.js?file=Extensions.h"></script>

<p>We can then import this single header file into a prefix header that is added to all source files. XCode projects often have a <code>.pch</code> file in the Supporting Files group for this very purpose.</p>

<script src="https://gist.github.com/1660134.js?file=pc.h"></script>

<h2>Next Up</h2>

<p>While adding and overriding classes is straightforward, there is one very big caveat when using Categories; you <strong>cannot add new instance variables</strong> to a class. We&#8217;ll take a look at working around this limitation in the next post.</p>

<h2><a name="tldr"></a> tl;dr</h2>

<ul>
<li>Use Objective-C categories to add functionality to existing classes without subclassing.</li>
<li>Avoid simple overrides with categories as it can cause problems with other frameworks.</li>
<li>Use prefix headers to easily import your extensions.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2012/01/23/monkey-patching-ios-with-objective-c-categories-part-1-simple-extensions-and-overrides/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Display Line Numbers on Embedded Gists</title>
		<link>http://blog.carbonfive.com/2012/01/12/display-line-numbers-on-embedded-gists/</link>
		<comments>http://blog.carbonfive.com/2012/01/12/display-line-numbers-on-embedded-gists/#comments</comments>
		<pubDate>Thu, 12 Jan 2012 22:59:45 +0000</pubDate>
		<dc:creator>Steven Harms</dc:creator>
				<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://blog.carbonfive.com/?p=5763</guid>
		<description><![CDATA[I've been working on a post here for C5 and in order to make my points, I was referencing gists hosted by GitHub. When those gists were shown as embeds, the line numbers, and thus the clarity of my documentation, &#8230; <a href="http://blog.carbonfive.com/2012/01/12/display-line-numbers-on-embedded-gists/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><script type="text/javascript"></p>
<p>/*
  * Add this to the top of your post.  This will get interpreted in and applies to your page
  * e.g.
  * 
  * (this code)
  *
  * # My Summer Vacation
  *
  * ## Grandma's House
  * 
  * We left for Grandma's house at 2pm on Friday.  I was so excited to see her pet Bear and Fox!
*/</p>
<p>var fixGistRules = [
".gist .gist-highlight {  border-left: 3ex solid #eee;  position: relative;}",
".gist .gist-highlight pre { counter-reset: linenumbers;}",
".gist .gist-highlight pre div:before { color: #aaa; content: counter(linenumbers); counter-increment: linenumbers;  left: -3ex; position: absolute; text-align: right; width: 2.5ex;}" ];</p>
<p>var head = document.getElementsByTagName('head')[0],
    style = document.createElement('style');</p>
<p>rules = new Array();
var i=0;
for ( i=0; i< fixGistRules.length; i++ ){
  var fullrule = document.createTextNode(fixGistRules[i]);
  rules.push(fullrule);
}</p>
<p>style.type = 'text/css';</p>
<p>for ( var i=0; i< rules.length; i++ ){
  if(style.styleSheet){
    style.styleSheet.cssText = rules[i].nodeValue;
  }else {
    style.appendChild(rules[i]);
    head.appendChild(style);
  }
}
</script></p>
<p>I've been working on a post here for C5 and in order to make my points, I was referencing gists hosted by <a href="http://github.com">GitHub</a>.  When those gists were shown as embeds, the line numbers, and thus the clarity of my documentation, was lost.  We use Markdown for the creation of the texts so I needed something I could write inside of a Markdown post that would be applied as CSS.</p>
<p>Thanks to these tips:</p>
<ol>
<li><a href="http://www.whyhat.com/2012/01/line-numbers-on-embedded-gists">http://www.whyhat.com/2012/01/line-numbers-on-embedded-gists</a></li>
<li><a href="http://stackoverflow.com/questions/524696/how-to-create-a-style-tag-with-javascript">http://stackoverflow.com/questions/524696/how-to-create-a-style-tag-with-javascript</a></li>
</ol>
<p>I was able to come up with the following:</p>
<p><script src="https://gist.github.com/1603633.js"> </script></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2012/01/12/display-line-numbers-on-embedded-gists/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

