<?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>Pivotal Labs &#187; Stephan Hagemann</title>
	<atom:link href="http://pivotallabs.com/author/shagemann/feed/" rel="self" type="application/rss+xml" />
	<link>http://pivotallabs.com</link>
	<description>Agility Developed</description>
	<lastBuildDate>Sat, 25 May 2013 22:23:05 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>Showing and hiding conditional HTML without Javascript</title>
		<link>http://pivotallabs.com/conditional-html-forms-without-javascript/</link>
		<comments>http://pivotallabs.com/conditional-html-forms-without-javascript/#comments</comments>
		<pubDate>Tue, 21 May 2013 05:27:24 +0000</pubDate>
		<dc:creator>Stephan Hagemann</dc:creator>
				<category><![CDATA[Labs]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://pivotallabs.com/?p=19039</guid>
		<description><![CDATA[<p>Have you ever filled out an address form that had a checkbox for &#8220;my shipping address differs from my mailing address&#8221;? When you click that box a conditional form part gets revealed that allows you to enter another address. We had to build something very similar the other day and stumbled on a neat way to make the conditional part show and hide with CSS only. Here is how: &#60;style&#62; .conditional_form_part { display: none; } .conditional_form_part_activator:checked + .conditional_form_part { display: block; } &#60;/style&#62; &#60;form&#62; Mailing address differs from home address &#60;input class="conditional_form_part_activator" type="checkbox"&#62; &#60;div class="conditional_form_part"&#62; some other content &#60;/div&#62; &#60;/form&#62; Here is a jsfiddle of the result: As you can see from the CSS section, the trick is the combination of the :checked pseudo selector with the + selector. When elements like radio and checkbox are checked, the :checked selector applies. The + selector applies when an element immediately follows&#8230;</p><p>The post <a href="http://pivotallabs.com/conditional-html-forms-without-javascript/">Showing and hiding conditional HTML without Javascript</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>Have you ever filled out an address form that had a checkbox for &#8220;my shipping address differs from my mailing address&#8221;? When you click that box a conditional form part gets revealed that allows you to enter another address. We had to build something very similar the other day and stumbled on a neat way to make the conditional part show and hide with CSS only.<br />
<span id="more-19039"></span><br />
Here is how:</p>
<pre><code>&lt;style&gt;
  .conditional_form_part {
    display: none;
  }

  .conditional_form_part_activator:checked + .conditional_form_part {
    display: block;
  }
&lt;/style&gt;

&lt;form&gt;
    Mailing address differs from home address
    &lt;input class="conditional_form_part_activator" type="checkbox"&gt;

    &lt;div class="conditional_form_part"&gt;
        some other content
    &lt;/div&gt;
&lt;/form&gt;</code></pre>
<p>Here is a jsfiddle of the result:</p>
<p><iframe src="http://jsfiddle.net/jBxnT/embedded/result,html,css,js" height="300" width="100%" allowfullscreen="allowfullscreen" frameborder="0"></iframe></p>
<p>As you can see from the CSS section, the trick is the combination of the <code>:checked</code> pseudo selector with the <code>+</code> selector. When elements like radio and checkbox are checked, the <code>:checked</code> selector applies. The <code>+</code> selector applies when an element immediately follows another element. In combination we can target the immediate sibling of a checked checkbox and use that for styling.</p>
<p>There are a couple of other CSS selectors that allow you to extend this example, e.g., the tilde operator, which selects any following element. Better <a href="http://www.w3.org/TR/css3-selectors/">brush up on your CSS selectors</a>.</p>
<h1>YMWBL &#8211; Your Mileage Will Be Limited</h1>
<p>Note, that you would not be able to make this example work, if the checkbox were wrapped in a <code>label</code> (or any other element). There is no selector with which you could target the conditional form part in that case. </p>
<p>As far as structural queries go, CSS is limited in expressive power to only allow selection deeper into the document tree (i.e., with the <code>&gt;</code> (child) selector) or downward within the current level (with <code>+</code> or <code>~</code>), but never upwards within the tree.</p>
<p>The post <a href="http://pivotallabs.com/conditional-html-forms-without-javascript/">Showing and hiding conditional HTML without Javascript</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://pivotallabs.com/conditional-html-forms-without-javascript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My must-see list from MWRC 2013</title>
		<link>http://pivotallabs.com/my-must-see-list-from-mwrc-2013/</link>
		<comments>http://pivotallabs.com/my-must-see-list-from-mwrc-2013/#comments</comments>
		<pubDate>Sun, 05 May 2013 02:55:35 +0000</pubDate>
		<dc:creator>Stephan Hagemann</dc:creator>
				<category><![CDATA[Labs]]></category>
		<category><![CDATA[conferences]]></category>

		<guid isPermaLink="false">http://pivotallabs.com/?p=18764</guid>
		<description><![CDATA[<p>TL;DR If you watch one talk from Mountain West Ruby 2013, watch Greg Baugues: Devs and Depression. Talks @ Mountain West Ruby Conference Mountain West Ruby, was a great conference: lots of content and awesome people. It had one DevOps day and two Ruby days. Its presentations have recently been posted on confreaks. There were a total of four talks by Pivots, including one by myself (in order of appearance): Andy Pliszka: Extending CRuby with native Graph data type. Matt Kocher: Ruby off the Rails: Building a distributed system in Ruby. Stephan Hagemann: Component-based Architectures in Ruby and Rails. Sarah Mei: Work, Play &#38; Code. What follows is the list of talks that I recommend watching. There is one talk that I want to highlight within my list of highlights: &#8220;Devs and Depression&#8221;. It is the last one in this list and as you can guess it is not about technology.&#8230;</p><p>The post <a href="http://pivotallabs.com/my-must-see-list-from-mwrc-2013/">My must-see list from MWRC 2013</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></description>
				<content:encoded><![CDATA[<h2>TL;DR</h2>
<p>If you watch one talk from Mountain West Ruby 2013, watch Greg Baugues: <a href="http://confreaks.com/videos/2341-mwrc2013-devs-and-depression">Devs and Depression</a>.</p>
<h2>Talks @ Mountain West Ruby Conference</h2>
<p><a href="http://mtnwestrubyconf.org/">Mountain West Ruby</a>, was a great conference: lots of content and awesome people. It had one DevOps day and two Ruby days. Its presentations have recently been posted on confreaks.</p>
<p>There were a total of four talks by Pivots, including one by myself (in order of appearance):</p>
<ul>
<li>Andy Pliszka: <a href="http://confreaks.com/videos/2351-mwrc2013-extending-cruby-with-native-graph-data-type">Extending CRuby with native Graph data type</a>.</li>
<li>Matt Kocher: <a href="http://confreaks.com/videos/2367-mwrc2013-ruby-off-the-rails-building-a-distributed-system-in-ruby">Ruby off the Rails: Building a distributed system in Ruby</a>.</li>
<li>Stephan Hagemann: <a href="http://confreaks.com/videos/2350-mwrc2013-component-based-architectures-in-ruby-and-rails">Component-based Architectures in Ruby and Rails</a>.</li>
<li>Sarah Mei: <a href="http://confreaks.com/videos/2333-mwrc2013-work-play-code">Work, Play &amp; Code</a>.</li>
</ul>
<p>What follows is the list of talks that I recommend watching.</p>
<p>There is one talk that I want to highlight within my list of highlights: &#8220;Devs and Depression&#8221;. It is the last one in this list and as you can guess it is not about technology. It&#8217;s different, bold, and in my opinion very important. Watch it!</p>
<p>Alright, here we go&#8230;</p>
<h2>DevOps Day</h2>
<p>Gene Kim: <a href="http://confreaks.com/videos/2353-mwrc2013-why-we-need-devops-now-a-fourteen-year-study-of-high-performing-it-organizations">Why we need devops?</a> - 30000 feet view of why devops is valuable and how to do it. It&#8217;s a 3 trillion market.</p>
<p>Will Farrington: <a href="http://confreaks.com/videos/2355-mwrc2013-boxen-how-to-manage-an-army-of-laptops-and-live-to-talk-about-it">Boxen: How to manage an army of laptops</a> &#8211; Some impressive stuff github is doing for machine management.</p>
<p>Lindsay Holmwood: <a href="http://confreaks.com/videos/2360-mwrc2013-escalating-complexity-devops-learnings-from-air-france-447">Escalating complexity: DevOps learnings from Air France 447</a> - Chilling: Case study of an airplane crash. Systems within complex systems. Local vs global rationality.</p>
<p><strong>If you want more:</strong></p>
<p>James Turnbull: <a href="http://confreaks.com/videos/2354-mwrc2013-hell-has-frozen-over-devops-security">Hell has frozen over: DevOps &amp; Security</a> &#8211; How security people should change their work and how they talk about it.</p>
<p>Drew Blas: <a href="http://confreaks.com/videos/2361-mwrc2013-migrating-a-live-site-across-the-country-without-downtime">Migrating a live site across the country without downtime</a> &#8211; Actionable story on how to move data centers.</p>
<p>Jesse Newland: <a href="http://confreaks.com/videos/2359-mwrc2013-chatops-at-github">ChatOps at Github</a> &#8211; Using hubot (in campfire chat) to manage puppet (and everything). Documenting, interacting, interfacing among remote teams.</p>
<h2>Ruby Day 1</h2>
<p>Yukihiro Matsumoto: <a href="http://confreaks.com/videos/2334-mwrc2013-ruby-2-0">Ruby 2.0</a> &#8211; History of Ruby and features of Ruby 2.0. Maybe don&#8217;t watch if you already know about the new features. Maybe watch it, because its Matz.</p>
<p>Michael Fairley: <a href="http://confreaks.com/videos/2337-mwrc2013-immutable-ruby">Immutable Ruby</a> &#8211; How immutability can benefit your code.</p>
<p>Daniel Huckstep: <a href="http://confreaks.com/videos/2347-mwrc2013-ruby-batteries-included">Ruby Batteries Included</a> &#8211; Don&#8217;t require gems: Use the Ruby Standard Library.</p>
<p>Ryan Davis: <a href="http://confreaks.com/videos/2343-mwrc2013-trolls-of-2013">Trolls of 2013</a> &#8211; Not abut trolls, but implementing an interpreter in Ruby. Talk got cancelled on the first day, due to a fire alarm. Way to deal with it Ryan!</p>
<p><strong>If you want more:</strong></p>
<p>John Pignata: <a href="http://confreaks.com/videos/2336-mwrc2013-code-smells-your-refactoring-cheat-codes">Code Smells: Your Refactoring Cheat Codes</a> &#8211; Run through a long list of code smells and refactorings.</p>
<h2>Ruby Day 2</h2>
<p>Brandon Keepers: <a href="http://confreaks.com/videos/2348-mwrc2013-ruby-at-github">Ruby at Github</a> &#8211; Musings on Ruby: when to use, why to use. And problems (over time) in a big setup.</p>
<p>Craig Kerstins: <a href="http://confreaks.com/videos/2338-mwrc2013-postgres-demystified">Postgres Demystified</a> &#8211; Lots of stuff you did not know about Postgres.</p>
<p>Greg Baugues: <a href="http://confreaks.com/videos/2341-mwrc2013-devs-and-depression">Devs and Depression</a> &#8211; Personal story of mental illness. Talks about depression and why we should be more attentive to our fellow developers.</p>
<p>The post <a href="http://pivotallabs.com/my-must-see-list-from-mwrc-2013/">My must-see list from MWRC 2013</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://pivotallabs.com/my-must-see-list-from-mwrc-2013/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GoSpotCheck Is Looking For A Web Application Developer</title>
		<link>http://pivotallabs.com/gospotcheck-is-looking-for-a-web-application-developer/</link>
		<comments>http://pivotallabs.com/gospotcheck-is-looking-for-a-web-application-developer/#comments</comments>
		<pubDate>Wed, 20 Feb 2013 15:52:26 +0000</pubDate>
		<dc:creator>Stephan Hagemann</dc:creator>
				<category><![CDATA[Labs]]></category>
		<category><![CDATA[boulder]]></category>
		<category><![CDATA[jobs]]></category>

		<guid isPermaLink="false">http://pivotallabs.com/?p=15473</guid>
		<description><![CDATA[<p>At Pivotal Labs, one of the services we provide our clients is helping them interview and hire. Pivotal Labs and our clients place a strong emphasis on Agile development and its many aspects: Pair Programming, Test-Driven Development, rapid iterations, and frequent refactoring. LEAD DEVELOPER GoSpotCheck is seeking a Ruby developer to join our growing team and take an integral role in building our product. GoSpotCheck is a simple way to collect, structure, and share retail intelligence for distributed ﬁeld teams. We have mobile applications for capturing data and a web application for digesting and analyzing ﬁeld intelligence. Our applications streamline the process of getting from data to insights to action for enterprise retail customers, enabling them to more effectively manage retail execution. JOB REQUIREMENTS Proven experience in development of ﬂexible and scalable web-based applications Passion for technology, speciﬁcally software development 2+ years of experience with Ruby language and the Rails framework, be proﬁcient with the&#8230;</p><p>The post <a href="http://pivotallabs.com/gospotcheck-is-looking-for-a-web-application-developer/">GoSpotCheck Is Looking For A Web Application Developer</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>At Pivotal Labs, one of the services we provide our clients is helping them interview and hire. Pivotal Labs and our clients place a strong emphasis on Agile development and its many aspects: Pair Programming, Test-Driven Development, rapid iterations, and frequent refactoring.</p>
<p>LEAD DEVELOPER<br />
GoSpotCheck is seeking a Ruby developer to join our growing team and take an integral role in building our product. GoSpotCheck is a simple way to collect, structure, and share retail intelligence for distributed ﬁeld teams. We have mobile applications for capturing data and a web application for digesting and analyzing ﬁeld intelligence. Our applications streamline the process of getting from data to insights to action for enterprise retail customers, enabling them to more effectively manage retail execution.</p>
<p>JOB REQUIREMENTS</p>
<ul>
<li>Proven experience in development of ﬂexible and scalable web-based applications</li>
<li>Passion for technology, speciﬁcally software development</li>
<li>2+ years of experience with Ruby language and the Rails framework, be proﬁcient with the entire Ruby on Rails stack</li>
<li>3+ years of hands-on web development, demonstrating:</li>
<li>Proﬁciency with HTML/XHTML, CSS, JavaScript and JQuery</li>
<li>Sound object oriented design skills and knowledge of application architecture patterns</li>
<li>Proﬁciency with relational databases, including design and development</li>
<li>Working knowledge in development of MVC-based web solutions</li>
<li>Competency managing source control and automated build processes</li>
<li>Excellent analytical and problem solving skills</li>
<li>Strong communication and interpersonal skills</li>
<li>Android and iOS a big plus</li>
</ul>
<p>ABOUT OUR COMPANY<br />
GoSpotCheck was founded in May 2011 and is a graduate of the renowned TechStars program. We are backed by some of the best early stage tech investors including 500Startups, Venture51, Doug Feirstein, Walter Winshall, Dave Carlson, and former Coca-Cola CMO Sergio Zyman.</p>
<p>BENEFITS &amp; COMPENSATION<br />
Along with a competitive salary and 100% paid beneﬁts, we offer a highly dynamic and exciting work environment where you will get the chance to make huge contributions to the company. We believe in giving everyone the ability to excel at their job, and that means giving our people the ability to create impact in any way they see ﬁt.</p>
<p>Contact careers@gospotcheck.com and we’ll get back to you ASAP!</p>
<p>The post <a href="http://pivotallabs.com/gospotcheck-is-looking-for-a-web-application-developer/">GoSpotCheck Is Looking For A Web Application Developer</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://pivotallabs.com/gospotcheck-is-looking-for-a-web-application-developer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Migrating from a single Rails app to a suite of Rails engines</title>
		<link>http://pivotallabs.com/migrating-from-a-single-rails-app-to-a-suite-of-rails-engines/</link>
		<comments>http://pivotallabs.com/migrating-from-a-single-rails-app-to-a-suite-of-rails-engines/#comments</comments>
		<pubDate>Tue, 13 Mar 2012 18:08:00 +0000</pubDate>
		<dc:creator>Stephan Hagemann</dc:creator>
				<category><![CDATA[Labs]]></category>
		<category><![CDATA[engines]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[refactoring]]></category>

		<guid isPermaLink="false">http://pivotallabs.com/migrating-from-a-rails-app-to-a-rails-engine/</guid>
		<description><![CDATA[<p><h2>TL;DR</h2>

<p>We moved a Rails app into an unbuilt engine of a new blank slate container app to allow new parts of our app to live next to it as engines as well. It has been working great for us!</p>

<p>I have a sample app <a href="https://github.com/shageman/rails_container_and_engines">rails_container_and_engines</a> of the result's structure on github.</p>

<p>Skip to the <a href="#pitfalls">pitfalls and discoveries section</a> to read about some of the speed bumps we during our transition. Interested in the why and how? Read on! </p> <a href="http://pivotallabs.com/migrating-from-a-single-rails-app-to-a-suite-of-rails-engines/">Continue reading <span class="meta-nav">&#8594;</span></a></p><p>The post <a href="http://pivotallabs.com/migrating-from-a-single-rails-app-to-a-suite-of-rails-engines/">Migrating from a single Rails app to a suite of Rails engines</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></description>
				<content:encoded><![CDATA[<h2>TL;DR</h2>
<p>We moved a Rails app into an unbuilt engine of a new blank slate container app to allow new parts of our app to live next to it as engines as well. It has been working great for us!</p>
<p>I have a sample app <a href="https://github.com/shageman/rails_container_and_engines">rails_container_and_engines</a> of the result&#8217;s structure on github.</p>
<p>Skip to the <a href="#pitfalls">pitfalls and discoveries section</a> to read about some of the speed bumps we during our transition. Interested in the why and how? Read on! </p>
<h2>Rationale</h2>
<p>As part of the project we had built a web app, a mobile app that talks to the web app&#8217;s API, two ETL tools to 1&#41; do the initial data import from the app we were replacing and 2&#41; get data into another of our client&#8217;s apps. At this point we knew that we would create one more big web app and several auxiliary apps.  </p>
<p>Running up to the decision to using unbuilt engines we had several intense discussions on how to build loosely-coupled, highly-cohesive systems with Rails applications. We saw basically three choices:</p>
<ul>
<li><em>All-in-one</em> app that could get more structure through namespacing of its interals.</li>
<li><em>Services</em> &#40;REST or whatever, but&#41; running as separate apps and communicating via APIs.</li>
<li><em>Engines</em> running within a mostly feature-less container app.</li>
</ul>
<p>The two big web apps share several models within the data access layer and use the same data. Because of this we chose the third option and left all of the apps within the same rails code base. </p>
<p>Internal discussions highlighted the costs/benefits of having all of these apps live within their own Rails project versus an engines approach. We feel that by using engines we are getting many of the benefits of a component based architecture without breaking Rails patterns. In addition, we feel that the cost of maintaining individual applications that share a central database or one giant application with less defined components would have been very high.</p>
<p>In order to make day to day development easier, and to avoid the “where do migrations live&#8230;” conversation and top level Rails deployment patterns, there is one twist to the architecture: everything resides in one git repo and engines are referenced from a single container application &#40;similar to old school enterprise archive files&#41;. Each application is exposed via a unique context or resource identifier &#40;each engine/app could also be isolated per instance via Apache&#41;. Here is the directory structure we ended up with:</p>
<pre><code>container_rails_app/
  ...
  app
  config
  engines/
    etl/
    shared_modules/
    web_app_1/
    web_app_2/
  ...
</code></pre>
<p>Mike described this pattern in his recent blog posts <a href="https://pivotallabs.com/users/mbarinek/blog/articles/2022-unbuilt-rails-dependencies-how-to-design-for-loosely-coupled-highly-cohesive-components-within-a-rails-application">Unbuilt Rails Dependencies: How to design for loosely-coupled, highly-cohesive components within a Rails application</a> and <a href="https://pivotallabs.com/users/mbarinek/blog/articles/2023-rails-contained-a-container-for-web-application-development-and-deployment">Rails Contained: A Container for Web Application Development and Deployment</a>. On how to make RubyMine work seamlessly with engines, read my post on <a href="https://pivotallabs.com/users/shagemann/blog/articles/2008-intellij-modules-in-rubymine-">IntelliJ Modules in Rubymine</a>.</p>
<h2>The steps we took</h2>
<ul>
<li>Generate a new, empty Rails app</li>
<li>Within the <code>engines</code> folder, create a new, mountable Rails engine</li>
<li>
<p>Copy all the tests from the original Rails app into the test directory and make them green.</p>
<p>Ok. This step is a bit more involved. Essentially that&#8217;s it thought. Find some of the pitfalls we ran into described below. Here are a couple of highlights of what needs to happen:</p>
<ul>
<li>Copy the files you need for a test to pass and namespace its class</li>
<li>Start with the model tests and work your way up towards integration and acceptance tests</li>
<li>Namespace everything with the name of the engine &#40;either by fully qualifying every name &#8211; don&#8217;t do that&#41; or with the lexical scope trick explained below. This includes tests and all classes.</li>
<li>Load needed gems explicitly: engines don&#8217;t load as much automatically as a Rails app</li>
<li>Namespace tables and assets</li>
</ul>
</li>
<li>Copy the old .git directory into the new root folder in order to not loose any history. For us, git was not able to detect the changes as moves in many cases. This is certainly an area where you can improve on our solution!</li>
</ul>
<p>For us, the real work started after this, when we started pullling out common code into a common models engine and began work on the second app.</p>
<p>We got all the tests to pass before we had namespaced any of the assets or rake tasks. That was an additional search-and-replace heavy step after the actual transition to an engine. It is not necessary right away if you do not have multiple applications at first, but to achieve the full effect, you will need to namespace the things as well.</p>
<p><a name="pitfalls" /></p>
<h2>Pitfalls and discoveries</h2>
<h4>Namespaces</h4>
<p>Modules in your enige are not automatically loaded: make sure you reference them yourself before they are needed in other files. </p>
<h4>Asset pre-compilation</h4>
<p>Rails creates a default <code>app/assets/stylesheets/application.css</code> file which contains these lines:</p>
<pre><code>/* ...
*= require_self
*= require_tree .
*/
</code></pre>
<p>If you have this file in your main app, all css files will be compiled into one file. For us, this made almost everything look right. Almost. Little things broke here and there. Our app contained a couple of sections for which the stylesheets were meant to be loaded separately. Add files that you want to have precompiled as individual files to <code>config.assets.precompile</code> list to have them precompiled into separate files and solve this problem. </p>
<h4>Are all your references and associations breaking?</h4>
<p>Try this</p>
<pre><code>class M::Y
  def use_y
    M::Y.do_it!
  end
end
class M::Y
  def self.do_it!
  end
end
</code></pre>
<p>instead of</p>
<pre><code>module M
  class X
    def use_y
      Y.do_it!
    end
  end
  class Y
    def self.do_it!
    end
  end
end
</code></pre>
<p>The first way sets the lexical scope to the module M as well as to the class Y allows you to references other classes in M without their full name. The second way sets the scope only to class M::Y and you have to fully qualify every class name to find it.</p>
<h4>Don&#8217;t fight conventions</h4>
<p>We were using fixture builder and while we were namespacing classes in modules we were trying to override the default table names to not be namespaced&#8230; Fixture builder didn&#8217;t like that at all. There may or may not be other dependencies that make leaving the conventions hard. So, save yourself the trouble and do the migrations &#40;and stay consistent!&#41; and namespace your tables as well!</p>
<h4>HABTM</h4>
<p>They seem to be falling out of favor, which is probably a good thing. With engines they don&#8217;t seem to work &#40;well&#41;. We ended up getting rid of our last two habtm relationships instead of trying to make them work. Creating the join as a class and adding the necessary has many :through relationships is straight forward enough. </p>
<p>We ended up with one production performance bug due to this: Rails   </p>
<h4>Engines depending on engines</h4>
<p>We used kaminari for our pagination requirements. When our app first became an engine, kaminari stopped picking up our custom views. Instead it used its standard views. The load order got screwed up to which there are basically two solutions:</p>
<ul>
<li>require => nil on both engines in the Gemfile and force the correct load order in your app, or&#8230; </li>
<li>avoid name clashes by namespacing your views &#40;which you were going to do anyways, right?&#41;</li>
</ul>
<p>The post <a href="http://pivotallabs.com/migrating-from-a-single-rails-app-to-a-suite-of-rails-engines/">Migrating from a single Rails app to a suite of Rails engines</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://pivotallabs.com/migrating-from-a-single-rails-app-to-a-suite-of-rails-engines/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Never use shared examples groups! Usually.</title>
		<link>http://pivotallabs.com/how-rspec-s-shared-example-group-highlights-bad-code/</link>
		<comments>http://pivotallabs.com/how-rspec-s-shared-example-group-highlights-bad-code/#comments</comments>
		<pubDate>Fri, 09 Mar 2012 20:45:00 +0000</pubDate>
		<dc:creator>Stephan Hagemann</dc:creator>
				<category><![CDATA[Labs]]></category>
		<category><![CDATA[rspec]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://pivotallabs.com/how-rspec-s-shared-example-group-highlights-bad-code/</guid>
		<description><![CDATA[<p><p><a href="https://www.relishapp.com/rspec/rspec-core/v/2-0/docs/example-groups/shared-example-group">Shared example groups</a> are a feature of rspec that allow specifying common behavior in a reusable group of specs.</p>

<p>I believe that there is a very specific way in which one can benefit from shared examples groups &#40;and should keep them&#41; and many more in which they come in handy at some point and should be refactored away from as development continues.</p> <a href="http://pivotallabs.com/how-rspec-s-shared-example-group-highlights-bad-code/">Continue reading <span class="meta-nav">&#8594;</span></a></p><p>The post <a href="http://pivotallabs.com/how-rspec-s-shared-example-group-highlights-bad-code/">Never use shared examples groups! Usually.</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></description>
				<content:encoded><![CDATA[<p><a href="https://www.relishapp.com/rspec/rspec-core/v/2-0/docs/example-groups/shared-example-group">Shared example groups</a> are a feature of rspec that allow specifying common behavior in a reusable group of specs.</p>
<p>I believe that there is a very specific way in which one can benefit from shared examples groups &#40;and should keep them&#41; and many more in which they come in handy at some point and should be refactored away from as development continues.</p>
<h2>When shared examples may seem a good idea</h2>
<p>If an application employs mechanisms such as  mixins, delegation, or inheritance &#40;which every Rails app by default does&#8230;&#41;, one can probably find some common behavior. Take a soft-delete functionality for example: specifying for each class that it&#8217;s objects are soft-deletable and that <code>it_behaves_like :soft_deletable</code> seems nice, but comes at a cost &#40;and isn&#8217;t appropriate&#41;.</p>
<h2>Shared examples make for a slow test suite</h2>
<p>If there are <code>n</code> test cases and <code>m</code> specs in the shared examples, there is a total of <code>n*m</code> specs that will run. Obviously the shared example saves a lot of spec coding: <code>m</code> shared specs, and <code>n</code> references to it. Meaning you need to write only <code>n+m</code> specs.</p>
<p>If, however, it were possible to test the common functionality separately &#40;<code>m</code> specs&#41; and then test only its integration &#40;<code>n</code> specs&#41;, there would still be <code>n+m</code> specs to write, but more importantly, there would also be only <code>n+m</code> specs to execute. </p>
<p><code>n*m</code> vs. <code>n+m</code>, that&#8217;s a <a href="http://en.wikipedia.org/wiki/Big_O_notation"><em>huge difference</em></a>.</p>
<h2>How to test common code without shared example groups</h2>
<p>There are a couple of ways to test common code without resorting to shared examples.</p>
<p>In your spec, write a test harness class that gets your mixin, delegate, or &#40;abstract&#41; super class. This class only has the abilities of a non-special object and the common code. Testing this class allows testing the common code in an isolated way. </p>
<p>If you happen to be relying on ActiveRecord for your mixin as soft-deletable probably would be, use <a href="https://github.com/jpignata/temping">Temping</a> to create an ActiveRecord object that only has ActiveRecord::Base behavior and that of the common code.</p>
<p>In case you have shared example groups in place, but can&#8217;t apply either of the above options, you probably haven&#8217;t extracted the code enough yet. Do that first and then come back here and refactor away from the shared example group.</p>
<h2>Is a shared example group ever the right thing to do?</h2>
<p>Imagine a mixin that has complex interactions with the objects it gets mixed in to, like a <code>it_behaves_like :fuzzy_matchable</code>. Fuzzy matching will always work in a similar way, but be working on different attributes or methods depending on the object. In this case the interactions between the object and the mixin are important to specify and verify. David Chelimsky describes this situation in his post about <a href="http://blog.davidchelimsky.net/2010/11/07/specifying-mixins-with-shared-example-groups-in-rspec-2/">specifying Mixins with shared example groups</a>. This kind of complex interaction seems to me to be the only case in which shared example groups are truly beneficial.</p>
<p>Am I missing good use cases of shared example groups here? Where do you use them?</p>
<p>The post <a href="http://pivotallabs.com/how-rspec-s-shared-example-group-highlights-bad-code/">Never use shared examples groups! Usually.</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://pivotallabs.com/how-rspec-s-shared-example-group-highlights-bad-code/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Specific interfaces &#8211; in the small</title>
		<link>http://pivotallabs.com/rspec-predicate-matchers-really/</link>
		<comments>http://pivotallabs.com/rspec-predicate-matchers-really/#comments</comments>
		<pubDate>Wed, 07 Mar 2012 19:55:00 +0000</pubDate>
		<dc:creator>Stephan Hagemann</dc:creator>
				<category><![CDATA[Labs]]></category>
		<category><![CDATA[rspec]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://pivotallabs.com/rspec-predicate-matchers-really/</guid>
		<description><![CDATA[<p><p>Everyone on the Web I found who states that quote I was looking for says "I don't know who said it, but be 'Generous on input, strict on output'" &#40;or some variation on this&#41;. While I am unsure about the first proposition, I wholeheartedly agree with the second. </p> <a href="http://pivotallabs.com/rspec-predicate-matchers-really/">Continue reading <span class="meta-nav">&#8594;</span></a></p><p>The post <a href="http://pivotallabs.com/rspec-predicate-matchers-really/">Specific interfaces &#8211; in the small</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>Everyone on the Web I found who states that quote I was looking for says &#8220;I don&#8217;t know who said it, but be &#8216;Generous on input, strict on output&#8217;&#8221; &#40;or some variation on this&#41;. While I am unsure about the first proposition, I wholeheartedly agree with the second. </p>
<p>Edit 3/8: the quote is known in a different wording as <a href="http://en.wikipedia.org/wiki/Jon_Postel#Postel.27s_Law"><em>Postel&#8217;s Law</em></a>, which shows up as the <a href="http://tools.ietf.org/html/rfc793#section-2.10">Robustness Principle in RFC 793, the specification of TCP</a>. Thanks for the hint, Austin!</p>
<p>Unfortunately, the closest a Rubyist typically gets to the implementation of an interface specification is his tests. This provides a pretty good, but somewhat disconnected specification that can sometimes cover up imprecisions in the interface&#8217;s implementation.</p>
<p>On top of that, sometimes our frameworks make it easy to forget what our tests are asserting or spec&#8217;ing.</p>
<p>Take rspec&#8217;s predicate matchers and this example:</p>
<pre><code>require 'rspec/core'

class VeryImportantQuestions
  def self.really?&#40;answer&#41;
    answer == 'Yes. I am telling you.'
  end

  def self.really_really?&#40;answer&#41;
    answer == 'Yes. I am telling you.' ? 42 : nil
  end
end

describe "really?" do
  context "using rspec predicate matchers" do
    context "if someone is telling you" do
      it "should be really really the case and return true" do
        VeryImportantQuestions.really?&#40;'Yes. I am telling you.'&#41;.should be_true
      end
    end
    context "if someone is not sure" do
      it "should return false" do
        VeryImportantQuestions.really?&#40;'I am not sure.'&#41;.should be_false
      end
    end
  end
end

describe "really_really?" do
  context "using rspec predicate matchers" do
    context "if someone is telling you" do
      it "should be really really the case and return true" do
        VeryImportantQuestions.really_really?&#40;'Yes. I am telling you.'&#41;.should be_true
      end
    end
    context "if someone is not sure" do
      it "should return false" do
        VeryImportantQuestions.really_really?&#40;'I am not sure.'&#41;.should be_false
      end
    end
  end
end
</code></pre>
<p><code>be_true</code> and <code>be_false</code> effectively hide the fact that what&#8217;s actually spec&#8217;ed is truthiness and falsiness. Only when the following context is added is this imprecision revealed:</p>
<pre><code>  context "spec'ing the actual output of the method fails" do
    context "if someone is telling you" do
      it "should be really really the case and return true" do
        VeryImportantQuestions.really_really?&#40;'Yes. I am telling you.'&#41;.should == true
      end
    end
    context "if someone is not sure" do
      it "should return false" do
        VeryImportantQuestions.really_really?&#40;'I am not sure.'&#41;.should == false
      end
    end
  end
</code></pre>
<p>With regard to rspec, I suggest to consider twice whether the benefits of using specific matchers to not outweigh their benefits in your situation. You might get nicer test output, but you might lose the ability to immediately tell what you&#8217;re spec&#8217;ing.</p>
<p>With regard to tests in general: be specific about what you output &#8211; aka be specific about what you test.</p>
<p>Here is the gist: <a href="https://gist.github.com/1998462">https://gist.github.com/1998462</a></p>
<p>The post <a href="http://pivotallabs.com/rspec-predicate-matchers-really/">Specific interfaces &#8211; in the small</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://pivotallabs.com/rspec-predicate-matchers-really/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Boulder Standup &#8211; Feb 16, 2012</title>
		<link>http://pivotallabs.com/boulder-standup-feb-16-2012/</link>
		<comments>http://pivotallabs.com/boulder-standup-feb-16-2012/#comments</comments>
		<pubDate>Thu, 16 Feb 2012 16:09:00 +0000</pubDate>
		<dc:creator>Stephan Hagemann</dc:creator>
				<category><![CDATA[Labs]]></category>
		<category><![CDATA[cancan]]></category>
		<category><![CDATA[rspec]]></category>
		<category><![CDATA[rubymine]]></category>

		<guid isPermaLink="false">http://pivotallabs.com/boulder-standup-feb-16-2012/</guid>
		<description><![CDATA[<p><h2>rspec should render_template still behaving weirdly</h2>

<blockquote>
    <p>Specing a partial being rendered with render_template blows up. What to do?</p>
</blockquote>

<p>render_template has been brittle for a long time. It obviously still is:</p>

<pre><code>response.should render_template&#40;"template"&#41; #works fine
response.should render_template&#40;partial: "template"&#41; #works fine
response.should render_template&#40;partial: "template", locals: {local_array: []}&#41; #blows up within rspec
</code></pre>

<p>You know how to fix it? <a href="http://stackoverflow.com/questions/9305125/how-do-you-test-render-remote-content-receives-the-correct-locals">Solve it here</a></p>

<h2>RubyMine 4 is out</h2>

<blockquote>
    <p>RubyMine "compare two files" isn't broken</p>
</blockquote>

<p>It is just really, really weird: if you have to scroll when comparing two files check the file that is above in the project drawer first. If you scroll up to do select the second file to compare, the compare window won't open.</p>

<h2>Stubbing <code>can?</code> can be hard</h2>

<blockquote>
    <p>In a system with a lot of <a href="https://github.com/ryanb/cancan">cancan</a> abilities - what is the best way to stub a particular ability for controller specs? In the hierarchy of controllers, a lot of abilities may be checked, all of which would need to stubbed in order to get to the code under test.</p>
</blockquote>

<p>Instead of stubbing the abilities, create a new, anonymous, ability class specific for your spec that gets all the necessary abilities and then stub <code>current_ability</code> to return an instance of that class. Internally cancan calls <code>current_ability</code> when you call <code>can?</code>: <a href="https://github.com/ryanb/cancan/blob/master/lib/cancan/controller_additions.rb#L371">cancan controller additions</a></p> <a href="http://pivotallabs.com/boulder-standup-feb-16-2012/">Continue reading <span class="meta-nav">&#8594;</span></a></p><p>The post <a href="http://pivotallabs.com/boulder-standup-feb-16-2012/">Boulder Standup &#8211; Feb 16, 2012</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></description>
				<content:encoded><![CDATA[<h2>rspec should render_template still behaving weirdly</h2>
<blockquote>
<p>Specing a partial being rendered with render_template blows up. What to do?</p>
</blockquote>
<p>render_template has been brittle for a long time. It obviously still is:</p>
<pre><code>response.should render_template&#40;"template"&#41; #works fine
response.should render_template&#40;partial: "template"&#41; #works fine
response.should render_template&#40;partial: "template", locals: {local_array: []}&#41; #blows up within rspec
</code></pre>
<p>You know how to fix it? <a href="http://stackoverflow.com/questions/9305125/how-do-you-test-render-remote-content-receives-the-correct-locals">Solve it here</a></p>
<h2>RubyMine 4 is out</h2>
<blockquote>
<p>RubyMine &#8220;compare two files&#8221; isn&#8217;t broken</p>
</blockquote>
<p>It is just really, really weird: if you have to scroll when comparing two files check the file that is above in the project drawer first. If you scroll up to do select the second file to compare, the compare window won&#8217;t open.</p>
<h2>Stubbing <code>can?</code> can be hard</h2>
<blockquote>
<p>In a system with a lot of <a href="https://github.com/ryanb/cancan">cancan</a> abilities &#8211; what is the best way to stub a particular ability for controller specs? In the hierarchy of controllers, a lot of abilities may be checked, all of which would need to stubbed in order to get to the code under test.</p>
</blockquote>
<p>Instead of stubbing the abilities, create a new, anonymous, ability class specific for your spec that gets all the necessary abilities and then stub <code>current_ability</code> to return an instance of that class. Internally cancan calls <code>current_ability</code> when you call <code>can?</code>: <a href="https://github.com/ryanb/cancan/blob/master/lib/cancan/controller_additions.rb#L371">cancan controller additions</a></p>
<p>The post <a href="http://pivotallabs.com/boulder-standup-feb-16-2012/">Boulder Standup &#8211; Feb 16, 2012</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://pivotallabs.com/boulder-standup-feb-16-2012/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>IntelliJ Modules in Rubymine</title>
		<link>http://pivotallabs.com/intellij-modules-in-rubymine/</link>
		<comments>http://pivotallabs.com/intellij-modules-in-rubymine/#comments</comments>
		<pubDate>Wed, 08 Feb 2012 02:06:00 +0000</pubDate>
		<dc:creator>Stephan Hagemann</dc:creator>
				<category><![CDATA[Labs]]></category>
		<category><![CDATA[engines]]></category>
		<category><![CDATA[rubymine]]></category>

		<guid isPermaLink="false">http://pivotallabs.com/intellij-modules-in-rubymine/</guid>
		<description><![CDATA[<p><p>IntelliJ has a feature called <a href="http://www.jetbrains.com/idea/webhelp/module.html">modules</a>: "a functional unit which you can compile, run, test and debug independently." </p>

<p><img src="http://assets.pivotallabs.com/1280/original/intellij_modules.png" alt="Modules in IntelliJ: Multiple top-level folders" /></p>

<p>A module in IntelliJ is a top-level view on a part of a codebase. IntelliJ is for Java, which is why I do not typically use it. I use Rubymine - no similar functionality exists here... but a way around that!</p> <a href="http://pivotallabs.com/intellij-modules-in-rubymine/">Continue reading <span class="meta-nav">&#8594;</span></a></p><p>The post <a href="http://pivotallabs.com/intellij-modules-in-rubymine/">IntelliJ Modules in Rubymine</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>IntelliJ has a feature called <a href="http://www.jetbrains.com/idea/webhelp/module.html">modules</a>: &#8220;a functional unit which you can compile, run, test and debug independently.&#8221; </p>
<p><img src="http://pivotallabs.com/wordpress/wp-content/uploads/2012/02/intellij_modules.png?48a6bc" alt="Modules in IntelliJ: Multiple top-level folders" /></p>
<p>A module in IntelliJ is a top-level view on a part of a codebase. IntelliJ is for Java, which is why I do not typically use it. I use Rubymine &#8211; no similar functionality exists here&#8230; but a way around that!</p>
<p>It may have been true at some point that these kind of modules were not something that Rails offered, but they have been around for quite a while: <a href="http://edgeapi.rubyonrails.org/classes/Rails/Engine.html">Engines</a>! </p>
<p>Engines are typically seen as a way to package a Rails app that can be reused and configured in the context of other Rails apps. However, many big Rails projects can benefit from engines and their ability to structure a large codebase into smaller, more independent parts. Namespacing within one Rails app can achieve a similar effect, but engines take it to the next level: all the code, including views, javascript, and even rake tasks and migrations can be separated consistently. Now, if the apps were totally separate, several independent Rails apps might be the right solution, but if those are tied together by the same database, one might do more harm then good when ripping that code apart&#8230; </p>
<h2>The Problem</h2>
<p>Imagine a Rails project with the following folder structure:</p>
<pre><code>rails_app/
  app/
  ...
  engines/
    custom_engine1/
    custom_engine2/
  ...
</code></pre>
<p>The engines are somewhat hidden away, two levels deep in the folder structure. Also, running specs for engines in these sub-folders won&#8217;t work from Rubymine, because the paths it tries to use are wrong.</p>
<p>Whether you are actually working with engines or just want to see multiple root folders in Rubymine at once, here is how to do it.</p>
<h2>Make modules work in Rubymine</h2>
<p>1&#41; You can get modules to work in Rubymine by opening your Rails project in IntelliJ: <code>Cmd + ;</code> opens the project structure dialog, select <code>Modules</code> from the list on the left and create a new module with the <code>+</code> button. Or, you can simply add a few files to your project&#8230;</p>
<p>2&#41; The .idea folder in the root of your project holds the Rubymine configuration files. Edit <code>modules.xml</code> and add a <code>module</code> line for every module you would like to create:</p>
<pre><code>&lt;!-- ROOT/.idea/modules.xml --&gt;
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;project version="4"&gt;
  &lt;component name="ProjectModuleManager"&gt;
    &lt;modules&gt;
      &lt;module fileurl="file://$PROJECT_DIR$/custom_engine1/module1.iml" filepath="$PROJECT_DIR$/custom_engine1/custom_engine1.iml" /&gt;
      &lt;module fileurl="file://$PROJECT_DIR$/custom_engine2/module2.iml" filepath="$PROJECT_DIR$/custom_engine2/custom_engine2.iml" /&gt;
    &lt;/modules&gt;
  &lt;/component&gt;
&lt;/project&gt;
</code></pre>
<p>In the root folder of every module create a <code>.iml</code> file with the name of that module like so:</p>
<pre><code>&lt;!-- ROOT/engines/custom_engine1/custom_engine1.iml --&gt;
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;module type="RUBY_MODULE" version="4"&gt;
  &lt;component name="NewModuleRootManager"&gt;
    &lt;content url="file://$MODULE_DIR$" /&gt;
    &lt;orderEntry type="inheritedJdk" /&gt;
    &lt;orderEntry type="sourceFolder" forTests="false" /&gt;
  &lt;/component&gt;
&lt;/module&gt;
</code></pre>
<p>Voila: The next time you open the project folder in Rubymine, the custom_engine folders show up as top-level entries in the projects file list! </p>
<p><img src="http://pivotallabs.com/wordpress/wp-content/uploads/2012/02/rubymine_modules.png?48a6bc" alt="Modules in Rubymine!" /></p>
<p>Here is the gist: <a href="https://gist.github.com/1764127">https://gist.github.com/1764127</a></p>
<p>This worked for me with Rubymine 3.2.4 and IntelliJ IDEA 11 CE.</p>
<p><em>Edit March 14: make sure that all module names are distinct and no module names are substrings of other module names. This confuses RubyMine and can prevent specs from running successfully.</em></p>
<p>The post <a href="http://pivotallabs.com/intellij-modules-in-rubymine/">IntelliJ Modules in Rubymine</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://pivotallabs.com/intellij-modules-in-rubymine/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Test your Rake tasks!</title>
		<link>http://pivotallabs.com/how-i-test-rake-tasks/</link>
		<comments>http://pivotallabs.com/how-i-test-rake-tasks/#comments</comments>
		<pubDate>Sun, 05 Feb 2012 18:05:00 +0000</pubDate>
		<dc:creator>Stephan Hagemann</dc:creator>
				<category><![CDATA[Labs]]></category>
		<category><![CDATA[rake]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://pivotallabs.com/how-i-test-rake-tasks/</guid>
		<description><![CDATA[<p><p>There are several reasons why you should test your Rake tasks:</p>

<ul>
<li>Rake tasks are code and as such deserve testing.</li>
<li>When untested Rake tasks have a tendency to become overly long and convoluted. Tests will help keep them in bay.</li>
<li>As Rake tasks typically depend on your models, you &#40;should&#41; loose confidence in them if you don't have tests and are attempting refactorings.</li>
</ul> <a href="http://pivotallabs.com/how-i-test-rake-tasks/">Continue reading <span class="meta-nav">&#8594;</span></a></p><p>The post <a href="http://pivotallabs.com/how-i-test-rake-tasks/">Test your Rake tasks!</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>There are several reasons why you should test your Rake tasks:</p>
<ul>
<li>Rake tasks are code and as such deserve testing.</li>
<li>When untested Rake tasks have a tendency to become overly long and convoluted. Tests will help keep them in bay.</li>
<li>As Rake tasks typically depend on your models, you &#40;should&#41; loose confidence in them if you don&#8217;t have tests and are attempting refactorings.</li>
</ul>
<h2>A problematic Rake task test</h2>
<p>Here is a Rake file&#8230;</p>
<pre><code>File: lib/tasks/bar_problematic.rake

namespace :foo do
  desc "bake some bars"
  task bake_a_problematic_bar: :environment do
    puts '*' * 60
    puts ' Step back: baking in action!'
    puts '*' * 60

    puts Bar.new.bake

    puts '*' * 60
    puts ' All done. Thank you for your patience.'
    puts '*' * 60
  end
end
</code></pre>
<p>&#8230;and its too simplistic spec:</p>
<pre><code>File: spec/tasks/bar_rake_problematic_spec.rb
require 'spec_helper'
require 'rake'

describe 'foo namespace rake task' do
  describe 'foo:bake_a_problematic_bar' do

    before do
      load File.expand_path&#40;"../../../lib/tasks/bar_problematic.rake", __FILE__&#41;
      Rake::Task.define_task&#40;:environment&#41;
    end

    it "should bake a bar" do
      Bar.any_instance.should_receive :bake
      Rake::Task["foo:bake_a_problematic_bar"].invoke
    end

    it "should bake a bar again" do
      Bar.any_instance.should_receive :bake
      Rake::Task["foo:bake_a_problematic_bar"].invoke
    end
  end
end
</code></pre>
<p>Some notable aspects of testing Rake tasks:</p>
<ul>
<li>Rake has to be required.</li>
<li>The Rake file under test has to be manually loaded.</li>
<li>In this example, the Rake task depends on the <code>environment</code> task, which is not automatically available in a spec. Since we are in rspec, the environment is already loaded and we can just define <code>environment</code> as an empty Rake task to make the bake task run in the test.</li>
</ul>
<p>When run, this spec fails on the second it block&#8230; and that is not the only problem with this spec and the Rake task:</p>
<ul>
<li>The Rake task duplicates code to output information to the user.</li>
<li>The spec &#8220;should bake a bar&#8221; will output that information when run, which clobbers the spec runners output.</li>
<li>The spec &#8220;should bake a bar&#8221; again will fail, because Rake tasks are built to only execute once per process. See <a href="https://github.com/ruby/ruby/blob/ruby_1_9_1/lib/rake.rb#L557">rake.rb</a>. This makes sense for the normal use of Rake tasks where a task may be named as the prerequisite of another task multiple times through multiple dependencies it might have &#8211; the task only needs to run once. In our tests we have to reenable the task.</li>
</ul>
<h2>A better Rake task test</h2>
<p>A new version of the above Rake file&#8230;</p>
<pre><code>File: lib/tasks/bar.rake
class BarOutput
  def self.banner text
    puts '*' * 60
    puts " #{text}"
    puts '*' * 60
  end

  def self.puts string
    puts string
  end
end

namespace :foo do
  desc "bake some bars"
  task bake_a_bar: :environment do
    BarOutput.banner " Step back: baking in action!"
    BarOutput.puts Bar.new.bake
    BarOutput.banner " All done. Thank you for your patience."
  end
end
</code></pre>
<p>&#8230; and its spec:</p>
<pre><code>File: spec/tasks/bar_rake_spec.rb
require 'spec_helper'
require 'rake'

describe 'foo namespace rake task' do
  before :all do
    Rake.application.rake_require "tasks/bar"
    Rake::Task.define_task&#40;:environment&#41;
  end

  describe 'foo:bar' do
    before do
      BarOutput.stub&#40;:banner&#41;
      BarOutput.stub&#40;:puts&#41;
    end

    let :run_rake_task do
      Rake::Task["foo:bake_a_bar"].reenable
      Rake.application.invoke_task "foo:bake_a_bar"
    end

    it "should bake a bar" do
      Bar.any_instance.should_receive :bake
      run_rake_task
    end

    it "should bake a bar again" do
      Bar.any_instance.should_receive :bake
      run_rake_task
    end

    it "should output two banners" do
      BarOutput.should_receive&#40;:banner&#41;.twice
      run_rake_task
    end

  end
end
</code></pre>
<p>This spec passes just fine and does not clobber the spec output. Again, let&#8217;s look at noteworthy things:</p>
<ul>
<li>The output of the Rake task now goes through the <code>BarOutput</code> class. This reduces code duplication and allows for easy stubbing. There are other ways to achieve a similar effect and not clobber test output: <a href="http://www.whatastruggle.com/stub-out-puts-or-print-with-rspec">Stub puts and print</a>, <a href="http://stackoverflow.com/questions/1546200/check-for-the-absence-of-puts-in-rspec">stub on $stdout</a>.</li>
<li><code>Rake.application</code> has a nicer way of requiring Rake files than a simple <code>load</code>, because <code>rake_require</code> knows where Rake files live.</li>
<li><code>Rake::Task["TASK"].reenable</code> reenables the task with name &#8220;TASK&#8221; so that it will be run again and can be called multiple times in a spec.</li>
</ul>
<p>Here is the gist: <a href="https://gist.github.com/1764423">https://gist.github.com/1764423</a></p>
<p>The post <a href="http://pivotallabs.com/how-i-test-rake-tasks/">Test your Rake tasks!</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://pivotallabs.com/how-i-test-rake-tasks/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Standup 11/11/2011: Some funkinesses</title>
		<link>http://pivotallabs.com/standup-11-11-2011-some-funkinesses/</link>
		<comments>http://pivotallabs.com/standup-11-11-2011-some-funkinesses/#comments</comments>
		<pubDate>Fri, 11 Nov 2011 17:06:00 +0000</pubDate>
		<dc:creator>Stephan Hagemann</dc:creator>
				<category><![CDATA[Labs]]></category>
		<category><![CDATA[rspec]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://pivotallabs.com/standup-11-11-2011-some-funkinesses/</guid>
		<description><![CDATA[<p><h2>Interesting</h2>

<ul>
<li><p>rspec <code>stub != stub!</code>. <code>stub!</code> is an alias method for <code>stub</code>. There is however also a method <code>stub</code> that is an alias for <code>double</code>. If you try to stub a method on the test class &#40;to stub it on the context&#41;, you should probably use the magic subject/helper/controller methods. If you don't, using <code>self.stub&#40;:name =&#62; 'result'&#41;</code> will create a double, while <code>self.stub!&#40;:name =&#62; 'result'&#41;</code> will stub the method as you would expect.</p></li>
<li><p>Asynchronous file creation and downloading: if an asynchronous process writes a file using <code>File.open</code> and <code>f.write</code>, an other process checking the presence of the file to determine whether it is already available for download, will deliver the empty file, if the file has been opened, but not yet written. </p>

<ul>
<li>Workarounds:
<ul>
<li>if you have one write to the file only: check filesize.</li>
<li>update an ActiveRecord attribute after the file writing is completed and check against that.</li>
</ul></li>
</ul></li>
<li><p>== on DelegateClass: newing up an instance <code>delegate_x</code> of DelegateClass from object <code>x</code>, <code>x == delegate_x</code>, while of course <code>x.class != delegate_x.class</code>.</p></li>
</ul>

<h2>Keystroke of the day</h2>

<ul>
<li>Rubymine KOTD: The search+replace mode you reach via <code>Cmd+r</code> allows you to see recent searches by hitting the down arrow. If that doesn't work for you in Lion, hit <code>Ctrl+h</code>.</li>
</ul> <a href="http://pivotallabs.com/standup-11-11-2011-some-funkinesses/">Continue reading <span class="meta-nav">&#8594;</span></a></p><p>The post <a href="http://pivotallabs.com/standup-11-11-2011-some-funkinesses/">Standup 11/11/2011: Some funkinesses</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></description>
				<content:encoded><![CDATA[<h2>Interesting</h2>
<ul>
<li>
<p>rspec <code>stub != stub!</code>. <code>stub!</code> is an alias method for <code>stub</code>. There is however also a method <code>stub</code> that is an alias for <code>double</code>. If you try to stub a method on the test class &#40;to stub it on the context&#41;, you should probably use the magic subject/helper/controller methods. If you don&#8217;t, using <code>self.stub&#40;:name =&gt; 'result'&#41;</code> will create a double, while <code>self.stub!&#40;:name =&gt; 'result'&#41;</code> will stub the method as you would expect.</p>
</li>
<li>
<p>Asynchronous file creation and downloading: if an asynchronous process writes a file using <code>File.open</code> and <code>f.write</code>, an other process checking the presence of the file to determine whether it is already available for download, will deliver the empty file, if the file has been opened, but not yet written. </p>
<ul>
<li>Workarounds:
<ul>
<li>if you have one write to the file only: check filesize.</li>
<li>update an ActiveRecord attribute after the file writing is completed and check against that.</li>
</ul>
</li>
</ul>
</li>
<li>
<p>== on DelegateClass: newing up an instance <code>delegate_x</code> of DelegateClass from object <code>x</code>, <code>x == delegate_x</code>, while of course <code>x.class != delegate_x.class</code>.</p>
</li>
</ul>
<h2>Keystroke of the day</h2>
<ul>
<li>Rubymine KOTD: The search+replace mode you reach via <code>Cmd+r</code> allows you to see recent searches by hitting the down arrow. If that doesn&#8217;t work for you in Lion, hit <code>Ctrl+h</code>.</li>
</ul>
<p>The post <a href="http://pivotallabs.com/standup-11-11-2011-some-funkinesses/">Standup 11/11/2011: Some funkinesses</a> appeared first on <a href="http://pivotallabs.com">Pivotal Labs</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://pivotallabs.com/standup-11-11-2011-some-funkinesses/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic (Feed is rejected)
Page Caching using apc
Database Caching using apc
Object Caching 1167/1263 objects using apc

 Served from: pivotallabs.com @ 2013-05-25 22:03:17 by W3 Total Cache -->