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

<channel>
	<title>Dr Nic &#187; Tutorial</title>
	<atom:link href="http://drnicwilliams.com/category/tutorial/feed/" rel="self" type="application/rss+xml" />
	<link>http://drnicwilliams.com</link>
	<description>Ruby makes Rails, Javascript makes Ajax, Dr Nic makes Magic</description>
	<lastBuildDate>Sat, 12 Nov 2011 01:05:17 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>Never fear $ in READMEs again</title>
		<link>http://drnicwilliams.com/2011/06/11/never-fear-dollar-in-readmes-again/</link>
		<comments>http://drnicwilliams.com/2011/06/11/never-fear-dollar-in-readmes-again/#comments</comments>
		<pubDate>Fri, 10 Jun 2011 15:37:37 +0000</pubDate>
		<dc:creator>Dr Nic</dc:creator>
				<category><![CDATA[Trick]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://drnicwilliams.com/?p=809</guid>
		<description><![CDATA[Ever see example shell commands like this and wish you could paste them in? Fear no more. A pastie is at hand. Here&#8217;s how to install it: In your `.bash_profile` add the following: Thanks @dwaite and others for `$@` instead of `$0 $1 &#8230;`. Related posts:Pastie paradise Summary: click to select Ever tried emailing someone [...]


Related posts:<ol><li><a href='http://drnicwilliams.com/2007/06/28/pastie-paradise/' rel='bookmark' title='Permanent Link: Pastie paradise'>Pastie paradise</a> <small>Summary: click to select Ever tried emailing someone a chunk...</small></li><li><a href='http://drnicwilliams.com/2006/09/22/remote-shell-with-ruby/' rel='bookmark' title='Permanent Link: Remote Shell with Ruby'>Remote Shell with Ruby</a> <small>I wrote Composite Primary Keys and Dr Nic&#8217;s Magic Models...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>Ever see example shell commands like this and wish you could paste them in?</p>
<p><script src="https://gist.github.com/1019041.js?file=example_readme.sh"></script></p>
<p>Fear no more. A <a href="https://gist.github.com/1019041">pastie is at hand</a>.</p>
<p><script src="https://gist.github.com/1019041.js?file=$"></script></p>
<p>Here&#8217;s how to install it:</p>
<p><script src="https://gist.github.com/1019041.js?file=install.sh"></script></p>
<p>In your `.bash_profile` add the following:</p>
<p><script src="https://gist.github.com/1019041.js?file=prompt_addition.sh"></script></p>
<h3>Thanks</h3>
<p><a href="http://twitter.com/dwaite">@dwaite</a> and others for `$@` instead of `$0 $1 &#8230;`.</p>


<p>Related posts:<ol><li><a href='http://drnicwilliams.com/2007/06/28/pastie-paradise/' rel='bookmark' title='Permanent Link: Pastie paradise'>Pastie paradise</a> <small>Summary: click to select Ever tried emailing someone a chunk...</small></li><li><a href='http://drnicwilliams.com/2006/09/22/remote-shell-with-ruby/' rel='bookmark' title='Permanent Link: Remote Shell with Ruby'>Remote Shell with Ruby</a> <small>I wrote Composite Primary Keys and Dr Nic&#8217;s Magic Models...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://drnicwilliams.com/2011/06/11/never-fear-dollar-in-readmes-again/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Making CI easier to do than not to with Hudson CI and Vagrant</title>
		<link>http://drnicwilliams.com/2010/11/09/making-ci-easier-to-do-than-not-to-with-hudson-ci-and-vagrant/</link>
		<comments>http://drnicwilliams.com/2010/11/09/making-ci-easier-to-do-than-not-to-with-hudson-ci-and-vagrant/#comments</comments>
		<pubDate>Mon, 08 Nov 2010 17:36:34 +0000</pubDate>
		<dc:creator>Dr Nic</dc:creator>
				<category><![CDATA[Hudson]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[VM]]></category>

		<guid isPermaLink="false">http://drnicwilliams.com/?p=784</guid>
		<description><![CDATA[It irked me a little that I could develop on one stack (OS X, Rubinius, Sqlite3), run continuous integration (CI) on another stack (Ubuntu, Ruby 1.8.7, Postgresql), and deploy into another stack (Gentoo, Ruby 1.9.2, MySQL). I think what irks and worries me is that there are three sets of differences to be aware of. [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://skitch.com/drnic/d9mk1/inconsistency-between-environments"><img src="http://img.skitch.com/20101108-j11f4dk5745wieuu8i9skybat4.preview.png" style="float: right; width: 200px;"></a></p>
<p>It irked me a little that I could develop on one stack (OS X, Rubinius, Sqlite3), run continuous integration (CI) on another stack (Ubuntu, Ruby 1.8.7, Postgresql), and deploy into another stack (Gentoo, Ruby 1.9.2, MySQL). I think what irks and worries me is that there are three sets of differences to be aware of. A bug in production? Was it a missing test scenario or one of the many differences between production and CI environments?</p>
<p>So I think I have two solutions. </p>
<p>First, use a VM that matches the production environment. Each different production environment would mean another VM. If you are managing your own production environment, then all you need is the tools (described in this article) to recreate your production environment in a VM. </p>
<p>Second, use a clone of your production environment. That is, if you deploy to Engine Yard AppCloud then run CI in Engine Yard AppCloud; if you deploy to a single Ubuntu instance on Slicehost, the have another matching Ubuntu instance on Slicehost.</p>
<p>I&#8217;ll write about the first solution &#8211; using VMs &#8211; here, and I&#8217;ll write on the <a href="http://www.engineyard.com/blog/" title="Ruby on Rails Blog | Engine Yard">Engine Yard Blog</a> about the solution for Engine Yard AppCloud customers. For AppCloud users life will be even easier because there are zero setup steps to ensure you have consistent environments. It&#8217;s been one of my favorite projects in the two months since I arrived at Engine Yard.</p>
<p>I&#8217;ll also introduce a CLI for talking to Hudson &#8211; one that assumes you are working on Ruby/Rails projects &#8211; and makes it really easy to get up and running with a server, your Rails/Ruby projects, and any VMs you need (optional for Hudson, but they are the point of my line of thinking).</p>
<p>And I&#8217;ll introduce Vagrant, a CLI for creating/managing/destroying VMs.</p>
<p>Oh, and I&#8217;ll introduce Hudson CI.</p>
<p>Ok, let&#8217;s fix all our CI problems in one go&#8230;</p>
<h3 id="hudson_ci">Hudson CI</h3>
<p>I needed a CI tool to allow tests to run inside VMs or on remote servers/VMs. Back in May I found and fell in love with <a href="http://hudson-ci.org/" title="Hudson CI">Hudson CI</a>. Fortunately it had support for &#8220;slaves&#8221;, and a way for CI jobs (your applications or rubygems) to select which slaves can be used. Hudson is also great because it is easy to try out (one click to <a href="https://hudson.dev.java.net/hudson.jnlp">install and launch</a>), easy to configure, and has 350+ plugins.</p>
<p><a href="http://wiki.hudson-ci.org/display/HUDSON/Meet+Hudson">What is Hudson?</a></p>
<h3 id="cli_for_hudson">CLI for Hudson</h3>
<p>Charles Lowell&#8217;s <a href="https://github.com/cowboyd/hudson.rb">hudson.rb</a> project is a CLI for launching Hudson (it&#8217;s bundled inside the gem), and a set of CLI tasks to add/remove projects (jobs), add slaves, trigger builds and more. </p>
<pre><code>gem install hudson
</code></pre>
<p>You can launch Hudson via:</p>
<pre><code>hudson server  # Default: --port 3001
open http://localhost:3001
</code></pre>
<p>It currently assumes you are working on Ruby projects, using bundler, and attempts to create a useful set of default steps for your CI jobs.</p>
<pre><code>cd /some/rails3/app
hudson create . --host localhost --port 3001 --template rails3
</code></pre>
<p>Hudson CI will automatically start running steps to install your application&#8217;s gems, database, and run your tests. When it does it on your local machine it&#8217;s not that impressive. When it happens on a fresh VM or slave node and you didn&#8217;t have to do anything to set it up, it&#8217;s awesome.</p>
<h3 id="v_is_for_vagrant_virtualbox_and_all_things_vm">V is for Vagrant, VirtualBox and all things VM</h3>
<p>If you can script it, then you can automate it. Fortunately, as a virtual machine <a href="http://www.virtualbox.org/" title="VirtualBox">VirtualBox</a> is both scriptable <em>and</em> FREE! Secondly, if you have a VM, you&#8217;ll need to script its setup/provisioning; so fortunately there exists <a href="https://github.com/opscode/chef">chef</a> and <a href="https://github.com/lak/puppet">puppet</a>, amongst others.</p>
<p>Thirdly, if you are really really really lazy, like me, you will want <a href="http://vagrantup.com/">Vagrant</a>. Created by <a href="http://mitchellhashimoto.com/">Mitchell Hashimoto</a> and <a href="http://nickelcode.com/">John Bender</a>, Vagrant is a tool for building and distributing virtualized development environments. Everyone in your team have their own OS/configuration? Got Windows users on your team? Use Vagrant.</p>
<p>Once you have VirtualBox installed, getting any of your projects live within a VM is trival:</p>
<pre><code>gem install vagrant
vagrant box add base http://files.vagrantup.com/lucid32.box
vagrant init
vagrant up
vagrant ssh
$ cd /vagrant/
$ ls -al
</code></pre>
<p>You will now see the contents of your project folder, but from within the VM instance! They are linked &#8211; a change to either is automatically reflected inside and outside of the VM.</p>
<p>In this example, the Guest OS being downloaded and installed into VirtualBox (note: without any GUI) is <a href="http://releases.ubuntu.com/lucid/" title="Ubuntu 10.04.1 LTS (Lucid Lynx)">Ubuntu Lucid</a>, but you could use any VirtualBox packaged unix system.</p>
<p>For wonderful guided tour of Vagrant see the <a href="http://vimeo.com/9976342">Getting Started</a> video.</p>
<p><iframe src="http://player.vimeo.com/video/9976342" width="400" height="225" frameborder="0"></iframe>
<p><a href="http://vimeo.com/9976342">Vagrant &#8211; Getting Started</a> from <a href="http://vimeo.com/mitchellh">Mitchell Hashimoto</a> on <a href="http://vimeo.com">Vimeo</a>.</p>
</p>
<h3 id="hudson_ci_vagrant_perfect_ci">Hudson CI + Vagrant = Perfect CI</h3>
<p>Whether you choose to use VMs for a production-like development environment (a good idea for anyone, a wonderful idea for Windows developers who are very far removed from their production experience), it is a very good idea to have a CI environment as similar to your production environment as possible. Here, we want a VM instance with all the components/utilities/rubies set up that you have in production.</p>
<p>I have created an <a href="https://github.com/drnic/railsapp-vagrant">example Rails application</a> that is setup to use Vagrant for a CI slave VM.</p>
<p>See the README for complete instructions. See the <a href="https://github.com/drnic/railsapp-vagrant/blob/master/Vagrantfile">Vagrantfile</a> and the <a href="https://github.com/drnic/railsapp-vagrant/tree/master/cookbooks/">cookbooks</a> folder for the configuration and provisioning recipes.</p>
<p>Once you have the VM instantiated, you add it to your Hudson CI master (either the localhost one above or your remotely hosted server) with the CLI:</p>
<pre><code>hudson add_node localhost --name "VM" --label railsapp-vagrant ...
</code></pre>
<p>(See the <a href="https://github.com/drnic/railsapp-vagrant">example Rails application</a> for the other flags I used to get this working). It is now available to all Hudson jobs; but has a label &#8220;railsapp-vagrant&#8221; to allow jobs (Hudson&#8217;s name for a project) to specify that slave node specifically.</p>
<p>To add the Rails application to Hudson CI, and force it to run the tests in this VM:</p>
<pre><code>hudson create . --template rails3 --assigned-node railsapp-vagrant
</code></pre>
<p>If you visit the Hudson master (at <code>http://localhost:3010</code> in the example) you will see the job automatically running (&#8220;building&#8221;) within your VM. It will use bundler to install the gems, and run all the tests.</p>
<p><img src="http://img.skitch.com/20101108-jpitj3arquqthqndhs4eagmy89.png"></p>
<p><img src="http://img.skitch.com/20101108-f4ndidacj2cjxy249nbd82sjg6.png"></p>
<h3 id="that8217s_it">That&#8217;s it?</h3>
<p>I know, CI is historically a pain in the arse. When CruiseControl was the only CI kid-on-the-block, it was standard for people to respond &#8220;4 days&#8221; to the question &#8220;How long does it take to get set up?&#8221; </p>
<p>It can now be really easy.</p>
<p>More importantly than being easy, you are running an application&#8217;s tests within an isolated VM that you can design to match your production environment.</p>
<p>I think there can be a good future for CI and Rails applications. <strong>Thoughts on this solution?</strong></p>
<h3 id="thanks">Thanks</h3>
<p>Some of the technology in this article is old, other bits are very new, but for all of it I thank all the creators and contributors. Hudson CI was created by <a href="http://www.kohsuke.org/">Kohsuke Kawaguchi</a> during his days at Sun. He is now offering Hudson support services via his company <a href="http://infradna.com/" title="InfraDNA | The Hudson company">InfraDNA</a>. </p>
<p>The <a href="https://github.com/cowboyd/hudson.rb">Hudson.rb project</a> was created by <a href="http://cogentdude.com/">Charles Lowell</a> to bundle the Hudson CI and some common useful plugins for Ruby/Rails projects. He came all the way to Gothenburg, Sweden for <a href="http://nordicruby.com/" title="Nordic Ruby Conference – Gothenburg, Sweden May 21-23, 2010">NordicRuby</a> conference (great conference by the way!) I fell in love with Hudson and started helping Charles on Hudson.rb.</p>
<p>Thanks also to both Kohsuke and Charles for starting work on a JRuby plugin for Hudson CI, and writing up a <a href="http://infradna.com/content/hudson-jruby-integration-preliminary-report">progress report</a>.</p>
<p>Thanks to everyone who agrees that Hudson CI is awesome.</p>
<p>Thanks to Mitchell Hashimoto and John Bender for creating Vagrant. It is an incredible tool for developing within a VM (on OS X <em>or</em> Windows).</p>
<p>Finally, thanks to <a href="http://bjeanes.com/">Bo Jeanes</a> who helped on the <a href="http://www.engineyard.com/products/appcloud">Engine Yard AppCloud</a> version of this project. Coming soon!</p>
<h3 id="rubyconf_rubybayou">RubyConf &amp; RubyBayou</h3>
<p>If you&#8217;re in New Orleans this week for RubyConf, I&#8217;ll be at the local Ruby group RubyBayou talking about Hudson CI, Vagrant, and AppCloud on <a href="http://www.meetup.com/RubyBayou/calendar/14580950/" title="RubyConf &amp; Code Quality -  Ruby Bayou (New Orleans, LA) - Meetup">Thursday night</a>. There&#8217;s a happy hour from 5pm till the 7pm start.</p>
<p>Location: <a href="http://goo.gl/maps/WLNW" title="LaunchPad NOLA 643 Magazine St New Orleans, LA 70130 - Google Maps">LaunchPad NOLA, 643 Magazine St, New Orleans, LA 70130</a></p>
<p>Come and let me convince you about the wonders of Hudson CI and having a CI test environment that matches your production env. You know you want to be convinced. It&#8217;s good for you, like fruit.</p>
<h3 id="don8217t_forget_chuck_norris">Don&#8217;t forget Chuck Norris</h3>
<p>Always remember to install the <a href="http://wiki.hudson-ci.org/display/HUDSON/ChuckNorris+Plugin" title="ChuckNorris Plugin - hudson - Hudson Wiki">Chuck Norris plugin</a> for Hudson, and enable it for each job. Don&#8217;t forget Chuck Norris.</p>
]]></content:encoded>
			<wfw:commentRss>http://drnicwilliams.com/2010/11/09/making-ci-easier-to-do-than-not-to-with-hudson-ci-and-vagrant/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Validate and Save your Ruby in TextMate &#8211; with secret Rubinus superpowers</title>
		<link>http://drnicwilliams.com/2010/06/01/validate-and-save-your-ruby-in-textmate-with-secret-rubinus-superpowers/</link>
		<comments>http://drnicwilliams.com/2010/06/01/validate-and-save-your-ruby-in-textmate-with-secret-rubinus-superpowers/#comments</comments>
		<pubDate>Tue, 01 Jun 2010 12:54:18 +0000</pubDate>
		<dc:creator>Dr Nic</dc:creator>
				<category><![CDATA[Mocra]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[TextMate]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://drnicwilliams.com/?p=751</guid>
		<description><![CDATA[In some TextMate bundles, if you save a file it will also validate the file and show any syntax errors in a tooltip. This is awesome. (e.g. JavaScript and CoffeeScript) So I added the same thing to my Ruby.tmbundle. Install this, save a dodgy Ruby file and you&#8217;ll now see something like: Rubinius superpowers Do [...]


Related posts:<ol><li><a href='http://drnicwilliams.com/2011/04/27/replacing-aliases-to-use-redcar-or-textmate/' rel='bookmark' title='Permanent Link: Trialing RedCar instead of TextMate &#8211; replacing my aliases'>Trialing RedCar instead of TextMate &#8211; replacing my aliases</a> <small>I&#8217;m interested to trial RedCar in my life, instead of...</small></li><li><a href='http://drnicwilliams.com/2010/08/01/packaging-textmate-bundles-in-os-x-dmgs/' rel='bookmark' title='Permanent Link: Packaging TextMate bundles in OS X DMGs'>Packaging TextMate bundles in OS X DMGs</a> <small>Last week Engine Yard released a CLI for their Engine...</small></li><li><a href='http://drnicwilliams.com/2008/12/11/future-proofing-your-ruby-code/' rel='bookmark' title='Permanent Link: Future proofing your Ruby code. Ruby 1.9.1 is coming.'>Future proofing your Ruby code. Ruby 1.9.1 is coming.</a> <small> Bugger. I&#8217;m a Ruby monogamist. I use the Ruby...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>In some TextMate bundles, if you save a file it will also validate the file and show any syntax errors in a tooltip. This is awesome. (e.g. <a href="http://github.com/subtleGradient/javascript-tools.tmbundle">JavaScript</a> and <a href="http://github.com/jashkenas/coffee-script-tmbundle">CoffeeScript</a>)</p>
<p>So I added the same thing to my <a href="http://github.com/drnic/ruby-tmbundle">Ruby.tmbundle</a>. Install this, save a dodgy Ruby file and you&#8217;ll now see something like:</p>
<p><img src="http://img.skitch.com/20100601-eiw1ugr2ma8xwxbecjfbbpfgpk.jpg" style="width: 90%" alt="Validate and Save - No Rubinius" /></p>
<h3 id="rubinius_superpowers">Rubinius superpowers</h3>
<p>Do you think the following syntax error tooltip is more useful?</p>
<p><img src="http://img.skitch.com/20100601-r66y9yr8nb14br4esi436prn1p.jpg" style="width: 90%" alt="Validate and Save - Rubinius installed" /></p>
<p>Yes it lovely, and the new Ruby.tmbundle will automatically do this if it can find <code>rbx</code> in your TextMate&#8217;s <code>$PATH</code>. Yeah yeah.</p>
<p>If you have <a href="http://github.com/mxcl/homebrew">Homebrew</a> installed:</p>
<pre><code>brew install rubinius
</code></pre>
<p>Then in TextMate, add your homebrew <code>bin</code> folder to the $PATH.</p>
<ul>
<li>Go to TextMate&#8217;s Preferences (Cmd+,)</li>
<li>Go to &#8220;Advanced&#8221;, then &#8220;Shell Variables&#8221;</li>
<li>Edit the <code>PATH</code> variable, and add &#8220;:/path/to/homebrew/bin&#8221;</li>
</ul>
<p>For example, if you have homebrew installed in <code>~/.homebrew</code> then you might add <code>:/Users/drnic/.homebrew/bin</code></p>
<p>. My complete <code>$PATH</code> in TextMate is:</p>
<pre>/usr/bin:/bin:/usr/sbin:/sbin:/opt/local/bin:/usr/local/bin/:/Users/drnic/.homebrew/bin</pre>
<p>Save a dodgy Ruby file and see the beautifully helpful syntax message.</p>
<h3 id="install_rubytmbundle">Install Ruby.tmbundle</h3>
<p>To install via Git:</p>
<pre><code>mkdir -p ~/Library/Application\ Support/TextMate/Bundles
cd ~/Library/Application\ Support/TextMate/Bundles
git clone git://github.com/drnic/ruby-tmbundle.git "Ruby.tmbundle"
osascript -e 'tell app "TextMate" to reload bundles'
</code></pre>


<p>Related posts:<ol><li><a href='http://drnicwilliams.com/2011/04/27/replacing-aliases-to-use-redcar-or-textmate/' rel='bookmark' title='Permanent Link: Trialing RedCar instead of TextMate &#8211; replacing my aliases'>Trialing RedCar instead of TextMate &#8211; replacing my aliases</a> <small>I&#8217;m interested to trial RedCar in my life, instead of...</small></li><li><a href='http://drnicwilliams.com/2010/08/01/packaging-textmate-bundles-in-os-x-dmgs/' rel='bookmark' title='Permanent Link: Packaging TextMate bundles in OS X DMGs'>Packaging TextMate bundles in OS X DMGs</a> <small>Last week Engine Yard released a CLI for their Engine...</small></li><li><a href='http://drnicwilliams.com/2008/12/11/future-proofing-your-ruby-code/' rel='bookmark' title='Permanent Link: Future proofing your Ruby code. Ruby 1.9.1 is coming.'>Future proofing your Ruby code. Ruby 1.9.1 is coming.</a> <small> Bugger. I&#8217;m a Ruby monogamist. I use the Ruby...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://drnicwilliams.com/2010/06/01/validate-and-save-your-ruby-in-textmate-with-secret-rubinus-superpowers/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Using CoffeeScript in Rails and even on Heroku</title>
		<link>http://drnicwilliams.com/2010/03/15/using-coffeescript-in-rails-and-even-on-heroku/</link>
		<comments>http://drnicwilliams.com/2010/03/15/using-coffeescript-in-rails-and-even-on-heroku/#comments</comments>
		<pubDate>Mon, 15 Mar 2010 12:46:52 +0000</pubDate>
		<dc:creator>Dr Nic</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Mocra]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://drnicwilliams.com/?p=713</guid>
		<description><![CDATA[I&#8217;m pretty excited about CoffeeScript as a clean-syntax replacement for pure JavaScript. What is CoffeeScript? Imagine all the syntactical delights of Ruby and Haml for your JavaScript. You write in a nice language, but get normal JavaScript at runtime. All whilst having full access to 3rd-party JavaScript libraries (jQuery, PrototypeJS), debugging support (it becomes pure, [...]


Related posts:<ol><li><a href='http://drnicwilliams.com/2010/06/01/validate-and-save-your-ruby-in-textmate-with-secret-rubinus-superpowers/' rel='bookmark' title='Permanent Link: Validate and Save your Ruby in TextMate &#8211; with secret Rubinus superpowers'>Validate and Save your Ruby in TextMate &#8211; with secret Rubinus superpowers</a> <small>In some TextMate bundles, if you save a file it...</small></li><li><a href='http://drnicwilliams.com/2010/05/28/showcase-of-coffeescript-2-5-mins-for-your-next-dev-group-meeting/' rel='bookmark' title='Permanent Link: Showcase of CoffeeScript &#8211; 2.5 mins for your next Dev Group meeting'>Showcase of CoffeeScript &#8211; 2.5 mins for your next Dev Group meeting</a> <small> If you are giving an &#8220;Introduction to CoffeeScript&#8221; talk...</small></li><li><a href='http://drnicwilliams.com/2009/11/12/dead-simple-javascript-unit-testing-in-rails/' rel='bookmark' title='Permanent Link: Dead simple JavaScript Unit Testing in Rails'>Dead simple JavaScript Unit Testing in Rails</a> <small> Formats: Video/Screencast (410 Mb, torrent) | Video only (vimeo)...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m pretty excited about <a href="http://jashkenas.github.com/coffee-script/">CoffeeScript</a> as a clean-syntax replacement for pure JavaScript. </p>
<h3 id="what_is_coffeescript">What is CoffeeScript?</h3>
<p><img src="http://img.skitch.com/20100315-mq3h882gd6742tixy78mnbc5jt.png" width="550px"></p>
<p>Imagine all the syntactical delights of Ruby and Haml for your JavaScript. You write in a nice language, but get normal JavaScript at runtime. All whilst having full access to 3rd-party JavaScript libraries (jQuery, PrototypeJS), debugging support (it becomes pure, readable JavaScript), existing support from test suites (it&#8217;s normal JavaScript) and growing support from various text editors (<a href="http://github.com/jashkenas/coffee-script-tmbundle">TextMate</a>, <a href="http://github.com/jashkenas/coffee-script/blob/master/extras/coffee.vim">Vim</a>, <a href="http://github.com/defunkt/coffee-mode">Emacs</a>).</p>
<p>What simple delights?</p>
<p>No trailing semi-colons. No <code>{ some_code() }</code> function/closure brackets. String interpolation. Multi-line strings. Explicit <code>class</code> syntax. Array slicing. An existential ? operator.</p>
<p>Scroll down the <a href="http://jashkenas.github.com/coffee-script/">home page</a> for awesome example after example.</p>
<p>These aren&#8217;t library extensions. This is clean, purposeful syntax.</p>
<p>You can play with the joyful syntax of CoffeeScript on the website. After reading the basic examples on the <a href="http://jashkenas.github.com/coffee-script/">CoffeeScript home page</a>, press &#8220;TRY COFFEESCRIPT&#8221; in the header menu.</p>
<p>As you play with the syntax, the equivalent JavaScript is printed on the right hand side (see image above).</p>
<p>How nice is that syntax? Very.</p>
<h3 id="installing_coffeescript">Installing CoffeeScript</h3>
<ol>
<li>Install NodeJS</li>
<li>Install CoffeeScript</li>
</ol>
<p>For NodeJS (<a href="http://nodejs.org/#download">get latest release URL</a>; using 0.1.31 as 0.1.32 doesn&#8217;t unpack for me):</p>
<pre><code>cd /usr/local/src
wget http://nodejs.org/dist/node-v0.1.31.tar.gz
tar xfv node-v0.1.31.tar.gz
cd node-v0.1.31
./configure
make
sudo make install
</code></pre>
<p>For CoffeeScript (<a href="http://jashkenas.github.com/coffee-script/#installation">get latest release URL</a>):</p>
<pre><code>cd /usr/local/src
wget http://github.com/jashkenas/coffee-script/tarball/0.5.5
tar xfv jashkenas-coffee-script-bcf7b3f.tar.gz
cd jashkenas-coffee-script-bcf7b3f
sudo bin/cake install
</code></pre>
<p>Now test that everything is in place:</p>
<pre><code>$ coffee --version
CoffeeScript version 0.5.5
$ coffee -e "sys: require 'sys'; sys.puts 'hello world\n'"
hello world
</code></pre>
<p>Phew!</p>
<p>Note, in the command-line/on the server, you are using the NodeJS JavaScript environment. It supports the <a href="http://commonjs.org/">CommonJS</a> API for loading modules (normal JavaScript: <code>var sys = require('sys')</code>).</p>
<h3 id="um_but_how_do_i_use_it_in_my_web_app">Um, but how do I use it in my web app?</h3>
<p>Your application source code will have <code>*.coffee</code> files containing your sexy, short CoffeeScript. But at runtime, the browser needs the generated JavaScript.</p>
<p>I&#8217;ve been using the Jonas Nicklas&#8217; <a href="http://github.com/jnicklas/bistro_car">bistro_car</a> gem:</p>
<pre><code>gem install bistro_car
mkdir -p app/scripts
</code></pre>
<p>In your Rails <code>config/environment.rb</code> file, add:</p>
<pre><code>config.gem 'bistro_car'
</code></pre>
<p>And in your layouts, such as <code>app/views/layouts/application.html.erb</code> add to the <code>&lt;head&gt;</code> or the bottom:</p>
<pre><code>&lt;%= coffee_script_bundle %&gt;
</code></pre>
<p>Now you&#8217;re good to go. Add your CoffeeScript files in <code>app/scripts/*.coffee</code> and they will be automatically available as JavaScript.</p>
<h3 id="warning_check_your_version_of_coffeescript">WARNING: Check your version of CoffeeScript</h3>
<p>Check that this hasn&#8217;t happened:</p>
<pre><code>$ coffee --version
CoffeeScript version 0.3.2
$ which coffee
/usr/bin/coffee
</code></pre>
<p>Arrgh, we should be using <code>/usr/local/bin/coffee</code>. <code>bistro_car</code> currently installs the old rubygem-based version of coffee-script; and you might be unlucky to have your $PATH find the wrong one first.</p>
<p>Either delete it (<code>sudo rm /usr/bin/coffee</code> and restart your shell) or make sure <code>/usr/local/bin</code> is earlier in your <code>$PATH</code> than <code>/usr/bin</code>, where RubyGems installed the old, unnecessary version of <code>coffee</code> command.</p>
<h3 id="let8217s_drink_the_coffeescript">Let&#8217;s drink the CoffeeScript</h3>
<p>Create a file <code>app/scripts/application.coffee</code> with contents:</p>
<pre><code>powers: [1,2,3,4].map (i) -&gt; i * i
alert powers
</code></pre>
<p>Load up a view in a browser and see <code>[1,4,9,16]</code>. You win! Throw in some jQuery/PrototypeJS/whatever. Beautiful.</p>
<p>View the source of the page, navigate to <code>public/javascripts/bundle/default.js</code> and you&#8217;ll see the generated source:</p>
<pre class="sh_javascript"><code>(function(){
  var powers;
  powers = [1, 2, 3, 4].map(function(i) {
    return i * i;
  });
  alert(powers);
})();
</code></pre>
<h3 id="the_problem_heroku_doesn8217t_have_coffeescript_installed">The problem: Heroku doesn&#8217;t have CoffeeScript installed</h3>
<p>Heroku is a great place to host apps. Though it doesn&#8217;t have CoffeeScript installed so it cannot dynamically convert the <code>*.coffee</code> files into JavaScript.</p>
<p>If you want to use Heroku I guess we need to perform the conversion locally and deploy it.</p>
<p>But. In development and integration testing I want bistro_car&#8217;s dynamically generated <code>default.js</code>. In production, I need a cached version.</p>
<p>In <code>application.html.haml</code> I use (I can&#8217;t keep pretending I use erb):</p>
<pre class="sh_ruby"><code>- if Rails.env.production?
  = javascript_include_tag "coffeescripts"
- else
  = coffee_script_bundle
</code></pre>
<p>Now we&#8217;re just left with the hassle of automatically generating <code>public/javascripts/coffeescripts.js</code>.</p>
<p>First, a rake task. Second, a git pre-commit hook.</p>
<p>Create <code>lib/tasks/bistro_car.rake</code>:</p>
<pre class="sh_ruby"><code>desc "Generate the cached bundle/default.js file from app/scripts/*.coffee files"
task :bistro_car =&gt; :environment do
  path = "public/javascripts/coffeescripts.js"
  puts "Building *.coffee -&gt; #{path}"
  File.open(path, "w") { |file| file &lt;&lt; BistroCar::Bundle.new('default').to_javascript }
end

file "public/javascripts/coffeescripts.js" =&gt; Dir[File.join(Rails.root, 'app/scripts/*.coffee')] do |t|
  Rake::Task["bistro_car"].invoke
end
</code></pre>
<p>Now you can create <code>coffeescripts.js</code> and add it to the repo with:</p>
<pre><code>rake public/javascripts/coffeescripts.js
git add public/javascripts/coffeescripts.js
git commit -m "Initial bundled coffeescripts file"
</code></pre>
<p>Now create <code>.git/hooks/pre-commit</code>:</p>
<pre class="sh_sh"><code>#!/bin/sh

exec rake public/javascripts/coffeescripts.js
</code></pre>
<p>And make it executable (and <code>git commit</code> will invoke it automatically):</p>
<pre><code>chmod +x .git/hooks/pre-commit
</code></pre>
<p>Phew.</p>
<p>Now, whenever you change a *.coffee script and you are about to commit it, the cached-production-only <code>coffeescripts.js</code> is automatically updated and included in the same commit.</p>
<p>Seems like a clean hack.</p>
<h3 id="summary">Summary</h3>
<p>Why not make a library to do this? Well I&#8217;m hoping there is a better, cleaner way. Perhaps <code>bistro_car</code> can include a rails generator to package these bits and pieces itself, if my approach happens to be the best way.</p>
<p>Nonetheless, let history record that CoffeeScript is very cool though in the world of Heroku living with it is non-trivial at the moment.</p>


<p>Related posts:<ol><li><a href='http://drnicwilliams.com/2010/06/01/validate-and-save-your-ruby-in-textmate-with-secret-rubinus-superpowers/' rel='bookmark' title='Permanent Link: Validate and Save your Ruby in TextMate &#8211; with secret Rubinus superpowers'>Validate and Save your Ruby in TextMate &#8211; with secret Rubinus superpowers</a> <small>In some TextMate bundles, if you save a file it...</small></li><li><a href='http://drnicwilliams.com/2010/05/28/showcase-of-coffeescript-2-5-mins-for-your-next-dev-group-meeting/' rel='bookmark' title='Permanent Link: Showcase of CoffeeScript &#8211; 2.5 mins for your next Dev Group meeting'>Showcase of CoffeeScript &#8211; 2.5 mins for your next Dev Group meeting</a> <small> If you are giving an &#8220;Introduction to CoffeeScript&#8221; talk...</small></li><li><a href='http://drnicwilliams.com/2009/11/12/dead-simple-javascript-unit-testing-in-rails/' rel='bookmark' title='Permanent Link: Dead simple JavaScript Unit Testing in Rails'>Dead simple JavaScript Unit Testing in Rails</a> <small> Formats: Video/Screencast (410 Mb, torrent) | Video only (vimeo)...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://drnicwilliams.com/2010/03/15/using-coffeescript-in-rails-and-even-on-heroku/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Hacking someone&#8217;s gem with github and gemcutter</title>
		<link>http://drnicwilliams.com/2009/11/04/hacking-someones-gem-with-github-and-gemcutter/</link>
		<comments>http://drnicwilliams.com/2009/11/04/hacking-someones-gem-with-github-and-gemcutter/#comments</comments>
		<pubDate>Wed, 04 Nov 2009 06:44:17 +0000</pubDate>
		<dc:creator>Dr Nic</dc:creator>
				<category><![CDATA[Gems]]></category>
		<category><![CDATA[Mocra]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://drnicwilliams.com/?p=635</guid>
		<description><![CDATA[Ever used a rubygem, found a bug, and just wanted to quickly bust out the big guns and fix it quickly? The gem command doesn&#8217;t come packed with a way to find the original source repository for a gem. At best, most gems at least come bundled with the complete source, tests and documentation. Some [...]


Related posts:<ol><li><a href='http://drnicwilliams.com/2008/12/21/migrating-project-websites-to-github-pages-with-sake-tasks-new-websites-with-jekyll_generator/' rel='bookmark' title='Permanent Link: Migrating project websites to github pages with sake tasks, new websites with jekyll_generator'>Migrating project websites to github pages with sake tasks, new websites with jekyll_generator</a> <small> Its almost Christmas time and that means presents. It...</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><img src="http://img.skitch.com/20091104-fthwimr335wsm3rfgad9a7jh5k.jpg" alt="gemcutter" style="float: right"/></p>
<p>Ever used a rubygem, found a bug, and just wanted to quickly bust out the big guns and fix it quickly?</p>
<p>The <code>gem</code> command doesn&#8217;t come packed with a way to find the original source repository for a gem. At best, most gems at least come bundled with the complete source, tests and documentation. Some gems <a href="http://github.com/notahat/machinist/issues#issue/14">don&#8217;t</a>. Fair enough, since having access to the complete source via the gem still doesn&#8217;t allow you to fix a bug and share it with the world.</p>
<p>For that you access to the repo, a quick way to fork it, and a post-github way to share a gem version from yours truly.</p>
<p>The <code>github</code> gem and gemcutter are the modern day tools of master hackermanship.</p>
<h1 id="instant_forking_fun">Instant forking fun</h1>
<p>Let&#8217;s say you find a bug in a gem, say <code>rails</code>, and you want to go to town on its source.</p>
<p>You know the gem is called <code>rails</code> but you&#8217;ve no idea what the github repo is called. Never fear. </p>
<pre><code>$ gem sources -a http://gemcutter.org
$ sudo gem install github
$ gh clone --search rails
Select a repository to clone:
1.  rails/rails                         # Ruby on Rails
2.  technoweenie/restful-authentication # Generates common user ...
3.  justinfrench/formtastic             # A Rails form builder plugin ...
?
</code></pre>
<p>Press <code>1</code> and you&#8217;ll get a clone of <code>rails/rails</code>.</p>
<p>Alternately, if you want a fork or you know the exact user/repo already:</p>
<pre><code>$ gh clone rails/rails
</code></pre>
<p>Now, fork your own version:</p>
<pre><code>$ cd rails
$ gh fork
</code></pre>
<p>You now have your own fork. The <code>origin</code> remote also now points to your fork rather than the <code>rails/rails</code> repository:</p>
<pre><code>$ git remote show origin
* remote origin
  Fetch URL: git@github.com:drnic/rails.git
  Push  URL: git@github.com:drnic/rails.git
</code></pre>
<p>So, make your changes, push them. Send a pull request or github issue or lighthouse ticket or what have you.</p>
<p>Want to get to the github project home page for your fork?</p>
<pre><code>$ gh home
</code></pre>
<h1 id="instant_gem_sharing">Instant gem sharing</h1>
<p>Let&#8217;s say you patched the <code>rails</code> gem <a href="http://github.com/drnic/rails/commit/3c26910cfd5aa4b484d63e912b3881c31f19782a">itself</a> but you want to share your changes via your own gem.</p>
<p>In the olden days, github did this for you. Now you use <a href="http://gemcutter.org/">gemcutter</a>, and a little manual effort to do your own renaming.</p>
<p>First, install the gems locally, use them, and make sure all is good.</p>
<p>For rails, you install the edge gems (3.0.pre) with:</p>
<pre><code>$ rake install
</code></pre>
<p>You can&#8217;t see &#8216;rake install&#8217; in the <code>rake -T</code> list (hence my patch), but I think the following expression displays all tasks regardless if they have a description or not:</p>
<pre><code>$ rake -P | grep "^r"
</code></pre>
<p>Rails is composed of several gems, unlike most projects that are distributed as a single gem. Here we want to share our commit within a new <code>drnic-rails</code> gem, but not touch the others.</p>
<p>Edit the <code>railties/rails.gemspec</code> file from:</p>
<pre><code>Gem::Specification.new do |s|
  s.platform = Gem::Platform::RUBY
  s.name = 'rails'
  s.version = '3.0.pre'
...
</code></pre>
<p>and give your personal gem a new name:</p>
<pre><code>Gem::Specification.new do |s|
  s.platform = Gem::Platform::RUBY
  s.name = 'drnic-rails'
  s.version = '3.0.pre'
</code></pre>
<p>To build and distribute the new gem:</p>
<pre><code>$ gem build railties/rails.gemspec
$ sudo gem install gemcutter
$ gem push drnic-rails-3.0.pre.gem
  Pushing gem to Gemcutter...
  Successfully registered gem: drnic-rails (3.0.pre)
</code></pre>
<p>Follow any first-time gemcutter instructions and SUCCESS! Now I have my own <a href="http://gemcutter.org/gems/drnic-rails">drnic-rails</a> gem.</p>
<h1 id="summary">Summary</h1>
<p>To find, clone, and fork any rubygem that is hosted on github:</p>
<pre><code>$ sudo gem install drnic-github
$ gh clone --search rails
$ gh fork
</code></pre>
<p>To personalise the gem and share it on gemcutter:</p>
<pre><code>&gt; edit the project.gemspec to have a unique name, e.g. yourname-project
$ gem build project.gemspec
$ sudo gem install gemcutter
$ gem push yourname-project-1.0.0.gem
</code></pre>
<p>I think this makes it much easier, faster and more fun to hack other people&#8217;s stuff.</p>


<p>Related posts:<ol><li><a href='http://drnicwilliams.com/2008/12/21/migrating-project-websites-to-github-pages-with-sake-tasks-new-websites-with-jekyll_generator/' rel='bookmark' title='Permanent Link: Migrating project websites to github pages with sake tasks, new websites with jekyll_generator'>Migrating project websites to github pages with sake tasks, new websites with jekyll_generator</a> <small> Its almost Christmas time and that means presents. It...</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>]]></content:encoded>
			<wfw:commentRss>http://drnicwilliams.com/2009/11/04/hacking-someones-gem-with-github-and-gemcutter/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
		<item>
		<title>First look at rails 3.0.pre</title>
		<link>http://drnicwilliams.com/2009/11/03/first-look-at-rails-3-0-pre/</link>
		<comments>http://drnicwilliams.com/2009/11/03/first-look-at-rails-3-0-pre/#comments</comments>
		<pubDate>Tue, 03 Nov 2009 04:05:16 +0000</pubDate>
		<dc:creator>Dr Nic</dc:creator>
				<category><![CDATA[Mocra]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://drnicwilliams.com/?p=630</guid>
		<description><![CDATA[This article is out of date in some aspects. See comments, and perhaps this summary of reading materials about Rails 3. Today I had my first look at rails 3.0.pre and below are the sequence of steps I had to take to create a rails 3.0.pre application, and get it&#8217;s generators to work. Why was [...]


Related posts:<ol><li><a href='http://drnicwilliams.com/2010/03/15/using-coffeescript-in-rails-and-even-on-heroku/' rel='bookmark' title='Permanent Link: Using CoffeeScript in Rails and even on Heroku'>Using CoffeeScript in Rails and even on Heroku</a> <small>I&#8217;m pretty excited about CoffeeScript as a clean-syntax replacement for...</small></li><li><a href='http://drnicwilliams.com/2009/11/12/dead-simple-javascript-unit-testing-in-rails/' rel='bookmark' title='Permanent Link: Dead simple JavaScript Unit Testing in Rails'>Dead simple JavaScript Unit Testing in Rails</a> <small> Formats: Video/Screencast (410 Mb, torrent) | Video only (vimeo)...</small></li><li><a href='http://drnicwilliams.com/2009/10/07/rails-themes-can-remember-things/' rel='bookmark' title='Permanent Link: Rails themes can remember things'>Rails themes can remember things</a> <small>I was getting annoyed at having to remember all the...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<div class="notice">
<p>This article is out of date in some aspects. See <a href="http://drnicwilliams.com/2009/11/03/first-look-at-rails-3-0-pre/#comments">comments</a>, and perhaps this summary of <a href="http://mediumexposure.com/rails-3-reading-material/">reading materials</a> about Rails 3.</p>
</div>
<p><img src="http://img.skitch.com/20091103-q3w8qjy8wmr3e9wasjqc95nf6g.jpg" alt="3.pre" style="float: right" /></p>
<p>Today I had my first look at rails 3.0.pre and below are the sequence of steps I had to take to create a rails 3.0.pre application, and get it&#8217;s generators to work.</p>
<p>Why was I looking at the top-secret, yet open-source Rails 3.0? Their generators are being migrated over to Thor and I wanted to see them in action. I was thinking I might migrate newgem to use Thor too.</p>
<p>Here&#8217;s a quick poke around of getting started and interesting things I found. Any hiccups and workarounds are meant as a guide to pre-pre-3.0 users/developers and not as a criticism of rails-core. Rails 3.0 is looking shiny and awesome.</p>
<p>NOTE: Since this is a &#8220;how to install and use&#8221; rails 3.0 edge, which is still in heavy development, this set of instructions might break. Let&#8217;s hope not.</p>
<h2 id="getting_started">Getting Started</h2>
<p>As of today, you cannot install 3.0.pre from rubygems [1]. So, let&#8217;s install them from source. Which is handy, you might like to patch something.</p>
<pre><code>$ cd ~/gems
$ git clone git://github.com/rails/rails.git
use_ruby_191 *
</code></pre>
<p>[*] If you are on OS X Snow Leopard I think you can ignore this. Otherwise, since you don&#8217;t have the 3.0.pre gems installed, you&#8217;re about to hit bump #1. Ruby 1.8.6 doesn&#8217;t have <code>Symbol#to_proc</code> but it&#8217;s required to create a rails app. This means you&#8217;ll need to be able to switch to another version of ruby temporarily if you&#8217;re on ruby 1.8.6 [2].</p>
<pre><code>cd ~/Sites
ruby ~/gems/rails/railties/bin/rails
</code></pre>
<p>Oooh, look at all the new options! Some new ones are:</p>
<pre><code>-F, [--freeze]             # Freeze Rails in vendor/rails from the gems
-O, [--skip-activerecord]  # Skip ActiveRecord files
-T, [--skip-testunit]      # Skip TestUnit files
-J, [--skip-prototype]     # Skip Prototype files
</code></pre>
<p>The <code>-D, --with-dispatchers</code> flags have been removed. <code>--freeze</code> isn&#8217;t new, but <code>-F</code> is.</p>
<p>So, to create an app, I dutifully used:</p>
<pre><code>ruby ~/gems/rails/railties/bin/rails edgerailsapp -F
</code></pre>
<p>BAM! Fail. The -F option to freeze/vendor rails fails without the gems installed. So don&#8217;t use it.</p>
<pre><code>ruby ~/gems/rails/railties/bin/rails edgerailsapp
ln -s ~/gems/rails vendor/rails
</code></pre>
<p>If you&#8217;re on Windows without the symlink command <code>ln</code>, then copy the downloaded rails source into <code>vendor/rails</code>.</p>
<h3 id="fetch_rails8217_dependencies">Fetch Rails&#8217; dependencies</h3>
<p>Rails 3.0 source uses the new bundler project to describe its own dependencies. From <a href="http://litanyagainstfear.com/blog/2009/10/14/gem-bundler-is-the-future/">Nick Quaranto&#8217;s article on bundler</a>, get the latest:</p>
<pre><code>cd ~/gems
git clone git://github.com/wycats/bundler
cd bundler
sudo rake install
</code></pre>
<p>Now, back in your app, you need to install some rails dependencies here too. It&#8217;s a good chance to see how you&#8217;ll bundle gem dependencies in the future.</p>
<pre><code>$ cd ~/Sites/edgerailsapp
</code></pre>
<p>Change the <code>Gemfile</code> in your project to the following:</p>
<pre><code>gem "rack",          "1.0.1"
gem "rack-mount",    :git =&gt; "git://github.com/rails/rack-mount.git"
gem "rack-test",     "~&gt; 0.5.0"
gem "erubis",        "~&gt; 2.6.0"
gem "arel",          :git =&gt; "git://github.com/rails/arel.git"
gem "sqlite3-ruby"
gem "rails", "3.0.pre", :git =&gt; "git://github.com/rails/rails.git"
</code></pre>
<p>Welcome to the future of gem dependencies for rails apps. Ultimately you won&#8217;t need to manually add these lines yourself. When rails is distributed as gems it will automatically install these for you, I assume/hope/guess. But for today, you seem to need them.</p>
<p>Now locally (within your app) install these gems:</p>
<pre><code>$ gem bundle
</code></pre>
<p>If you get &#8220;can&#8217;t convert Pathname into String&#8221; then revert to ruby 1.8.X and reinstall bundler into your 1.8 gem cache.</p>
<p>Phew. Ooh, my god. Phew. Only now will <code>script/generate</code> work.</p>
<pre><code>$ script/generate
</code></pre>
<p>For me, this outputs:</p>
<pre><code>Please select a generator.
Builtin: app, controller, generator, helper, integration_test, mailer, metal, migration, model, model_subclass, observer, performance_test, plugin, resource, scaffold, scaffold_controller, session_migration, stylesheets.
Others: app_layout:app_layout, check_migration_version:check_migration_version, home_route:home_route.
</code></pre>
<p>The &#8220;Builtin&#8221; generators are the latest and greatest in Thor technology. Rails 3.0 no longer uses its own generator but is built upon Thor.</p>
<p>For example, our old favourite <code>model</code> generator works thusly:</p>
<pre><code>$ script/generate model Post title:string --no-fixture
    invoke  active_record
    create    db/migrate/20091103030824_create_posts.rb
    create    app/models/post.rb
    invoke    test_unit
    create      test/unit/post_test.rb
</code></pre>
<p>Interestingly, <code>--no-fixture</code> isn&#8217;t mentioned in the usage information for <code>script/generate model</code>. It mentions the <code>--fixture</code> flag, but I had to guess that <code>--no-fixture</code> was also supported.</p>
<p>Hmm, I want to use rspec. So, let&#8217;s destroy these files:</p>
<pre><code>$ script/destroy model Post title:string
      invoke  active_record
.../vendor/gems/dirs/rails/railties/lib/rails/generators/active_record.rb:14:in
  `next_migration_number': uninitialized constant ActiveRecord::Base (NameError)
</code></pre>
<p>Oh well.</p>
<p>What if I wanted to run rspec and cucumber generators, for example, against an edge rails app?</p>
<h2 id="rails_2_generators">Rails 2 generators</h2>
<p>The &#8220;Others&#8221; generators are my own local generators from <code>~/.rails/generators</code>. Amusingly, instead of <code>app_layout</code> it is called <code>app_layout:app_layout</code>. Not surprisingly at all, if I try to run the rails 2 generator it fails:</p>
<pre><code>$ script/generate app_layout:app_layout
[WARNING] Could not load generator at "/Users/drnic/.rails/generators/app_layout/app_layout_generator.rb". Error: uninitialized constant Rails::Generator
Could not find generator app_layout:app_layout.
</code></pre>
<p>Poop. </p>
<p>Note, I have rspec, rspec-rails and cucumber gems installed locally but I cannot see their rails generators above. Rails 3 doesn&#8217;t look for generators in the same way and old Rails 2 generators don&#8217;t work anymore.</p>
<p>That&#8217;s the news: every rails 2 generator is broken. </p>
<p>When I start to migrate some of mine I&#8217;ll post about it. In the meantime, <a href="http://twitter.com/josevalim">José Valim</a> has written some introduction thoughts on <a href="http://blog.plataformatec.com.br/2009/07/creating-your-own-generators-with-thor/">using Thor as a generator</a>.</p>
<p>You can also probably learn about how to write rails 3.0 generators by looking at the source code for the new generators like <a href="http://github.com/rails/rails/blob/master/railties/lib/rails/generators/rails/app/app_generator.rb">rails</a>, model (see <a href="http://github.com/rails/rails/blob/master/railties/lib/rails/generators/rails/model/model_generator.rb">main</a> and  <a href="http://github.com/rails/rails/blob/master/railties/lib/rails/generators/test_unit/model/model_generator.rb">test_unit</a>), and <a href="http://github.com/rails/rails/blob/master/railties/lib/rails/generators/rails/resource/resource_generator.rb">scaffold/resource</a>.</p>
<p>Finally, José Valim has a <a href="http://github.com/josevalim/third_rails">sample Rails 3 app</a> with some vendored generators in it.</p>
<p>These are the things I&#8217;m researching now.</p>
<h2 id="summary">Summary</h2>
<p>This article is long, mostly because rails 3.0.pre hasn&#8217;t been released as a set of RubyGems. If it had, then all the dependencies would be installed automatically.</p>
<p>It also introduces gem/plugin writers to the first upgrade issue: your current generators are neither discovered nor work by a rails 3.0 app. We&#8217;re all clever cookies, so here&#8217;s hoping we can figure out the upgrade path and that it&#8217;s simple enough to not be the topic of Dan Brown&#8217;s next book.</p>
<h2 id="footnotes">Footnotes</h2>
<p>[1] Two portions of rails 3.0.pre are available as pre-release gems: activesupport (which is now very modularised and only loads up the parts that you require) and activemodel (which is shiny and new and hence completely safe for rails-core to release).</p>
<p>[2] There are two popular ways to have easy, non-intrusive access to alternate versions of ruby: <a href="http://www.rubyinside.com/rvm-ruby-version-manager-2347.html">rvm</a> and <a href="http://blog.thinkrelevance.com/2009/7/29/ruby-switcher-working-with-multiple-ruby-versions-has-never-been-this-easy">ruby_switcher.sh</a>.</p>


<p>Related posts:<ol><li><a href='http://drnicwilliams.com/2010/03/15/using-coffeescript-in-rails-and-even-on-heroku/' rel='bookmark' title='Permanent Link: Using CoffeeScript in Rails and even on Heroku'>Using CoffeeScript in Rails and even on Heroku</a> <small>I&#8217;m pretty excited about CoffeeScript as a clean-syntax replacement for...</small></li><li><a href='http://drnicwilliams.com/2009/11/12/dead-simple-javascript-unit-testing-in-rails/' rel='bookmark' title='Permanent Link: Dead simple JavaScript Unit Testing in Rails'>Dead simple JavaScript Unit Testing in Rails</a> <small> Formats: Video/Screencast (410 Mb, torrent) | Video only (vimeo)...</small></li><li><a href='http://drnicwilliams.com/2009/10/07/rails-themes-can-remember-things/' rel='bookmark' title='Permanent Link: Rails themes can remember things'>Rails themes can remember things</a> <small>I was getting annoyed at having to remember all the...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://drnicwilliams.com/2009/11/03/first-look-at-rails-3-0-pre/feed/</wfw:commentRss>
		<slash:comments>36</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[Mocra]]></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 [...]


Related posts:<ol><li><a href='http://drnicwilliams.com/2010/03/15/using-coffeescript-in-rails-and-even-on-heroku/' rel='bookmark' title='Permanent Link: Using CoffeeScript in Rails and even on Heroku'>Using CoffeeScript in Rails and even on Heroku</a> <small>I&#8217;m pretty excited about CoffeeScript as a clean-syntax replacement for...</small></li><li><a href='http://drnicwilliams.com/2009/11/12/dead-simple-javascript-unit-testing-in-rails/' rel='bookmark' title='Permanent Link: Dead simple JavaScript Unit Testing in Rails'>Dead simple JavaScript Unit Testing in Rails</a> <small> Formats: Video/Screencast (410 Mb, torrent) | Video only (vimeo)...</small></li><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></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/2010/03/15/using-coffeescript-in-rails-and-even-on-heroku/' rel='bookmark' title='Permanent Link: Using CoffeeScript in Rails and even on Heroku'>Using CoffeeScript in Rails and even on Heroku</a> <small>I&#8217;m pretty excited about CoffeeScript as a clean-syntax replacement for...</small></li><li><a href='http://drnicwilliams.com/2009/11/12/dead-simple-javascript-unit-testing-in-rails/' rel='bookmark' title='Permanent Link: Dead simple JavaScript Unit Testing in Rails'>Dead simple JavaScript Unit Testing in Rails</a> <small> Formats: Video/Screencast (410 Mb, torrent) | Video only (vimeo)...</small></li><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></ol></p>]]></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 [...]


Related posts:<ol><li><a href='http://drnicwilliams.com/2009/10/07/hash-bang-cucumber/' rel='bookmark' title='Permanent Link: hash bang cucumber'>hash bang cucumber</a> <small>I don&#8217;t know if this is a good idea or...</small></li><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></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/10/07/hash-bang-cucumber/' rel='bookmark' title='Permanent Link: hash bang cucumber'>hash bang cucumber</a> <small>I don&#8217;t know if this is a good idea or...</small></li><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></ol></p>]]></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>Closing in on The Dream: &#8220;one-click-to-deploy Rails apps&#8221;</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[Mocra]]></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 [...]


Related posts:<ol><li><a href='http://drnicwilliams.com/2010/03/15/using-coffeescript-in-rails-and-even-on-heroku/' rel='bookmark' title='Permanent Link: Using CoffeeScript in Rails and even on Heroku'>Using CoffeeScript in Rails and even on Heroku</a> <small>I&#8217;m pretty excited about CoffeeScript as a clean-syntax replacement for...</small></li><li><a href='http://drnicwilliams.com/2009/11/12/dead-simple-javascript-unit-testing-in-rails/' rel='bookmark' title='Permanent Link: Dead simple JavaScript Unit Testing in Rails'>Dead simple JavaScript Unit Testing in Rails</a> <small> Formats: Video/Screencast (410 Mb, torrent) | Video only (vimeo)...</small></li><li><a href='http://drnicwilliams.com/2009/11/03/first-look-at-rails-3-0-pre/' rel='bookmark' title='Permanent Link: First look at rails 3.0.pre'>First look at rails 3.0.pre</a> <small> This article is out of date in some aspects....</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/2010/03/15/using-coffeescript-in-rails-and-even-on-heroku/' rel='bookmark' title='Permanent Link: Using CoffeeScript in Rails and even on Heroku'>Using CoffeeScript in Rails and even on Heroku</a> <small>I&#8217;m pretty excited about CoffeeScript as a clean-syntax replacement for...</small></li><li><a href='http://drnicwilliams.com/2009/11/12/dead-simple-javascript-unit-testing-in-rails/' rel='bookmark' title='Permanent Link: Dead simple JavaScript Unit Testing in Rails'>Dead simple JavaScript Unit Testing in Rails</a> <small> Formats: Video/Screencast (410 Mb, torrent) | Video only (vimeo)...</small></li><li><a href='http://drnicwilliams.com/2009/11/03/first-look-at-rails-3-0-pre/' rel='bookmark' title='Permanent Link: First look at rails 3.0.pre'>First look at rails 3.0.pre</a> <small> This article is out of date in some aspects....</small></li></ol></p>]]></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[Mocra]]></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 [...]


Related posts:<ol><li><a href='http://drnicwilliams.com/2009/11/12/dead-simple-javascript-unit-testing-in-rails/' rel='bookmark' title='Permanent Link: Dead simple JavaScript Unit Testing in Rails'>Dead simple JavaScript Unit Testing in Rails</a> <small> Formats: Video/Screencast (410 Mb, torrent) | Video only (vimeo)...</small></li><li><a href='http://drnicwilliams.com/2009/10/07/hash-bang-cucumber/' rel='bookmark' title='Permanent Link: hash bang cucumber'>hash bang cucumber</a> <small>I don&#8217;t know if this is a good idea or...</small></li><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></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/11/12/dead-simple-javascript-unit-testing-in-rails/' rel='bookmark' title='Permanent Link: Dead simple JavaScript Unit Testing in Rails'>Dead simple JavaScript Unit Testing in Rails</a> <small> Formats: Video/Screencast (410 Mb, torrent) | Video only (vimeo)...</small></li><li><a href='http://drnicwilliams.com/2009/10/07/hash-bang-cucumber/' rel='bookmark' title='Permanent Link: hash bang cucumber'>hash bang cucumber</a> <small>I don&#8217;t know if this is a good idea or...</small></li><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></ol></p>]]></content:encoded>
			<wfw:commentRss>http://drnicwilliams.com/2009/03/26/testing-outbound-emails-with-cucumber/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
	</channel>
</rss>

