<?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>/dev/caffeine &#187; cflipse</title>
	<atom:link href="http://devcaffeine.com/author/admin/feed/" rel="self" type="application/rss+xml" />
	<link>http://devcaffeine.com</link>
	<description>anything worth taking seriously is worth making fun of</description>
	<lastBuildDate>Thu, 24 Sep 2009 20:50:49 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Specify a relative time in Cucumber</title>
		<link>http://devcaffeine.com/2009/08/17/relative-time-in-cucumber/</link>
		<comments>http://devcaffeine.com/2009/08/17/relative-time-in-cucumber/#comments</comments>
		<pubDate>Mon, 17 Aug 2009 17:52:59 +0000</pubDate>
		<dc:creator>cflipse</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[cucumber]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://devcaffeine.com/?p=96</guid>
		<description><![CDATA[Prepping for working on a feature at $work that involves limiting documents by relative time, I hashed out the following steps.  Posting here in case they prove useful for anyone.
I want to be able to specify an arbitrary time, in english, relative to the current time, in my Cucumber steps.  For example,

Scenario: Only [...]]]></description>
			<content:encoded><![CDATA[<p>Prepping for working on a feature at $work that involves limiting documents by relative time, I hashed out the following steps.  Posting here in case they prove useful for anyone.</p>
<p>I want to be able to specify an arbitrary time, in english, relative to the current time, in my Cucumber steps.  For example,</p>

<div class="wp_syntax"><div class="code"><pre class="cucumber" style="font-family:monospace;">Scenario: Only posts from the last two months are shown
  Given the following posts:
    | title           | posted_at           |
    | recent post     | 2 days ago          |
    | recent post 2   | yesterday           |
    | older post      | 2 months ago        |
    | really old post | 2 months, 1 day ago |
    | tomorrow's post | 1 day from now      |
  When I go to the posts page
  Then I should see 3 posts</pre></div></div>

<p>The desire, there, is to be able to specify a date relative to the current time, in plain english.  The tricky bit is being able to chain them together, as in <code>1 year, 3 months, 2 days ago</code></p>
<p>I got this worked out by stringing a few regular expressions together in my step definition helper.  It depends on the 2.days.ago type dsl in ActiveSupport.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">Given <span style="color:#006600; font-weight:bold;">/</span>^the following posts?:?<span style="color:#006600; font-weight:bold;">/</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>table<span style="color:#006600; font-weight:bold;">|</span>
  table.<span style="color:#9900CC;">map_column</span>!<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'posted_at'</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">|</span>date<span style="color:#006600; font-weight:bold;">|</span> interpret_time<span style="color:#006600; font-weight:bold;">&#40;</span>date<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
  table.<span style="color:#9900CC;">hashes</span>.<span style="color:#9900CC;">each</span><span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">|</span>hash<span style="color:#006600; font-weight:bold;">|</span> Factory <span style="color:#ff3333; font-weight:bold;">:post</span>, hash<span style="color:#006600; font-weight:bold;">&#125;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> interpret_time<span style="color:#006600; font-weight:bold;">&#40;</span>time<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#0000FF; font-weight:bold;">nil</span> <span style="color:#9966CC; font-weight:bold;">if</span> time.<span style="color:#9900CC;">blank</span>?
  <span style="color:#0000FF; font-weight:bold;">return</span> time <span style="color:#9966CC; font-weight:bold;">if</span> time.<span style="color:#9900CC;">kind_of</span>?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC00FF; font-weight:bold;">Time</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">or</span> time.<span style="color:#9900CC;">kind_of</span>?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC00FF; font-weight:bold;">Date</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  named_time<span style="color:#006600; font-weight:bold;">&#40;</span>time<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">||</span> time_by_regex<span style="color:#006600; font-weight:bold;">&#40;</span>time<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">||</span> <span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">parse</span><span style="color:#006600; font-weight:bold;">&#40;</span>time<span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">def</span> named_time<span style="color:#006600; font-weight:bold;">&#40;</span>time<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">case</span> time.<span style="color:#9900CC;">downcase</span>
  <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#996600;">&quot;today&quot;</span> : <span style="color:#CC00FF; font-weight:bold;">Date</span>.<span style="color:#9900CC;">today</span>
  <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#996600;">&quot;now&quot;</span> : <span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">now</span>
  <span style="color:#008000; font-style:italic;"># etc ...</span>
  <span style="color:#9966CC; font-weight:bold;">else</span> <span style="color:#0000FF; font-weight:bold;">nil</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">def</span> time_by_regex<span style="color:#006600; font-weight:bold;">&#40;</span>time<span style="color:#006600; font-weight:bold;">&#41;</span>
  directional_regex = <span style="color:#006600; font-weight:bold;">/</span><span style="color:#006600; font-weight:bold;">&#40;</span>ago<span style="color:#006600; font-weight:bold;">|</span>from now<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">/</span>i
  time_regex = <span style="color:#006600; font-weight:bold;">/</span><span style="color:#006600; font-weight:bold;">&#40;</span>\d<span style="color:#006600; font-weight:bold;">+</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#40;</span>minute<span style="color:#006600; font-weight:bold;">|</span>hour<span style="color:#006600; font-weight:bold;">|</span>day<span style="color:#006600; font-weight:bold;">|</span>week<span style="color:#006600; font-weight:bold;">|</span>month<span style="color:#006600; font-weight:bold;">|</span>year<span style="color:#006600; font-weight:bold;">&#41;</span>s?<span style="color:#006600; font-weight:bold;">/</span>i
&nbsp;
  direction = time.<span style="color:#9900CC;">scan</span><span style="color:#006600; font-weight:bold;">&#40;</span>directional_regex<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">flatten</span>
  shifts = time.<span style="color:#9900CC;">scan</span><span style="color:#006600; font-weight:bold;">&#40;</span>time_regex<span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
  <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#0000FF; font-weight:bold;">nil</span> <span style="color:#9966CC; font-weight:bold;">if</span> direction.<span style="color:#9900CC;">empty</span>? <span style="color:#9966CC; font-weight:bold;">or</span> shifts.<span style="color:#9900CC;">empty</span>?
  forward = direction.<span style="color:#9900CC;">first</span> == <span style="color:#996600;">&quot;from now&quot;</span>
&nbsp;
  result = <span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">now</span>
  shifts.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>count, unit<span style="color:#006600; font-weight:bold;">|</span>
    <span style="color:#008000; font-style:italic;">#depends on the 1.week type DSL for time measurements</span>
    adjust = count.<span style="color:#9900CC;">to_i</span>.<span style="color:#9900CC;">send</span><span style="color:#006600; font-weight:bold;">&#40;</span>unit<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#008000; font-style:italic;"># move time in correct direction</span>
    result = forward ? <span style="color:#006600; font-weight:bold;">&#40;</span>result <span style="color:#006600; font-weight:bold;">+</span> adjust<span style="color:#006600; font-weight:bold;">&#41;</span> : <span style="color:#006600; font-weight:bold;">&#40;</span>result <span style="color:#006600; font-weight:bold;">-</span> adjust<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  result
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://devcaffeine.com/2009/08/17/relative-time-in-cucumber/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>hardware: intel X25-M SSD</title>
		<link>http://devcaffeine.com/2009/04/12/hardware-intel-x25-m-ssd/</link>
		<comments>http://devcaffeine.com/2009/04/12/hardware-intel-x25-m-ssd/#comments</comments>
		<pubDate>Sun, 12 Apr 2009 14:43:34 +0000</pubDate>
		<dc:creator>cflipse</dc:creator>
				<category><![CDATA[hardware]]></category>
		<category><![CDATA[IBM X25-M]]></category>
		<category><![CDATA[ssd]]></category>
		<category><![CDATA[thinkpad]]></category>

		<guid isPermaLink="false">http://devcaffeine.com/?p=93</guid>
		<description><![CDATA[Got myself a little post tax-return treat this week:  An Intel X25-M SSD for my laptop.  Basically, it&#8217;s an 80 gig solid state hard disk.  Flash memory, like what&#8217;s in your iPod these days.
It arrived at the start of the weekend, and I took a bit of time to install it in [...]]]></description>
			<content:encoded><![CDATA[<p>Got myself a little post tax-return treat this week:  An <a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16820167005">Intel X25-M SSD</a> for my laptop.  Basically, it&#8217;s an 80 gig solid state hard disk.  Flash memory, like what&#8217;s in your iPod these days.</p>
<p>It arrived at the start of the weekend, and I took a bit of time to install it in my laptop, a Thinkpad T61p, about a year old.  The installation was pretty easy &#8212; one screw to get at the laptop&#8217;s main drive, and pull the sled out.  I had a little bit of difficulty getting the sled screws out of the old HD, as they were in pretty tight.  Other than that, it was a smooth swapout.</p>
<p>I installed the most recent Ubuntu beta, which went swimmingly.  Better than any Windows install I&#8217;ve ever done.  The bottleneck there, unsurprisingly, was the CD drive.</p>
<p>It&#8217;s impressive how much quieter the laptop has become, without the spinning drive.  plus &#8230; it&#8217;s <i>fast</i>.  I&#8217;m not going to compare boot numbers, because I&#8217;m not booting the exact same OS after install &#8230; but, the boot time is impressive.  Under 30 seconds from powered off to login prompt, by my stopwatch.  Of that, 7 is spent on the bios screen, and another 5 at the grub menu.  All told, it takes about 15 seconds to boot, once the linux kernel starts loading.  No reason to worry about turning this thing off anymore&#8230; Just need to teach gnome to save my entire session on shutdown, and I&#8217;m good.  (I have <i>never</i> had any luck with hibernating a laptop, so I&#8217;m considering that a non-option)</p>
<p>So, install is done, and I&#8217;m pondering how aggressive I want/need to be about limiting writes to the drive.  I have no particular worry that I&#8217;m going to burn the drive out anytime soon, and my track record with hard drives has always been a little bumpy, so I&#8217;m not terribly worried about it.  By the time I <i>do</i> burn through all the writes on this drive, I&#8217;m sure that I won&#8217;t be using this laptop anymore.  It&#8217;ll probably last longer than a normal drive would.</p>
<p>I&#8217;m still getting set up and running it through it&#8217;s paces, and I still have to see what kind of an impact it has on my battery life through normal use (when I&#8217;m not draining the battery with tons of install related network traffic and CD spinning).  Overall, however, I&#8217;m <i>really</i> impressed with the difference this makes.</p>
]]></content:encoded>
			<wfw:commentRss>http://devcaffeine.com/2009/04/12/hardware-intel-x25-m-ssd/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Integration testing SSL with Cucumber</title>
		<link>http://devcaffeine.com/2009/02/16/integration-testing-ssl-with-cucumber/</link>
		<comments>http://devcaffeine.com/2009/02/16/integration-testing-ssl-with-cucumber/#comments</comments>
		<pubDate>Mon, 16 Feb 2009 18:50:27 +0000</pubDate>
		<dc:creator>cflipse</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[work]]></category>
		<category><![CDATA[cucumber]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ssl]]></category>

		<guid isPermaLink="false">http://devcaffeine.com/?p=81</guid>
		<description><![CDATA[Cucumber, for those who aren&#8217;t up to speed on the latest in testing hotness, is an integration testing framework for Ruby.  While it&#8217;s not strictly limited to integration testing Rails applications, that&#8217;s the context i use it in most of the time.
I saw a question on the rspec list recently asking about how you [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://github.com/aslakhellesoy/cucumber/wikis">Cucumber</a>, for those who aren&#8217;t up to speed on the latest in testing hotness, is an integration testing framework for Ruby.  While it&#8217;s not strictly limited to integration testing Rails applications, that&#8217;s the context i use it in most of the time.</p>
<p>I saw a question on the rspec list recently asking about how you test an SSL required page within cucumber, and I realized that I&#8217;ve had that, and even more cert-related chaos, figured out at $WORK, and that I should probably talk a little bit about it.</p>
<p>Simple scenario is that you&#8217;ve got some controller on your site that is supposed to only be accessible via https, and you want to make sure it behaves correctly in cucumber.  In your standard deployment scenario, mongrel never really sees anything about SSL; that&#8217;s all handled by Apache.  Apache will set some headers for you, which rails can check to determine if you&#8217;re using SSL.  Since you&#8217;re not testing with Apache at this testing level, you just need to set the relevant HTTP headers.</p>
<blockquote><p>
Given I am using HTTPS<br />
When I visit /payments<br />
Then I should see the payments page</p>
<p>Given I am not using HTTPS<br />
When I visit /payments<br />
Then I should see an SSL error page
</p></blockquote>
<p>If I&#8217;m using <a href="http://gitrdoc.com/brynary/webrat/tree/master/">webrat</a> (which is <i>highly</i> recommended here) this becomes as simple as setting a header value.  In recent versions of webrat, that boils down to:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">Given <span style="color:#006600; font-weight:bold;">/</span>I am using HTTPS<span style="color:#006600; font-weight:bold;">/</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  header<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;HTTPS&quot;</span>, <span style="color:#996600;">&quot;on&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
Given <span style="color:#006600; font-weight:bold;">/</span>I am <span style="color:#9966CC; font-weight:bold;">not</span> using HTTPS<span style="color:#006600; font-weight:bold;">/</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  <span style="color:#008000; font-style:italic;"># this space left intentionally blank</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>If you&#8217;re NOT using webrat, but still at the rails integration test level,  the call is a bit uglier</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  get <span style="color:#ff3333; font-weight:bold;">:show</span>, <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#ff3333; font-weight:bold;">:id</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">1234</span> <span style="color:#006600; font-weight:bold;">&#125;</span>, <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#ff3333; font-weight:bold;">:https</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'on'</span> <span style="color:#006600; font-weight:bold;">&#125;</span></pre></div></div>

<p>The <code>get</code> method at the integration test level actually takes a third argument, which is the HTTP headers set on that request.  At the functional / controller example level, the same method <i>might</i> work &#8212; I don&#8217;t know, I havn&#8217;t actually tested this at that level, instead I&#8217;ve just stubbed the <code>https?</code> method as needed.</p>
<p>Now, for bonus points.  At $WORK, I exist in one of those ideal closed environments where x509 authentication actually stands a <i>chance</i> of working.  That is, everyone gets a client certificate, which they send to us with the HTTPS request.  We check against an external service, see that the cert is good, and viola, we can pre-populate with all sorts of juicy user information.  Pipe dream on the internet, but it works well on an intranet. (having worked with this stuff, it&#8217;s no surprise to me at <i>all</i> that x509 client certs havn&#8217;t even managed to catch on with <i>banks</i> much less the general public &#8230;)</p>
<p>Apache takes care of checking the certificate, making sure it&#8217;s valid and well formed, and that it&#8217;s not in any CRL, and that it&#8217;s trusted.  Makes my life easier, at the Rails level, we just have to check against the external service and we&#8217;re off to the races.  And, happily, apache will pass things on in the headers.</p>
<blockquote><p>
Given I use the client certificate for &#8220;Joe&#8221;<br />
Then when I visit /administration<br />
I should be let in
</p></blockquote>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">Given <span style="color:#006600; font-weight:bold;">/</span>I use the client certificate <span style="color:#9966CC; font-weight:bold;">for</span> <span style="color:#996600;">&quot;(.*)&quot;</span><span style="color:#006600; font-weight:bold;">/</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>cert_user<span style="color:#006600; font-weight:bold;">|</span>
  <span style="color:#008000; font-style:italic;">#lookup or generate stub certificate information</span>
  header<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;X_CLIENT_CERT&quot;</span>, certificate.<span style="color:#9900CC;">certificate</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  header<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;X_CLIENT_DN&quot;</span>, certificate.<span style="color:#9900CC;">dn</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  header<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;HTTPS&quot;</span>, <span style="color:#996600;">&quot;on&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
  DirectoryService.<span style="color:#9900CC;">instance</span>.<span style="color:#9900CC;">stub</span>!<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:lookup</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">with</span><span style="color:#006600; font-weight:bold;">&#40;</span>certificate.<span style="color:#9900CC;">dn</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">and_return</span> certificate.<span style="color:#9900CC;">remote_xml</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>I&#8217;m hand-waving around some of the stubbing that would have to go on here, as far as generating dummy information goes, but the basic idea should be sound.  In this case, I&#8217;m stubbing the entire <code>DiectoryService.lookup</code> method for a particular DN, which I set in the headers, and returning &#8220;remote_xml&#8221; which is a stand in for the XML document that the remote system returns.  This lets me cut out the remote system, which wouldn&#8217;t appreciate being hit for all sorts of trash data every time the tests run, while still exercising most of the relevant internal code.</p>
<p>The general idea of an integration test is to see all of the pieces of the system working together.  At this point, Cucumber is exercising everything in the stack below Apache. Since certificates and x509 client certificates are largely dealt with <i>by</i> apache, we have to stub those ins and outs to work through the rest of the system.  The system is otherwise left unstubbed, and we check those integration points during manual testing.</p>
]]></content:encoded>
			<wfw:commentRss>http://devcaffeine.com/2009/02/16/integration-testing-ssl-with-cucumber/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Spec a FormBuilder in RSpec</title>
		<link>http://devcaffeine.com/2009/02/06/spec-a-formbuilder-in-rspec/</link>
		<comments>http://devcaffeine.com/2009/02/06/spec-a-formbuilder-in-rspec/#comments</comments>
		<pubDate>Fri, 06 Feb 2009 16:04:31 +0000</pubDate>
		<dc:creator>cflipse</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[rspec]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://devcaffeine.com/?p=62</guid>
		<description><![CDATA[yesterday, I started trying to work on a helper for generating a frequently-repeated calendar widget for the rails app at $WORK.  Being the good BDDer that I am, I launched off a new spec to test the form builder &#8212; and to attempt to backfill specs and cover up the evidence of my naughty [...]]]></description>
			<content:encoded><![CDATA[<p>yesterday, I started trying to work on a helper for generating a frequently-repeated calendar widget for the rails app at $WORK.  Being the good <abbr title="behavior driven development">BDD</abbr>er that I am, I launched off a new spec to test the form builder &#8212; and to attempt to backfill specs and cover up the evidence of my naughty non-testing past.</p>
<p>This is a form builder we use in a couple of heavily used forms on the site, so we &#8220;know&#8221; this works, aside from the new code I want to add.  But in moving in to backfill some specs, I discovered that, like many things relating to form builders in rails, it&#8217;s not the easiest thing to do, nor is it exactly well documented &#8230;</p>
<p>After a bit of digging, I finally managed to work out the right setup to get this going.  Documented below for posterity</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;"># spec/helper/random_form_builder_spec.rb</span>
  describe RandomFormBuilder <span style="color:#9966CC; font-weight:bold;">do</span>
    attr_reader <span style="color:#ff3333; font-weight:bold;">:builder</span>, <span style="color:#ff3333; font-weight:bold;">:helper</span>
    before <span style="color:#9966CC; font-weight:bold;">do</span>
      <span style="color:#0066ff; font-weight:bold;">@helper</span> = <span style="color:#CC00FF; font-weight:bold;">Object</span>.<span style="color:#9900CC;">extend</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#6666ff; font-weight:bold;">ActionView::Helpers::FormHelper</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#0066ff; font-weight:bold;">@object</span> = stub_model<span style="color:#006600; font-weight:bold;">&#40;</span>Random<span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#0066ff; font-weight:bold;">@builder</span> = RandomFormBuilder.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:random</span>, <span style="color:#0066ff; font-weight:bold;">@object</span>, <span style="color:#0066ff; font-weight:bold;">@helper</span>, <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span>, <span style="color:#0000FF; font-weight:bold;">nil</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>You can then spec as normal, calling methods on builder and verifying the result.</p>
<p>The tricky part is the constructor.</p>
<dl>
<dt>:random</dt>
<dd>This is the name of the object, by analog, the first argument of a  <tt>#form_for</tt></dd>
<dt>@object</dt>
<dd>The object you run with; where the form pulls field values from</dd>
<dt>@helper</dt>
<dd>this is the tricky one.  A form builder is really just a pass-through, decorating calls down to methods that live in FormHelper.  If you don&#8217;t have a template that defines the FormHelper methods, failures abound.</p>
<dt>{}</dt>
</dd>
<dd>Options for the FormBuilder.  Here, unused</dd>
<dt>nil</dt>
<dd>A proc</dd>
</dl>
]]></content:encoded>
			<wfw:commentRss>http://devcaffeine.com/2009/02/06/spec-a-formbuilder-in-rspec/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Voted</title>
		<link>http://devcaffeine.com/2008/11/04/voted/</link>
		<comments>http://devcaffeine.com/2008/11/04/voted/#comments</comments>
		<pubDate>Tue, 04 Nov 2008 14:45:41 +0000</pubDate>
		<dc:creator>cflipse</dc:creator>
				<category><![CDATA[life]]></category>
		<category><![CDATA[politics voting]]></category>

		<guid isPermaLink="false">http://devcaffeine.com/?p=60</guid>
		<description><![CDATA[Popped down the street to my place of voting.  Lines were nice and short &#8212; for my little chunk of the alphabet anyway.  There was another line that was nearly out the back door of the school, but I got right up to the registration desk.
When I got there, they asked if I [...]]]></description>
			<content:encoded><![CDATA[<p>Popped down the street to my place of voting.  Lines were nice and short &#8212; for my little chunk of the alphabet anyway.  There was another line that was nearly out the back door of the school, but I got right up to the registration desk.</p>
<p>When I got there, they asked if I wanted a paper ballot.  Yes, yes and yes!  For those who don&#8217;t know, those touch screen, paperless voting machines scare the hell out of us programmers, for a variety of reasons that have been well covered elsewhere.</p>
<p>Fill in a couple of bubbles with the provided pen (just a cheap bic) and run it through the scanning machine, and you&#8217;re done.  No muss, no fuss.  And it works if you lose power.</p>
<p>Now, off to spend the rest of the day pretending to work, instead of watching poll results like one of pavlov&#8217;s dogs &#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://devcaffeine.com/2008/11/04/voted/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>athas.org gone live</title>
		<link>http://devcaffeine.com/2008/02/05/athasorg-gone-live/</link>
		<comments>http://devcaffeine.com/2008/02/05/athasorg-gone-live/#comments</comments>
		<pubDate>Tue, 05 Feb 2008 15:24:06 +0000</pubDate>
		<dc:creator>cflipse</dc:creator>
				<category><![CDATA[darksun]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://devcaffeine.com/2008/02/05/athasorg-gone-live/</guid>
		<description><![CDATA[So, I finally pulled the trigger this weekend:  Athas.org is no longer written in PHP.
I&#8217;ve been working on a Rails based re-write on-and-off for the last few months, and we&#8217;ve been using the new site internally, as I work through various different approaches to the project.
By far, one of the trickiest things was figuring [...]]]></description>
			<content:encoded><![CDATA[<p>So, I finally pulled the trigger this weekend:  Athas.org is no longer written in PHP.</p>
<p>I&#8217;ve been working on a Rails based re-write on-and-off for the last few months, and we&#8217;ve been using the new site internally, as I work through various different approaches to the project.</p>
<p>By far, one of the trickiest things was figuring out how to deal with file distribution and versioning.  Shipping out files, PDFs primarily, is the entire reason for the site[0].  We tend to do multiple releases of the same product &#8212; beta/playtesting releases, followed by revisions, followed eventually by a &#8220;final&#8221; release.  (I put final in quotes, because we can always go back and revisit a product) &#8230;</p>
<p>I wrestled for a long time with how to manage this versioning issue; I&#8217;m still not necessarily satisified with the current solution.  Which is:  A product (which contains multiple files) is what holds the current status &#8212; Internal, Beta, Final, Under Review.  Files are associated with the product, but aren&#8217;t really tracked themselves.  They&#8217;re either public or private (for purely internal development files) and can be archived.  Basically, the product is a big bucket for all of the associated files, but the file records themselves are &#8220;dumb&#8221;.</p>
<p>It seems to work out well enough.  Time, I suppose, will tell.</p>
<p>[0] For the moment; I do plan on making a much more web-based interface for distributing 4e material in development.</p>
]]></content:encoded>
			<wfw:commentRss>http://devcaffeine.com/2008/02/05/athasorg-gone-live/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rubyconf</title>
		<link>http://devcaffeine.com/2007/10/30/rubyconf/</link>
		<comments>http://devcaffeine.com/2007/10/30/rubyconf/#comments</comments>
		<pubDate>Tue, 30 Oct 2007 16:06:56 +0000</pubDate>
		<dc:creator>cflipse</dc:creator>
				<category><![CDATA[life]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://devcaffeine.com/2007/10/30/rubyconf/</guid>
		<description><![CDATA[I&#8217;ll be heading to rubyconf this weekend, along with about half of my project team.
We&#8217;ll see if I actually blog anything, since I didn&#8217;t write a damned thing about Railsconf.
]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ll be heading to rubyconf this weekend, along with about half of my project team.</p>
<p>We&#8217;ll see if I actually blog anything, since I didn&#8217;t write a damned thing about Railsconf.</p>
]]></content:encoded>
			<wfw:commentRss>http://devcaffeine.com/2007/10/30/rubyconf/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Printing error in IE</title>
		<link>http://devcaffeine.com/2007/02/22/printing-error-in-ie/</link>
		<comments>http://devcaffeine.com/2007/02/22/printing-error-in-ie/#comments</comments>
		<pubDate>Thu, 22 Feb 2007 14:51:30 +0000</pubDate>
		<dc:creator>cflipse</dc:creator>
				<category><![CDATA[web]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://devcaffeine.com/2007/02/22/printing-error-in-ie/</guid>
		<description><![CDATA[So &#8230; that was fun.
Bug report gets filed about the application at work.  It seems that there&#8217;s an error that crops up when you print from IE.  The error, of course, being the characteristically unhelpful dialog of garbage that IE likes to throw at you.  After a bit of digging, it got [...]]]></description>
			<content:encoded><![CDATA[<p>So &#8230; <i>that</i> was fun.</p>
<p>Bug report gets filed about the application at work.  It seems that there&#8217;s an error that crops up when you print from IE.  The error, of course, being the characteristically unhelpful dialog of garbage that IE likes to throw at you.  After a bit of digging, it got even better.  I was <i>hoping</i> I&#8217;d be able to respond with something technically snotty, like &#8220;Do you have your printer installed?&#8221; </p>
<p>But, I managed to reproduce the bug.  Even better, I managed to narrow down it&#8217;s occurance.  It turned out that when you were logged in, the error would occur, but <b>only</b> if you were logged in.  Now that&#8217;s strange, since we&#8217;re using application level (cookie based) authentication &#8212; IE wouldn&#8217;t know anything about your logged in state.  Everything works fine in Firefox (of course, the browser with good diagnostic tools doesn&#8217;t show the problem &#8230;)</p>
<p>So, in stumbling around trying to find some clue as to what the problem is, I came across <a href="http://meyerweb.com/eric/thoughts/2005/08/29/reserved-id-values/">this</a> &#8230; It seems that <code>id="tags"</code> ends up conflicting with some builtin function in IE that&#8217;s used in printing.  Sure enough, we had a field with <code>&lt;input name="tags" id="tags" type="text"&gt;</code> that was wrapped inside an <code>if logged_in?</code> check. Renamed the field, and printing now works like it&#8217;s supposed to.</p>
<p>So, what could have been really long and painful was short circuited by a lucky find in my net searches.  No thanks to IE, it&#8217;s non-reserved reserved fields and opaque error messages.  Have I mentioned lately how much I hate IE?</p>
]]></content:encoded>
			<wfw:commentRss>http://devcaffeine.com/2007/02/22/printing-error-in-ie/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Oracle and rails 1.2.1</title>
		<link>http://devcaffeine.com/2007/02/08/rails-12-database-indexes/</link>
		<comments>http://devcaffeine.com/2007/02/08/rails-12-database-indexes/#comments</comments>
		<pubDate>Thu, 08 Feb 2007 23:09:53 +0000</pubDate>
		<dc:creator>cflipse</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[work]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://devcaffeine.com/2007/02/08/rails-12-database-indexes/</guid>
		<description><![CDATA[Grrr &#8230; So, in the course of updating to rails 1.2, it seems that the automagically generated names for database indexes were changed.  Went from &#8220;#{table}_#{columns}_index&#8221; to &#8220;index_#{table}_on_#{columns}&#8221; &#8230; an annoying little change that bumps me up against some sort of Oracle column name length ceiling.  And has the effect of probably breaking [...]]]></description>
			<content:encoded><![CDATA[<p>Grrr &#8230; So, in the course of updating to rails 1.2, it seems that the automagically generated names for database indexes were changed.  Went from &#8220;#{table}_#{columns}_index&#8221; to &#8220;index_#{table}_on_#{columns}&#8221; &#8230; an annoying little change that bumps me up against some sort of Oracle column name length ceiling.  And has the effect of probably breaking down migrations.</p>
<p>So, I&#8217;m gonna jump into the migrations and patch the existing add_index calls to specify a :name => value for all of the existing indexes, so that migrations will actually <i>work</i> and leave me with a database that matches the one in production &#8230;. </p>
<p>Figuring out why I suddenly couldn&#8217;t build my test database was not exactly the way I meant to spend the last hour &#8230;.</p>
<p><b>Update</b></p>
<p>Changeset 4768 is responsible for all this.  Apparently, to allow reverse parsing of the indexes from the index name.  Not alltogether a bad goal, but it still breaks down migrations &#8230;  (thanks to <a href=http://blog.twifkak.com/articles/2007/02/08/using-rails-migrations-add-remove_index-upgrading-to-1-2">Devin</a> for find this one)</p>
<p>And, I discovered another problem last night.  Seems that all of my text fields have a default value of &#8220;empy_clob()&#8221;  &#8230; not the function, but <i>that actual string</i>.  Sort of trashes one&#8217;s assumptions about unset fields.  Apparently (thanks Roy) this has been worked out in <a href="http://dev.rubyonrails.org/ticket/7344">ticket 7344</a> and already applied to Edge.  Some sort of thing that only applies to Oracle, because, of course, nobody tests Rails on Oracle, it&#8217;s all MySQL.  And I can&#8217;t really look into the patch attached to the ticket, because I keep getting Trac errors.  Shaping up to have been a lovely adventure &#8230;</p>
<p><b>update</b><br />
Finally got through to the site, and worked out a monkey patch to fix this.  For those of you who might be running with oracle, and can&#8217;t upgrade to Edge (gee, wonder why not) the patch is below.   This is a temporary thing, given that the ticket is closed, and will hopefully be fixed in 1.2.2 &#8230;<br />
[ruby]<br />
class ActiveRecord::ConnectionAdapters::OracleColumn<br />
  attr_writer :default<br />
end if defined? ActiveRecord::ConnectionAdapters::OracleColumn</p>
<p>class ActiveRecord::ConnectionAdapters::OracleAdapter<br />
  def quote(value, column = nil) #:nodoc:<br />
    if value &#038;&#038; column &#038;&#038; [:text, :binary].include?(column.type)<br />
      %Q{empty_#{ column.sql_type.downcase rescue &#8216;blob&#8217; }()}<br />
    else<br />
       super<br />
    end<br />
  end</p>
<p>  alias columns_orig columns<br />
  def columns(*a)<br />
    columns_orig(*a).each do |col|<br />
      col.default = nil if col.default =~ /^(null|empty_[bc]lob())$/i<br />
    end<br />
  end<br />
end if defined? ActiveRecord::ConnectionAdapters::OracleAdapter<br />
[/ruby]</p>
<p>This appears to do the trick &#8230; a dump of the test schema no longer defaults all of our text columns to &#8220;empty_clob()&#8221; and tests are again passing  &#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://devcaffeine.com/2007/02/08/rails-12-database-indexes/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Railsconf 2007</title>
		<link>http://devcaffeine.com/2007/02/08/railsconf-2007/</link>
		<comments>http://devcaffeine.com/2007/02/08/railsconf-2007/#comments</comments>
		<pubDate>Thu, 08 Feb 2007 17:07:49 +0000</pubDate>
		<dc:creator>cflipse</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[conferences]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://devcaffeine.com/2007/02/08/railsconf-2007/</guid>
		<description><![CDATA[I&#8217;m signed up for railsconf 2007, which runs in late May of 2007, up in Portland, Oregon.  Looks like I&#8217;m one of about 10 NoVaRUG members going.
]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m signed up for <a href="http://conferences.oreillynet.com/rails/">railsconf 2007</a>, which runs in late May of 2007, up in Portland, Oregon.  Looks like I&#8217;m one of about 10 <a href="http://novarug.org">NoVaRUG</a> members going.</p>
]]></content:encoded>
			<wfw:commentRss>http://devcaffeine.com/2007/02/08/railsconf-2007/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
