<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" version="2.0">

<channel>
	<title>Dr Nic</title>
	
	<link>http://drnicwilliams.com</link>
	<description>Ruby makes Rails, Javascript makes Ajax, Dr Nic makes Magic</description>
	<lastBuildDate>Sun, 05 Jul 2009 03:35:36 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/DrNic" type="application/rss+xml" /><feedburner:emailServiceId xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">DrNic</feedburner:emailServiceId><feedburner:feedburnerHostname xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://feedburner.google.com</feedburner:feedburnerHostname><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
		<title>Proof of Doctorhoodedness</title>
		<link>http://drnicwilliams.com/2009/07/05/proof-of-doctorhoodedness/</link>
		<comments>http://drnicwilliams.com/2009/07/05/proof-of-doctorhoodedness/#comments</comments>
		<pubDate>Sun, 05 Jul 2009 03:34:42 +0000</pubDate>
		<dc:creator>Dr Nic</dc:creator>
				<category><![CDATA[For Hire]]></category>
		<category><![CDATA[Speaking]]></category>

		<guid isPermaLink="false">http://drnicwilliams.com/?p=564</guid>
		<description><![CDATA[At recent conferences, other speakers have taken up an amusing new sport: ask Dr Nic to prove he&#8217;s a real doctor. Traditionally my reply is &#8220;I&#8217;m just not that clever to make it up.&#8221; Undeterred the personal challenges continued. At JAOO in Sydney and Brisbane (my home town) Glenn Vanderburg even challenged me to bring [...]]]></description>
			<content:encoded><![CDATA[<p>At recent conferences, other speakers have taken up an amusing new sport: ask Dr Nic to prove he&#8217;s a real doctor. Traditionally my reply is &#8220;I&#8217;m just not that clever to make it up.&#8221; Undeterred the personal challenges continued. At JAOO in Sydney and Brisbane (my home town) <a href="http://www.vanderburg.org/Blog">Glenn Vanderburg</a> even challenged me to bring my thesis to the conference. I accepted this challenge but then promptly forgot.</p>
<p>Today I actually found the thing. It&#8217;s red. The colour of the binding was my only chance to impose some sense of personalisation.</p>
<p>The title was <strong>The Morphing Architecture: Runtime Evolution of Distribute Applications.</strong> The abstract is too long to be bothered reciting here. Succinctly, as best I remember it, it could be:</p>
<blockquote><p>If you have distributed applications (components owned by multiple organisations) that run 24&#215;7, and you need to upgrade behaviour, how the hell do you sequence the live upgrade?</p></blockquote>
<div class="thumbnail"><a href="http://skitch.com/drnic/bst6h/the-thesis-cover"><img src="http://img.skitch.com/20090705-r57qnqxhbas51hr44fn5p2err8.preview.jpg" alt="the thesis: cover" /></a></div>
<p><br/></p>
<div class="thumbnail"><a href="http://skitch.com/drnic/bst67/the-thisis-submission"><img src="http://img.skitch.com/20090705-c63dw6t2fq16m817nite8n7dkc.preview.jpg" alt="the thisis: submission" /></a></div>
<p><br/></p>
<div class="thumbnail"><a href="http://skitch.com/drnic/bst66/the-thesis-acceptance"><img src="http://img.skitch.com/20090705-mekj64x9jbpcx7aqi5xx9cbe2e.preview.jpg" alt="the thesis: acceptance" /></a></div>
<p><br/></p>
<p>Like most PhDs, it is a project of theoretical usefulness, but not significantly close to any commercial interests so that some large company doesn&#8217;t solve all your interesting problems before you get around to writing a 200 page thesis.</p>
<p>In 220+ pages, the only interesting parts (to me now) are from my Acknowledgments section:</p>
<blockquote><p>As [my parent's] eldest of two sons, I am that person in each family who is the &#8220;first experiment in parenting.&#8221;</p></blockquote>
<p>The Acknowledgements section ended with this:</p>
<blockquote><p>And finally [thanks]&#8230;<br />
To all the people who ever came up to me&#8230;<br />
&nbsp;&nbsp;&nbsp;&nbsp;Asked me how my thesis was going&#8230;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Laughed hideously&#8230;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;And ran off.</p></blockquote>
<p>Ah, memories.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/DrNic?a=OJrYBs_5TWY:j6iXfdFepPU:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/DrNic?i=OJrYBs_5TWY:j6iXfdFepPU:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/DrNic?a=OJrYBs_5TWY:j6iXfdFepPU:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/DrNic?i=OJrYBs_5TWY:j6iXfdFepPU:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/DrNic?a=OJrYBs_5TWY:j6iXfdFepPU:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/DrNic?i=OJrYBs_5TWY:j6iXfdFepPU:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://drnicwilliams.com/2009/07/05/proof-of-doctorhoodedness/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Nifty Threaded IM Chat within Gtalk/Gmail Chat</title>
		<link>http://drnicwilliams.com/2009/07/04/nifty-threaded-im-chat-within-gtalkgmail-chat/</link>
		<comments>http://drnicwilliams.com/2009/07/04/nifty-threaded-im-chat-within-gtalkgmail-chat/#comments</comments>
		<pubDate>Fri, 03 Jul 2009 20:00:54 +0000</pubDate>
		<dc:creator>Dr Nic</dc:creator>
				<category><![CDATA[Announcement]]></category>
		<category><![CDATA[Greasemonkey]]></category>
		<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://drnicwilliams.com/?p=550</guid>
		<description><![CDATA[Ever had IM chats where a conversation splits into multiple topics? You&#8217;ll be able to follow along, intelligently piecing together which-message-goes-with-which-topic, until the following scenario inevitably occurs:

  me: What's on this weekend? Going to the football?
  me: Are you and Jackie still seeing each other?
  you: Yes
  me: Eh? Yes - [...]


Related posts:<ol><li><a href='http://drnicwilliams.com/2009/06/07/tdd-for-greasemonkey-scripts-and-introducing-ninja-search-js/' rel='bookmark' title='Permanent Link: TDD for Greasemonkey scripts; and introducing Ninja Search JS'>TDD for Greasemonkey scripts; and introducing Ninja Search JS</a> <small>&#8220;this article shows how I used test-driven development tools and...</small></li><li><a href='http://drnicwilliams.com/2006/09/11/prototype-call-dollar-on-string/' rel='bookmark' title='Permanent Link: Prototype: &#8220;element-id&#8221;.$() instead of $(&#8217;element-id&#8217;)'>Prototype: &#8220;element-id&#8221;.$() instead of $(&#8217;element-id&#8217;)</a> <small>The Prototype library gives us the $() operation for converting...</small></li><li><a href='http://drnicwilliams.com/2006/08/29/yehuda-katz-starts-a-blog/' rel='bookmark' title='Permanent Link: Yehuda Katz starts a blog'>Yehuda Katz starts a blog</a> <small>Yehuda is the creator of autoDB &#8211; the wonderful admin...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>Ever had IM chats where a conversation splits into multiple topics? You&#8217;ll be able to follow along, intelligently piecing together which-message-goes-with-which-topic, until the following scenario inevitably occurs:</p>
<pre>
  me: What's on this weekend? Going to the football?
  me: Are you and Jackie still seeing each other?
  you: Yes
  me: Eh? Yes - football or yes to Jackie?
</pre>
<p>That is, eventually the messages become ambiguous as to which topic they go to.</p>
<h3 id="the_solution">The solution</h3>
<p><img alt="" src="http://img.skitch.com/20090703-js9ahnd44qmq6ue8ya8fdiryau.preview.jpg" title="Threaded example" class="alignright" width="265" height="311" /></p>
<p>A <a href="http://designbyelle.com/" target="_blank">designer friend of mine</a> and I discovered this problem every day as we talked about different projects and completely unrelated things. Ironically, this led to a new inline topic: <em>what if each thread/topic could be visually identifiable?</em></p>
<p>Perhaps we could just modify one of the HTML-based IM clients, such as Gmail Chat/Gtalk (same could be done for Facebook&#8217;s IM client I guess), and use twitter-esque #tags to identify threads (no fancy jabber protocol changes). If we did this we could prototype something, see if it was a useful way to solve the multi-threaded IM chat problem. <em>I mean, how hard could it be?</em></p>
<h3 id="prototype_greasemonkey_script_firefox_safari">Prototype: Greasemonkey Script (Firefox + Safari)</h3>
<p>Since I have a thing for <a href="https://addons.mozilla.org/en-US/firefox/addon/748">Greasemonkey</a> scripts at the moment (which also run on Safari/<a href="http://mailplaneapp.com/">Mailplane</a> using <a href="http://8-p.info/greasekit/">GreaseKit</a>), it immediately came to mind as a way to hack into Gmail&#8217;s Chat.</p>
<p>After installing Greasemonkey or GreaseKit, <a href="http://drnic.github.com/threaded-gtalk-gmscript/dist/threaded_gtalk.user.js">click to install the extension</a> for Gmail&#8217;s inline Jabber/Gtalk chat.</p>
<p>Restart Gmail, fire up a chat to someone (for example, complain of bugs to <a href="drnicwilliams@gmail.com">drnicwilliams@gmail.com</a>) and try the following:</p>
<pre>
  greasemonkey is fun
  gmailchat is very nifty and hackable
  its cool that I can annotate gmail chat with #greasemonkey
  no way, #gmailchat is colour highlighted
  sexy
</pre>
<p>Which will look something like the picture at the top.</p>
<p>Sadly, I&#8217;m talking to myself here. QA testing can be a lonely man&#8217;s sport.</p>
<h3 id="success">Success?</h3>
<p>Technically, yes. I mean, it works. You use a different #tag and it will be a different colour. </p>
<p>It was a prototype to determine if using #tags was a friendly, non-invasive way to identify threads. And it kind-of works, as long as you remember to use them. In IM, less-so than twitter, it seems unnatural to add #tags, or prefix a keyword with a # character. But, in time, I think you&#8217;d learn to do it to get the benefit.</p>
<p>The bigger issue is that I don&#8217;t want to use Gmail&#8217;s Chat for my IM client. I didn&#8217;t find the source to Apple&#8217;s iChat client lying around on github; and I really don&#8217;t want to go hacking Cocoa/Win32 apps just to try out an idea. A greasemonkey script is an awesome way to try out something like this.</p>
<p>Now, if everyone could just make this idea of #tagging intra-IM conversation threads/topics, then perhaps 5 years from now Apple will pick it up and implement it in iChat. Any of the more accessible, open source clients could implement this too. Probably a lot sooner.</p>
<h3 id="known_bugs">Known bugs</h3>
<p>In Mailplane (though not Safari), the 2nd+ threads aren&#8217;t coloured differently. I&#8217;m having trouble fixing this at the moment due to an <a href="http://github.com/relevance/blue-ridge/issues/#issue/13">issue</a> in <a href="http://github.com/relevance/blue-ridge">blue-ridge</a>&#8217;s setup on Safari.</p>
<p>It currently shares thread colouring across all open chat windows. Probably not a big issue. I forgot to consider multiple chat windows when I wrote the code.</p>
<p>When you use a new #tag, it only finds one previous message with &#8216;tag&#8217; in it. Really, once a word is #tagged, then any message containing &#8216;tagged&#8217; could be included in the thread.</p>
<h3 id="quirky_thing_i_learnt">Quirky thing I learned</h3>
<p>You can&#8217;t really use the <a href="http://docs.jquery.com/Plugins/livequery">jquery.livequery.js</a> plugin to watch for DOM changes in Greasemonkey scripts. It works by hooking into jQuery DOM modification calls, such as <code>append</code> and <code>prepend</code>, to know instantly that something has changed. Gmail, and many other websites, don&#8217;t use jQuery. So it doesn&#8217;t work. Even though your beautiful unit tests say it will. Use <code>setInterval</code> instead.</p>
<h3 id="project_status">Project status</h3>
<p>It&#8217;s finished. It was a prototype to try out an idea. It has unit tests, it works and if you want to use it for your own research project or &#8220;oh oh oh how cool would it be if&#8230;?&#8221; hackathon, go for gold with the code base. Rename it, abuse it. Have fun.</p>
<p>Source on github: <a href="http://github.com/drnic/threaded-gtalk-gmscript/">http://github.com/drnic/threaded-gtalk-gmscript/</a></p>
<h3 id="a_pleasant_word_from_my_sponsor">A pleasant word from my sponsor</h3>
<p>When I was hacking on Threaded Gtalk GMScript, I wasn&#8217;t doing something more productive at my firm <a href="http://mocra.com/">Mocra</a>. Ironically, you could reward my wayward efforts by considering us for your awesome new Rails or iPhone project. It will make you happy. Especially if its chock-full of JavaScript.</p>


<p>Related posts:<ol><li><a href='http://drnicwilliams.com/2009/06/07/tdd-for-greasemonkey-scripts-and-introducing-ninja-search-js/' rel='bookmark' title='Permanent Link: TDD for Greasemonkey scripts; and introducing Ninja Search JS'>TDD for Greasemonkey scripts; and introducing Ninja Search JS</a> <small>&#8220;this article shows how I used test-driven development tools and...</small></li><li><a href='http://drnicwilliams.com/2006/09/11/prototype-call-dollar-on-string/' rel='bookmark' title='Permanent Link: Prototype: &#8220;element-id&#8221;.$() instead of $(&#8217;element-id&#8217;)'>Prototype: &#8220;element-id&#8221;.$() instead of $(&#8217;element-id&#8217;)</a> <small>The Prototype library gives us the $() operation for converting...</small></li><li><a href='http://drnicwilliams.com/2006/08/29/yehuda-katz-starts-a-blog/' rel='bookmark' title='Permanent Link: Yehuda Katz starts a blog'>Yehuda Katz starts a blog</a> <small>Yehuda is the creator of autoDB &#8211; the wonderful admin...</small></li></ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/DrNic?a=fxw_KuHc_mk:ipGXFJSG45A:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/DrNic?i=fxw_KuHc_mk:ipGXFJSG45A:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/DrNic?a=fxw_KuHc_mk:ipGXFJSG45A:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/DrNic?i=fxw_KuHc_mk:ipGXFJSG45A:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/DrNic?a=fxw_KuHc_mk:ipGXFJSG45A:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/DrNic?i=fxw_KuHc_mk:ipGXFJSG45A:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://drnicwilliams.com/2009/07/04/nifty-threaded-im-chat-within-gtalkgmail-chat/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Refer us a client for fun and profit</title>
		<link>http://drnicwilliams.com/2009/06/30/refer-us-a-client-for-fun-and-profit/</link>
		<comments>http://drnicwilliams.com/2009/06/30/refer-us-a-client-for-fun-and-profit/#comments</comments>
		<pubDate>Tue, 30 Jun 2009 00:10:02 +0000</pubDate>
		<dc:creator>Dr Nic</dc:creator>
				<category><![CDATA[Announcement]]></category>
		<category><![CDATA[Mocra]]></category>

		<guid isPermaLink="false">http://drnicwilliams.com/?p=545</guid>
		<description><![CDATA[There&#8217;s only so many hours in the day and only so many technologies people can be awesome at. So sometimes there are projects that developers can&#8217;t do themselves. Either the scope is too big, the timeframe to urgent, or it falls outside their areas of expertise. Or you&#8217;ve already got yourself a sexy job and [...]


Related posts:<ol><li><a href='http://drnicwilliams.com/2009/04/06/easy-scheduling-by-location-tasks-and-people-a-case-study-of-a-client-application-from-mocra/' rel='bookmark' title='Permanent Link: Easy scheduling by location, tasks and people &#8211; a case study of a client application from Mocra'>Easy scheduling by location, tasks and people &#8211; a case study of a client application from Mocra</a> <small> UPDATE: Orchestrate was reported in TechCrunch Several years ago...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>There&#8217;s only so many hours in the day and only so many technologies people can be awesome at. So sometimes there are projects that developers can&#8217;t do themselves. Either the scope is too big, the timeframe to urgent, or it falls outside their areas of expertise. Or you&#8217;ve already got yourself a sexy job and you just don&#8217;t need the work. If this situation ever happens to you I would love for you to ask me if I can help with the work you can&#8217;t do or don&#8217;t want.</p>
<p>Hopefully you can find good reasons to refer clients to myself and the crack-squad at <a href="http://mocra.com/">Mocra</a>. For example, we have had two client Rails projects appear in TechCrunch in 2009 (<a href="http://www.techcrunch.com/2009/04/08/orchestrate-saas-task-management-for-service-and-maintenance-businesses/">Orchestrate</a> and <a href="http://www.techcrunch.com/2009/05/25/connect-your-thoughts-to-the-mindex-with-imindi-private-beta-invites/">Imindi</a>). Also, our Oakley Surf Report iPhone app has appeared in Apple&#8217;s own TV commercials for the AppStore (first 10 secs of video below).</p>
<p><object width="560" height="340"><param name="movie" value="http://www.youtube.com/v/p9yYdGvCA3M&amp;hl=en&amp;fs=1&amp;rel=0&amp;color1=0x006699&amp;color2=0x54abd6"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/p9yYdGvCA3M&amp;hl=en&amp;fs=1&amp;rel=0&amp;color1=0x006699&amp;color2=0x54abd6" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="560" height="340"></embed></object></p>
<p>In the past, we&#8217;ve received lots of referrals but rarely have we gone beyond saying &#8220;thank you&#8221;. We think its time to put a dollar value on all our future &#8220;thank you&#8221;s. They are incredibly valuable to us, so we&#8217;d like to share some of the value.</p>
<p>To say thanks to you, we want to share 10% of the total consulting fees for any new client work as a referral incentive.</p>
<p>If we can help a friend or client of yours and we receive $10k in fees, then we&#8217;ll give you 10% or $1k. If we receive $250k, then we&#8217;ll give you $25k.</p>
<h2 id="how_to_refer">How to refer?</h2>
<p>There&#8217;s no wrong way to ping us with a referral for a client we can potentially help.</p>
<p>One approach is to email me at <a href="mailto:referrals@mocra.com">referrals@mocra.com</a> or on Skype at <code>nicwilliams</code>. We can quickly check if we&#8217;re able to help with the project, discuss anything interesting, and then contact the client. </p>
<p>Alternatively, you can give your friend/client our enquiry emails (<a href="mailto:rails@mocra.com">rails@mocra.com</a> or <a href="mailto:iphone@mocra.com">iphone@mocra.com</a>), or skype at <code>nicwilliams</code>. Then you claim the referral via an email to <a href="mailto:referrals@mocra.com">referrals@mocra.com</a>.</p>
<p>In the medium-term future, we&#8217;ll release a Referral Management system so you can see the status of your referrals, payments etc. Until then, use <a href="mailto:referrals@mocra.com">email</a> to ask questions.</p>
<h2 id="receiving_payments">Receiving payments</h2>
<p>In order to distribute payments to you, could you please email us at <a href="mailto:referrals@mocra.com">referrals@mocra.com</a> with your contact details and either PayPal address or international banking details. Telepathic transfer of banking details nor referrals isn&#8217;t guaranteed to work. Emails are much more likely to succeed.</p>
<p>You are providing us with a valued service of marketing/advertising. We think you are awesome and will invite you to Christmas parties. Australian GST-registered businesses will have 10% GST added to payments.</p>
<h2 id="basic_referral_rules">Basic referral rules</h2>
<p>Whilst we continue to draw up the fancy pants, small-print rules, some of the basic ones are:</p>
<ul>
<li>We&#8217;ll send out payments within a month of receipt of client payments. </li>
<li>We don&#8217;t think you&#8217;re a bad person if your referral doesn&#8217;t hire us.</li>
<li>In the event there is a dispute by 2+ claimants for a referral, the decision by me is final.</li>
<li>You cannot work with or be a family member of Mocra nor the referred client.</li>
<li>You are providing Mocra with a service. It makes us very happy. So we&#8217;re paying you for it.</li>
<li>You may be required to send us a Tax Invoice for each amount payable (templates available).</li>
<li>You can give away your referral income to charity or use it to fund open source development.</li>
<li>We think you are awesome for reading this far, even if you never refer any work to us. Thanks for caring.</li>
</ul>
<h2 id="happy_developers">Happy developers</h2>
<p>It makes us very happy to be contacted by new clients who tell us &#8220;I was told I should contact you.&#8221; Hopefully we can thank every referrer explicitly from now on. Thanks in advance.</p>


<p>Related posts:<ol><li><a href='http://drnicwilliams.com/2009/04/06/easy-scheduling-by-location-tasks-and-people-a-case-study-of-a-client-application-from-mocra/' rel='bookmark' title='Permanent Link: Easy scheduling by location, tasks and people &#8211; a case study of a client application from Mocra'>Easy scheduling by location, tasks and people &#8211; a case study of a client application from Mocra</a> <small> UPDATE: Orchestrate was reported in TechCrunch Several years ago...</small></li></ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/DrNic?a=mZ100MrmMUc:5kDZDpwSdiU:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/DrNic?i=mZ100MrmMUc:5kDZDpwSdiU:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/DrNic?a=mZ100MrmMUc:5kDZDpwSdiU:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/DrNic?i=mZ100MrmMUc:5kDZDpwSdiU:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/DrNic?a=mZ100MrmMUc:5kDZDpwSdiU:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/DrNic?i=mZ100MrmMUc:5kDZDpwSdiU:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://drnicwilliams.com/2009/06/30/refer-us-a-client-for-fun-and-profit/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>TDD for Greasemonkey scripts; and introducing Ninja Search JS</title>
		<link>http://drnicwilliams.com/2009/06/07/tdd-for-greasemonkey-scripts-and-introducing-ninja-search-js/</link>
		<comments>http://drnicwilliams.com/2009/06/07/tdd-for-greasemonkey-scripts-and-introducing-ninja-search-js/#comments</comments>
		<pubDate>Sat, 06 Jun 2009 23:00:40 +0000</pubDate>
		<dc:creator>Dr Nic</dc:creator>
				<category><![CDATA[Announcement]]></category>
		<category><![CDATA[Greasemonkey]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://drnicwilliams.com/?p=523</guid>
		<description><![CDATA[&#8220;this article shows how I used test-driven development tools and processes on a Greasemonkey script.&#8221; Though it also includes free ninjas.

When I do online banking I need to select from a large list of other people&#8217;s bank accounts to which I might like to transfer money too. It is the massive drop down list that [...]


Related posts:<ol><li><a href='http://drnicwilliams.com/2009/07/04/nifty-threaded-im-chat-within-gtalkgmail-chat/' rel='bookmark' title='Permanent Link: Nifty Threaded IM Chat within Gtalk/Gmail Chat'>Nifty Threaded IM Chat within Gtalk/Gmail Chat</a> <small>Ever had IM chats where a conversation splits into multiple...</small></li><li><a href='http://drnicwilliams.com/2008/11/10/to-webkit-or-not-to-webkit-within-your-iphone-app/' rel='bookmark' title='Permanent Link: To WebKit or not to WebKit within your iPhone app?'>To WebKit or not to WebKit within your iPhone app?</a> <small> I know HTML. Its on my CV. Expert level....</small></li><li><a href='http://drnicwilliams.com/2008/10/31/newgem-100-all-thanks-to-cucumber/' rel='bookmark' title='Permanent Link: newgem 1.0.0 all thanks to Cucumber'>newgem 1.0.0 all thanks to Cucumber</a> <small>The New Gem Generator (newgem) was exciting, moderately revolutionary, and...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p><em>&#8220;this article shows how I used test-driven development tools and processes on a Greasemonkey script.&#8221;</em> Though it also includes free ninjas.</p>
<div class="thumbnail"><a href="http://skitch.com/drnic/b19kn/1-long-drop-downs-hate-humans"><img style="width: 200px; float: right;" src="http://img.skitch.com/20090605-fjjyx32iidgw1jtq1kbys8tbr7.preview.jpg" alt="1. Long drop downs hate humans" /></a></div>
<p>When I do online banking I need to select from a large list of other people&#8217;s bank accounts to which I might like to transfer money too. It is the massive drop down list that I must scroll through that I wish to raise issue with today. The problem of having to give other people money is probably a different discussion.</p>
<p>And take those time-zone selector drop down lists, for example, the massively long list rendered by Rails&#8217; <code>time_zone_select</code> helper. Granted, I am thankful for you letting me choose my timezone in your web app. Though for those of us not living in the USA we must hunt for our closest city in the list. Dozens of locations, ordered by time zone and not the name of the city (see adjacent image). Unfortunately you can&#8217;t easily type a few letters of your current city to find it. Rather, you have to scroll. And if you live in the GMT+1000 time zone group (Eastern Australia), you have to scroll all the way to the bottom.</p>
<div class="thumbnail"><a href="http://skitch.com/drnic/b19kx/5-choose-from-a-small-list"><img style="width: 200px; float: right;" alt="5. Choose from a small list" src="http://img.skitch.com/20090605-t82418x1j76w4fm8s44cec9cr3.preview.jpg"/></a></div>
<p>So I got to thinking I&#8217;d like a <a href="http://www.greasespot.net/">Greasemonkey</a> (for Firefox) or <a href="http://8-p.info/greasekit/" title="GreaseKit - User Scripting for all WebKit applications">GreaseKit</a> (for Safari) script that automatically converted all ridiculously long HTML drop down lists into a sexy, autocompletion text field. You could then type in &#8220;bris&#8221; and be presented with &#8220;(GMT+1000) Brisbane&#8221;, or given the less amusing banking scenario then I could type &#8220;ATO&#8221; and get the bank account details for the Australian Tax Office.</p>
<p><strong>I mean, how hard could it be?</strong></p>
<p>This article is two things: an introduction to Ninja Search JS which gives a friendly ninja for every drop down field to solve the above problem. Mostly, the rest of this article shows how I used test-driven development tools and processes on a Greasemonkey script.</p>
<h2 id="introducing_ninja_search_js">Introducing Ninja Search JS</h2>
<div class="thumbnail"><a href="http://drnic.github.com/ninja-search-js/"><img src="http://img.skitch.com/20090606-xy454r3b8u29hsykjs1gfhu259.jpg" alt="Ninja Search JS banner" /></a></div>
<p>Click the banner to learn about and install the awesome Ninja Search JS. It includes free ninjas.</p>
<p>Currently it is a script for Greasemonkey (FireFox) or GreaseKit (Safari). It could be dynamically installed as necessary via a bookmarklet. I just haven&#8217;t done that yet. It could also be a FireFox extension so it didn&#8217;t have to fetch remote CSS and JS assets each time.</p>
<p>Ninja Search JS uses <a href="http://github.com/rmm5t/liquidmetal">liquidmetal</a> and <a href="http://rmm5t.github.com/jquery-flexselect">jquery-flexselect</a> projects created by <a href="http://www.emacsblog.org/">Ryan McGeary</a>.</p>
<p>Most importantly of all, I think, is that I wrote it all using TDD. That is, tests first. I don&#8217;t think this is an erroneous statement given the relatively ridiculous, and unimportant nature of Ninja Search JS itself.</p>
<h2 id="tdd_for_greasemonkey_scripts">TDD for Greasemonkey scripts</h2>
<p>I love the simple idea of Greasemonkey scripts: run a script on a subset of all websites you visit. You can&#8217;t easily do this on desktop apps, which is why web apps are so awesome &#8211; its just HTML inside <em>your</em> browser, and with Greasemoney or browser extensions you can hook into that HTML, add your own DOM, remove DOM, add events etc.</p>
<p>But what stops me writing more of them is that once you cobble together a script, you push it out into the wild and then bug reports start coming back. Or feature requests, preferably. I&#8217;d now have a code base without any test coverage, so each new change is likely to break something else. Its also difficult to isolate bugs across different browsers, or in different environments (running Ninja Search JS in a page that used <a href="http://www.prototypejs.org/">prototypejs</a> originally failed), without a test suite.</p>
<p>And the best way to get yourself a test suite is to write it before you write the code itself. I believe this to be true because I know it sucks writing tests <em>after</em> I&#8217;ve writing the code.</p>
<p>I mostly focused on unit testing this script rather than integration testing. With integration testing I&#8217;d need to install the script into Greasemonkey, then display some HTML, then run the tests. I&#8217;ve no idea how&#8217;d I&#8217;d do that.</p>
<div class="thumbnail"><a href="http://skitch.com/drnic/bunyt/testing-running"><img style="width: 200px; float: right;" src="http://img.skitch.com/20090606-d7usrgr8i1qjs3ji45xfkra3hs.preview.jpg" alt="testing running" /></a></div>
<p>But I do know how to unit test JavaScript, and if I can get good coverage of the core libraries, then I should be able to slap the Greasemonkey specific code on top and do manual QA testing after that. The Greasemonkey specific code shouldn&#8217;t ever change much (it just loads up CSS and more JS code dynamically) so I feel ok about this approach.</p>
<p>For this project I used <a href="http://github.com/nkallen/screw-unit/tree/master">Screw.Unit</a> for the first time (via a modified version of the <a href="http://github.com/relevance/blue-ridge/tree/master">blue-ridge rails plugin</a>) and it was pretty sweet. Especially being able to run single tests or groups of tests in isolation.</p>
<h3 id="project_structure">Project structure</h3>
<div class="thumbnail"><a href="http://skitch.com/drnic/bunbd/summary-of-project-structure"><img src="http://img.skitch.com/20090606-x7h9yhp9s3pt6y86r5q1mm1wf8.jpg" alt="summary of project structure" /></a></div>
<p>All the JavaScript source &#8211; including dependent libraries such as jquery and jquery-flexselect &#8211; was put into the <code>public</code> folder. This is because I needed to be able to load the files into the browser without using <code>file://</code> protocol (which was failing for me). So, I moved the entire project into my Sites folder, and added the project as a Passenger web app. I&#8217;m ahead of myself, but there is a reason I went with <code>public</code> for the JavaScript + assets folder.</p>
<p>In <code>vendor/plugins</code>, The blue-ridge rails plugin is a composite of several JavaScript libraries, including the test framework Screw.Unit, and a headless rake task to run all the tests without browser windows popping up everywhere. In my code base blue-ridge is slightly modified since my project doesn&#8217;t look like a rails app.</p>
<p>Our tests go in <code>spec</code>. In a Rails app using blue-ridge, they&#8217;d go in <code>spec/javascripts</code>, but since JavaScript is all we have in this project I&#8217;ve flattened the spec folder structure.</p>
<p>The <code>website</code> folder houses the github pages website (a git submodule to the gh-pages branch) and also the greasemonkey script and its runtime JavaScript, CSS, and ninja image assets.</p>
<h3 id="a_simple_first_test">A simple first test</h3>
<p>For the Ninja Search JS I wanted to add the little ninja icon next to every <code>&lt;select&gt;</code> element on every page I ever visited. When the icon is clicked, it would convert the corresponding <code>&lt;select&gt;</code> element into a text field with fantastical autocompletion support.</p>
<p>For Screw.Unit, the first thing we need is a <code>spec/ninja_search_spec.js</code> file for the tests, and an HTML fixture file that will be loaded into the browser. The HTML file&#8217;s name must match to the corresponding test name, so it must be <code>spec/fixtures/ninja_search.html</code>.</p>
<p>For our first test we want the cute ninja icon to appear next to <code>&lt;select&gt;</code> drop downs.</p>
<pre lang="javascript">
require("spec_helper.js");
require("../public/ninja_search.js"); // relative to spec folder

Screw.Unit(function(){
  describe("inline activation button", function(){
    it("should display NinjaSearch image button", function(){
      var button = $('a.ninja_search_activation');
      expect(button.size()).to(be_gte, 1);
    });
  });
});
</pre>
<p>The <a href="http://github.com/karnowski/blue-ridge-tmbundle/tree/master">Blue Ridge textmate bundle</a> makes it really easy to create the <code>describe</code> (<code>des</code>) and <code>it</code> (<code>it</code>) blocks, and <code>ex</code> expands into a useful <code>expects(...).to(matcher, ...)</code> snippet.</p>
<p>The two ellipses are values that are compared by a matcher. Matchers are available via global names such as <code>equals</code>, <code>be_gte</code> (greater than or equal) etc. See the <a href="http://github.com/nathansobo/screw-unit/blob/master/javascript/lib/screw/matchers.js">matchers.js</a> file for the default available matchers.</p>
<p>The HTML fixture file is important in that it includes the sample HTML upon which the tests are executed.</p>
<pre lang="html">
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;

&lt;head&gt;
  &lt;title&gt;Ninja Search | JavaScript Testing Results&lt;/title&gt;
  &lt;link rel="stylesheet" href="screw.css" type="text/css" charset="utf-8" /&gt;
  &lt;script src="../../vendor/plugins/blue-ridge/lib/blue-ridge.js"&gt;&lt;/script&gt;
&lt;/head&gt;

&lt;body&gt;
  &lt;div&gt;
    &lt;label for="person_user_time_zone_id"&gt;Main drop down for tests&lt;/label&gt;
    &lt;select name="person[user][time_zone_id]" id="person_user_time_zone_id" style="display: inline;"&gt;
      &lt;option value="Hawaii"&gt;(GMT-10:00) Hawaii&lt;/option&gt;
      &lt;option value="Alaska"&gt;(GMT-09:00) Alaska&lt;/option&gt;
      &lt;option value="Pacific Time (US &amp; Canada)"&gt;(GMT-08:00) Pacific Time (US &#038; Canada)&lt;/option&gt;
      &lt;option value="Arizona"&gt;(GMT-07:00) Arizona&lt;/option&gt;
      &lt;option value="Mountain Time (US &amp; Canada)"&gt;(GMT-07:00) Mountain Time (US &#038; Canada)&lt;/option&gt;
      &lt;option value="Central Time (US &amp; Canada)"&gt;(GMT-06:00) Central Time (US &#038; Canada)&lt;/option&gt;
      &lt;option value="Eastern Time (US &amp; Canada)"&gt;(GMT-05:00) Eastern Time (US &#038; Canada)&lt;/option&gt;
    &lt;/select&gt;
  &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>In its header it loads the blue-ridge JavaScript library, which in turn loads Screw.Unit and ultimately our spec.js test file (based on corresponding file name), so <code>ninja_search.html</code> will cause a file <code>spec/ninja_search_spec.js</code> to be loaded.</p>
<p>To run our first test just load up the <code>spec/fixtures/ninja_search.html</code> file into your browser.</p>
<p>Your first test will fail. But that&#8217;s ok, that&#8217;s the point of TDD. <a href="http://en.wikipedia.org/wiki/Test-driven_development">Red, green, refactor</a>.</p>
<h3 id="simple_passing_code">Simple passing code</h3>
<p>So now we need some code to make the test pass.</p>
<p>Create a file <code>public/ninja_search.js</code> and something like the following should work:</p>
<pre lang="javascript">
(function($){
  $(function() {
    $('select').each(function(index) {
      var id = $(this).attr('id');

      // create the Ninja Search button, with rel attribute referencing corresponding &gt;select id="...">
      $('&gt; class="ninja_search_activation" rel="' + id + '">ninja search&gt;/a>')
      .insertAfter($(this));
    });
  });
})(jQuery);
</pre>
<p>Reload your test fixtures HTML file and the test should pass.</p>
<p>Now rinse and repeat. The final suite of <a href="http://github.com/drnic/ninja-search-js/tree/master/spec">tests and fixture files</a> for Ninja Search JS are on github.</p>
<h3 id="building_a_greasemonkey_script">Building a Greasemonkey script</h3>
<p>Typically Greasemonkey scripts are all-inclusive affairs. One JavaScript file, named <code>my_script.user.js</code>, typically does the trick.</p>
<p>I decided I wanted a thin Greasemonkey script that would dynamically load my <code>ninja-search.js</code>, and any stylesheets and dependent libraries. This would allow people to install the thin Greasemonkey script once, and I can deploy new versions of the actual code base over time without them having to re-install anything.</p>
<p>Ultimately in production, the stylesheets, images, and JavaScript code would be hosted on the intertubes somewhere. Though during development that would be long-winded and painful to push the code to a remote host just to run tests.</p>
<p>So I have three Greasemonkey scripts:</p>
<ul>
<li><code>public/ninja_search.dev.user.js</code> &#8211; loads each dependent library and asset from the local file system</li>
<li><code>public/ninja_search.local.user.js</code> &#8211; loads compressed library and asset from the local file system</li>
<li><code>public/ninja_search.user.js</code> &#8211; loads compressed library and assets from remote server</li>
</ul>
<p>Let&#8217;s ignore the optimisation of compressing dependent JavaScript libraries for the moment and just look at the <code>dev.user.js</code> and <code>user.js</code> files.</p>
<p>The two scripts differ in the target host from which they load assets and libraries. <a href="http://github.com/drnic/ninja-search-js/blob/master/public/ninja-search.dev.user.js">ninja_search.dev.user.js</a> loads them from the local machine and <a href="http://github.com/drnic/ninja-search-js/blob/master/public/ninja-search.user.js">ninja_search.user.js</a> loads them from a remote server.</p>
<p>For example <code>ninja_search.dev.user.js</code> loads local dependencies like this:</p>
<pre lang="javascript">
require("http://ninja-search-js.local/jquery.js");
require("http://ninja-search-js.local/ninja_search.js");
</pre>
<p>And <code>ninja_search.user.js</code> loads remote dependencies like this:</p>
<pre lang="javascript">
require("http://drnic.github.com/ninja-search-js/dist/jquery.js");
require("http://drnic.github.com/ninja-search-js/dist/ninja_search.js");
</pre>
<p>In the final version of <a href="http://github.com/drnic/ninja-search-js/blob/master/public/ninja-search.user.js">ninja_search.user.js</a> we load a simple, conpressed library containing jquery, our code, and other dependencies, called <a href="http://github.com/drnic/ninja-search-js/blob/master/public/ninja_search_complete.js">ninja_search_complete.js</a>.</p>
<h3 id="using_passenger_to_server_local_libraries">Using Passenger to server local libraries</h3>
<p>The problem with loading local JavaScript libraries using the <code>file://</code> protocol, inferred earlier, is that it doesn&#8217;t work. So if I can&#8217;t load libraries using <code>file://</code> then I must use the <code>http://</code> protocol. That means I must route the requests through Apache/Ningx.</p>
<p>Fortunately there is a very simple solution: use <a href="http://www.modrails.com/">Phusion Passenger</a> which serves a &#8220;web app&#8217;s&#8221; <code>public</code> folder automatically. That&#8217;s why all the javascript, CSS and image assets have been placed in a folder <code>public</code> instead of <code>src</code> or <code>lib</code> or <code>javascript</code>.</p>
<p>On my OS X machine, I moved the repository folder into my <code>Sites</code> folder and wired up the folder as a Passenger web app using <a href="http://github.com/alloy/passengerpane/tree/master">PassengerPane</a>. It took 2 minutes and now I had <a href="http://ninja-search.local">http://ninja-search.local</a> as a valid base URL to serve my JavaScript libraries to my Greasemonkey script.</p>
<h3 id="testing_the_greasemonkey_scripts">Testing the Greasemonkey scripts</h3>
<p>I can only have one of the three Greasemonkey scripts installed at a time, so I install the <code>ninja-search.dev.user.js</code> file to check that everything is basically working inside a browser on interesting, foreign sites (outside of the unit test HTML pages).</p>
<p>Once I&#8217;ve deployed the JavaScript files and assets to the remote server I can then install the <code>ninja-search.user.js</code> file (<a href="http://drnic.github.com/ninja-search-js/dist/ninja-search.user.js">so can you</a>) and double check that I haven&#8217;t screwed anything up.</p>
<h3 id="deploying_via_github_pages">Deploying via GitHub Pages</h3>
<p>The normal, community place to upload and share Greasemonkey scripts is <a href="http://userscripts.org/">userscripts.org</a>. This is great for one file scripts, though if your script includes CSS and image assets, let alone additional JavaScript libraries, then I don&#8217;t think its as helpful, which is a pity.</p>
<p>So I decided to deploy the ninja-search-js files into the project&#8217;s own GitHub Pages site.</p>
<p>After creating the GitHub Pages site using <a href="http://github.com/blog/277-pages-generator">Pages Generator</a>, I then pulled down the gh-pages branch, and then linked (via submodules) that branch into my master branch as <code>website</code> folder.</p>
<p>Something like:</p>
<pre><code>
git checkout origin/gh-pages -b gh-pages
git checkout master
git submodule add -b gh-pages git@github.com:drnic/ninja-search-js.git website
</code></pre>
<p>Now I can access the gh-pages branch from my master branch (where the code is).</p>
<p>Then to deploy our Greasemonkey script we just copy over all the <code>public</code> files into <code>website/dist</code>, and then commit and push the changes to the gh-pages branch.</p>
<pre><code>
mkdir -p website/dist
cp -R public/* website/dist/
cd website
git commit -a "latest script release"
git push origin gh-pages
cd ..
</code></pre>
<p>Then you wait very patiently for GitHub to deploy your latest website, which now contains your Greasemonkey script (<code>dist/ninja-search.user.js</code>) and all the libraries (our actual code), stylesheets and images.</p>
<h3 id="summary">Summary</h3>
<p>Greasemonkey scripts might seem like small little chunks of code. But all code starts small and grows. At some stage you&#8217;ll wish you had some test coverage. And later you&#8217;ll hate yourself for ever having release the bloody thing in the first place.</p>
<p>I wrote all this up to summarise how I&#8217;d done TDD for the <a href="http://drnic.github.com/ninja-search-js/">Ninja Search JS</a> project, which is slightly different from how I added test cases to _why&#8217;s <a href="http://github.com/drnic/8cpj/tree/master">the octocat&#8217;s pajamas</a> greasemonkey script when I first started hacking with unit testing Greasemonkey scripts. The next one will probably be slightly different again.</p>
<p>I feel good about the current project structure, I liked Screw.Unit and blue-ridge, and I&#8217;m amused by my use of GitHub Pages to deploy the application itself.</p>
<p>If anyone has any ideas on how this could be improved, or done radically differently, I&#8217;d love to hear them!</p>
<h3 id="polish_your_rails_project_with_mocra">Polish your Rails project with Mocra</h3>
<p>I want to help you, your business, your boss and your project reach delightful levels of wickedly awesomeness. I’m so proud of the small team of ace Rails developers here at Mocra and what I know we can do for you.</p>
<p>Send an email to <a href="mailto:&#x72;&#x61;&#x69;&#x6C;&#x73;&#x40;&#x6D;&#x6F;&#x63;&#x72;&#x61;&#x2E;&#x63;&#x6F;&#x6D;">rails@mocra.com</a> about your current/future projects. Dare us to be more awesome!</p>
<p>While you wait for a reply perhaps you&#8217;d like to learn more about <a href="http://mocra.com/how-we-do-it/">How we do it</a> at <a href="http://mocra.com/">Mocra</a>?</p>


<p>Related posts:<ol><li><a href='http://drnicwilliams.com/2009/07/04/nifty-threaded-im-chat-within-gtalkgmail-chat/' rel='bookmark' title='Permanent Link: Nifty Threaded IM Chat within Gtalk/Gmail Chat'>Nifty Threaded IM Chat within Gtalk/Gmail Chat</a> <small>Ever had IM chats where a conversation splits into multiple...</small></li><li><a href='http://drnicwilliams.com/2008/11/10/to-webkit-or-not-to-webkit-within-your-iphone-app/' rel='bookmark' title='Permanent Link: To WebKit or not to WebKit within your iPhone app?'>To WebKit or not to WebKit within your iPhone app?</a> <small> I know HTML. Its on my CV. Expert level....</small></li><li><a href='http://drnicwilliams.com/2008/10/31/newgem-100-all-thanks-to-cucumber/' rel='bookmark' title='Permanent Link: newgem 1.0.0 all thanks to Cucumber'>newgem 1.0.0 all thanks to Cucumber</a> <small>The New Gem Generator (newgem) was exciting, moderately revolutionary, and...</small></li></ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/DrNic?a=ne7i_RSH84g:36RxnD0qlSc:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/DrNic?i=ne7i_RSH84g:36RxnD0qlSc:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/DrNic?a=ne7i_RSH84g:36RxnD0qlSc:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/DrNic?i=ne7i_RSH84g:36RxnD0qlSc:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/DrNic?a=ne7i_RSH84g:36RxnD0qlSc:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/DrNic?i=ne7i_RSH84g:36RxnD0qlSc:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://drnicwilliams.com/2009/06/07/tdd-for-greasemonkey-scripts-and-introducing-ninja-search-js/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Cucumber: building a better World (object)</title>
		<link>http://drnicwilliams.com/2009/04/15/cucumber-building-a-better-world-object/</link>
		<comments>http://drnicwilliams.com/2009/04/15/cucumber-building-a-better-world-object/#comments</comments>
		<pubDate>Wed, 15 Apr 2009 02:48:48 +0000</pubDate>
		<dc:creator>Dr Nic</dc:creator>
				<category><![CDATA[Cucumber]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://drnicwilliams.com/?p=513</guid>
		<description><![CDATA[How to write helper libraries for your Cucumber step definitions and how to upgrade your support libraries from Cucumber 0.2 to 0.3 (released today).
In cucumber, each scenario step in a .feature file matches to a Given, When, Then step definition. The step definitions are normal Ruby code. First class, bonnified, honky-tonk Ruby code. And what&#8217;s [...]


Related posts:<ol><li><a href='http://drnicwilliams.com/2009/03/26/testing-outbound-emails-with-cucumber/' rel='bookmark' title='Permanent Link: Testing outbound emails with Cucumber'>Testing outbound emails with Cucumber</a> <small> My testimonial for Cucumber still stands even in 2009....</small></li><li><a href='http://drnicwilliams.com/2008/10/31/newgem-100-all-thanks-to-cucumber/' rel='bookmark' title='Permanent Link: newgem 1.0.0 all thanks to Cucumber'>newgem 1.0.0 all thanks to Cucumber</a> <small>The New Gem Generator (newgem) was exciting, moderately revolutionary, and...</small></li><li><a href='http://drnicwilliams.com/2006/10/12/my-irbrc-for-consoleirb/' rel='bookmark' title='Permanent Link: My .irbrc for console/irb'>My .irbrc for console/irb</a> <small>The relatively unspoken warhorse of Ruby/Rails programming is the irb/console...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p><em>How to write helper libraries for your Cucumber step definitions and how to upgrade your support libraries from Cucumber 0.2 to 0.3 (released today).</em></p>
<p>In cucumber, each scenario step in a <em>.feature</em> file matches to a <code>Given</code>, <code>When</code>, <code>Then</code> step definition. The step definitions are normal Ruby code. First class, bonnified, honky-tonk Ruby code. And what&#8217;s the one thing we love to do to Ruby code on a rainy Sunday afternoon? Refactor it. Turn messy code into readable &#8220;return in 50 years, on the time capsule, and get back to work quickly&#8221; code.</p>
<p>In Cucumber we use a special, until-now unknown, magic technique for refactoring step definitions. They are called &#8220;Ruby methods&#8221;. Oooh, feel the magic. You take some code in a step definition and you refactor it into a method. And you&#8217;re done. For example:</p>
<pre>When /I fill in the Account form/ do
  fill_in("account_name", :with => "Mocra")
  fill_in("account_abn", :with => "12 345 678 901")
  click_button("Submit")
end
</pre>
<p>Could be refactored into:</p>
<pre>When /I fill in the Account form/ do
  fill_in_account_form
end

def fill_in_account_form
  fill_in("account_name", :with => "Mocra")
  fill_in("account_abn", :with => "12 345 678 901")
  click_button("Submit")
end
</pre>
<p>Good work. Or is it? No, we&#8217;ve done something a little naughty. We&#8217;ve polluted the global object space with our method and turns out it just isn&#8217;t necessary. There&#8217;s a nicer way and a clean idiom for how/where to write helper methods.</p>
<p>Annoyingly, that idiom broke with the release of Cucumber 0.3. So I&#8217;ll introduce both so you can fix any bugs that you spot and know how to fix them.</p>
<p>The solution is to understand the existence of the World object and the clean technique for writing <em>features/support/foobar_helpers.rb</em> libraries of helper methods.</p>
<h3 id="introducing_the_world_object">Introducing the World object</h3>
<p>To ensure that each cucumber scenario starts with a clean slate, your scenarios are run upon a blank <code>Object.new</code> object. Or in a Rails project its a new Rails test session <code>ActionController::IntegrationTest</code>.</p>
<p>These are called <code>World</code> objects (see <a href="http://wiki.github.com/aslakhellesoy/cucumber/a-whole-new-world">cucumber wiki</a>). You pass in a specific World object you&#8217;d like to use, else it defaults to <code>Object.new</code> For a Rails project, you&#8217;re using <code>Cucumber::Rails::World.new</code> for your world object each time, which is a subclass of <code>ActionController::IntegrationTest</code>.</p>
<p>The benefit of a World object starting point for each scenario is that you can add methods to it, that won&#8217;t affect the rest of the Ruby world you live in: which will be the Cucumber runner. That is, you cannot accidently blow up Cucumber.</p>
<h3 id="extending_the_world_object">Extending the World object</h3>
<p>Step 1, put methods in a module. Step 2, add the module to your World object.</p>
<p>So that we&#8217;re all extending Cucumber in the same way, there is a folder for where your helper methods should be stored, and a programming idiomatic way to do it. It has changed slight from Cucumber 0.2 to 0.3 so I&#8217;ll show both.</p>
<p>For our helper method <code>fill_in_account_form</code> above:</p>
<ol>
<li>Create <em>features/support/form_submission_helpers.rb</em> (its automatically loaded)</li>
<li>Wrap the helper method in a module <code>module FormSubmissionHelpers ... end</code></li>
<li>Tell Cucumber to include the module into each World object for each Scenario</li>
</ol>
<p>In Cucumber 0.3+ your complete helper file would look like:</p>
<pre>module FormSubmissionHelpers
  def fill_in_account_form
    fill_in("account_name", :with => "Mocra")
    fill_in("account_abn", :with => "12 345 678 901")
    click_button("Submit")
  end
end
World(FormSubmissionHelpers)
</pre>
<p>For Cucumber 0.2 your complete helper file might have looked like:</p>
<pre>module FormSubmissionHelpers
  def fill_in_account_form
    fill_in("account_name", :with => "Mocra")
    fill_in("account_abn", :with => "12 345 678 901")
    click_button("Submit")
  end
end
World do |world|
  world.extend FormSubmissionHelpers
end
</pre>
<p>Where the difference is the last part of the file. This mechanism is deprecated and results in the following error message after upgrading to Cucumber 0.3:</p>
<pre>/Library/Ruby/Gems/1.8/gems/cucumber-0.3.0/bin/../lib/cucumber/step_mother.rb:189:in `World': You can only pass a proc to #World once, but it's happening (Cucumber::MultipleWorld)
in 2 places:

vendor/plugins/cucumber/lib/cucumber/rails/world.rb:72:in `World'
vendor/plugins/email-spec/lib/email_spec/cucumber.rb:18:in `World'
</pre>
<h3 id="summary">Summary</h3>
<p>Refactor step definitions. Put it in <em>features/support/&#8230;_helpers.rb</em> files, inside modules that are assigned to the World object.</p>
<h3>And a word from our sponsor</h3>
<p>Starting a new Rails project and need the team that is up-to-date with all the latest and greatest gadgetry, plugins and gems, styles and processes for enterprise and web2.0 web applications? <a href="http://mocra.com/contact">Ask us at Mocra</a>.</p>
<p>Need professionals to help your Rails project burst over the finish line? <a href="http://mocra.com/contact">Ask us at Mocra</a>.</p>


<p>Related posts:<ol><li><a href='http://drnicwilliams.com/2009/03/26/testing-outbound-emails-with-cucumber/' rel='bookmark' title='Permanent Link: Testing outbound emails with Cucumber'>Testing outbound emails with Cucumber</a> <small> My testimonial for Cucumber still stands even in 2009....</small></li><li><a href='http://drnicwilliams.com/2008/10/31/newgem-100-all-thanks-to-cucumber/' rel='bookmark' title='Permanent Link: newgem 1.0.0 all thanks to Cucumber'>newgem 1.0.0 all thanks to Cucumber</a> <small>The New Gem Generator (newgem) was exciting, moderately revolutionary, and...</small></li><li><a href='http://drnicwilliams.com/2006/10/12/my-irbrc-for-consoleirb/' rel='bookmark' title='Permanent Link: My .irbrc for console/irb'>My .irbrc for console/irb</a> <small>The relatively unspoken warhorse of Ruby/Rails programming is the irb/console...</small></li></ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/DrNic?a=Tv1RSK4PYWg:e2RVcViOt2c:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/DrNic?i=Tv1RSK4PYWg:e2RVcViOt2c:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/DrNic?a=Tv1RSK4PYWg:e2RVcViOt2c:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/DrNic?i=Tv1RSK4PYWg:e2RVcViOt2c:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/DrNic?a=Tv1RSK4PYWg:e2RVcViOt2c:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/DrNic?i=Tv1RSK4PYWg:e2RVcViOt2c:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://drnicwilliams.com/2009/04/15/cucumber-building-a-better-world-object/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Easy scheduling by location, tasks and people – a case study of a client application from Mocra</title>
		<link>http://drnicwilliams.com/2009/04/06/easy-scheduling-by-location-tasks-and-people-a-case-study-of-a-client-application-from-mocra/</link>
		<comments>http://drnicwilliams.com/2009/04/06/easy-scheduling-by-location-tasks-and-people-a-case-study-of-a-client-application-from-mocra/#comments</comments>
		<pubDate>Mon, 06 Apr 2009 07:02:22 +0000</pubDate>
		<dc:creator>Dr Nic</dc:creator>
				<category><![CDATA[Mocra]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://drnicwilliams.com/?p=504</guid>
		<description><![CDATA[
UPDATE: Orchestrate was reported in TechCrunch
Several years ago Andy Wright uncovered a problem. Small and large businesses can have the same problem: orchestrating to get a qualified person to perform a job. Who&#8217;s got the skills? Who&#8217;s available? What tasks have you offered/sold to your customers? 
Its hard enough getting customers and finding great staff/contractors, [...]


Related posts:<ol><li><a href='http://drnicwilliams.com/2009/06/30/refer-us-a-client-for-fun-and-profit/' rel='bookmark' title='Permanent Link: Refer us a client for fun and profit'>Refer us a client for fun and profit</a> <small>There&#8217;s only so many hours in the day and only...</small></li><li><a href='http://drnicwilliams.com/2007/06/09/smart-people-doing-smart-things-in-netherlands-rubyenrails-2007/' rel='bookmark' title='Permanent Link: Smart people doing smart things in Netherlands &#8211; RubyEnRails 2007'>Smart people doing smart things in Netherlands &#8211; RubyEnRails 2007</a> <small>Summary: click to select Photo by Thijs van der Vossen,Fingertips...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p><a href="http://orchestrateapp.com"><img width="250" src="http://orchestrateapp.com/images/content/home_page_illustration.png" class="alignright"/></a></p>
<p><strong>UPDATE:</strong> Orchestrate was reported in <a href="http://www.techcrunch.com/2009/04/08/orchestrate-saas-task-management-for-service-and-maintenance-businesses/">TechCrunch</a></p>
<p>Several years ago <a href="http://elevensoft.com/">Andy Wright</a> uncovered a problem. Small and large businesses can have the same problem: orchestrating to get a qualified person to perform a job. Who&#8217;s got the skills? Who&#8217;s available? What tasks have you offered/sold to your customers? </p>
<p>Its hard enough getting customers and finding great staff/contractors, but then you might spend many nervous hours juggling demand against availability. Then you need to keep a history of jobs and tasks performed. Did your staff do the work? Does anyone need to follow up?</p>
<p>The same types of jobs, the same set of qualified staff, the same process of orchestration. Every day. Bah. Fortunately Andy invested the last several years into solution towards automation: <a href="http://orchestrateapp.com">Orchestrate</a>. </p>
<p><a href="http://orchestrateapp.com/tour.html"><img src="http://orchestrateapp.com/images/content/tour_images/schedule_popup_large.jpg" width="550"></a></p>
<p>I&#8217;m in love with this application because <a href="http://mocra.com">Mocranites</a> Bo Jeanes, Ryan Bigg, Jack Chen and myself helped it mature over the last 6 months into a production-ready, enterprise scaling mega app. From adolescence to adulthood.</p>
<p>Orchestrate has now graduated &#8220;Rails Development University&#8221; and <strong>gone live</strong>, after a two month stint in beta.</p>
<p>The design for Orchestrate was done by <a href="http://hicksdesign.co.uk/">Jon Hicks</a>, world famous as the creator of the FireFox logo. The original code base was created by <a href="http://jonathanleighton.com/">Jon Leighton</a>. Both Jons were brilliant to work with and we hope to run into them again on future projects. More recently, the marketing/main site of Orchestrate was developed by Ryan Carson and his team at <a href="http://www.carsonified.com/">Carsonified</a>.</p>
<p>Andy has brought together some of the best developers and designers in the world for this project, and it is so wonderful that at Mocra we can now proudly point to Orchestrate as one of its growing number of world-class client projects.</p>
<p>Here&#8217;s hoping for a TechCrunch write up&#8230; ! (<strong>Yay it came true!</strong>)</p>
<h3 id="polish_your_rails_project_with_mocra">Polish your Rails project with Mocra</h3>
<p>I want to help you, your business, your boss and your project reach delightful levels of wickedly awesomeness. I&#8217;m so proud of the small team of ace Rails developers here at Mocra and what I know we can do for you. Orchestrate is delicious proof of pudding.</p>
<p>Send an email to <a href="mailto:rails@mocra.com">rails@mocra.com</a> about your current/future projects. Its free to ask for help and I&#8217;ll even throw in the answers for free. Dare us to be more awesome!</p>
<p>While you wait for a reply perhaps learn more about <a href="http://mocra.com/how-we-do-it/">How we do it</a>?</p>


<p>Related posts:<ol><li><a href='http://drnicwilliams.com/2009/06/30/refer-us-a-client-for-fun-and-profit/' rel='bookmark' title='Permanent Link: Refer us a client for fun and profit'>Refer us a client for fun and profit</a> <small>There&#8217;s only so many hours in the day and only...</small></li><li><a href='http://drnicwilliams.com/2007/06/09/smart-people-doing-smart-things-in-netherlands-rubyenrails-2007/' rel='bookmark' title='Permanent Link: Smart people doing smart things in Netherlands &#8211; RubyEnRails 2007'>Smart people doing smart things in Netherlands &#8211; RubyEnRails 2007</a> <small>Summary: click to select Photo by Thijs van der Vossen,Fingertips...</small></li></ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/DrNic?a=iQYXrg0i0pE:v4qrHUHQAyw:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/DrNic?i=iQYXrg0i0pE:v4qrHUHQAyw:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/DrNic?a=iQYXrg0i0pE:v4qrHUHQAyw:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/DrNic?i=iQYXrg0i0pE:v4qrHUHQAyw:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/DrNic?a=iQYXrg0i0pE:v4qrHUHQAyw:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/DrNic?i=iQYXrg0i0pE:v4qrHUHQAyw:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://drnicwilliams.com/2009/04/06/easy-scheduling-by-location-tasks-and-people-a-case-study-of-a-client-application-from-mocra/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Closing in on The Dream: “one-click-to-deploy Rails apps”</title>
		<link>http://drnicwilliams.com/2009/03/30/closing-in-on-the-dream-one-click-to-deploy-rails-apps/</link>
		<comments>http://drnicwilliams.com/2009/03/30/closing-in-on-the-dream-one-click-to-deploy-rails-apps/#comments</comments>
		<pubDate>Mon, 30 Mar 2009 06:03:30 +0000</pubDate>
		<dc:creator>Dr Nic</dc:creator>
				<category><![CDATA[Announcement]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://drnicwilliams.com/?p=483</guid>
		<description><![CDATA[
Got a simple app you want to build? Allocate 5 minutes for initial code generation, slice setup, and initial deployment. All from the command line. In one command. Booya!
How long does it take to start a new Rails project? Surely just a moment? rails new_project -m path/to/some/template.rb
But your application isn&#8217;t deployed yet. The DNS isn&#8217;t [...]


Related posts:<ol><li><a href='http://drnicwilliams.com/2009/02/16/need-rails-developers-hire-australians/' rel='bookmark' title='Permanent Link: Need Rails Developers? Hire Australians'>Need Rails Developers? Hire Australians</a> <small> There&#8217;s been some malarky very recently about &#8220;how do...</small></li><li><a href='http://drnicwilliams.com/2008/07/04/unit-testing-iphone-apps-with-ruby-rbiphonetest/' rel='bookmark' title='Permanent Link: Unit Testing iPhone apps with Ruby: rbiphonetest'>Unit Testing iPhone apps with Ruby: rbiphonetest</a> <small> Everything to love about Ruby: the concise, powerful language;...</small></li><li><a href='http://drnicwilliams.com/2008/06/06/composite-primary-keys-goes-100-for-rails-21/' rel='bookmark' title='Permanent Link: Composite Primary Keys goes 1.0.0 for Rails 2.1'>Composite Primary Keys goes 1.0.0 for Rails 2.1</a> <small>Two years ago Dave Thomas did a keynote at the...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p><img alt="" src="http://img.skitch.com/20090330-8wwbeef7ngijh3qmu6g4ksr7ha.png" title="Logged in via twitter oauth" class="alignright" width="191" height="191" /></p>
<p>Got a simple app you want to build? Allocate 5 minutes for initial code generation, slice setup, and initial deployment. All from the command line. In one command. Booya!</p>
<p>How long does it take to start a new Rails project? Surely just a moment? <code>rails new_project -m path/to/some/template.rb</code></p>
<p>But your application isn&#8217;t deployed yet. The DNS isn&#8217;t ready, the remote slice doesn&#8217;t exist or the config for this new application isn&#8217;t setup. Heck, the code hasn&#8217;t even been pushed to a non-existent remote repository yet.</p>
<p>And what if you&#8217;re going to use something like twitter_auth for authentication? You&#8217;ll need to register your application with Twitter at <a href="http://twitter.com/oauth_clients">http://twitter.com/oauth_clients</a>.</p>
<p>All these things could be automated, surely. Surely?</p>
<p>If they were then you&#8217;d have a &#8220;one click&#8221; command. A new Rails app, pushed into production, and ready to rock and roll. Complete with either restful_authentication or twitter-based oauth integration.</p>
<h3 id="what_does_a_8220one_click8221_rails_and_deploy_command_look_like">What does a &#8220;one click&#8221; rails and deploy command look like?</h3>
<pre>cd Sites
rails -m rails-templates/mocra.rb default-twitter-auth-app

1. restful_authentication
2. twitter_auth
Which user authentication system? 2

1. mocra-primary
2. mocra-secondary
3. crazy-pron-sites
Install http://default-twitter-auth-app.mocra.com application on which slice? 3^H1

1. drnic
2. mocra
Which twitter user?  1
</pre>
<p><strong>Then you wait 3 minutes and 53 seconds.</strong></p>
<div style="margin-left: 30px;">
<p><a href="http://img.skitch.com/20090330-m19kq398xd47cefxu5wcxbp1d5.png"><img alt="" src="http://img.skitch.com/20090330-xjk5rhx5sgkbh22tfqxrfib3i6.png" title="1" class="alignleft" width="152" height="150" style="background-color: #FFFBCC; padding: 5px; margin: 2px; "/></a></p>
<p><a href="http://img.skitch.com/20090330-m46w5d9hqqcp87yx75bwr71ku6.png"><img alt="" src="http://img.skitch.com/20090330-m6p457erdaj14c162kth3a8m5p.png" title="2" class="alignleft" width="150" height="150" style="background-color: #FFFBCC; padding: 5px; margin: 2px" /></a></p>
<p><a href="http://img.skitch.com/20090330-83miatnsgiu6mjw66f4jaip314.png"><img alt="" src="http://img.skitch.com/20090330-8wwbeef7ngijh3qmu6g4ksr7ha.png" title="3" class="alignleft" width="150" height="150" style="background-color: #FFFBCC; padding: 5px; margin: 2px" /></a>
</div>
<p>Then you visit <a href="http://default-twitter-auth-app.mocra.com">http://default-twitter-auth-app.mocra.com</a> and it is working. You click the &#8220;Protected&#8221; link and you are redirected to Twitter to click the &#8220;Allow&#8221; link. You return to the app. You are registered with an account and logged in. You see your own face. You rock.</p>
<p>The rest of the article shows you how to test run it yourself, explain the dependencies and how to install them, and how to unit test your own templates to do similarly fancy things. Hopefully its helpful.</p>
<h3 id="waiting_a_minute_is_tutorial_destructive_to_my_precious_slices">WAITING A MINUTE &#8211; is this tutorial destructive to my precious slices?</h3>
<p>It is safe. <strong>IF you have an existing slicehost slice that was created with the latest deprec gem.</strong></p>
<p>Perhaps backup your slice anyway. But it should be safe. </p>
<p>Deprec installs each application in its own folder and the apache settings are in their own file etc. But when deprec installs apache, passenger, etc it <em>may</em> put them in places you aren&#8217;t expecting. It might not. I just can&#8217;t promise anything.</p>
<h3 id="testimonial_that_the_tutorial_works">Testimonial that the tutorial works</h3>
<p>Ryan Bigg offers the following testimonial to encourage you to actually try out the tutorial:</p>
<blockquote><p>&#8220;I have, dear readers, with as little effort as a few keystrokes, an an application base that allows my users to sign up using their twitter credentials. I have my code base here on my machine, and the running application in production over there at <a href="http://ryan.mocra.com">http://ryan.mocra.com</a>&#8221; Ryan Bigg (<a href="http://github.com/radar">radar</a>)</p></blockquote>
<h3 id="required_gems_for_the_template">Required gems for the template</h3>
<p>There are a couple of one-time-only steps to run to install some gems and setup github and slicehost API keys locally.</p>
<pre>gem install highline
gem install deprec
gem install defunkt-github --source http://gems.github.com
gem install booster-slicehost-tools --source=http://gems.github.com
</pre>
<p>To setup the github gem with your API key:</p>
<pre>* login to [http://github.com/](http://github.com/)
* click [account](https://github.com/account)
* click "Global Git Config"
* copy and paste the two lines of config into the terminal to install the config
</pre>
<p>The github gem will now use this configuration automatically.</p>
<p>To setup the slicehost gem with your API key:</p>
<p>slicehost-slice list<br />
   Please enter your API key since you did not provide one: </p>
<p>To get your slicehost API:</p>
<ul>
<li>login to <a href="https://manage.slicehost.com">https://manage.slicehost.com</a></li>
<li>click &#8220;Account&#8221;</li>
<li>click <a href="https://manage.slicehost.com/api/">API Access</a></li>
<li>click &#8220;Enable API Access&#8221;</li>
<li>copy + paste the API Password into the terminal above</li>
</ul>
<h3 id="required_gems_and_steps_for_using_twitter_auth">Required gems and steps for using twitter_auth</h3>
<p>My fork of the twitter gem includes a <code>twitter register_oauth ...</code> command. If John integrates the code, or writes his own, I&#8217;ll drop my fork and rewrite my template to use his gem. Til then use this one.</p>
<pre>gem install drnic-twitter --source=http://gems.github.com
twitter install
twitter add
</pre>
<p>And enter your twitter account details. You can run the last command any number of times to add personal and corporate/product twitter accounts. I am really impressed with the internals of this gem &#8211; it stores your data in a sqlite3 gem and uses ActiveRecord models to retrieve it. Might create a generator for this in newgem. I also liked the use of the <code>main</code> gem for its command definition. Anyway, we&#8217;re off the topic.</p>
<h3 id="cloning_and_running_the_rails_templates">Cloning and running the rails-templates</h3>
<p>Imagine the above steps were &#8220;Buy an Xbox 360. Buy Guitar Hero.&#8221; Now its the final step. It&#8217;s time to rock.</p>
<pre>cd ~/Sites
git clone git://github.com/drnic/rails-templates.git
DOMAIN=yourdomain.com ORGANIZATION="Your Company of Legends" rails -m rails-templates/mocra.rb my_app
</pre>
<p>A few minutes later you can open <a href="http://my-app.yourdomain.com">http://my-app.yourdomain.com</a> in a browser. It will have <a href="http://github.com/technoweenie/restful-authentication/tree/master">restful_authentication</a>  or twitter oauth integration all setup and working (except email settings for restful_authentication).</p>
<p>It makes me very happy watching it work.</p>
<p>If the above command has stalled after printing &#8216;executing  slicehost-slice list&#8217; then you haven&#8217;t set up your slicehost API key. See the instructions above.</p>
<h3 id="dirty_nasty_assumptions">Dirty, nasty assumptions?</h3>
<p>How can you deploy an entire app and have it up and running without some more configuration? Surely&#8230; surely I&#8217;ve made some nasty assumptions and come up with some dirty defaults?</p>
<p>Yes.</p>
<p>Your application url will be <code>my-app-name.mocra.com</code>. The subdomain is a dasherized version of your application&#8217;s folder name. Use <code>DOMAIN=mycompany.com</code> to change the domain.</p>
<p>Your local and remote database is mysql, accessible with user <code>root</code> and no password. I&#8230; look&#8230; you see there was this dog&#8230; and he ate my homework&#8230; it wasn&#8217;t me&#8230; there was an earthquate, a volcano, a flood&#8230; it wasn&#8217;t me!</p>
<p>You are deploying to slicehost. I do. It has command-line applications to manage slices and DNS. Since I&#8217;m deploying to a subdomain of mocra.com I use slicehost to create a CNAME in the DNS.</p>
<p>Your target slice already exists and has been built using the latest <a href="http://deprec.failmode.com/">deprec</a>. The template let&#8217;s you select an existing slicehost slice to use. If you don&#8217;t have one that was built with deprec, perhaps create a new one.</p>
<p>Gems? Plugins? Yes this template installs the ones that I want. That&#8217;s the point of rails templates &#8211; you create your own set of defaults.</p>
<h3 id="what_do_i_do_to_get_my_own_uber_template">What do I do to get my own uber-template?</h3>
<p>Copy + paste the <em>mocra.rb</em> template and hack in your configuration. Fork the github project and push up your file so others can see your awesomeness. </p>
<p>See the section on unit testing templates too.</p>
<h3 id="what8217s_missing">What&#8217;s missing?</h3>
<p>The primary thing that I want that I haven&#8217;t gotten around to writing/fixing/finding a solution is the creation of private, company github projects. That is, instead of public/open-source, personal projects using <code>github create-from-local</code>.</p>
<p>I guess I would want a <code>github create-from-local --private</code> flag to create a private repo instead of a public repo.</p>
<p>Then I&#8217;d want the github gem to know that I live in a world of multiple github accounts: my personal account (<a href="http://github.com/drnic/">drnic</a>) and my company&#8217;s account (<a href="http://github.com/mocra/">mocra</a>). That is, I&#8217;ll want new private company projects to go on the company account.</p>
<p>And then I&#8217;ll want it to add me (drnic) as a collaborator. Or a whole group of people.</p>
<p>Since the github gem currently derives its user + API token information from your global git config (<code>git config --get github.user</code>), instead of a nice external sqlite3 database like the twitter gem, I&#8217;m not sure what the best/correct data structure would be to add multiple user support to the github gem. </p>
<p>Or perhaps the <code>github create-from-local</code> mechanism should be extracted out of the github gem all together into a <code>github-admin</code> gem which would have multiple users, create public/private repos, add collaborators etc. Yeah, that might be better.</p>
<h3 id="want_a_default_application_theme">Want a default application theme?</h3>
<p>The template will attempt to invoke a generator <code>app_layout</code> if it can find it. Watch the <a href="http://railscasts.com/episodes/58-how-to-make-a-generator">railscast on generators</a> for an example of how to create a local generator and he gives an example of creating a default application theme generator. That&#8217;s why all the railscasts applications look the same!</p>
<h3 id="bonus_section_unit_testing_a_rails_template">Bonus section: unit testing a Rails template</h3>
<p>If you look in the rails-templates project you cloned you&#8217;ll see a <em>spec</em> folder. There is a mock <em>template_runner.rb</em> which is used by the <em>spec/mocra/template_spec.rb</em>. This way I can stub out calls to command-line tools like <code>slicehost-slice list</code> and <code>twitter register_oauth</code> and check that the template installs the correct plugins, creates the correct files, etc without actually installing or creating anything.</p>
<p>More importantly its a lot bloody faster to run than the full template.</p>
<p>If you&#8217;re creating Rails templates with interesting logic in them then writing some unit tests for your template might be a helpful idea to save time.</p>


<p>Related posts:<ol><li><a href='http://drnicwilliams.com/2009/02/16/need-rails-developers-hire-australians/' rel='bookmark' title='Permanent Link: Need Rails Developers? Hire Australians'>Need Rails Developers? Hire Australians</a> <small> There&#8217;s been some malarky very recently about &#8220;how do...</small></li><li><a href='http://drnicwilliams.com/2008/07/04/unit-testing-iphone-apps-with-ruby-rbiphonetest/' rel='bookmark' title='Permanent Link: Unit Testing iPhone apps with Ruby: rbiphonetest'>Unit Testing iPhone apps with Ruby: rbiphonetest</a> <small> Everything to love about Ruby: the concise, powerful language;...</small></li><li><a href='http://drnicwilliams.com/2008/06/06/composite-primary-keys-goes-100-for-rails-21/' rel='bookmark' title='Permanent Link: Composite Primary Keys goes 1.0.0 for Rails 2.1'>Composite Primary Keys goes 1.0.0 for Rails 2.1</a> <small>Two years ago Dave Thomas did a keynote at the...</small></li></ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/DrNic?a=I71zCUTAZ_8:xlGHmAWh5vk:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/DrNic?i=I71zCUTAZ_8:xlGHmAWh5vk:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/DrNic?a=I71zCUTAZ_8:xlGHmAWh5vk:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/DrNic?i=I71zCUTAZ_8:xlGHmAWh5vk:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/DrNic?a=I71zCUTAZ_8:xlGHmAWh5vk:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/DrNic?i=I71zCUTAZ_8:xlGHmAWh5vk:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://drnicwilliams.com/2009/03/30/closing-in-on-the-dream-one-click-to-deploy-rails-apps/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Testing outbound emails with Cucumber</title>
		<link>http://drnicwilliams.com/2009/03/26/testing-outbound-emails-with-cucumber/</link>
		<comments>http://drnicwilliams.com/2009/03/26/testing-outbound-emails-with-cucumber/#comments</comments>
		<pubDate>Thu, 26 Mar 2009 04:59:08 +0000</pubDate>
		<dc:creator>Dr Nic</dc:creator>
				<category><![CDATA[Cucumber]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://drnicwilliams.com/?p=474</guid>
		<description><![CDATA[
My testimonial for Cucumber still stands even in 2009. In fact I promise to let you know when I don&#8217;t think Cucumber is the bees-knees of integration testing. I love the step-by-step English instructions of user usage scenarios backed by a simple Ruby DSL for describing real actions on your application for each step.
For testing [...]


Related posts:<ol><li><a href='http://drnicwilliams.com/2009/04/15/cucumber-building-a-better-world-object/' rel='bookmark' title='Permanent Link: Cucumber: building a better World (object)'>Cucumber: building a better World (object)</a> <small>How to write helper libraries for your Cucumber step definitions...</small></li><li><a href='http://drnicwilliams.com/2008/10/31/newgem-100-all-thanks-to-cucumber/' rel='bookmark' title='Permanent Link: newgem 1.0.0 all thanks to Cucumber'>newgem 1.0.0 all thanks to Cucumber</a> <small>The New Gem Generator (newgem) was exciting, moderately revolutionary, and...</small></li><li><a href='http://drnicwilliams.com/2008/02/19/one-stop-javascript-unit-testing-for-rails2/' rel='bookmark' title='Permanent Link: One-stop JavaScript Unit Testing for Rails 2.0'>One-stop JavaScript Unit Testing for Rails 2.0</a> <small>Previously, I mentioned a multi-step/multi-project solution to doing JavaScript Unit...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p><a href="http://cukes.info"><img alt="" src="http://img.skitch.com/20090326-nihhcfit3a54xgqb9tfcspd827.preview.jpg" title="Cucumber testimonial" class="alignright" width="340" height="216" /></a></p>
<p>My testimonial for <a href="http://cukes.info/">Cucumber</a> still stands even in 2009. In fact I promise to let you know when I don&#8217;t think Cucumber is the bees-knees of integration testing. I love the step-by-step English instructions of user usage scenarios backed by a simple Ruby DSL for describing real actions on your application for each step.</p>
<p>For testing Rails apps, Cucumber defaults to using <a href="http://github.com/brynary/webrat/tree/master">Webrat</a> on top of Rails&#8217; own integration sessions. With Webrat you actually test that your views match to your controller actions. If I click the &#8220;Submit&#8221; button, then it checks that it invokes an available action correctly. Before Cucumber I could appreciate the merit of Webrat alone, but the two tools combined are instant superheroes of my Rails development crime fighting team. That is, like any superhero TV show at least once every 30 minutes you find yourself saying &#8220;Thank you Mr Cucumber and your trusty sidekick Webrat, you&#8217;re my heroes&#8221;. (BTW, <a href="http://twitter.com/agenteo/status/1386578002">I&#8217;m not alone</a> in this analogy)</p>
<h3 id="testing_emails">Testing emails</h3>
<p>But I wanted to test emails. More interestingly, emails containing links back into my application. Like an activation email on sign up.</p>
<p>Specifically, I wanted a cucumber scenario like this:</p>
<pre>Scenario: Signup for new account
  Given I am on the signup form
  When I fill in "Email" with "drnic@mocra.com"
  And I press "Join"
  Then I should see "An activation email has been sent"
  And I should receive an activation email
  When I click the activation email link
  Then I should see "Your account is active"
</pre>
<p>Within this scenario there are 7 steps. Lines 2, 3, 4 and 7 match to steps from the generated <em>webrat_steps.rb</em> file when you install cucumber.</p>
<p>Line 1 also matches to a webrat step definition. But it requires that you define what &#8220;the signup form&#8221; maps to in your routes. So you need to update <em>features/support/paths.rb</em> to specify what &#8220;the signup form&#8221; url is:</p>
<pre>module NavigationHelpers
  def path_to(page_name)
    case page_name
    when /the signup form/
      signup_path
    end
  end
end
</pre>
<p>So, that leaves us with lines 5 and 6.</p>
<h3 id="email_spec_plugin">email-spec plugin</h3>
<p>I&#8217;m happy using the <a href="http://github.com/bmabey/email-spec/tree/master">email-spec</a> gem/plugin from <a href="http://www.benmabey.com/">Ben Mabey</a>, who is also the lead maintainer of the awesome <a href="http://github.com/bmabey/cucumber-tmbundle/tree/master">Cucumber TextMate bundle</a> and did a wonderful presentation on <a href="http://mwrc2009.confreaks.com/14-mar-2009-15-00-bdd-with-cucumber-ben-mabey.html">Outside-In Development with Cucumber</a> at the recent Mountain West RubyConf (lots of <a href="http://mwrc2009.confreaks.com">great videos available</a>)</p>
<p>To install as a plugin:</p>
<pre>script/plugin install git://github.com/bmabey/email-spec.git</pre>
<p>Then add the following line to your *feature/support/env.rb* file:</p>
<pre>require 'email_spec/cucumber'</pre>
<p>Finally, the plugin comes with some bonus cucumber step definitions which wrap around lots of nice helpers:</p>
<pre>script/generate email_spec</pre>
<h3 id="using_email_spec_step_definitions">Using email-spec step definitions</h3>
<p>Let&#8217;s ignore my desired lines 5 and 6 above and use the step definitions that we get with email-spec. We can replace the two lines with the following:</p>
<pre>And I should receive an email
When I open the email
Then I should see "Please activate your new account" in the subject
When I click the first link in the email
</pre>
<p><strong>Update:</strong> The last line didn&#8217;t used to be in email-spec but it now is. I&#8217;ve removed the example from this article.</p>
<p>I did all this for an existing application and every line of the scenario tested positive/green. Yay!</p>
<h3 id="refactoring_four_steps_into_two">Refactoring four steps into two</h3>
<p>For the sake of demonstration, you now might want to refactor these four steps into two steps to keep your scenarios nice and readable. </p>
<p>That is, how can we convert these 4 steps into our original lines 5 and 6?</p>
<p>The quickest way is to copy and paste the lines and slap some quotes around the text:</p>
<pre>Then /^I should receive an activation email$/ do |email|
  Then 'I should receive an email'
  When 'I open the email'
  Then 'I should see "Please activate your new account" in the subject'
end

When /^I click the activation email link$/ do
  When 'I click the first link in the email'
end
</pre>
<p>That&#8217;s right, you can use <code>Given</code>/<code>When</code>/<code>Then</code> as invocation methods as well as step definition methods. If you don&#8217;t pass these methods a do&#8230;end block then they will match/find/invoke a step rather than define a new one. Very cool.</p>
<p>Alternately, you could implement the two steps using the underlying email helper methods provided by the email-spec plugin:</p>
<pre>Then /^I should receive an activation email$/ do
  unread_emails_for(current_email_address).size.should == 1
  open_email(current_email_address)
  current_email.should have_subject(/Please activate your new account/))
end

When /^I click the activation email link$/ do
  click_first_link_in_email
end
</pre>
<p>Your choice.</p>
<h3 id="configuring_current_email_address">Configuring current_email_address</h3>
<p>All the email-spec helper methods assume that the &#8220;I&#8221; in the scenario has an email address. It uses a method <code>current_email_address</code> for this.</p>
<p>You must change the <code>current_email_address</code> method in the <em>email_steps.rb</em> file to pull out email addresses from wherever they might be located within any given scenario.</p>
<p>For example, here is one definition of the method from one of my projects:</p>
<pre>def current_email_address
  @email || (@current_user &#038;&#038; @current_user.email) || "drnic@mocra.com"
end
</pre>
<h3 id="summary">Summary</h3>
<p>With Cucumber and email-spec it is very easy to send and test emails. So my thanks go to Ben Mabey for this plugin.</p>


<p>Related posts:<ol><li><a href='http://drnicwilliams.com/2009/04/15/cucumber-building-a-better-world-object/' rel='bookmark' title='Permanent Link: Cucumber: building a better World (object)'>Cucumber: building a better World (object)</a> <small>How to write helper libraries for your Cucumber step definitions...</small></li><li><a href='http://drnicwilliams.com/2008/10/31/newgem-100-all-thanks-to-cucumber/' rel='bookmark' title='Permanent Link: newgem 1.0.0 all thanks to Cucumber'>newgem 1.0.0 all thanks to Cucumber</a> <small>The New Gem Generator (newgem) was exciting, moderately revolutionary, and...</small></li><li><a href='http://drnicwilliams.com/2008/02/19/one-stop-javascript-unit-testing-for-rails2/' rel='bookmark' title='Permanent Link: One-stop JavaScript Unit Testing for Rails 2.0'>One-stop JavaScript Unit Testing for Rails 2.0</a> <small>Previously, I mentioned a multi-step/multi-project solution to doing JavaScript Unit...</small></li></ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/DrNic?a=5Uq4qIrSAlc:ObVCL0n205w:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/DrNic?i=5Uq4qIrSAlc:ObVCL0n205w:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/DrNic?a=5Uq4qIrSAlc:ObVCL0n205w:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/DrNic?i=5Uq4qIrSAlc:ObVCL0n205w:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/DrNic?a=5Uq4qIrSAlc:ObVCL0n205w:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/DrNic?i=5Uq4qIrSAlc:ObVCL0n205w:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://drnicwilliams.com/2009/03/26/testing-outbound-emails-with-cucumber/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>RailsCamp.au #5 – book now</title>
		<link>http://drnicwilliams.com/2009/02/22/railscampau-5-book-now/</link>
		<comments>http://drnicwilliams.com/2009/02/22/railscampau-5-book-now/#comments</comments>
		<pubDate>Sun, 22 Feb 2009 03:24:01 +0000</pubDate>
		<dc:creator>Dr Nic</dc:creator>
				<category><![CDATA[Announcement]]></category>
		<category><![CDATA[Conferences]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://drnicwilliams.com/?p=466</guid>
		<description><![CDATA[
Imagine yourself and a posse of like-minded Ruby hackers on a country retreat with zero internet for a weekend of fun. You&#8217;ll laugh, hack, learn, cry (well, you probably won’t cry… but you know… it felt poetic) and most likely play a crap-load of guitar hero. [manifesto]
In chronological order, the first RailsCamps in Australia were [...]


Related posts:<ol><li><a href='http://drnicwilliams.com/2007/07/09/web-directions-south-workshop/' rel='bookmark' title='Permanent Link: I Still Call Australia Home'>I Still Call Australia Home</a> <small>On the 25th of September I&#8217;m doing a one-day workshop...</small></li><li><a href='http://drnicwilliams.com/2007/04/26/introducing-myconfplan/' rel='bookmark' title='Permanent Link: Railsconf &#8211; the sessions I&#8217;ll be attending'>Railsconf &#8211; the sessions I&#8217;ll be attending</a> <small> http://myconfplan.com/conferences/RailsConf2007/users/drnic This is a new site called MyConfPlan, built...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p><a href="http://railscampau.github.com"><img alt="" src="http://railscampau.github.com/images/yield.png" title="Yield" class="alignright" width="247" height="166" /></a></p>
<blockquote><p>Imagine yourself and a posse of like-minded Ruby hackers on a country retreat with zero internet for a weekend of fun. You&#8217;ll laugh, hack, learn, cry (well, you probably won’t cry… but you know… it felt poetic) and most likely play a crap-load of guitar hero. [<a href="http://railscamp08.org/" title="Rails Camps">manifesto</a>]</p></blockquote>
<p>In chronological order, the first RailsCamps in Australia were in the states: New South Wales, Victoria, New South Wales, and South Australia. </p>
<p>This time, between May 15th and 18th, it&#8217;s in Queensland. God&#8217;s Country. The Sunshine State. Home of <a href="http://en.wikipedia.org/wiki/Steve_Irwin">Steve Irwin</a> (deceased), <a href="http://en.wikipedia.org/wiki/Joh_Bjelke-Petersen">Sir Joh Bjelke-Petersen</a> (deceased), <a href="http://en.wikipedia.org/wiki/Greg_Norman">Greg Norman</a> (expat), <a href="http://images.google.com.au/images?hl=en&amp;client=firefox-a&amp;rls=org.mozilla:en-US:official&amp;q=Keith%20Urban%20Nicole%20Kidman&amp;um=1&amp;ie=UTF-8&amp;sa=N&amp;tab=wi">Keith Urban</a> (expat), and <a href="http://images.google.com.au/images?q=Kristy%20Hinze&amp;oe=utf-8&amp;rls=org.mozilla:en-US:official&amp;client=firefox-a&amp;um=1&amp;ie=UTF-8&amp;sa=N&amp;hl=en&amp;tab=wi">Kristy Hinze</a> (marrying ex-Silicon Graphics/ex-Netscape billionaire Jim Clark; expat). So its a pretty famous and popular place to come from.</p>
<p><a href="http://www.flickr.com/photos/lachlanhardy/3045076837/" title="More Mexican (by Lachlan Hardy)"><img title="More Mexican (by Lachlan Hardy)" class="alignright" src="http://farm4.static.flickr.com/3016/3045076837_f1ff415033_m.jpg" alt="More Mexican (by Lachlan Hardy)" width="240" height="160"></a></p>
<p><a href="http://railscampau5.eventwax.com/rails-camp-5/register">Book your tickets now</a> for <a href="http://railscampau.github.com">RailsCamp #5</a>.</p>
<p><span id="more-466"></span></p>
<ul>
<li>Date: May 15-18 2009</li>
<li>Cost: $164</li>
<li>Where: <a href="http://www.koonjewarre.com/index.html">Koonjewarre Retreat Centre</a>, Gold Coast Hinterland, Queensland</li>
<li>Airport: Gold Coast Airport, Coolangatta</li>
<li>Website for bookings: <a href="http://railscampau.github.com/" title="RailsCamp.au 5 - May 15-18th 2008">http://railscampau.github.com/</a>
</ul>
<h3 id="foreigners_and_railscampau">Foreigners and RailsCamp.au</h3>
<p>There is no official foreigners policy. More generally, there aren&#8217;t too many policies on anything for RailsCamps. Its noteworthy that we&#8217;re a country founded 200 years ago on Britain&#8217;s primary export in the 1800s: shoplifters. So we&#8217;ll accept just about anyone. If you can get through Customs and Quarantine into our country, then we&#8217;ll let you come to RailsCamp. </p>
<p>Since RailsCamp.au starts just after RailsConf finishes, it would seem like an idea back-to-back &#8220;working&#8221; holiday. If you arrive early into Brisbane we&#8217;ll find you some office space to hang out in, or we&#8217;ll point you in the direction of some places to go touristing.</p>
<p>RailsCamp tickets sell out faster than RailsConf tickets, so <a href="http://railscampau.github.com/">decide fast</a>.</p>


<p>Related posts:<ol><li><a href='http://drnicwilliams.com/2007/07/09/web-directions-south-workshop/' rel='bookmark' title='Permanent Link: I Still Call Australia Home'>I Still Call Australia Home</a> <small>On the 25th of September I&#8217;m doing a one-day workshop...</small></li><li><a href='http://drnicwilliams.com/2007/04/26/introducing-myconfplan/' rel='bookmark' title='Permanent Link: Railsconf &#8211; the sessions I&#8217;ll be attending'>Railsconf &#8211; the sessions I&#8217;ll be attending</a> <small> http://myconfplan.com/conferences/RailsConf2007/users/drnic This is a new site called MyConfPlan, built...</small></li></ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~f/DrNic?a=DieRawcH"><img src="http://feeds.feedburner.com/~f/DrNic?i=DieRawcH" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/DrNic?a=U7Ul8sUR"><img src="http://feeds.feedburner.com/~f/DrNic?i=U7Ul8sUR" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/DrNic?a=h1GleNw8"><img src="http://feeds.feedburner.com/~f/DrNic?i=h1GleNw8" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://drnicwilliams.com/2009/02/22/railscampau-5-book-now/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Need Rails Developers? Hire Australians</title>
		<link>http://drnicwilliams.com/2009/02/16/need-rails-developers-hire-australians/</link>
		<comments>http://drnicwilliams.com/2009/02/16/need-rails-developers-hire-australians/#comments</comments>
		<pubDate>Mon, 16 Feb 2009 01:24:07 +0000</pubDate>
		<dc:creator>Dr Nic</dc:creator>
				<category><![CDATA[Mocra]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://drnicwilliams.com/?p=445</guid>
		<description><![CDATA[
There&#8217;s been some malarky very recently about &#8220;how do I find a lot of mature, awesome Rails developers?&#8221; (rails-business + #rmm)
I think this is the wrong question. And the wrong question will lead to the wrong answer.
What is the right question?
The right question can lead to a right answer. The right question you should ask [...]


Related posts:<ol><li><a href='http://drnicwilliams.com/2009/03/30/closing-in-on-the-dream-one-click-to-deploy-rails-apps/' rel='bookmark' title='Permanent Link: Closing in on The Dream: &#8220;one-click-to-deploy Rails apps&#8221;'>Closing in on The Dream: &#8220;one-click-to-deploy Rails apps&#8221;</a> <small> Got a simple app you want to build? Allocate...</small></li><li><a href='http://drnicwilliams.com/2008/02/27/rails-textmate-tasty-tidbit-respond_to/' rel='bookmark' title='Permanent Link: Rails 2.0 TextMate bundle &#8211; Tasty Tidbit &#8211; respond_to and view navigation'>Rails 2.0 TextMate bundle &#8211; Tasty Tidbit &#8211; respond_to and view navigation</a> <small>The new release of the Rails TextMate bundle is coming...</small></li><li><a href='http://drnicwilliams.com/2008/02/19/one-stop-javascript-unit-testing-for-rails2/' rel='bookmark' title='Permanent Link: One-stop JavaScript Unit Testing for Rails 2.0'>One-stop JavaScript Unit Testing for Rails 2.0</a> <small>Previously, I mentioned a multi-step/multi-project solution to doing JavaScript Unit...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p><img src="http://drnicwilliams.com/wp-content/uploads/2009/02/rubyaustralia1-300x273.png" alt="Ruby in Australia" title="Ruby in Australia" width="300" height="273" class="alignright size-medium wp-image-459" /></p>
<p>There&#8217;s been some malarky very recently about &#8220;how do I find a lot of mature, awesome Rails developers?&#8221; (<a href="http://groups.google.com/group/rails-business/browse_thread/thread/e24cfda7947fda10">rails-business</a> + <a href="http://search.twitter.com/search?q=rmm">#rmm</a>)</p>
<p>I think this is the wrong question. And the wrong question will lead to the wrong answer.</p>
<h3 id="what_is_the_right_question">What is the right question?</h3>
<p>The right question can lead to a right answer. The right question you should ask yourself every day:</p>
<p>&#8220;<strong>Where</strong> do I find a lot of mature, awesome Rails developers?&#8221;</p>
<p><span id="more-445"></span></p>
<h2 id="the_right_answer_is_australia">The right answer is: Australia.</h2>
<p>Australia has a bucket load of awe-inspiring Rails developers. And you should hire them all before anyone else figures this out.</p>
<p>What follows below is the uncovering of sensational economically vital information that you, your company, your boss and your client need to know about. Some of it may not seem entirely relevant upon first reading, but if you read right to the end you&#8217;ll be emotionally and logically convinced of the answer as I am.</p>
<p>Firstly, let&#8217;s explore some solid facts. Then we&#8217;ll explore the economic consequences, and finally what you should do about it.</p>
<h3 id="the_facts">The Facts</h3>
<p>The aggregated open source contributions from all Australian Rails developers is tremendous. Most Rails projects around the world would be using a plugin or gem created or maintained by an Australian. I&#8217;m sure there are Australian Bureau of Statistics quarterly reports to prove this.</p>
<p>Twice a year we have RailsCamp (next is mid May, see below) at which 60+ developers from around Australia converge on a barn in the middle of nowhere to hack and play Guitar Hero, Werewolf and Mexican.</p>
<p>And Australians are good looking. All of us.</p>
<p>Nearly all Australian Rails developers are part-time magazine models so all our photos are covered by copyright so I cannot reproduce them here, but suffice to say we have &#8220;The Look&#8221; covered.</p>
<p>We speak &#8220;Proper English&#8221;, aka &#8220;British English&#8221;, <em>and</em> we speak &#8220;American English.&#8221; That&#8217;s two languages. Bilingual. We learn these both by watching American TV and British comedies. The latter pokes fun at the former, so its a balanced linguistic education.</p>
<p>With so many extra-curricular speciality boxes already ticked off, you might wonder how we have the time to become exceptionally competent at software development using Ruby on Rails.</p>
<p>You see, our attitude to software development awesomeness is paralleled to our international awesomeness at Sport. With a population of only 21 million super-humans it would be ridiculous to spread ourselves too thinly across many pursuits. Instead, all 21 million of us specialise in one of two professional categories: Sport and Ruby on Rails development.</p>
<p>In the 2008 Olympics Australia came 5th in the medal tally by population (<a href="http://www.symworld.com/medals/index.php?sort=total">table</a>), and in 2004 we came 3rd (<a href="http://abs.gov.au/Ausstats/abs@.nsf/57a31759b55dc970ca2568a1002477b6/be9f47591541e29eca256ef40004f25a!OpenDocument">table</a>). In the latter we were beaten by Norway, an arch-nemesis in both Sport and Ruby on Rails about whom I shall discuss later.</p>
<p>If you assume the same model of Sporting excellence has been applied to our Ruby on Rails proficiency you will finish with the same surprising conclusion I diagnosed: you should to hire Australians for your Ruby on Rails projects.</p>
<p>Let&#8217;s explore three ways to get your hands on a team of Australian Rails developers: one is gratuitously self-promotional and the other two are not. All will solve your short and long-term Rails staffing requirements forever, so listen up.</p>
<h3 id="choose_your_own_australian_adventure">Choose your own Australian adventure</h3>
<p><a href="http://mocra.com"><img src="http://drnicwilliams.com/wp-content/uploads/2009/02/logo.png" alt="logo" title="logo" width="187" height="170" class="alignright size-full wp-image-457" /></a></p>
<p>Option #1 is to pick the premier Rails consultancy, <a href="http://mocra.com">Mocra</a>. Mocra was created to seize an untapped market inefficiency: Australian Rails developers were spread all over the place doing their awesome work. So instead, Mocra is jam-packed full of Australian Rails developers all in one place. Within shouting distance of each other are <a href="http://frozenplague.net/">Ryan Bigg</a>, <a href="http://github.com/bjeanes">Bo Jeanes</a>, <a href="http://github.com/chendo">Jack Chen</a> and myself.</p>
<p>So when you realise that you need a team of Australian Rails developers to &#8220;make it happen&#8221; then there&#8217;s only one email to ping (<a href="mailto:&#x72;&#x61;&#x69;&#x6C;&#x73;&#x40;&#x6D;&#x6F;&#x63;&#x72;&#x61;&#x2E;&#x63;&#x6F;&#x6D;">rails@mocra.com</a>) and one phone number to call <a href="callto://+61731023237">+61 7 3102 3237</a>. Or if you&#8217;re in the USA then use: <a href="callto://+14156709237">+1 (415) 670-9237</a>.</p>
<p>Option #2 is to pick and choose from several hundred Australian Rails developers, then go to <a href="http://workingwithrails.com/browse/people/country/Australia">Working With Rails > Browse by Country: Australia</a>.</p>
<p>In Firefox run the following JavaScript in the latest Firebug on the page to only show the &#8220;Available for Hire&#8221; ones:</p>
<pre lang="js">var list = $$('ul.entry-list li');
for (var i = 0; i < list.length; i++) {
  var li = list[i];
  if (!(li.innerHTML.match(/Available for hire/))) {
    li.parentNode.removeChild(li);
  }
}</pre>
<p>As WWR site doesn&#8217;t seem to have any JavaScript libraries attached to it my guess is that <code>$$</code> is available via Firebug.</p>
<p><a target="_blank" href="http://rubyonrails.com.au"><img src="http://drnicwilliams.com/wp-content/uploads/2009/02/roro.png" alt="roro" title="roro" width="129" height="96" class="alignright size-full wp-image-455" /></a></p>
<p>Option #3 is to get in contact with all the Ruby on Rails Dev Groups via the <a href="http://rubyonrails.com.au">RORO</a> sidebar.</p>
<p>Alternately, jump on IRC into #roro and find happy Australians buzzing away.</p>
<h3 id="why_not_a_norwegian">Why not a Norwegian?</h3>
<p>Since Norway beat Australia in the 2004 Olympics &#8220;by-population&#8221; medal tally, and I&#8217;ve gone to excessive lengths to allude that this means all our Ruby on Rails developers are Awesome <em>and</em> Good Looking <em>and</em> Multi-lingual, then shouldn&#8217;t I be authoring an article about &#8220;Hire a Norwegian?&#8221;</p>
<p>You make an excellent point.</p>
<p>Indeed, if I had the time I would definitely espouse the many virtues of Norwegian Rails developers. I&#8217;ve been to Norway several times. I&#8217;ve met a whole bunch of their Rails developers. There isn&#8217;t a Norwegian I didn&#8217;t like and several like an awful lot. Do you use <a href="http://github.com/aslakhellesoy/cucumber/wikis">Cucumber</a>? Made by Aslak Hellesøy, Oslo, Norway.</p>
<p>But its winter time there now, so its dark, and they hibernate during the winter. Or they go skiing all the time. Or they are swimming in their massive oil reserves. These are hobbies that would never distract an Australian from the job at hand.</p>
<h3 id="economic_opportunity">Economic Opportunity</h3>
<p>The first person to discover an imbalance in the free markets of capitalism wins. I think its called &#8220;<a href="http://en.wikipedia.org/wiki/Arbitrage">arbitrage</a>&#8221;, or something like it. Not only could you be first to discover the Rails&#8217; equivalent of the &#8220;New World&#8221; but our currency is in the toilet at the moment.</p>
<p>In the last few months the Australian dollar has lost 40+% of its value against the American dollar. I&#8217;m not an economic expert but I think this means that we&#8217;re cheap.</p>
<h3 id="what_should_you_do_about_it">What should you do about it?</h3>
<p>I may have been too subtle up to this point. If so, I apologise. </p>
<p>Australia is home to a lot of the best Rails developers in the world. Use them.</p>
<h3 id="should_i_emigrate_to_australia">Should I emigrate to Australia?</h3>
<p>Yes. Its very nice here.</p>


<p>Related posts:<ol><li><a href='http://drnicwilliams.com/2009/03/30/closing-in-on-the-dream-one-click-to-deploy-rails-apps/' rel='bookmark' title='Permanent Link: Closing in on The Dream: &#8220;one-click-to-deploy Rails apps&#8221;'>Closing in on The Dream: &#8220;one-click-to-deploy Rails apps&#8221;</a> <small> Got a simple app you want to build? Allocate...</small></li><li><a href='http://drnicwilliams.com/2008/02/27/rails-textmate-tasty-tidbit-respond_to/' rel='bookmark' title='Permanent Link: Rails 2.0 TextMate bundle &#8211; Tasty Tidbit &#8211; respond_to and view navigation'>Rails 2.0 TextMate bundle &#8211; Tasty Tidbit &#8211; respond_to and view navigation</a> <small>The new release of the Rails TextMate bundle is coming...</small></li><li><a href='http://drnicwilliams.com/2008/02/19/one-stop-javascript-unit-testing-for-rails2/' rel='bookmark' title='Permanent Link: One-stop JavaScript Unit Testing for Rails 2.0'>One-stop JavaScript Unit Testing for Rails 2.0</a> <small>Previously, I mentioned a multi-step/multi-project solution to doing JavaScript Unit...</small></li></ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~f/DrNic?a=3aZkkVMX"><img src="http://feeds.feedburner.com/~f/DrNic?i=3aZkkVMX" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/DrNic?a=XXENY6e6"><img src="http://feeds.feedburner.com/~f/DrNic?i=XXENY6e6" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/DrNic?a=BXFgkToU"><img src="http://feeds.feedburner.com/~f/DrNic?i=BXFgkToU" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://drnicwilliams.com/2009/02/16/need-rails-developers-hire-australians/feed/</wfw:commentRss>
		<slash:comments>25</slash:comments>
		</item>
	</channel>
</rss>
