<?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>Rails on the Run &#187; BDD</title>
	<atom:link href="http://railsontherun.com/tag/bdd/feed/" rel="self" type="application/rss+xml" />
	<link>http://railsontherun.com</link>
	<description>Rails experiments by Matt Aimonetti</description>
	<lastBuildDate>Tue, 23 Feb 2010 07:28:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
<xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" />
		<item>
		<title>Misc tips and tricks</title>
		<link>http://railsontherun.com/2008/01/30/misc-tips-and-tricks/</link>
		<comments>http://railsontherun.com/2008/01/30/misc-tips-and-tricks/#comments</comments>
		<pubDate>Wed, 30 Jan 2008 08:00:00 +0000</pubDate>
		<dc:creator>Matt Aimonetti</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[autotest]]></category>
		<category><![CDATA[BDD]]></category>
		<category><![CDATA[integration]]></category>
		<category><![CDATA[RSpec]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[zentest]]></category>

		<guid isPermaLink="false">http://railsontherun.com/2008/01/30/misc-tips-and-tricks</guid>
		<description><![CDATA[I haven&#8217;t posted for quite a long time. The thing is I moved to a new place and I&#8217;m really busy on working clients + setting up my new office + dealing with way too much paperwork. Anyway, enough excuses, here are few tips that I believe will be useful to some of you: ZenTest [...]]]></description>
			<content:encoded><![CDATA[<p>I haven&#8217;t posted for quite a long time. The thing is I moved to a new place and I&#8217;m really busy on working clients + setting up my new office + dealing with way too much paperwork. </p>
<p>Anyway, enough excuses, here are few tips that I believe will be useful to some of you:</p>
<h2><a href="http://www.zenspider.com/ZSS/Products/ZenTest/">ZenTest Autotest</a></h2>
<p>I love autotest, but you might have noticed that sometimes (especially on big projects), ZenTest might start using more CPU than expected. On my machine, that results in the fan going off and annoying the crap out of me.</p>
<p>The solution is quite simple, exclude all folders you don&#8217;t need to monitor. To do that, update ZenTest to version 3.8.X </p>
<pre><code>sudo gem update ZenTest
</code></pre>
<p>(older version had a different syntax)</p>
<p>Now, edit your .autotest that should be located in ~/.autotest  (if it doesn&#8217;t exist, create it).</p>
<p>Finally add the following code:</p>
<table class="CodeRay">
<tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }">
<pre>1<tt>
</tt>2<tt>
</tt>3<tt>
</tt>4<tt>
</tt></pre>
</td>
<td class="code">
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><tt>
</tt>  <span class="co">Autotest</span>.add_hook <span class="sy">:initialize</span> <span class="r">do</span> |at|<tt>
</tt>    <span class="s"><span class="dl">%w{</span><span class="k">.svn .hg .git vendor</span><span class="dl">}</span></span>.each {|exception| at.add_exception(exception)}<tt>
</tt>  <span class="r">end</span><tt>
</tt></pre>
</td>
</tr>
</table>
<p>I personally freeze rails in vendor and I autotest is way happier when it doesn&#8217;t have to monitor some extra files. (note that we also exclude folders such as .git or .svn)<br />
(you can also include files etc&#8230; read more <a href="http://blog.davidchelimsky.net/articles/2008/01/15/rspec-1-1-2-and-zentest-3-8-0">there</a>)</p>
<h2><a href="http://rspec.info">RSpec</a></h2>
<p>RSpec is certainly my favorite Ruby tool and I&#8217;m glad to say that most of my <a href="http://sdruby.com/">SD.rb</a> friends finally got convinced!</p>
<p>Now, few people complained to me about spec failures outputting the full stack such as:</p>
<table class="CodeRay">
<tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }">
<pre>1<tt>
</tt>2<tt>
</tt>3<tt>
</tt>4<tt>
</tt><strong>5</strong><tt>
</tt>6<tt>
</tt>7<tt>
</tt>8<tt>
</tt>9<tt>
</tt><strong>10</strong><tt>
</tt>11<tt>
</tt>12<tt>
</tt>13<tt>
</tt>14<tt>
</tt><strong>15</strong><tt>
</tt>16<tt>
</tt>17<tt>
</tt>18<tt>
</tt>19<tt>
</tt><strong>20</strong><tt>
</tt>21<tt>
</tt>22<tt>
</tt>23<tt>
</tt>24<tt>
</tt><strong>25</strong><tt>
</tt>26<tt>
</tt></pre>
</td>
<td class="code">
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><tt>
</tt> <span class="co">The</span> <span class="co">Sessions</span> controller should fail since it<span class="s"><span class="dl">'</span><span class="k">s a test</span><span class="dl">'</span></span> <span class="co">FAILED</span><tt>
</tt> expected <span class="pc">true</span>, got <span class="pc">false</span><tt>
</tt> test_app-git/trunk/vendor/plugins/rspec/lib/spec/expectations.rb:<span class="i">52</span><span class="sy">:in</span> <span class="sh"><span class="dl">`</span><span class="k">fail_with'<tt>
</tt> test_app-git/trunk/vendor/plugins/rspec/lib/spec/expectations/handler.rb:21:in </span><span class="dl">`</span></span>handle_matcher<span class="s"><span class="dl">'</span><span class="k"><tt>
</tt> test_app-git/trunk/vendor/plugins/rspec/lib/spec/expectations/extensions/object.rb:34:in `should</span><span class="dl">'</span></span><tt>
</tt> ./spec/controllers/sessions_controller_spec.rb:<span class="i">25</span>:<tt>
</tt> test_app-git/trunk/vendor/plugins/rspec/lib/spec/example/example_methods.rb:<span class="i">78</span><span class="sy">:in</span> <span class="sh"><span class="dl">`</span><span class="k">instance_eval'<tt>
</tt> test_app-git/trunk/vendor/plugins/rspec/lib/spec/example/example_methods.rb:78:in </span><span class="dl">`</span></span>run_with_description_capturing<span class="s"><span class="dl">'</span><span class="k"><tt>
</tt> test_app-git/trunk/vendor/plugins/rspec/lib/spec/example/example_methods.rb:19:in `execute</span><span class="dl">'</span></span><tt>
</tt> <span class="rx"><span class="dl">/</span><span class="k">opt</span><span class="dl">/</span></span>local/lib/ruby/<span class="fl">1.8</span>/timeout.rb:<span class="i">48</span><span class="sy">:in</span> <span class="sh"><span class="dl">`</span><span class="k">timeout'<tt>
</tt> test_app-git/trunk/vendor/plugins/rspec/lib/spec/example/example_methods.rb:16:in </span><span class="dl">`</span></span>execute<span class="s"><span class="dl">'</span><span class="k"><tt>
</tt> test_app-git/trunk/vendor/plugins/rspec/lib/spec/example/example_group_methods.rb:288:in `execute_examples</span><span class="dl">'</span></span><tt>
</tt> test_app-git/trunk/vendor/plugins/rspec/lib/spec/example/example_group_methods.rb:<span class="i">287</span><span class="sy">:in</span> <span class="sh"><span class="dl">`</span><span class="k">each'<tt>
</tt> test_app-git/trunk/vendor/plugins/rspec/lib/spec/example/example_group_methods.rb:287:in </span><span class="dl">`</span></span>execute_examples<span class="s"><span class="dl">'</span><span class="k"><tt>
</tt> test_app-git/trunk/vendor/plugins/rspec/lib/spec/example/example_group_methods.rb:121:in `run</span><span class="dl">'</span></span><tt>
</tt> test_app-git/trunk/vendor/plugins/rspec/lib/spec/runner/example_group_runner.rb:<span class="i">22</span><span class="sy">:in</span> <span class="sh"><span class="dl">`</span><span class="k">run'<tt>
</tt> test_app-git/trunk/vendor/plugins/rspec/lib/spec/runner/example_group_runner.rb:21:in </span><span class="dl">`</span></span>each<span class="s"><span class="dl">'</span><span class="k"><tt>
</tt> test_app-git/trunk/vendor/plugins/rspec/lib/spec/runner/example_group_runner.rb:21:in `run</span><span class="dl">'</span></span><tt>
</tt> test_app-git/trunk/vendor/plugins/rspec/lib/spec/runner/options.rb:<span class="i">89</span><span class="sy">:in</span> <span class="sh"><span class="dl">`</span><span class="k">run_examples'<tt>
</tt> test_app-git/trunk/vendor/plugins/rspec/lib/spec/runner/command_line.rb:19:in </span><span class="dl">`</span></span>run<span class="s"><span class="dl">'</span><span class="k"><tt>
</tt> script/spec:4:<tt>
</tt><tt>
</tt>  Finished in 6.035147 seconds<tt>
</tt><tt>
</tt>  400 examples, 1 failure<tt>
</tt></span></span></pre>
</td>
</tr>
</table>
<p>We can really easily change that, open you spec.opts file located in your spec folder.</p>
<p>it probably looks like that:</p>
<table class="CodeRay">
<tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }">
<pre>1<tt>
</tt>2<tt>
</tt>3<tt>
</tt>4<tt>
</tt><strong>5</strong><tt>
</tt>6<tt>
</tt>7<tt>
</tt>8<tt>
</tt></pre>
</td>
<td class="code">
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><tt>
</tt>  --colour<tt>
</tt>  --format<tt>
</tt>  progress<tt>
</tt>  --loadby<tt>
</tt>  mtime<tt>
</tt>  --reverse<tt>
</tt>  --backtrace<tt>
</tt></pre>
</td>
</tr>
</table>
<p>Get rid of &#8220;&#8211;backtrace&#8221; and your new failure should look like:</p>
<table class="CodeRay">
<tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }">
<pre>1<tt>
</tt>2<tt>
</tt>3<tt>
</tt>4<tt>
</tt><strong>5</strong><tt>
</tt>6<tt>
</tt>7<tt>
</tt>8<tt>
</tt>9<tt>
</tt><strong>10</strong><tt>
</tt>11<tt>
</tt></pre>
</td>
<td class="code">
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><tt>
</tt>  <span class="i">1</span>)<tt>
</tt>  <span class="s"><span class="dl">'</span><span class="k">The Sessions controller The Sessions controller should fail since it</span><span class="dl">'</span></span>s a test<span class="s"><span class="dl">'</span><span class="k"> FAILED<tt>
</tt>  expected false, got true<tt>
</tt>  ./spec/controllers/sessions_controller_spec.rb:25:<tt>
</tt>  script/spec:4:<tt>
</tt><tt>
</tt>  Finished in 0.269956 seconds<tt>
</tt><tt>
</tt>  15 examples, 1 failure<tt>
</tt>  <tt>
</tt></span></span></pre>
</td>
</tr>
</table>
<h2>Other stuff you may find interesting (in no particular order):</h2>
<ul>
<li><a href="http://opensource.thinkrelevance.com/wiki/spec-converter">spec converter</a></li>
<li><a href="http://cells.rubyforge.org/overview.html">Rails Cell</a></li>
<li><a href="http://jointheconversation.org/railsgit">Git to manage and deploy a Rails app</a></li>
<li><a href="http://rufy.com/contacts/doc/">contacts (retrieve user&#8217;s contacts from yahoo, gmail etc..)</a></li>
<li><a href="http://www.hashrocket.com/">Hashrocket</a></li>
<li><a href="http://www.amazon.com/Rails-Way-Addison-Wesley-Professional-Ruby/dp/0321445619">one of the best Rails book of the moment</a></li>
<li><a href="http://famspam.com/">err&#8217;s new baby</a> </li>
<li><a href="http://blog.caboo.se/articles/2008/1/30/caboose-conf-2008">caboose conf 08</a></li>
<li><a href="http://github.com/">git hub</a></li>
<li><a href="http://swxruby.org/">SWX Ruby (or how to get Rails to talk with Flash even faster)</a></li>
<li><a href="http://ruby.reddit.com">Ruby Reddit</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://railsontherun.com/2008/01/30/misc-tips-and-tricks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sexy Chart &#8211; The video</title>
		<link>http://railsontherun.com/2007/11/20/sexy-chart-the-video/</link>
		<comments>http://railsontherun.com/2007/11/20/sexy-chart-the-video/#comments</comments>
		<pubDate>Tue, 20 Nov 2007 04:46:00 +0000</pubDate>
		<dc:creator>Matt Aimonetti</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[amcharts]]></category>
		<category><![CDATA[BDD]]></category>
		<category><![CDATA[charts]]></category>
		<category><![CDATA[podcast]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[RSpec]]></category>
		<category><![CDATA[san diego]]></category>
		<category><![CDATA[sdruby]]></category>
		<category><![CDATA[video]]></category>

		<guid isPermaLink="false">http://railsontherun.com/2007/11/20/sexy-chart-the-video</guid>
		<description><![CDATA[A bit more than a month ago I posted a tutorial on how to use Flash with Rails to create some awesome/sexy graphs. Since a lot of people seemed interested by the topic, the SDRuby guys asked me to do a intro talk on how to create Sexy Charts with super sexy Rails. In the [...]]]></description>
			<content:encoded><![CDATA[<p>A bit more than a month ago I posted a <a href="http://railsontherun.com/2007/10/4/sexy-charts-in-less-than-5-minutes">tutorial</a> on how to use Flash with Rails to <a href="http://railsontherun.com/2007/10/4/sexy-charts-in-less-than-5-minutes">create some awesome/sexy graphs</a>.</p>
<p><img src="http://content.screencast.com/media/e0605640-1100-43dc-90f9-d8c2083c0f7c_74569570-772f-4886-b2ea-f305d1ede3aa_static_0_0_00000016.png" alt="chart"/></p>
<p>Since a lot of people seemed interested by the topic, the <a href="http://sdruby.com/">SDRuby</a> guys asked me to do a intro talk on how to create Sexy Charts with super sexy Rails.</p>
<p>In the mean time, a lot of people were asking for a example app to look at. People knowing me know that I&#8217;m quite lazy and I don&#8217;t like repeating tasks. I therefore decided to kill 2 birds with one stone and wrote a demo app that I would use during my <a href="http://podcast.sdruby.com/2007/11/13/episode-037-sexy-charts">presentation</a></p>
<p>As I was writing the demo app, I quickly realized that my talk would be even sexier if I would show some best practices. After all, an introduction talk is meant to help newbies learning the tricks that will change them in ninjas! </p>
<p>Sexy charts are sexy now, but in 15 years they might not look so sexy anymore. However <a href="http://en.wikipedia.org/wiki/Behavior_driven_development">BDD</a> is super hot now and will always be sexy! (even though we&#8217;ll probably adopt other even hotter approaches).</p>
<p>Based on the circumstances I decided that Sexy charts would become an excuse to show people how to do BDD using <a href="http://rspec.rubyforge.org">RSpec</a> and how to test a XML view  as described in <a href="http://railsontherun.com/2007/10/31/how-to-test-a-xml-builder-view">this previous post</a></p>
<p>During my presentation I totally forgot to show people what what kind of XML we were trying to feed amCharts, so here is the file:</p>
<p><a href="http://pastie.caboo.se/120055">http://pastie.caboo.se/120055</a></p>
<p>The code used in the presentation is also available <a href="http://railsontherun.com/assets/sexy_charts.zip">here</a></p>
<p>Presentation available <a href="http://podcast.sdruby.com/2007/11/13/episode-037-sexy-charts">here</a> (the sound is a bit saturated, sorry about that. Note that we made the video big enough so you can follow with the code if you don&#8217;t understand my accent <img src='http://railsontherun.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  )</p>
<p>Feel free to watch the other <a href="http://podcast.sdruby.com/">SDRuby podcasts</a> or even better, <a href="http://feeds.feedburner.com/sdrbpodcast">subscribe to our feed</a>.</p>
<h2>Next SDRuby meeting will be Thursday, December 6 @ 7:30pm</h2>
<p>Location: <a href="http://tinyurl.com/2f486e">UCSD CS Building</a></p>
<p>We&#8217;ll be talking about <a href="http://groups.google.com/group/sdruby/browse_thread/thread/d488b70d67f84a5f#">Unobtrusive Javascript</a>, the <a href="http://groups.google.com/group/sdruby/browse_thread/thread/d488b70d67f84a5f#">Facebook API</a>, and hosting our first Rails Roundtable.</p>
<h2>Newbies and experts welcome!</h2>
]]></content:encoded>
			<wfw:commentRss>http://railsontherun.com/2007/11/20/sexy-chart-the-video/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to test a XML builder view</title>
		<link>http://railsontherun.com/2007/10/31/how-to-test-a-xml-builder-view/</link>
		<comments>http://railsontherun.com/2007/10/31/how-to-test-a-xml-builder-view/#comments</comments>
		<pubDate>Wed, 31 Oct 2007 08:32:00 +0000</pubDate>
		<dc:creator>Matt Aimonetti</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[BDD]]></category>
		<category><![CDATA[hpricot]]></category>
		<category><![CDATA[parser]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[RSpec]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[TDD]]></category>
		<category><![CDATA[test]]></category>
		<category><![CDATA[view]]></category>
		<category><![CDATA[xml builder]]></category>

		<guid isPermaLink="false">http://railsontherun.com/2007/10/31/how-to-test-a-xml-builder-view</guid>
		<description><![CDATA[As a good Rubyist, I do TDD and even BDD. Since I&#8217;ve started using RSpec I&#8217;ve started writing tests against my views. RSpec makes things really easy and I&#8217;ve been enjoying testing my views. I&#8217;m not the only one having fun, check this great post from Mr Planet Argon aka Robby Russel Recently I was [...]]]></description>
			<content:encoded><![CDATA[<p>As a good Rubyist, I do <a href="http://en.wikipedia.org/wiki/Test-driven_development">TDD</a> and even <a href="http://en.wikipedia.org/wiki/Behavior_driven_development">BDD</a>. </p>
<p>Since I&#8217;ve started using <a href="http://rspec.rubyforge.org/">RSpec</a> I&#8217;ve started writing tests against my views. RSpec makes things really easy and I&#8217;ve been enjoying testing my views.</p>
<p>I&#8217;m not the only one having fun, check <a href="http://www.robbyonrails.com/articles/2007/08/02/spec-your-views">this great post</a> from Mr <a href="http://www.planetargon.com/">Planet Argon</a> aka <a href="http://www.robbyonrails.com">Robby Russel</a></p>
<p>Recently I was working on implementing some <a href="http://railsontherun.com/2007/10/4/sexy-charts-in-less-than-5-minutes">Sexy Charts</a> and I was using a XML builder to create an XML view of for a controller. Since I wanted to be a good Rails Ninja and obey the BDD rules, I figured I needed to test my XML view. Making sure that the nodes and the attributes were properly created. Turned out that is wasn&#8217;t too hard, there was many options but none were very well documented so I decided to write this quick tutorial.</p>
<h2>UPDATE 31 Oct 2007: After a comment from <a href="http://joshknowles.com">Josh Knowles</a>, I updated the tests to test with have_tags (built in RSpec) and hpricot.</h2>
<h2>Hpricot</h2>
<p><a href="http://code.whytheluckystiff.net/hpricot/">hpricot</a> is a awesome HTML parser perfect for <a href="http://en.wikipedia.org/wiki/Screen_scraping">screen scraping</a>. But wait, there&#8217;s more to this awesome library, <a href="http://code.whytheluckystiff.net/hpricot/wiki/HpricotXML">hpricot can also parse XML</a>.</p>
<p>If you watched the excellent <a href="http://peepcode.com/products">RSpec peepcasts</a> you probably noticed that <a href="http://topfunky.com/">topfunky</a> aka <a href="http://geoffreygrosenbach.com/">Geoffrey Grosenbach</a> uses hpricot to test a remote API.</p>
<p>In our case, we&#8217;ll use hpricot to test that our generated XML follows our expectations.</p>
<h2>XML Builder + RSpec</h2>
<p>Let&#8217;s write a quick test to make sure our controller uses a XML builder view:</p>
<table class="CodeRay">
<tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }">
<pre>1<tt>
</tt>2<tt>
</tt>3<tt>
</tt>4<tt>
</tt><strong>5</strong><tt>
</tt>6<tt>
</tt>7<tt>
</tt>8<tt>
</tt>9<tt>
</tt><strong>10</strong><tt>
</tt>11<tt>
</tt>12<tt>
</tt>13<tt>
</tt>14<tt>
</tt><strong>15</strong><tt>
</tt>16<tt>
</tt>17<tt>
</tt></pre>
</td>
<td class="code">
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">  describe <span class="co">AveragesController</span>, <span class="s"><span class="dl">&quot;</span><span class="k">handling GET /averages.xml</span><span class="dl">&quot;</span></span> <span class="r">do</span><tt>
</tt><tt>
</tt>    before <span class="r">do</span><tt>
</tt>      <span class="co">Average</span>.stub!(<span class="sy">:find</span>).and_return(<span class="iv">@average</span>)<tt>
</tt>    <span class="r">end</span><tt>
</tt>  <tt>
</tt>    <span class="r">def</span> <span class="fu">do_get</span><tt>
</tt>      <span class="iv">@request</span>.env[<span class="s"><span class="dl">&quot;</span><span class="k">HTTP_ACCEPT</span><span class="dl">&quot;</span></span>] = <span class="s"><span class="dl">&quot;</span><span class="k">application/xml</span><span class="dl">&quot;</span></span><tt>
</tt>      get <span class="sy">:index</span><tt>
</tt>    <span class="r">end</span><tt>
</tt>  <tt>
</tt>    it <span class="s"><span class="dl">&quot;</span><span class="k">should render the action using the XML builder</span><span class="dl">&quot;</span></span> <span class="r">do</span><tt>
</tt>      do_get<tt>
</tt>      response.should render_template(<span class="s"><span class="dl">'</span><span class="k">averages/index.xml.builder</span><span class="dl">'</span></span>)<tt>
</tt>    <span class="r">end</span><tt>
</tt><tt>
</tt>  <span class="r">end</span></pre>
</td>
</tr>
</table>
<p>To make this example pass, we need to modify our rspec generated controller.</p>
<table class="CodeRay">
<tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }">
<pre>1<tt>
</tt>2<tt>
</tt>3<tt>
</tt>4<tt>
</tt><strong>5</strong><tt>
</tt>6<tt>
</tt>7<tt>
</tt>8<tt>
</tt></pre>
</td>
<td class="code">
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">  <span class="r">def</span> <span class="fu">index</span><tt>
</tt>    <span class="iv">@averages</span> = <span class="co">Average</span>.find(<span class="sy">:all</span>)<tt>
</tt>  <tt>
</tt>    respond_to <span class="r">do</span> |format|<tt>
</tt>      format.html <span class="c"># index.html.erb</span><tt>
</tt>      format.xml  { render <span class="sy">:action</span> =&gt; <span class="s"><span class="dl">&quot;</span><span class="k">index.xml.builder</span><span class="dl">&quot;</span></span>, <span class="sy">:layout</span> =&gt; <span class="pc">false</span> }<tt>
</tt>    <span class="r">end</span><tt>
</tt>  <span class="r">end</span></pre>
</td>
</tr>
</table>
<p>(Please note that I&#8217;m using Rails 2.0 and that&#8217;s why I&#8217;m not using a .rxml view)</p>
<p>Here is what our XML file should end up looking like:</p>
<table class="CodeRay">
<tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }">
<pre>1<tt>
</tt>2<tt>
</tt>3<tt>
</tt>4<tt>
</tt><strong>5</strong><tt>
</tt>6<tt>
</tt>7<tt>
</tt>8<tt>
</tt>9<tt>
</tt><strong>10</strong><tt>
</tt>11<tt>
</tt>12<tt>
</tt>13<tt>
</tt>14<tt>
</tt><strong>15</strong><tt>
</tt>16<tt>
</tt>17<tt>
</tt>18<tt>
</tt>19<tt>
</tt><strong>20</strong><tt>
</tt>21<tt>
</tt>22<tt>
</tt>23<tt>
</tt>24<tt>
</tt><strong>25</strong><tt>
</tt>26<tt>
</tt>27<tt>
</tt>28<tt>
</tt>29<tt>
</tt><strong>30</strong><tt>
</tt>31<tt>
</tt>32<tt>
</tt>33<tt>
</tt>34<tt>
</tt><strong>35</strong><tt>
</tt>36<tt>
</tt>37<tt>
</tt>38<tt>
</tt>39<tt>
</tt><strong>40</strong><tt>
</tt>41<tt>
</tt>42<tt>
</tt>43<tt>
</tt>44<tt>
</tt><strong>45</strong><tt>
</tt>46<tt>
</tt>47<tt>
</tt>48<tt>
</tt>49<tt>
</tt><strong>50</strong><tt>
</tt>51<tt>
</tt>52<tt>
</tt>53<tt>
</tt>54<tt>
</tt></pre>
</td>
<td class="code">
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">  &lt;<span class="i">?x</span>ml version=<span class="s"><span class="dl">&quot;</span><span class="k">1.0</span><span class="dl">&quot;</span></span> encoding=<span class="s"><span class="dl">&quot;</span><span class="k">UTF-8</span><span class="dl">&quot;</span></span>?&gt;<tt>
</tt>  &lt;chart&gt;<tt>
</tt>    &lt;series&gt;<tt>
</tt>      &lt;value xid=<span class="s"><span class="dl">&quot;</span><span class="k">0</span><span class="dl">&quot;</span></span>&gt;<span class="co">January</span>&lt;<span class="rx"><span class="dl">/</span><span class="k">value&gt;<tt>
</tt>      &lt;value xid=&quot;1&quot;&gt;February&lt;</span><span class="dl">/</span></span>value&gt;<tt>
</tt>      &lt;value xid=<span class="s"><span class="dl">&quot;</span><span class="k">2</span><span class="dl">&quot;</span></span>&gt;<span class="co">March</span>&lt;<span class="rx"><span class="dl">/</span><span class="k">value&gt;<tt>
</tt>      &lt;value xid=&quot;3&quot;&gt;April&lt;</span><span class="dl">/</span></span>value&gt;<tt>
</tt>      &lt;value xid=<span class="s"><span class="dl">&quot;</span><span class="k">4</span><span class="dl">&quot;</span></span>&gt;<span class="co">May</span>&lt;<span class="rx"><span class="dl">/</span><span class="k">value&gt;<tt>
</tt><tt>
</tt>      &lt;value xid=&quot;5&quot;&gt;June&lt;</span><span class="dl">/</span></span>value&gt;<tt>
</tt>      &lt;value xid=<span class="s"><span class="dl">&quot;</span><span class="k">6</span><span class="dl">&quot;</span></span>&gt;<span class="co">July</span>&lt;<span class="rx"><span class="dl">/</span><span class="k">value&gt;<tt>
</tt>      &lt;value xid=&quot;7&quot;&gt;August&lt;</span><span class="dl">/</span></span>value&gt;<tt>
</tt>      &lt;value xid=<span class="s"><span class="dl">&quot;</span><span class="k">8</span><span class="dl">&quot;</span></span>&gt;<span class="co">September</span>&lt;<span class="rx"><span class="dl">/</span><span class="k">value&gt;<tt>
</tt>      &lt;value xid=&quot;9&quot;&gt;October&lt;</span><span class="dl">/</span></span>value&gt;<tt>
</tt>      &lt;value xid=<span class="s"><span class="dl">&quot;</span><span class="k">10</span><span class="dl">&quot;</span></span>&gt;<span class="co">November</span>&lt;<span class="rx"><span class="dl">/</span><span class="k">value&gt;<tt>
</tt><tt>
</tt>      &lt;value xid=&quot;11&quot;&gt;December&lt;</span><span class="dl">/</span></span>value&gt;<tt>
</tt>    &lt;<span class="rx"><span class="dl">/</span><span class="k">series&gt;<tt>
</tt>    &lt;graphs&gt;<tt>
</tt>      &lt;graph fill_alpha=&quot;50&quot; color=&quot;#FF0000&quot; fill_color=&quot;#CC0000&quot; title=&quot;high&quot;&gt;<tt>
</tt>        &lt;value xid=&quot;0&quot;&gt;65.1&lt;</span><span class="dl">/</span></span>value&gt;<tt>
</tt>        &lt;value xid=<span class="s"><span class="dl">&quot;</span><span class="k">1</span><span class="dl">&quot;</span></span>&gt;<span class="fl">65.7</span>&lt;<span class="rx"><span class="dl">/</span><span class="k">value&gt;<tt>
</tt>        &lt;value xid=&quot;2&quot;&gt;64.9&lt;</span><span class="dl">/</span></span>value&gt;<tt>
</tt><tt>
</tt>        &lt;value xid=<span class="s"><span class="dl">&quot;</span><span class="k">3</span><span class="dl">&quot;</span></span>&gt;<span class="fl">66.7</span>&lt;<span class="rx"><span class="dl">/</span><span class="k">value&gt;<tt>
</tt>        &lt;value xid=&quot;4&quot;&gt;67.1&lt;</span><span class="dl">/</span></span>value&gt;<tt>
</tt>        &lt;value xid=<span class="s"><span class="dl">&quot;</span><span class="k">5</span><span class="dl">&quot;</span></span>&gt;<span class="fl">69.3</span>&lt;<span class="rx"><span class="dl">/</span><span class="k">value&gt;<tt>
</tt>        &lt;value xid=&quot;6&quot;&gt;73.0&lt;</span><span class="dl">/</span></span>value&gt;<tt>
</tt>        &lt;value xid=<span class="s"><span class="dl">&quot;</span><span class="k">7</span><span class="dl">&quot;</span></span>&gt;<span class="fl">74.8</span>&lt;<span class="rx"><span class="dl">/</span><span class="k">value&gt;<tt>
</tt>        &lt;value xid=&quot;8&quot;&gt;75.4&lt;</span><span class="dl">/</span></span>value&gt;<tt>
</tt><tt>
</tt>        &lt;value xid=<span class="s"><span class="dl">&quot;</span><span class="k">9</span><span class="dl">&quot;</span></span>&gt;<span class="fl">73.4</span>&lt;<span class="rx"><span class="dl">/</span><span class="k">value&gt;<tt>
</tt>        &lt;value xid=&quot;10&quot;&gt;68.9&lt;</span><span class="dl">/</span></span>value&gt;<tt>
</tt>        &lt;value xid=<span class="s"><span class="dl">&quot;</span><span class="k">11</span><span class="dl">&quot;</span></span>&gt;<span class="fl">65.3</span>&lt;<span class="rx"><span class="dl">/</span><span class="k">value&gt;<tt>
</tt>      &lt;</span><span class="dl">/</span></span>graph&gt;<tt>
</tt>      &lt;graph fill_alpha=<span class="s"><span class="dl">&quot;</span><span class="k">50</span><span class="dl">&quot;</span></span> color=<span class="s"><span class="dl">&quot;</span><span class="k">#0000CC</span><span class="dl">&quot;</span></span> fill_color=<span class="s"><span class="dl">&quot;</span><span class="k">#0000CC</span><span class="dl">&quot;</span></span> title=<span class="s"><span class="dl">&quot;</span><span class="k">low</span><span class="dl">&quot;</span></span>&gt;<tt>
</tt>        &lt;value xid=<span class="s"><span class="dl">&quot;</span><span class="k">0</span><span class="dl">&quot;</span></span>&gt;<span class="fl">48.9</span>&lt;<span class="rx"><span class="dl">/</span><span class="k">value&gt;<tt>
</tt>        &lt;value xid=&quot;1&quot;&gt;50.7&lt;</span><span class="dl">/</span></span>value&gt;<tt>
</tt><tt>
</tt>        &lt;value xid=<span class="s"><span class="dl">&quot;</span><span class="k">2</span><span class="dl">&quot;</span></span>&gt;<span class="fl">52.9</span>&lt;<span class="rx"><span class="dl">/</span><span class="k">value&gt;<tt>
</tt>        &lt;value xid=&quot;3&quot;&gt;55.6&lt;</span><span class="dl">/</span></span>value&gt;<tt>
</tt>        &lt;value xid=<span class="s"><span class="dl">&quot;</span><span class="k">4</span><span class="dl">&quot;</span></span>&gt;<span class="fl">59.2</span>&lt;<span class="rx"><span class="dl">/</span><span class="k">value&gt;<tt>
</tt>        &lt;value xid=&quot;5&quot;&gt;61.9&lt;</span><span class="dl">/</span></span>value&gt;<tt>
</tt>        &lt;value xid=<span class="s"><span class="dl">&quot;</span><span class="k">6</span><span class="dl">&quot;</span></span>&gt;<span class="fl">65.7</span>&lt;<span class="rx"><span class="dl">/</span><span class="k">value&gt;<tt>
</tt>        &lt;value xid=&quot;7&quot;&gt;67.3&lt;</span><span class="dl">/</span></span>value&gt;<tt>
</tt><tt>
</tt>        &lt;value xid=<span class="s"><span class="dl">&quot;</span><span class="k">8</span><span class="dl">&quot;</span></span>&gt;<span class="fl">65.7</span>&lt;<span class="rx"><span class="dl">/</span><span class="k">value&gt;<tt>
</tt>        &lt;value xid=&quot;9&quot;&gt;61.0&lt;</span><span class="dl">/</span></span>value&gt;<tt>
</tt>        &lt;value xid=<span class="s"><span class="dl">&quot;</span><span class="k">10</span><span class="dl">&quot;</span></span>&gt;<span class="fl">54.0</span>&lt;<span class="rx"><span class="dl">/</span><span class="k">value&gt;<tt>
</tt>        &lt;value xid=&quot;11&quot;&gt;48.7&lt;</span><span class="dl">/</span></span>value&gt;<tt>
</tt>      &lt;<span class="rx"><span class="dl">/</span><span class="k">graph&gt;<tt>
</tt>    &lt;</span><span class="dl">/</span></span>graphs&gt;<tt>
</tt>  &lt;<span class="rx"><span class="dl">/</span><span class="k">chart&gt;<tt>
</tt>  </span></span></pre>
</td>
</tr>
</table>
<p>Let&#8217;s write some tests to make sure our view is ok:</p>
<p>index.xml.builder_spec.rb</p>
<table class="CodeRay">
<tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }">
<pre>1<tt>
</tt>2<tt>
</tt>3<tt>
</tt>4<tt>
</tt><strong>5</strong><tt>
</tt>6<tt>
</tt>7<tt>
</tt>8<tt>
</tt>9<tt>
</tt><strong>10</strong><tt>
</tt>11<tt>
</tt>12<tt>
</tt>13<tt>
</tt>14<tt>
</tt><strong>15</strong><tt>
</tt>16<tt>
</tt>17<tt>
</tt>18<tt>
</tt>19<tt>
</tt><strong>20</strong><tt>
</tt>21<tt>
</tt>22<tt>
</tt>23<tt>
</tt>24<tt>
</tt><strong>25</strong><tt>
</tt>26<tt>
</tt>27<tt>
</tt>28<tt>
</tt>29<tt>
</tt><strong>30</strong><tt>
</tt>31<tt>
</tt>32<tt>
</tt>33<tt>
</tt>34<tt>
</tt><strong>35</strong><tt>
</tt>36<tt>
</tt>37<tt>
</tt>38<tt>
</tt>39<tt>
</tt><strong>40</strong><tt>
</tt>41<tt>
</tt>42<tt>
</tt>43<tt>
</tt>44<tt>
</tt><strong>45</strong><tt>
</tt>46<tt>
</tt>47<tt>
</tt>48<tt>
</tt>49<tt>
</tt><strong>50</strong><tt>
</tt>51<tt>
</tt>52<tt>
</tt>53<tt>
</tt>54<tt>
</tt><strong>55</strong><tt>
</tt>56<tt>
</tt>57<tt>
</tt>58<tt>
</tt>59<tt>
</tt><strong>60</strong><tt>
</tt>61<tt>
</tt>62<tt>
</tt>63<tt>
</tt>64<tt>
</tt><strong>65</strong><tt>
</tt>66<tt>
</tt>67<tt>
</tt>68<tt>
</tt>69<tt>
</tt><strong>70</strong><tt>
</tt>71<tt>
</tt>72<tt>
</tt>73<tt>
</tt>74<tt>
</tt><strong>75</strong><tt>
</tt>76<tt>
</tt>77<tt>
</tt>78<tt>
</tt>79<tt>
</tt><strong>80</strong><tt>
</tt>81<tt>
</tt></pre>
</td>
<td class="code">
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">require <span class="co">File</span>.dirname(<span class="pc">__FILE__</span>) + <span class="s"><span class="dl">'</span><span class="k">/../../spec_helper</span><span class="dl">'</span></span><tt>
</tt>require <span class="s"><span class="dl">'</span><span class="k">hpricot</span><span class="dl">'</span></span><tt>
</tt><tt>
</tt>describe <span class="s"><span class="dl">&quot;</span><span class="k">/averages/index.xml.builder</span><span class="dl">&quot;</span></span> <span class="r">do</span><tt>
</tt>  include <span class="co">AveragesHelper</span><tt>
</tt>  <tt>
</tt>  before <span class="r">do</span><tt>
</tt>    average_1 = mock_model(<span class="co">Average</span>)<tt>
</tt>    average_1.stub!(<span class="sy">:month</span>).and_return(<span class="s"><span class="dl">&quot;</span><span class="k">January</span><span class="dl">&quot;</span></span>)<tt>
</tt>    average_1.stub!(<span class="sy">:high</span>).and_return(<span class="s"><span class="dl">&quot;</span><span class="k">74.5</span><span class="dl">&quot;</span></span>)<tt>
</tt>    average_1.stub!(<span class="sy">:low</span>).and_return(<span class="s"><span class="dl">&quot;</span><span class="k">61.5</span><span class="dl">&quot;</span></span>)<tt>
</tt>    average_2 = mock_model(<span class="co">Average</span>)<tt>
</tt>    average_2.stub!(<span class="sy">:month</span>).and_return(<span class="s"><span class="dl">&quot;</span><span class="k">February</span><span class="dl">&quot;</span></span>)<tt>
</tt>    average_2.stub!(<span class="sy">:high</span>).and_return(<span class="s"><span class="dl">&quot;</span><span class="k">82.5</span><span class="dl">&quot;</span></span>)<tt>
</tt>    average_2.stub!(<span class="sy">:low</span>).and_return(<span class="s"><span class="dl">&quot;</span><span class="k">71.5</span><span class="dl">&quot;</span></span>)<tt>
</tt><tt>
</tt>    assigns[<span class="sy">:averages</span>] = [average_1, average_2]<tt>
</tt>  <span class="r">end</span><tt>
</tt><tt>
</tt>  it <span class="s"><span class="dl">&quot;</span><span class="k">should render the months in the series</span><span class="dl">&quot;</span></span> <span class="r">do</span><tt>
</tt>    render <span class="s"><span class="dl">&quot;</span><span class="k">/averages/index.xml.builder</span><span class="dl">&quot;</span></span><tt>
</tt>    response.should have_tag(<span class="s"><span class="dl">&quot;</span><span class="k">value</span><span class="dl">&quot;</span></span>, <span class="s"><span class="dl">'</span><span class="k">January</span><span class="dl">'</span></span>)<tt>
</tt>    response.should have_tag(<span class="s"><span class="dl">&quot;</span><span class="k">value</span><span class="dl">&quot;</span></span>, <span class="s"><span class="dl">'</span><span class="k">February</span><span class="dl">'</span></span>)<tt>
</tt>    <span class="c"># Same thing but with Hpricot</span><tt>
</tt>    doc = <span class="co">Hpricot</span>.XML(response.body.to_s)<tt>
</tt>    (doc/<span class="sy">:value</span>).first.inner_html.should == <span class="s"><span class="dl">'</span><span class="k">January</span><span class="dl">'</span></span><tt>
</tt>    (doc/<span class="sy">:value</span>)[<span class="i">1</span>].inner_html.should == <span class="s"><span class="dl">'</span><span class="k">February</span><span class="dl">'</span></span><tt>
</tt>  <span class="r">end</span><tt>
</tt>  <tt>
</tt>  it <span class="s"><span class="dl">&quot;</span><span class="k">should set the xid attributes for the series</span><span class="dl">&quot;</span></span> <span class="r">do</span><tt>
</tt>    render <span class="s"><span class="dl">&quot;</span><span class="k">/averages/index.xml.builder</span><span class="dl">&quot;</span></span><tt>
</tt>    response.should have_tag(<span class="s"><span class="dl">&quot;</span><span class="k">value[xid=0]:first-child</span><span class="dl">&quot;</span></span>)<tt>
</tt>    response.should have_tag(<span class="s"><span class="dl">&quot;</span><span class="k">value[xid=1]:last-child</span><span class="dl">&quot;</span></span>)<tt>
</tt>    <span class="c"># Same thing but with Hpricot</span><tt>
</tt>    doc = <span class="co">Hpricot</span>.XML(response.body.to_s)<tt>
</tt>    (doc/<span class="sy">:value</span>).first[<span class="s"><span class="dl">&quot;</span><span class="k">xid</span><span class="dl">&quot;</span></span>].should == <span class="s"><span class="dl">'</span><span class="k">0</span><span class="dl">'</span></span><tt>
</tt>    (doc/<span class="sy">:value</span>).last[<span class="s"><span class="dl">&quot;</span><span class="k">xid</span><span class="dl">&quot;</span></span>].should == <span class="s"><span class="dl">'</span><span class="k">1</span><span class="dl">'</span></span><tt>
</tt>  <span class="r">end</span><tt>
</tt>  <tt>
</tt>  it <span class="s"><span class="dl">&quot;</span><span class="k">should have 2 graphs and they should have a title</span><span class="dl">&quot;</span></span> <span class="r">do</span><tt>
</tt>    render <span class="s"><span class="dl">&quot;</span><span class="k">/averages/index.xml.builder</span><span class="dl">&quot;</span></span><tt>
</tt>    response.should have_tag(<span class="s"><span class="dl">&quot;</span><span class="k">graph[title=high]:first-child</span><span class="dl">&quot;</span></span>)<tt>
</tt>    response.should have_tag(<span class="s"><span class="dl">&quot;</span><span class="k">graph[title=low]:last-child</span><span class="dl">&quot;</span></span>)<tt>
</tt>    <span class="c"># Same thing but with Hpricot</span><tt>
</tt>    doc = <span class="co">Hpricot</span>.XML(response.body.to_s)<tt>
</tt>    (doc/<span class="sy">:graph</span>).size.should == <span class="i">2</span><tt>
</tt>    (doc/<span class="sy">:graph</span>).first[<span class="s"><span class="dl">&quot;</span><span class="k">title</span><span class="dl">&quot;</span></span>].should == <span class="s"><span class="dl">'</span><span class="k">high</span><span class="dl">'</span></span><tt>
</tt>    (doc/<span class="sy">:graph</span>).last[<span class="s"><span class="dl">&quot;</span><span class="k">title</span><span class="dl">&quot;</span></span>].should == <span class="s"><span class="dl">'</span><span class="k">low</span><span class="dl">'</span></span><tt>
</tt>  <span class="r">end</span><tt>
</tt>  <tt>
</tt>  it <span class="s"><span class="dl">&quot;</span><span class="k">should have a color set by graph</span><span class="dl">&quot;</span></span> <span class="r">do</span><tt>
</tt>    render <span class="s"><span class="dl">&quot;</span><span class="k">/averages/index.xml.builder</span><span class="dl">&quot;</span></span><tt>
</tt>    response.should have_tag(<span class="s"><span class="dl">&quot;</span><span class="k">graph[color]:first-child</span><span class="dl">&quot;</span></span>)<tt>
</tt>    response.should have_tag(<span class="s"><span class="dl">&quot;</span><span class="k">graph[color]:last-child</span><span class="dl">&quot;</span></span>)<tt>
</tt>    response.should have_tag(<span class="s"><span class="dl">&quot;</span><span class="k">graph[fill_color]:last-child</span><span class="dl">&quot;</span></span>)<tt>
</tt>    response.should have_tag(<span class="s"><span class="dl">&quot;</span><span class="k">graph[fill_alpha]:last-child</span><span class="dl">&quot;</span></span>)<tt>
</tt>    <span class="c"># Same thing but with Hpricot</span><tt>
</tt>    doc = <span class="co">Hpricot</span>.XML(response.body.to_s)<tt>
</tt>    (doc/<span class="sy">:graph</span>).first[<span class="s"><span class="dl">&quot;</span><span class="k">color</span><span class="dl">&quot;</span></span>].should_not be_nil<tt>
</tt>    (doc/<span class="sy">:graph</span>).last[<span class="s"><span class="dl">&quot;</span><span class="k">color</span><span class="dl">&quot;</span></span>].should_not be_nil<tt>
</tt>    (doc/<span class="sy">:graph</span>).last[<span class="s"><span class="dl">&quot;</span><span class="k">fill_color</span><span class="dl">&quot;</span></span>].should_not be_nil<tt>
</tt>    (doc/<span class="sy">:graph</span>).last[<span class="s"><span class="dl">&quot;</span><span class="k">fill_alpha</span><span class="dl">&quot;</span></span>].should_not be_nil<tt>
</tt>  <span class="r">end</span><tt>
</tt>  <tt>
</tt>  it <span class="s"><span class="dl">&quot;</span><span class="k">should have an xid for each graph value</span><span class="dl">&quot;</span></span> <span class="r">do</span><tt>
</tt>    render <span class="s"><span class="dl">&quot;</span><span class="k">/averages/index.xml.builder</span><span class="dl">&quot;</span></span><tt>
</tt>    response.should have_tag(<span class="s"><span class="dl">&quot;</span><span class="k">graph &gt; value[xid=0]:first-child</span><span class="dl">&quot;</span></span>)<tt>
</tt>    <span class="c"># Same thing but with Hpricot</span><tt>
</tt>    doc = <span class="co">Hpricot</span>.XML(response.body.to_s)<tt>
</tt>    (doc/<span class="sy">:graph</span>/<span class="sy">:value</span>).first[<span class="s"><span class="dl">&quot;</span><span class="k">xid</span><span class="dl">&quot;</span></span>].should == <span class="s"><span class="dl">&quot;</span><span class="k">0</span><span class="dl">&quot;</span></span><tt>
</tt>  <span class="r">end</span><tt>
</tt>  <tt>
</tt>  it <span class="s"><span class="dl">&quot;</span><span class="k">should have the high average as values of the first graph</span><span class="dl">&quot;</span></span> <span class="r">do</span><tt>
</tt>    render <span class="s"><span class="dl">&quot;</span><span class="k">/averages/index.xml.builder</span><span class="dl">&quot;</span></span><tt>
</tt>    response.should have_tag(<span class="s"><span class="dl">&quot;</span><span class="k">graph &gt; value:first-child</span><span class="dl">&quot;</span></span>, <span class="s"><span class="dl">&quot;</span><span class="k">74.5</span><span class="dl">&quot;</span></span>)<tt>
</tt>    <span class="c"># Same thing but with Hpricot</span><tt>
</tt>    doc = <span class="co">Hpricot</span>.XML(response.body.to_s)<tt>
</tt>    (doc/<span class="sy">:graph</span>/<span class="sy">:value</span>).first.inner_html.should == <span class="s"><span class="dl">&quot;</span><span class="k">74.5</span><span class="dl">&quot;</span></span><tt>
</tt>  <span class="r">end</span><tt>
</tt>  <tt>
</tt><span class="r">end</span></pre>
</td>
</tr>
</table>
<p>The first thing you must do (after installing the hpricot gem) is to require hpricot in your test:</p>
<table class="CodeRay">
<tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }">
<pre><tt>
</tt></pre>
</td>
<td class="code">
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">  require <span class="s"><span class="dl">'</span><span class="k">hpricot</span><span class="dl">'</span></span></pre>
</td>
</tr>
</table>
<p>Now that hpricot is created we can use it to parse the response and check against our expectations.</p>
<p>(we create mock objects to pass to the view so we know exactly what to expect and we separate Model/Controller/Views tests)</p>
<p>To check against our response we have to use hpricot parser syntax. It might look at bit funny at first, but believe me it&#8217;s really easy once you get it.</p>
<p>But first, let&#8217;s parse the view:</p>
<table class="CodeRay">
<tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }">
<pre>1<tt>
</tt>2<tt>
</tt>3<tt>
</tt>4<tt>
</tt></pre>
</td>
<td class="code">
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><span class="c"># Render the mocked up data using the xml view</span><tt>
</tt>render <span class="s"><span class="dl">&quot;</span><span class="k">/averages/index.xml.builder</span><span class="dl">&quot;</span></span><tt>
</tt><span class="c"># Load and parse the view response body:</span><tt>
</tt>doc = <span class="co">Hpricot</span>.XML(response.body.to_s)  </pre>
</td>
</tr>
</table>
<p>Let&#8217;s look at the first test:</p>
<table class="CodeRay">
<tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }">
<pre>1<tt>
</tt>2<tt>
</tt>3<tt>
</tt>4<tt>
</tt><strong>5</strong><tt>
</tt>6<tt>
</tt></pre>
</td>
<td class="code">
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">  it <span class="s"><span class="dl">&quot;</span><span class="k">should render the months in the series</span><span class="dl">&quot;</span></span> <span class="r">do</span><tt>
</tt>    render <span class="s"><span class="dl">&quot;</span><span class="k">/averages/index.xml.builder</span><span class="dl">&quot;</span></span><tt>
</tt>    doc = <span class="co">Hpricot</span>.XML(response.body.to_s)<tt>
</tt>    (doc/<span class="sy">:value</span>).first.inner_html.should == <span class="s"><span class="dl">'</span><span class="k">January</span><span class="dl">'</span></span><tt>
</tt>    (doc/<span class="sy">:value</span>)[<span class="i">1</span>].inner_html.should == <span class="s"><span class="dl">'</span><span class="k">February</span><span class="dl">'</span></span><tt>
</tt>  <span class="r">end</span></pre>
</td>
</tr>
</table>
<p>(doc/:value) returns all the value nodes, we take the first one and extract its content. We expect that it would match the name of the month for the first average.</p>
<p>Let&#8217;s now look at another test:</p>
<table class="CodeRay">
<tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }">
<pre>1<tt>
</tt>2<tt>
</tt>3<tt>
</tt>4<tt>
</tt><strong>5</strong><tt>
</tt>6<tt>
</tt>7<tt>
</tt></pre>
</td>
<td class="code">
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">  it <span class="s"><span class="dl">&quot;</span><span class="k">should have 2 graphs and they should have a title</span><span class="dl">&quot;</span></span> <span class="r">do</span><tt>
</tt>    render <span class="s"><span class="dl">&quot;</span><span class="k">/averages/index.xml.builder</span><span class="dl">&quot;</span></span><tt>
</tt>    doc = <span class="co">Hpricot</span>.XML(response.body.to_s)<tt>
</tt>    (doc/<span class="sy">:graph</span>).size.should == <span class="i">2</span><tt>
</tt>    (doc/<span class="sy">:graph</span>).first[<span class="s"><span class="dl">&quot;</span><span class="k">title</span><span class="dl">&quot;</span></span>].should == <span class="s"><span class="dl">'</span><span class="k">high</span><span class="dl">'</span></span><tt>
</tt>    (doc/<span class="sy">:graph</span>).last[<span class="s"><span class="dl">&quot;</span><span class="k">title</span><span class="dl">&quot;</span></span>].should == <span class="s"><span class="dl">'</span><span class="k">low</span><span class="dl">'</span></span><tt>
</tt>  <span class="r">end</span></pre>
</td>
</tr>
</table>
<p>The thing to look at here is the fact that we are checking on the node&#8217;s attribute &#8220;title&#8221;. Really simple syntax and clean test, isn&#8217;t it?</p>
<p>Finally let&#8217;s look at the last example:</p>
<table class="CodeRay">
<tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }">
<pre>1<tt>
</tt>2<tt>
</tt>3<tt>
</tt>4<tt>
</tt><strong>5</strong><tt>
</tt></pre>
</td>
<td class="code">
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">  it <span class="s"><span class="dl">&quot;</span><span class="k">should have the high average as values of the first graph</span><span class="dl">&quot;</span></span> <span class="r">do</span><tt>
</tt>    render <span class="s"><span class="dl">&quot;</span><span class="k">/averages/index.xml.builder</span><span class="dl">&quot;</span></span><tt>
</tt>    doc = <span class="co">Hpricot</span>.XML(response.body.to_s)<tt>
</tt>    (doc/<span class="sy">:graph</span>/<span class="sy">:value</span>).first.inner_html.should == <span class="s"><span class="dl">&quot;</span><span class="k">74.5</span><span class="dl">&quot;</span></span><tt>
</tt>  <span class="r">end</span></pre>
</td>
</tr>
</table>
<p>We are checking that the content of the first value node nested inside a graph node is equal to 74.5 which is the high average for the first month. </p>
<p>In practice, you probably won&#8217;t write all these tests at once, but anyway, let&#8217;s look at our XML builder which will make all these tests pass:</p>
<table class="CodeRay">
<tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }">
<pre>1<tt>
</tt>2<tt>
</tt>3<tt>
</tt>4<tt>
</tt><strong>5</strong><tt>
</tt>6<tt>
</tt>7<tt>
</tt>8<tt>
</tt>9<tt>
</tt><strong>10</strong><tt>
</tt>11<tt>
</tt>12<tt>
</tt>13<tt>
</tt>14<tt>
</tt><strong>15</strong><tt>
</tt>16<tt>
</tt>17<tt>
</tt>18<tt>
</tt>19<tt>
</tt><strong>20</strong><tt>
</tt>21<tt>
</tt>22<tt>
</tt>23<tt>
</tt></pre>
</td>
<td class="code">
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">xml.instruct! <span class="sy"> <img src='http://railsontherun.com/wp-includes/images/smilies/icon_mad.gif' alt=':x' class='wp-smiley' /> ml</span>, <span class="sy">:version</span>=&gt;<span class="s"><span class="dl">&quot;</span><span class="k">1.0</span><span class="dl">&quot;</span></span>, <span class="sy">:encoding</span>=&gt;<span class="s"><span class="dl">&quot;</span><span class="k">UTF-8</span><span class="dl">&quot;</span></span><tt>
</tt>xml.chart <span class="r">do</span><tt>
</tt>  xml.series <span class="r">do</span>    <tt>
</tt>    <span class="iv">@averages</span>.each_with_index <span class="r">do</span> |average, index|<tt>
</tt>      xml.value average.month, <span class="sy"> <img src='http://railsontherun.com/wp-includes/images/smilies/icon_mad.gif' alt=':x' class='wp-smiley' /> id</span> =&gt; index<tt>
</tt>    <span class="r">end</span><tt>
</tt>  <span class="r">end</span><tt>
</tt>  <tt>
</tt>  xml.graphs <span class="r">do</span><tt>
</tt>    xml.graph <span class="sy">:title</span> =&gt; <span class="s"><span class="dl">'</span><span class="k">high</span><span class="dl">'</span></span>, <span class="sy">:color</span> =&gt; <span class="s"><span class="dl">&quot;</span><span class="k">#FF0000</span><span class="dl">&quot;</span></span>, <span class="sy">:fill_alpha</span> =&gt; <span class="s"><span class="dl">&quot;</span><span class="k">50</span><span class="dl">&quot;</span></span>, <span class="sy">:fill_color</span> =&gt; <span class="s"><span class="dl">&quot;</span><span class="k">#CC0000</span><span class="dl">&quot;</span></span> <span class="r">do</span><tt>
</tt>      <span class="iv">@averages</span>.each_with_index <span class="r">do</span> |average, index|<tt>
</tt>        xml.value average.high, <span class="sy"> <img src='http://railsontherun.com/wp-includes/images/smilies/icon_mad.gif' alt=':x' class='wp-smiley' /> id</span> =&gt; index<tt>
</tt>      <span class="r">end</span><tt>
</tt>    <span class="r">end</span><tt>
</tt>    <tt>
</tt>    xml.graph <span class="sy">:title</span> =&gt; <span class="s"><span class="dl">'</span><span class="k">low</span><span class="dl">'</span></span>, <span class="sy">:color</span> =&gt; <span class="s"><span class="dl">&quot;</span><span class="k">#0000CC</span><span class="dl">&quot;</span></span>, <span class="sy">:fill_alpha</span> =&gt; <span class="s"><span class="dl">&quot;</span><span class="k">50</span><span class="dl">&quot;</span></span>, <span class="sy">:fill_color</span> =&gt; <span class="s"><span class="dl">&quot;</span><span class="k">#0000CC</span><span class="dl">&quot;</span></span> <span class="r">do</span><tt>
</tt>      <span class="iv">@averages</span>.each_with_index <span class="r">do</span> |average, index|<tt>
</tt>        xml.value average.low, <span class="sy"> <img src='http://railsontherun.com/wp-includes/images/smilies/icon_mad.gif' alt=':x' class='wp-smiley' /> id</span> =&gt; index<tt>
</tt>      <span class="r">end</span><tt>
</tt>    <span class="r">end</span><tt>
</tt>  <span class="r">end</span><tt>
</tt>  <tt>
</tt><span class="r">end</span></pre>
</td>
</tr>
</table>
<p>Hpricot is a <em>really</em> nice tool which can make your BDD life much easier. And even if you don&#8217;t do BDD/TDD yet, it&#8217;s a great way to verify that any XML data you receive/generate is valid.</p>
<h2>Happy testing</h2>
]]></content:encoded>
			<wfw:commentRss>http://railsontherun.com/2007/10/31/how-to-test-a-xml-builder-view/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>restful_authentication and RSpec tip</title>
		<link>http://railsontherun.com/2007/07/13/restful_authentication-and-rspec-tip/</link>
		<comments>http://railsontherun.com/2007/07/13/restful_authentication-and-rspec-tip/#comments</comments>
		<pubDate>Fri, 13 Jul 2007 05:55:00 +0000</pubDate>
		<dc:creator>Matt Aimonetti</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[authentication]]></category>
		<category><![CDATA[BDD]]></category>
		<category><![CDATA[helper]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[restful]]></category>
		<category><![CDATA[restful_authentication]]></category>
		<category><![CDATA[RSpec]]></category>
		<category><![CDATA[tests]]></category>
		<category><![CDATA[tip]]></category>

		<guid isPermaLink="false">http://railsontherun.com/2007/07/13/restful_authentication-and-rspec-tip</guid>
		<description><![CDATA[resftul_authentication is a great plugin, but not always resftful&#8230; especially if like me you dropped unit test for RSpec. I have a set of RSpec examples I use all the time on all my projects requiring restful_authentication, obviously I always end up tweaking them because each application has its specific needs. However, I was recently [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://svn.techno-weenie.net/projects/plugins/restful_authentication/">resftul_authentication</a> is a great plugin, but not always resftful&#8230; especially if like me you dropped unit test for RSpec.</p>
<p><img src="http://myskitch.com/matt_a/p-restful_24x40.jpg__jpeg_image__2224x1475_pixels__-_scaled__43__-20070712-224940.jpg" width='490px' alt="" title=""></p>
<p>I have a set of RSpec examples I use all the time on all my projects requiring restful_authentication, obviously I always end up tweaking them because each application has its specific needs.</p>
<p>However, I was recently asked <em>what&#8217;s the way of dealing with controllers specs when a controller has a limited access ?</em></p>
<p>Let&#8217;s look at the following controller for instance:</p>
<pre><code>class AssetController &lt; ApplicationController
 before_filter :login_required, :except =&gt; [ :index, :show ]
</code></pre>
<p>my assets_controller_spec.rb file will have the following code:</p>
<pre><code>describe AssetController, "handling GET /assets/new" do

  before do
    @asset = mock_model(Asset)
    Asset.stub!(:new).and_return(@asset)
  end

  def do_get
    get :new
  end

  it "should be successful" do
    do_get
    response.should be_success
  end

end
</code></pre>
<p>and guess what&#8230; it will fail! Why? simply because we are trying to access an action requiring login. Right, so what&#8217;s the best way of dealing with this issue and get our test to pass?</p>
<p>The best solution I found was to use a simple helper that I put in my spec_helper.rb file</p>
<pre><code>def login_as(user)
  case user
    when :admin
      @current_user = mock_model(User)
      User.should_receive(:find_by_id).any_number_of_times.and_return(@current_user)
      request.session[:user] = @current_user
    else
      request.session[:user] = nil
  end
end
</code></pre>
<p>You might wonder why I use when :user, well, in a lot of the application I&#8217;m working on, I have different levels of access and  I want to tests different accounts so I the case conditional loop.</p>
<p>Anyway, let&#8217;s implement our helper in our previous RSpec example:</p>
<pre><code>describe AssetController, "handling GET /assets/new" do

  before do
    login_as :admin
    @asset = mock_model(Asset)
    Asset.stub!(:new).and_return(@asset)
  end

  def do_get
    get :new
  end

  it "should be successful" do
    do_get
    response.should be_success
  end

end
</code></pre>
<p>and there you go, now your example passes properly <img src='http://railsontherun.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Have fun</p>
]]></content:encoded>
			<wfw:commentRss>http://railsontherun.com/2007/07/13/restful_authentication-and-rspec-tip/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Create a Rails Edge / RSpec project</title>
		<link>http://railsontherun.com/2007/06/06/create-a-rails-edge-rspec-project/</link>
		<comments>http://railsontherun.com/2007/06/06/create-a-rails-edge-rspec-project/#comments</comments>
		<pubDate>Wed, 06 Jun 2007 19:34:00 +0000</pubDate>
		<dc:creator>Matt Aimonetti</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[autotest]]></category>
		<category><![CDATA[BDD]]></category>
		<category><![CDATA[edge]]></category>
		<category><![CDATA[growl]]></category>
		<category><![CDATA[hackfest]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[RSpec]]></category>
		<category><![CDATA[svn]]></category>
		<category><![CDATA[TDD]]></category>
		<category><![CDATA[texmate]]></category>
		<category><![CDATA[zentest]]></category>

		<guid isPermaLink="false">http://railsontherun.com/2007/06/06/create-a-rails-edge-rspec-project</guid>
		<description><![CDATA[Recently I helped few people moving to Rails Edge and start using RSpec. I realized that I learned few tricks and even if for me everything seemed quite simple, things are not that simple when you recently started with Rails. This would work on Mac and Linux, sorry Windows users, you&#8217;ll have to slightly change [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I helped few people moving to <a href="http://dev.rubyonrails.org/">Rails Edge</a> and start using <a href="http://rspec.rubyforge.org">RSpec</a>. I realized that I learned few tricks and even if for me everything seemed quite simple, things are not that simple when you recently started with Rails.</p>
<p>This would work on Mac and Linux, sorry Windows users, you&#8217;ll have to slightly change the code below.</p>
<h1>Live on the Edge</h1>
<p>This is actually a bit tricky but it was very well covered by <a href="http://addictedtonew.com/about/">John Nunemaker</a> in <a href="http://railstips.org/2007/5/31/even-edgier-than-edge-rails">this post</a></p>
<p>To sum John&#8217;s post:</p>
<p>Create a normal rails project:</p>
<pre><code>$ rails my_project
$ cd my_project

$ rake rails:freeze:edge
</code></pre>
<p>(or use checkout edge in the vendor folder)</p>
<pre><code>$ cd ..
$ ruby my_project/vendor/rails/railties/bin/rails my_edgie_project
</code></pre>
<p>You now have have a real Edge project called my<em>edgie</em>project. You can delete the my_project folder since we only used it to create our real edge project.</p>
<p>Now, we are not really done since we need to add the Edge files into our vendor folder so we don&#8217;t use our local rails gem.</p>
<p>I would refer to another post from John, that you can find <a href="http://railstips.org/2007/3/5/my-local-rails-setup">there</a></p>
<pre><code>$ mkdir ~/rails
$ cd ~/rails
$ svn co http://dev.rubyonrails.com/svn/rails/trunk .
</code></pre>
<p>We just created a rails folder called rails in our home folder and we checked out edge/trunk in it.<br />
Now let&#8217;s go in our Rails app and setup a symlink to the trunk folder we just created.</p>
<pre><code>$ cd ~/rails_projects/my_edgie_project
$ ln -s ~/rails/trunk vendor/rails
</code></pre>
<p>If you are using subversion, you can ignore the symlink so it doesnâ€™t try to version it:</p>
<pre><code>$ svn propset svn:ignore "rails" vendor/
$ svn commit -m "using new sweet rails setup as recommended by John Nunemaker"
$ svn up
</code></pre>
<p><a href="http://railstips.org/2007/3/5/my-local-rails-setup">Read more</a> for advanced settings etc&#8230;</p>
<h1>Install RSpec</h1>
<p>Very straight forward, you just need to follow <a href="http://rspec.rubyforge.org/documentation/rails/install.html">the documentation</a></p>
<pre><code>$ cd ~/rails_projects/my_edgie_project
$ ruby script/plugin install svn://rubyforge.org/var/svn/rspec/tags/CURRENT/rspec
$ ruby script/plugin install svn://rubyforge.org/var/svn/rspec/tags/CURRENT/rspec_on_rails
</code></pre>
<p>If you have TextMate, you might want to download the <a href="http://rubyforge.org/frs/?group_id=797">latest RSpec-X.Y.Z.tmbundle.tgz Bundle</a></p>
<p>Next thing you want to do is to install <a href="http://www.zenspider.com/ZSS/Products/ZenTest/">ZenTest</a></p>
<pre><code>$ sudo gem install ZenTest
</code></pre>
<p>Make sure you install all the required packages.</p>
<p>If you are using <a href="http://growl.info/">Growl</a> create a new file called .autotest in your home directory:</p>
<pre><code>$mate ~./autotest
</code></pre>
<p>and add the following 2 lines to be warned when your specs/examples fail/pass</p>
<pre><code>require 'autotest/redgreen'
require 'autotest/growl'
</code></pre>
<p>Now, lets go back to our project and create a model using the rspec scaffold (it uses scaffold_resource generator and create all the specs for you)</p>
<pre><code>$ cd ~/rails_projects/my_edgie_project
$ ruby script/generate rspec_scaffold User first_name:string last_name:string :age:integer
</code></pre>
<p>Now, let&#8217;s start autotest (from zentest) so out code is tested in the background</p>
<pre><code>$ autotest
</code></pre>
<p>There you go, really to modify your RSpec examples, make them fail, fix your code, examples should pass, refactor your code and start again <img src='http://railsontherun.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://railsontherun.com/2007/06/06/create-a-rails-edge-rspec-project/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Oops, DrNic Did it again</title>
		<link>http://railsontherun.com/2007/04/26/myconfplan-com/</link>
		<comments>http://railsontherun.com/2007/04/26/myconfplan-com/#comments</comments>
		<pubDate>Thu, 26 Apr 2007 10:33:00 +0000</pubDate>
		<dc:creator>Matt Aimonetti</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[BDD]]></category>
		<category><![CDATA[bundle]]></category>
		<category><![CDATA[conference]]></category>
		<category><![CDATA[DrNic]]></category>
		<category><![CDATA[failure]]></category>
		<category><![CDATA[myconfplan.com]]></category>
		<category><![CDATA[railsconf]]></category>
		<category><![CDATA[RSpec]]></category>
		<category><![CDATA[spec]]></category>
		<category><![CDATA[textmate]]></category>
		<category><![CDATA[web2.0]]></category>

		<guid isPermaLink="false">http://railsontherun.com/2007/04/26/myconfplan-com</guid>
		<description><![CDATA[DrNic the most famous Australian Rails developer surprisingly doesn&#8217;t spend most of his time working on Rails read interview That&#8217;s maybe why he recently became so active in the Rails community ( see Magic Multi-Connections, Magic Models, map_by_methods, Gem Generator etc..) Today he released something very helpful for the Rails Community, not another Gem or [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://drnicwilliams.com/">DrNic</a> the most famous Australian Rails developer surprisingly doesn&#8217;t spend most of his time working on Rails  <a href="http://www.akitaonrails.com/pages/drnic">read interview</a><br />
That&#8217;s maybe why he recently became so active in the Rails community ( see <a href="http://www.loudthinking.com/arc/000610.html">Magic Multi-Connections</a>, Magic Models, map_by_methods, Gem Generator etc..)</p>
<p>Today he released something very helpful for the Rails Community, not another Gem or another cool plugin to extend Rails but a <a href="http://myconfplan.com">web application</a> to help you planning your conferences. We already had other tools such as <a href="http://railsconf2007.conferencemeetup.com/p/276-matt-aimonetti">conference meetup</a> but it&#8217;s the first time that we get a product helping you to plan a conference by scheduling the sessions you want to attend.</p>
<p><img src="http://farm1.static.flickr.com/169/473390616_12c7596617.jpg?v=0" alt="screenshot"/></p>
<p><a href="http://flickr.com/photos/railsontherun/473389852/in/photostream/">screenshot of the entire schedule</a></p>
<p>I had a quick chat with DrNic about his latest creation and here is what he said:</p>
<p>&#8220;its been fun building just how I thought session selection might look + feel<br />
web2.0 = permissive voyeurism I think!&#8221;</p>
<p>I share the same vision than Nic on session selection and I really enjoyed booking my Rails sessions and seeing what other people selected. (I guess that&#8217;s my voyeur side, don&#8217;t you like web2.0?)</p>
<p>If you wanna see what I planned on attending, checkout my schedule: <a href="http://myconfplan.com/conferences/RailsConf2007/users/matt">my schedule</a></p>
<p>Thanks Nic for the good work and too bad you are not presenting anything at the RailsConf (move your bum to come up with a <em>better</em> submission next year!)</p>
]]></content:encoded>
			<wfw:commentRss>http://railsontherun.com/2007/04/26/myconfplan-com/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Restful Rails and Flash</title>
		<link>http://railsontherun.com/2007/04/09/rails-and-flash/</link>
		<comments>http://railsontherun.com/2007/04/09/rails-and-flash/#comments</comments>
		<pubDate>Mon, 09 Apr 2007 07:41:00 +0000</pubDate>
		<dc:creator>Matt Aimonetti</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[actionScript]]></category>
		<category><![CDATA[adobe]]></category>
		<category><![CDATA[BDD]]></category>
		<category><![CDATA[bundle]]></category>
		<category><![CDATA[failure]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[flex]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[RSpec]]></category>
		<category><![CDATA[scaffhold_resource]]></category>
		<category><![CDATA[spec]]></category>
		<category><![CDATA[textmate]]></category>

		<guid isPermaLink="false">http://railsontherun.com/2007/04/19/rails-and-flash</guid>
		<description><![CDATA[With the recent Buzz around Adobe Apollo I figured out that since I recently switched to Mac and that I didn&#8217;t try the latest Flex upgrade, I should try Flex 2.01 for Mac. I really like what Adobe did with Flex, Unit testing, better accessibility, etc&#8230; but one thing I regret, it&#8217;s getting closer and [...]]]></description>
			<content:encoded><![CDATA[<p>With the recent Buzz around <a href="http://labs.adobe.com/wiki/index.php/Apollo">Adobe Apollo</a> I figured out that since I recently switched to Mac and that I didn&#8217;t try the latest Flex upgrade, I should try <a href="http://www.adobe.com/products/flex/">Flex 2.01</a> for Mac. </p>
<p>I really like what Adobe did with Flex, Unit testing, better accessibility, etc&#8230; but one thing I regret, it&#8217;s getting closer and closer to Java and <a href="http://flexblog.faratasystems.com/?p=115">AS3 syntax</a> is a pain to use when you got used to Ruby. </p>
<p>Anyway, what I really wanted to do was to have Flash quickly access my Restful Rails app. The adobe guys came up with a <a href="http://code.google.com/p/rubyonrails-ria-sdk-by-adobe/">RoR Ria SDK</a> but well&#8230;.   it only covers Flex and requires FlashPlayer 9.<br />
I also found some great <a href="http://blog.vixiom.com/2006/08/23/flash-remoting-for-rails-tutorial/">tutorials</a> on how to use the efficient  <a href="http://osflash.org/documentation/amf">AMF messaging protocol</a> with Rails using the <a href="http://www.themidnightcoders.com/weborb/rubyonrails/index.htm">WebOrb for Rails plugins</a></p>
<p>All that was really nice and I had fun, but it was an overkill for what I wanted to do. Let me show you how in less than 5 minutes how you can access you Rails Model from Flash and add some new item directly from Flash.</p>
<p>Create your new Rails app and use the script/generate scaffold_resource command to generate your Event Model.</p>
<pre><code>script/generate scaffold_resource Event
</code></pre>
<p>It should create all that for you:</p>
<pre><code>exists  app/models/
  exists  app/controllers/
  exists  app/helpers/
  create  app/views/events
  exists  test/functional/
  exists  test/unit/
  create  app/views/events/index.rhtml
  create  app/views/events/show.rhtml
  create  app/views/events/new.rhtml
  create  app/views/events/edit.rhtml
  create  app/views/layouts/events.rhtml
  identical  public/stylesheets/scaffold.css
  create  app/models/event.rb
  create  app/controllers/events_controller.rb
  create  test/functional/events_controller_test.rb
  create  app/helpers/events_helper.rb
  create  test/unit/event_test.rb
  create  test/fixtures/events.yml
  exists  db/migrate
  create  db/migrate/001_create_events.rb
  route  map.resources :events
</code></pre>
<p>let&#8217;s edit the migration file:<br />
db/migrate/001<em>create</em>events.rb</p>
<pre><code>class CreateEvents &lt; ActiveRecord::Migration
  def self.up
    create_table :events do |t|
      t.column :title, :string
      t.column :description, :string
      t.column :location, :string
        t.column :starts_at, :datetime
        t.column :ends_at, :datetime
    end
  end

  def self.down
    drop_table :events
  end
end
</code></pre>
<p>And let&#8217;s add some fixtures:<br />
test/fixtures/events.yml</p>
<pre><code>meeting:
  id: 1
  title: Meeting
  description: Boring meeting with the whole staff
  location: conference room
  starts_at: 2007-11-02 09:00:00
  ends_at: 2007-11-02 10:30:00
Joe_bday:
  id: 2
  title: Joe Bday Party
  description: Come and celebrate Joe's Birthday
  location: Lapin Agile Pub
  starts_at: 2007-09-07 20:00:00
  ends_at: 2007-09-07 23:30:00
</code></pre>
<p>Ok, now simply migrate your database,load the fixtures and start the webrick:</p>
<pre><code>rake db:migrate
rake db:fixtures:load
script/server
</code></pre>
<p>Great, we are done with Rails.  </p>
<p>Let&#8217;s launch Flash</p>
<p>Create a new Flash document and create a new .As fie in TextMate (or your favorite editor). We&#8217;ll write a quick ActionScript class to access Rails.</p>
<pre><code>class Restfulflash{
    public var gateway:String;

    function Resftfulflash(gateway:String){
        this.set_gateway(gateway);
    }
    public function set_gateway(gateway:String){
        this.gateway = gateway;
        trace("gateway set to:"+gateway);
    }

    public function get(model, callback){
        var railsReply:XML = new XML();
        railsReply.ignoreWhite = true;
        railsReply.onLoad = function(success:Boolean){
            if (success) {
                    trace ('Rails responded: '+railsReply);
                    callback.text = railsReply;
            } else {
                    trace ('Error while waiting for Rails to reply');
               callback.text = 'error';
            }
        }
        var railsRequest:XML = new XML();
        railsRequest.contentType="application/xml";
        railsRequest.sendAndLoad(this.gateway+model, railsReply);
        delete railsRequest;
    }

    public function create(model, newItem){
        railsRequest.onLoad = function(success){
                trace("Item creation success: " + success);
                trace(this);
        };
        var railsRequest:XML = new XML();
        railsRequest.parseXML(newItem);
        railsRequest.contentType="application/xml";
        railsRequest.sendAndLoad(this.gateway+model+'/create/', railsRequest,'POST');
        delete railsRequest;
    }
}
</code></pre>
<p>Save this file in the same directory as your .fla file  </p>
<p>In your fla file add:</p>
<pre><code>// Create a XML object to hold the events from our Rails app
rails_events = new XML();

// Prepare the connection to Rails (it would be nicer to do that in 1 step, but to make things clearer i decided to do it in 2)
var rails:Restfulflash = new Restfulflash();
rails.set_gateway("http://localhost:3000/");

// Get the events from rails and load the result in the rails_event XML object.
rails.get('events', rails_events);
trace(rails_events);

// Let's create a new event
newEvent = new XML('&lt;event&gt;&lt;description&gt;Spend some time with Grandma before its too late&lt;/description&gt;&lt;ends-at type="datetime"&gt;2007-11-02T18:30:00-07:00&lt;/ends-at&gt;&lt;id type="integer"&gt;1&lt;/id&gt;&lt;location&gt;Paris, France&lt;/location&gt;&lt;starts-at type="datetime"&gt;2007-11-02T16:00:00-07:00&lt;/starts-at&gt;&lt;title&gt;Visit Grandma&lt;/title&gt;&lt;/event&gt;&amp;#8217;)
rails.create(&amp;#8216;events&amp;#8217;, newEvent);

// Verify  that the event was added
rails.get(&amp;#8216;events&amp;#8217;, rails_events);
trace(rails_events);
</code></pre>
<p>There you go, you have all the events provided to you by Rails nicely prepared in an easy to parse XML object. You can bind the results to a Datagrid or display the info the way you want it. Ohh and by the way, we just added a new Event to the database&#8230; easy, isn&#8217;t it?  The code is a bit dirty but it&#8217;s still a good example why you need to use REST and how easy it is to get Flash to talk with Rails. (I strongly encourage that you also look at the very good WebOrb plugin for Rails)</p>
]]></content:encoded>
			<wfw:commentRss>http://railsontherun.com/2007/04/09/rails-and-flash/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Migrating a legacy app to Rails Part II</title>
		<link>http://railsontherun.com/2007/04/02/migrating-legacy-app-part-2/</link>
		<comments>http://railsontherun.com/2007/04/02/migrating-legacy-app-part-2/#comments</comments>
		<pubDate>Mon, 02 Apr 2007 18:31:00 +0000</pubDate>
		<dc:creator>Matt Aimonetti</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[activeRecord]]></category>
		<category><![CDATA[BDD]]></category>
		<category><![CDATA[bundle]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[failure]]></category>
		<category><![CDATA[legacy]]></category>
		<category><![CDATA[migration]]></category>
		<category><![CDATA[module]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[RSpec]]></category>
		<category><![CDATA[spec]]></category>
		<category><![CDATA[textmate]]></category>

		<guid isPermaLink="false">http://railsontherun.com/2007/05/22/migrating-legacy-app-part-2</guid>
		<description><![CDATA[In part I I quickly explained what I had to do, my limitations and a potential solution to connect to a legacy database. In this post I&#8217;ll try to go through setting up a plugin for migration and start using RSpec for developing the migration plugin. What we want is to migrate sites using the [...]]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://www.railsontherun.com/2007/3/30/migrating-legacy-app-part-1">part I</a> I quickly explained what I had to do, my limitations and a potential solution to connect to a legacy database.</p>
<p>In this post I&#8217;ll try to go through setting up a plugin for migration and start using <a href="http://rspec.rubyforge.org/">RSpec</a> for developing the migration plugin.</p>
<p>What we want is to migrate sites using the legacy application to our new Rails application. That means that new users won&#8217;t be be migrated. It therefore makes sense not to add the migrating logic to the main application but to create a plugin. (if you are not familiar with Rails plugins check this <a href="http://nubyonrails.com/articles/2006/05/04/the-complete-guide-to-rails-plugins-part-i">blog post from Geoffrey Grosenbach about plugins</a>)</p>
<p>Let&#8217;s create our plugin</p>
<pre><code>./script/generate plugin legacy_migration</code></pre>
<p>Rails should have generated something like that:</p>
<pre><code>legacy_migration
|-- init.rb
|-- install.rb
|-- uninstall.rb
|-- Rakefile
|-- README
|-- lib/
|   |-- legacy_migration.rb
|-- tasks/
|   |-- legacy_migration_tasks.rake
|-- test
|   |-- legacy_migration_test.rb</code></pre>
<p>Since we are going to use RSpec, we can remove the test folder and create a spec folder. In our spec folder, let&#8217;s add some subfolders to organize our files. Let&#8217;s create a fixtures folder to hold, a helpers folder, a migrate folder (we&#8217;ll use that to migrate our legacy database) and finally, a models folder.</p>
<p>Our plugin folder should look more or less like that:</p>
<pre><code>legacy_migration
|-- init.rb
|-- install.rb
|-- uninstall.rb
|-- Rakefile
|-- README
|-- lib/
|   |-- legacy_migration.rb
|-- tasks/
|   |-- legacy_migration_tasks.rake
|-- spec
|   |-- fixtures
|   |-- helpers
|   |-- migrate
|   |-- models</code></pre>
<p>Great, let&#8217;s get started and let&#8217;s create our first spec. We should probably start by migrating users so I&#8217;ll create a new spec in the spec/models folder called legacy_user_spec.rb and add the following code:</p>
<pre><code>require File.dirname(<i>FILE</i>) + '/../helpers/legacy_user_helper'
require File.dirname(<i>FILE</i>) + '/../helpers/spec_helper'</code></pre>
<pre><code>describe "a connection to the legacy application" do
  setup do
    @connection_status = LEGACY.connect
  end
end</code></pre>
<pre><code>it "should be connected to the legacy database" do
  @connection_status.current_database.should == ActiveRecord::Base.configurations<a href="'database'">'legacy'</a>

end</code></pre>
<p>Note that I&#8217;m using RSpec trunk/edge and I use &#8220;describe&#8221; instead of &#8220;context&#8221; and &#8220;it&#8221; instead of &#8220;specify&#8221;. For more information on how to run RSpec edge with TextMate read <a href="http://www.railsontherun.com/2007/3/30/rspec-textmate-bundle-edge">this previous post</a>.</p>
<p>If we look at the code above, we start by requiring 2 helpers, a general helper called spec_helper and a helper just for this spec called legacy_user_helper (we will obviously need to create them otherwise our spec will failed).</p>
<p>Then we start our first spec by describing a connection to the legacy application and we specify that it should be connected to the legacy database.</p>
<p>Here is our setup code:</p>
<pre><code>setup do
  @connection_status = LEGACY.connect
end</code></pre>
<p>What I want is to retrieve a connection status after I connect to our legacy application. To manage the connection to the legacy application we will create a <span class="caps">LEGACY</span> module. We will need to connect to many legacy applications/sites and our module should help us doing that.</p>
<p>Then we can read that our spec checks that we are connected to the legacy database.</p>
<pre><code>it "should be connected to the legacy database" do
  @connection_status.current_database.should == ActiveRecord::Base.configurations<a href="'database'">'legacy'</a>
end</code></pre>
<p>That means we want to compare the connection status to the &#8216;legacy&#8217; environment defined in the database.yml file.</p>
<p>We now need to get this spec to pass.</p>
<p>Let&#8217;s get started by adding a legacy environment to our database.yml and creating our <span class="caps">LEGACY</span> module in our legacy_migration.rb file.</p>
<p>Add the following to your database.yml</p>
<pre><code>legacy:
  adapter: mysql
  database: legacy
  username: root
  password:
  host: localhost</code></pre>
<p>Now, let&#8217;s create the <span class="caps">LEGACY</span> module in our legacy_migration.rb file</p>
<pre><code>
module LEGACY

  # Connect to a Legacy database.
  # Usage:
  # Manual connection: LEGACY.connect(:database => 'legacy-database', :adapter => 'mysql', :username => 'root', :password => '', :host => 'localhost')
  # Auto connection to the database.yml defined legacy DB: LEGACY.connect
  # Connection to any database available in database.yml LEGACY.connect('legacy_test')
  # Connect a class to a specific database: LEGACY.connect(LegacyInstaller, ActiveRecord::Base.configurations['legacy_installer'])
  def self.connect(spec = nil, opt_env = nil)
    case spec
      # Automatically connect to the legacy environment database defined in the database.yml
    when nil
      raise 'Legacy Database not defined' unless defined? ActiveRecord::Base.configurations['legacy']
      LegacyActiveRecord.establish_connection(ActiveRecord::Base.configurations['legacy'])
      # Return the connections status
      LegacyActiveRecord.connection
      # A connection's name from the database.yml can be passed
    when Symbol, String
      if configuration = ActiveRecord::Base.configurations[spec.to_s]
        LegacyActiveRecord.establish_connection(configuration)
      else
        raise "#{spec} database is not configured"
      end
      # Connect a Model to a specific Database
    when Class
      raise 'Environment connection not provided or nil' unless defined? opt_env || opt_env['database'] == nil
      if spec.connection.current_database == opt_env['database']
        spec.connection
      else
        spec.establish_connection(opt_env)
      end
      # An array can be passed to establish the connection
    else
      spec = spec.symbolize_keys
      unless spec.key?(:adapter) then raise "database configuration does not specify adapter" end
        adapter_method = "#{spec[:adapter]}_connection"
        LegacyActiveRecord.establish_connection(spec)
      end
    end
  end</code></pre>
<p>There we go, we have a really cool connect function, we can easily connect to the default legacy environment defined in the database.yml file, we can specify the connection settings, connect to another environment database and even connect one specific class/model to a specific environment. (that will useful since we have many databases). If we wanted to follow the <span class="caps">TDD</span> rules, I shouldn&#8217;t have written so much code&#8230; as a matter of fact, when I worked on this project I did not, but since I don&#8217;t have much time, I won&#8217;t go through the re-factoring steps.</p>
<p>One thing you might have noticed is that we establish a connection between LegacyActiveRecord and the legacy database. (instead of connecting ActiveRecord to the legacy database).</p>
<pre><code>LegacyActiveRecord.establish_connection(ActiveRecord::Base.configurations['legacy'])</code></pre>
<p>The problem is that we didn&#8217;t create the LegacyActiveRecord model yet. Let&#8217;s do that right away. Let&#8217;s add a new folder called models in our lib folder. In the models folder, let&#8217;s create a legacy_active_record.rb file and add the following code:</p>
<pre><code>class LegacyActiveRecord &lt; ActiveRecord::Base
  self.abstract_class = true
end</code></pre>
<p>Cool, now let&#8217;s have fun with our new module, fire the console (./script/console) and try <span class="caps">LEGACY</span>.connect<br />
Here is what we get back:</p>
<pre><code>
    &gt;&gt; <span class="caps">LEGACY</span>.connect
    =&gt; #<activeRecord::ConnectionAdapters::MysqlAdapter:0x32a09d8 @runtime=0.000155925750732422, @config={:password=>nil, :database=&gt;&#8221;legacy&#8221;, :allow_concurrency=&gt;false, :host=&gt;&#8221;localhost&#8221;, :username=&gt;&#8221;root&#8221;, :adapter=&gt;&#8221;mysql&#8221;}, @connection_options=[&#8220;localhost&#8221;, &#8220;root&#8221;, &#8221;&#8221;, &#8220;legacy&#8221;, nil, nil], [...]

</code></pre>
<p>let&#8217;s try to get the database we connected to:</p>
<pre><code>&gt;&gt;LEGACY.connect.current_database
    =&gt; &#8220;legacy&#8221;

</code></pre>
<p>Awesome, we can now get our LegacyActiveRecord model to connect to our legacy database and return the connections status. Let&#8217;s run our specs&#8230;&#8230;&#8230;.. they pass.</p>
<p>Sweet, we setup our migration plugin, got our first spec written, added the code needed to get the spec to pass, I think we are done with <span class="caps">PART 2</span> <img src='http://railsontherun.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://railsontherun.com/2007/04/02/migrating-legacy-app-part-2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>RSpec Textmate bundle and RSpec edge</title>
		<link>http://railsontherun.com/2007/03/30/rspec-textmate-bundle-edge/</link>
		<comments>http://railsontherun.com/2007/03/30/rspec-textmate-bundle-edge/#comments</comments>
		<pubDate>Fri, 30 Mar 2007 04:21:00 +0000</pubDate>
		<dc:creator>Matt Aimonetti</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[BDD]]></category>
		<category><![CDATA[bundle]]></category>
		<category><![CDATA[failure]]></category>
		<category><![CDATA[RSpec]]></category>
		<category><![CDATA[rspec textmate]]></category>
		<category><![CDATA[spec]]></category>
		<category><![CDATA[textmate]]></category>

		<guid isPermaLink="false">http://railsontherun.com/2007/04/12/rspec-textmate-bundle-edge</guid>
		<description><![CDATA[UPDATE: Aslak Hellesoy just mentioned in a comment that the trunk version of RSpec bundle for TextMate ( svn://rubyforge.org/var/svn/rspec/trunk ) doesn&#8217;t require the RSpec Gem installed anymore. To install the bundle: cd ~/Library/Application\ Support/TextMate/Bundles/ svn co svn://rubyforge.org/var/svn/rspec/branches/0.9-dev/RSpec.tmbundle I recently discovered RSpec, well, not really, but I finally got to start using RSpec. For those who [...]]]></description>
			<content:encoded><![CDATA[<h2>UPDATE:</h2>
<p><a href='http://blog.aslakhellesoy.com/' target='blank'> Aslak Hellesoy</a> just mentioned in a comment that the trunk version of RSpec bundle for TextMate ( svn://rubyforge.org/var/svn/rspec/trunk ) doesn&#8217;t require the RSpec Gem installed anymore.<br />
<br/><br/></p>
<p>To install the bundle:</p>
<pre><code>
cd ~/Library/Application\ Support/TextMate/Bundles/
 svn co svn://rubyforge.org/var/svn/rspec/branches/0.9-dev/RSpec.tmbundle
</code></pre>
<p><br/></p>
<hr />
<br/><br/><br/></p>
<p>I recently discovered RSpec, well, not really, but I finally got to start using<br />
RSpec.<br/><br />
For those who don&#8217;t know<br />
<a href="http://rspec.rubyforge.org/" target="blank_" title="RSpec">RSpec</a> ,<br />
RSpec is a BDD testing framework, or in better words: RSpec is a Behaviour<br />
Definition Framework well suited for practicing Behaviour Driven Development<br />
(BDD) in Ruby.<br/><br />
<br/><br />
If you don&#8217;t know what is BDD, then just check out<br />
<a href="http://behaviour-driven.org/" target="blank_" title="http://behaviour-driven.org/">http://behaviour-driven.org/</a>, in few words, it&#8217;s TDD (Test Driven Development in better)<br/><br />
<br/><br />
Anyway, I&#8217;m working on a Rails project where we use the trunk/edge version RSpec<br />
plugin. I&#8217;m using my favorite editor:<br />
<a href="http://macromates.com/" target="blank_" title="TextMate">TextMate</a><br />
and I noticed that the RSpec team created a<br />
<a href="http://rspec.rubyforge.org/tools/extensions/editors/textmate.html" target="blank_" title="cool bundle for textmate">cool<br />
bundle for textmate</a>.<br/><br />
<br/><br />
I was quite excited until I tried running a spec and realized that the task<br />
failed giving some errors about some missing methods&#8230; Well, the thing is we<br />
replaced &#8220;context &#8230; do&#8221; by &#8220;describe &#8230; do&#8221; and &#8220;specify &#8230; do&#8221; by &#8220;it &#8230;<br />
do&#8221; see<br />
<a href="http://blog.davidchelimsky.net/articles/2007/03/11/describe-it-with-rspec" title="David's post">David&#8217;s<br />
post</a> about this specific change in trunk:<br/><br />
<br/><br />
The Textmate bundle uses the ruby gem instead of the plugin and since I&#8217;m trying<br />
to use methods only defined in trunk the bundle simply dies on me every time I<br />
try to run my specs.<br/><br />
<br/><br />
The only solution for me was to run a trunk version of the RSpec gem, here is<br />
what to do:<br/><br />
<br/><br />
<span style="FONT-STYLE:italic">Check out RSpec trunk from:<br />
svn://rubyforge.org/var/svn/rspec/trunk</span><br style="FONT-STYLE:italic"/><br />
<span style="FONT-STYLE:italic">Check out RSpec trunk into its own project, or<br />
if you&#8217;re interested in</span><br style="FONT-STYLE:italic"/><br />
<span style="FONT-STYLE:italic">using/learning RSpec for a particular Rails<br />
project, consider using</span><br style="FONT-STYLE:italic"/><br />
<span style="FONT-STYLE:italic">svn:externals to check out RSpec trunk into your<br />
[RailsRoot]/vendor</span><br style="FONT-STYLE:italic"/><br />
<span style="FONT-STYLE:italic">directory:</span><br style="FONT-STYLE:italic"/><br />
<br style="FONT-STYLE:italic"/><br />
<span style="FONT-STYLE:italic">svn propset svn:externals &#8220;rspec<br />
svn://rubyforge.org/var/svn/rspec/trunk&#8221;</span><br style="FONT-STYLE:italic"/><br />
<span style="FONT-STYLE:italic">vendor</span><br style="FONT-STYLE:italic"/><br />
<br style="FONT-STYLE:italic"/><br />
<span style="FONT-STYLE:italic">then update to grab the latest code from RSpec<br />
trunk:</span><br style="FONT-STYLE:italic"/><br />
<br style="FONT-STYLE:italic"/><br />
<span style="FONT-STYLE:italic">svn update<br />
vendor</span><br style="FONT-STYLE:italic"/><br />
<br style="FONT-STYLE:italic"/><br />
<span style="FONT-STYLE:italic">Next, build the gem.&nbsp; You have to be<br />
standing in vendor/rspec if you&#8217;re</span><br style="FONT-STYLE:italic"/><br />
<span style="FONT-STYLE:italic">using svn:externals (as described above) or the<br />
root of RSpec if you checked</span><br style="FONT-STYLE:italic"/><br />
<span style="FONT-STYLE:italic">it out as its own<br />
project.</span><br style="FONT-STYLE:italic"/><br />
<br style="FONT-STYLE:italic"/><br />
<span style="FONT-STYLE:italic">rake gem</span><br style="FONT-STYLE:italic"/><br />
<br style="FONT-STYLE:italic"/><br />
<span style="FONT-STYLE:italic">then install<br />
it:</span><br style="FONT-STYLE:italic"/><br />
<br style="FONT-STYLE:italic"/><br />
<span style="FONT-STYLE:italic">gem install pkg/rspec-X.X.X.gem (where X.X.X is<br />
the version number reported</span><br style="FONT-STYLE:italic"/><br />
<span style="FONT-STYLE:italic">in the output from &#8220;rake gem&#8221;)</span><br/><br />
<br/><br />
&#8212;- from<br />
<a href="http://rubyforge.org/pipermail/rspec-users/2006-November/000135.html" target="blank_" title="http://rubyforge.org/pipermail/rspec-users/2006-November/000135.html">http://rubyforge.org/pipermail/rspec-users/2006-November/000135.html</a><br/><br />
<br/><br />
That&#8217;s it, now I can run my specs directly from Textmate the same way I was<br />
doing with Unit Test.<br/><br />
<br/><br />
( on a different post I&#8217;ll explain why I couldn&#8217;t simply run rake:spec )<br/><br />
<br/><br />
<br/><br />
<br/><br />
<br/><br />
<br/></p>
]]></content:encoded>
			<wfw:commentRss>http://railsontherun.com/2007/03/30/rspec-textmate-bundle-edge/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

