<?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>Carbon Five Community &#187; andy</title>
	<atom:link href="http://blog.carbonfive.com/author/andy/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.carbonfive.com</link>
	<description></description>
	<lastBuildDate>Fri, 27 Aug 2010 00:24:40 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Javascript Testing Talk in Oakland</title>
		<link>http://blog.carbonfive.com/2010/03/software-design/javascript-testing-talk-in-oakland</link>
		<comments>http://blog.carbonfive.com/2010/03/software-design/javascript-testing-talk-in-oakland#comments</comments>
		<pubDate>Mon, 08 Mar 2010 17:40:13 +0000</pubDate>
		<dc:creator>andy</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[JavaScript / AJAX]]></category>
		<category><![CDATA[Software Design]]></category>
		<category><![CDATA[Speaking]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://blog.carbonfive.com/?p=903</guid>
		<description><![CDATA[Next week at EBig Jonah and I are wrapping up our world tour of talking about Javascript testing. March 17th in Oakland: &#8221;Recent evolutions in Javascript testing frameworks now allow creating test suites, test-driving development, and running tests on a continuous integration server. This allows us to support more complex Javascript, have confidence in the implementation, [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.ebig.org/index.cfm?fuseaction=Calendar.eventDetail&amp;eventID=158" target="_blank">Next week at EBig</a> Jonah and I are wrapping up our world tour of talking about Javascript testing. March 17th in Oakland: &#8221;Recent evolutions in Javascript testing frameworks now allow creating test suites, test-driving development, and running tests on a continuous integration server. This allows us to support more complex Javascript, have confidence in the implementation, and push more of the logic from the server into the browser, reducing the load on the server.&#8221; The focus of the talk is walking through a suite of tests we build for a real-world example.</p>
<p>For those of you who caught it last week at the SDForum, here are the links people requested:</p>
<ul>
<li><a href="http://code.google.com/p/javascript-test-maven-plugin/">Maven plugin for Javascript Unit Testing with Rhino/ScrewUnit</a> (from C5)</li>
<li><a href="http://github.com/ndp/wizardize">The current code for the &#8220;wizardize&#8221; example we walked through</a>.</li>
<li><a href="http://github.com/relevance/blue-ridge">Blue Ridge (Rails integration tool)</a></li>
<li><a href="http://pivotallabs.com/users/nick/blog/articles/455-better-javascript-testing-through-screwunit">ScrewUnit</a></li>
<li><a href="http://www.slideshare.net/jeresig/understanding-javascript-testing">JResig&#8217;s Presentation on JS Testing</a></li>
<li><a href="http://dl.dropbox.com/u/1399422/Javascript%20Unit%20Testing%2C%20Yes%20We%20Can%20Slides.pdf">The slides we used</a></li>
</ul>
<p>To sign up for next Wednesday, go to the <a href="http://www.ebig.org/index.cfm?fuseaction=Calendar.eventDetail&amp;eventID=158">EBig site</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2010/03/software-design/javascript-testing-talk-in-oakland/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Test-Driven JavaScript with ScrewUnit and BlueRidge</title>
		<link>http://blog.carbonfive.com/2010/02/software-design/test-driven-javascript-with-screwunit-and-blueridge</link>
		<comments>http://blog.carbonfive.com/2010/02/software-design/test-driven-javascript-with-screwunit-and-blueridge#comments</comments>
		<pubDate>Fri, 26 Feb 2010 01:33:04 +0000</pubDate>
		<dc:creator>andy</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[JavaScript / AJAX]]></category>
		<category><![CDATA[Ruby (on Rails)]]></category>
		<category><![CDATA[Software Design]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://blog.carbonfive.com/?p=893</guid>
		<description><![CDATA[Jonah and I are taking our presentation about Javascript Testing on the road next Tuesday at 6:30 in Palo Alto, at the SDForum The teaser for it&#8230; Recent evolutions in JavaScript testing frameworks now allow creating test suites, test-driving development, and running tests on a continuous integration server. This allows us to support more complex JavaScript, [...]]]></description>
			<content:encoded><![CDATA[<p>Jonah and I are taking our presentation about Javascript Testing on the road <a href="http://www.sdforum.org/index.cfm?fuseaction=Calendar.eventDetail&amp;eventID=13629&amp;pageId=471">next Tuesday at 6:30 in Palo Alto, at the SDForum</a></p>
<p>The teaser for it&#8230; Recent evolutions in JavaScript testing frameworks now allow creating test suites, test-driving development, and running tests on a continuous integration server. This allows us to support more complex JavaScript, have confidence in the implementation, and push more of the logic from the server into the browser, reducing the load on the server&#8230;</p>
<p>Hope to see you there.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2010/02/software-design/test-driven-javascript-with-screwunit-and-blueridge/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Recipe for 5 Whys with an Agile Software Team</title>
		<link>http://blog.carbonfive.com/2010/01/agile/recipe-for-5-whys-with-an-agile-software-team</link>
		<comments>http://blog.carbonfive.com/2010/01/agile/recipe-for-5-whys-with-an-agile-software-team#comments</comments>
		<pubDate>Wed, 27 Jan 2010 04:53:33 +0000</pubDate>
		<dc:creator>andy</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[rapid development]]></category>
		<category><![CDATA[xp]]></category>

		<guid isPermaLink="false">http://blog.carbonfive.com/?p=818</guid>
		<description><![CDATA[5 Whys is a great way to get at the root of quality problems. On my last three projects, when I felt like code quality was dropping, I ran a &#8220;5 Whys&#8221; session. I have found it adds variety, solves a very specific problem, and plugs right in as an alternative to an agile reflection. [...]]]></description>
			<content:encoded><![CDATA[<p>5 Whys is a great way to get at the root of quality problems. On my last three projects, when I felt like code quality was dropping, I ran a &#8220;5 Whys&#8221; session. I have found it adds variety, solves a very specific problem, and plugs right in as an alternative to an <a href="http://blog.carbonfive.com/2009/12/agile/recipe-for-simple-agile-retrospectives">agile reflection</a>.</p>
<p>It&#8217;s not in every agile software team&#8217;s bag of tricks. Asking around our fairy savvy office, I discovered it&#8217;s far from universal. In the <a href="http://www.versionone.com/whitepapers.asp">&#8220;State of Agile&#8221; report from Version One</a>, which includes survey results from 2500 software developers, it wasn&#8217;t mentioned. Since I haven&#8217;t seen it show up that much in other agile writings, I thought I&#8217;d share my experiences here.<span id="more-818"></span></p>
<p><strong>What is &#8220;5 Whys&#8221;?</strong> I picked up &#8220;5 Whys&#8221; from the lean software movement, which sprang from Toyota manufacturing.  You can read about its history on <a href="http://en.wikipedia.org/wiki/5_Whys">wikipedia</a>, but it&#8217;s pretty simple: at the end of the assembly line, when a widget comes out with a problem, you stop the line and ask &#8220;Why?&#8221; Whatever the reason, you ask the &#8220;Why?&#8221; again. Repeat at least 5 times. The goal is to discover the &#8220;root cause&#8221; of the defect, and fix the root cause, not just some symptom. Wikipedia has a good example around car repair. Here&#8217;s a software example:</p>
<blockquote><p>1. Why did Sheryl say the sign-up flow was broken?<br />
<em>A: Because she was trying to sign up a second time. Duh.</em><br />
2. Yeah, but why did the flow break if the user is already signed up?<br />
<em>A: It&#8217;s a bug. We didn&#8217;t have a test case for that.</em><br />
3. Why didn&#8217;t we have a test case for it?<br />
<em>A: I just didn&#8217;t think of it.</em><br />
4. Why didn&#8217;t you think about it?<br />
<em>A: The story seemed easy&#8211; I guess I didn&#8217;t think it through.</em><br />
5. Why do you think you didn&#8217;t think it through?&#8221;<br />
<em>A: I guess I was working alone and was in a hurry.</em><br />
&#8230;</p></blockquote>
<p>Obviously you don&#8217;t have ask &#8220;Why?&#8221; exactly five times, but that does seem to be a pretty good number. The point is you start articulating the behaviors and procedures that cause the problems.</p>
<p><strong>Taking It for a Spin. </strong> I&#8217;ve come up with exercise for agile software teams.  Like I mentioned, when quality drops below your comfort level, give it a try:</p>
<ol>
<li>(2 minutes) Make a list of the most recent bugs you&#8217;ve uncovered. I&#8217;ve found that the last 10 is usually enough&#8211; if not too much. You can put these on a white board, index cards or a wiki page&#8211; all will work.</li>
<li>(2 minutes) Prioritize them based on the ones you want to talk about. Which caused the most embarrassment or cost? You usually only have energy to talk about 5 or 6 of them.</li>
<li>(15 minutes) For each bug, ask &#8220;Why did this happen?&#8221; Then, probe deeper until you can&#8217;t get much further. Write the answers down where everyone can see.</li>
<li>(5 minutes) When you&#8217;re done with all the bugs (or out of time), circle common root causes.</li>
<li>(10 minutes) Brainstorm ways to mitigate or eliminate the root causes. Come of with one or two SMART goals for the team.</li>
</ol>
<p>Some of the root causes we&#8217;ve gotten to recently:</p>
<ul>
<li> we didn&#8217;t pair on hard features</li>
<li> we didn&#8217;t ask for clarifications on the requirements</li>
<li> one engineer didn&#8217;t understand the intent behind the code</li>
<li> nobody looked at the app on Internet Explorer 6</li>
</ul>
<p>Just like in agile reflections, the changes made coming out of these meetings stick with the team. During one session, the developers decided that there were just too many mistakes that someone else would have easily caught&#8211; so they always needed two sets of eyes on every checkin. I&#8217;d advocated this before, but it was never applied consistently. To my surprise though, after the reflection, everyone was  disciplined about this policy&#8211; and our quality was much better.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2010/01/agile/recipe-for-5-whys-with-an-agile-software-team/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Agile Practices&#8230; visualized?</title>
		<link>http://blog.carbonfive.com/2009/10/javascript-ajax/agile-practices-visualized</link>
		<comments>http://blog.carbonfive.com/2009/10/javascript-ajax/agile-practices-visualized#comments</comments>
		<pubDate>Wed, 07 Oct 2009 16:19:35 +0000</pubDate>
		<dc:creator>andy</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[JavaScript / AJAX]]></category>

		<guid isPermaLink="false">http://blog.carbonfive.com/?p=684</guid>
		<description><![CDATA[Only pure agile devotees will find it interesting&#8230; Revisiting agile methodologies, I wanted to solidify my understanding of the differences between agile, scrum, XP, etc. I went through a mini-research project of reviewing the &#8220;canonical&#8221; sources of these practices, and then built a quick visualization to clarify my understanding: http://ndpsoftware.com/agile_methods/agile_methods.html Hint: Try dragging around the [...]]]></description>
			<content:encoded><![CDATA[<p>Only pure agile devotees will find it interesting&#8230; Revisiting agile methodologies, I wanted to solidify my understanding of the differences between agile, scrum, XP, etc. I went through a mini-research project of reviewing the &#8220;canonical&#8221; sources of these practices, and then built a quick visualization to clarify my understanding:</p>
<p><a title="Agile Methods Visualized" href="http://ndpsoftware.com/agile_methods/agile_methods.html">http://ndpsoftware.com/agile_methods/agile_methods.html</a></p>
<p><em>Hint: Try dragging around the boxes</em> to see how practices are related to each other.</p>
<p><em>Warning: If it doesn&#8217;t draw anything interesting for you, refresh your browser&#8230;</em> there&#8217;s a large component of &#8220;randomness&#8221; to the algorithm and it can get stuck easily.</p>
<p><em>Warning II: Don&#8217;t leave it running in your browser</em>, as it&#8217;s somewhat sluggish Javascript&#8230; this was a demo thrown together in a couple hours.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2009/10/javascript-ajax/agile-practices-visualized/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>assert_changes and assert_no_changes in Ruby</title>
		<link>http://blog.carbonfive.com/2009/04/testing/assert_changes-and-assert_no_changes-in-ruby</link>
		<comments>http://blog.carbonfive.com/2009/04/testing/assert_changes-and-assert_no_changes-in-ruby#comments</comments>
		<pubDate>Sat, 04 Apr 2009 00:26:51 +0000</pubDate>
		<dc:creator>andy</dc:creator>
				<category><![CDATA[Ruby (on Rails)]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[Agile]]></category>
		<category><![CDATA[fixtures]]></category>

		<guid isPermaLink="false">http://blog.carbonfive.com/?p=567</guid>
		<description><![CDATA[Update: This code and documentation is now available on github: http://github.com/ndp/assert_changes/tree/master The Problem On our work on gobalto.com, we spend time to have good fixture data for our tests&#8211; data that can represent all the important application states that our tests require. As a result, our tests are very dependent on the data. It&#8217;s important [...]]]></description>
			<content:encoded><![CDATA[<h3><span style="color: #000080;">Update:</span><span style="color: #000080;"> This code and documentation is now available on github:<a href="http://github.com/ndp/assert_changes/tree/master" target="_blank"> http://github.com/ndp/assert_changes/tree/master</a></span></h3>
<h2>The Problem</h2>
<p>On our work on <a href="http://www.gobalto.com">gobalto.com</a>, we spend time to have good fixture data for our tests&#8211; data that can represent all the important application states that our tests require. As a result, our tests are very dependent on the data. It&#8217;s important that someone doesn&#8217;t inadvertantly change it in subtle ways. This has led us to write not only asserts at the end of tests, but pre-conditions as well. For example,</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">    ...
    <span style="color:#9900CC;">inotech</span> = companies<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:inotech</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    assert inotech.<span style="color:#9900CC;">services</span>.<span style="color:#9900CC;">public</span>.<span style="color:#9966CC; font-weight:bold;">include</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>categories<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:a</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    assert inotech.<span style="color:#9900CC;">services</span>.<span style="color:#9900CC;">public</span>.<span style="color:#9966CC; font-weight:bold;">include</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>categories<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:b</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    assert inotech.<span style="color:#9900CC;">services</span>.<span style="color:#9900CC;">public</span>.<span style="color:#9966CC; font-weight:bold;">include</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>categories<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:c</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
    post <span style="color:#ff3333; font-weight:bold;">:edit_services_dialog</span>, <span style="color:#ff3333; font-weight:bold;">:id</span>=<span style="color:#006600; font-weight:bold;">&amp;</span>gt;inotech.<span style="color:#9900CC;">id</span>,
                                          <span style="color:#ff3333; font-weight:bold;">:service_category_id</span>=<span style="color:#006600; font-weight:bold;">&amp;</span>gt;categories<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:a</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">id</span>
    inotech.<span style="color:#9900CC;">reload</span>
&nbsp;
    assert inotech.<span style="color:#9900CC;">services</span>.<span style="color:#9900CC;">public</span>.<span style="color:#9966CC; font-weight:bold;">include</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>categories<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:a</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    assert !inotech.<span style="color:#9900CC;">services</span>.<span style="color:#9900CC;">public</span>.<span style="color:#9966CC; font-weight:bold;">include</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>categories<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:b</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    assert !inotech.<span style="color:#9900CC;">services</span>.<span style="color:#9900CC;">public</span>.<span style="color:#9966CC; font-weight:bold;">include</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>categories<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:c</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>Although the pre-conditions were introduced to guard against accidentally changing fixture data (or just to figure out what&#8217;s going on), we don&#8217;t necessarily delete them. They provide stronger tests. And in some ways, leaving in pre-conditions make the code more readable by providing documentation of your assumptions to the readers. The code above would be hard to follow without the clarifying pre-conditions. What do we expect to change and what stays the same?</p>
<p>Unfortunately all these asserts make the tests twice as long. And there&#8217;s a subtle readability problem: there&#8217;s no relationship between the corresponding pre- and post-conditions. In the example above, you have to scan carefully to see that the three assertions are repeated, but negated (b and c only). The reader must mentally put pieces together. And it&#8217;s not DRY. Using local variables doesn&#8217;t help much.</p>
<h2>The Solution</h2>
<p>I was inspired by a nice little test helper called assert_difference. It takes a string to evaluate and a block to execute. It&#8217;s useful for checking on state changes&#8211; especially database changes&#8211; during a test:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">assert_difference<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;color: blue;">'Company.count'</span>, <span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    Company.<span style="color:#9900CC;">delete_one</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>(Without this method, we rely on a count of all database records, or merely look for specific ones. The former approach leads to brittle tests, and the latter to incomplete assertions.)</p>
<p>A limitation of assert_difference is that it only deals with integers. What if it were generalized? Here goes:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">    i = <span style="color:#0000FF; font-weight:bold;">true</span>
    assert_changes <span style="color:#996600;color: blue;">'i'</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#0000FF; font-weight:bold;">false</span> <span style="color:#9966CC; font-weight:bold;">do</span>   <span style="color:#008000; font-style:italic;"># read as: i changes to false</span>
      i = <span style="color:#0000FF; font-weight:bold;">false</span>
    <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p><span id="more-567"></span>The string passed to assert changes is evaluated in the block context, both before and after the block is run. So this block asserts that i becomes false (and by deduction, starts out as true). It executes asserts on both ends, just like we want.</p>
<p>Of course sometimes you want to be explicit about a state change, so you can specify both the starting and ending values using an array:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">    o.<span style="color:#9900CC;">answer</span> = <span style="color:#996600;color: blue;">'yes'</span>
    assert_changes <span style="color:#996600;color: blue;">'o.answer'</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;color: blue;">'yes'</span>,<span style="color:#996600;color: blue;">'no'</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      o.<span style="color:#9900CC;">answer</span> = <span style="color:#996600;color: blue;">'no'</span>
    <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>To handle the original example, you can pass multiple pre/post conditions of arbitrary complexity and they are all evaluated before and after the block is executed:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">      assert_changes <span style="color:#996600;color: blue;">'post(:a).status'</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:preview</span>, <span style="color:#ff3333; font-weight:bold;">:published</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
                            <span style="color:#996600;color: blue;">'comment(:c).status'</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:preview</span>, <span style="color:#ff3333; font-weight:bold;">:deleted</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
        ...
      <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Finally, I added support for a :no_change symbol. Now I can re-write my original problem in a clearer form:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">    assert_changes
        <span style="color:#996600;color: blue;">'inotech.services.public.include?(categories(:a))'</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#0000FF; font-weight:bold;">true</span>, <span style="color:#ff3333; font-weight:bold;">:no_change</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
            <span style="color:#996600;color: blue;">'inotech.services.public.include?(categories(:b))'</span>=<span style="color:#006600; font-weight:bold;">&amp;</span>gt;false,
            <span style="color:#996600;color: blue;">'inotech.services.public.include?(categories(:c))'</span>=<span style="color:#006600; font-weight:bold;">&amp;</span>gt;false <span style="color:#9966CC; font-weight:bold;">do</span>
      post <span style="color:#ff3333; font-weight:bold;">:edit_services_dialog</span>, <span style="color:#ff3333; font-weight:bold;">:id</span>=<span style="color:#006600; font-weight:bold;">&amp;</span>gt;inotech.<span style="color:#9900CC;">id</span>, <span style="color:#ff3333; font-weight:bold;">:service_category_id</span>=<span style="color:#006600; font-weight:bold;">&amp;</span>gt;categories<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:a</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">id</span>
      inotech.<span style="color:#9900CC;">reload</span>
    <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>For completeness, I added assert_no_changes, with slightly extended parameter possibilities:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">    i,j = <span style="color:#996600;color: blue;">'hello'</span>,<span style="color:#996600;color: blue;">'hi'</span>
    assert_no_changes <span style="color:#996600;color: blue;">'i'</span> <span style="color:#9966CC; font-weight:bold;">do</span> ...  <span style="color:#008000; font-style:italic;"># i (before) == i (after)</span>
    assert_no_changes <span style="color:#996600;color: blue;">'i'</span>=<span style="color:#006600; font-weight:bold;">&amp;</span>gt;<span style="color:#996600;color: blue;">'hello'</span> <span style="color:#9966CC; font-weight:bold;">do</span> ... <span style="color:#008000; font-style:italic;"># i == 'hello' before and after</span>
    assert_no_changes <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;color: blue;">'i'</span>,<span style="color:#996600;color: blue;">'j'</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#9966CC; font-weight:bold;">do</span> ... <span style="color:#008000; font-style:italic;"># neither i or j change</span>
    assert_no_changes <span style="color:#996600;color: blue;">'i'</span>=<span style="color:#006600; font-weight:bold;">&amp;</span>gt;<span style="color:#996600;color: blue;">'hello'</span>,<span style="color:#996600;color: blue;">'j'</span>=<span style="color:#006600; font-weight:bold;">&amp;</span>gt;<span style="color:#996600;color: blue;">'hi'</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#008000; font-style:italic;"># or be explicit</span></pre></div></div>

<h3><span style="color: #000080;">Update:</span><span style="color: #000080;"> This code and documentation is now available on github:<a href="http://github.com/ndp/assert_changes/tree/master" target="_blank"> http://github.com/ndp/assert_changes/tree/master</a></span></h3>
<p>Thoughts? Comments?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2009/04/testing/assert_changes-and-assert_no_changes-in-ruby/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Convenient CSS and Javascript in Ruby on Rails</title>
		<link>http://blog.carbonfive.com/2009/03/javascript-ajax/convenient-css-and-javascript-in-ruby-on-rails</link>
		<comments>http://blog.carbonfive.com/2009/03/javascript-ajax/convenient-css-and-javascript-in-ruby-on-rails#comments</comments>
		<pubDate>Mon, 09 Mar 2009 00:41:11 +0000</pubDate>
		<dc:creator>andy</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[JavaScript / AJAX]]></category>
		<category><![CDATA[Ruby (on Rails)]]></category>
		<category><![CDATA[prototyping]]></category>
		<category><![CDATA[rapid development]]></category>
		<category><![CDATA[Software Design]]></category>

		<guid isPermaLink="false">http://blog.carbonfive.com/?p=480</guid>
		<description><![CDATA[I get tired of hunting through a hierarchy of folders and files, from the views to the public folder, to locate a certain CSS or Javascript file. It&#8217;d be convenient to have them right with the markup, but embedding these definitions within your HTML markup is a bad idea for several reasons. For our current [...]]]></description>
			<content:encoded><![CDATA[<p>I get tired of hunting through a hierarchy of folders and files, from the views to the public folder, to locate a certain CSS or Javascript file. It&#8217;d be convenient to have them right with the markup, but embedding these definitions within your HTML markup is a bad idea for several reasons. For our current project, I proposed we put everything in the view directory so they are easy to find:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">app<span style="color: #339933;">/</span>
  views<span style="color: #339933;">/</span>
    home<span style="color: #339933;">/</span>
      index.<span style="color: #006633;">html</span>.<span style="color: #006633;">rb</span>
      index.<span style="color: #006633;">css</span>
      index.<span style="color: #006633;">js</span></pre></div></div>

<p>The convention is clear: to add page-specific CSS code, just create a new file with the same name as the view, in the same folder. Easy to add, edit and remove. The alternative (using the public folder), usually leads to a parallel hierarchy and the inconvenience of that.</p>
<p>I also thought, that this being Rails and all, the files should be included automatically. It turned out to be pretty easy.<span id="more-480"></span></p>
<h2>The Implementation</h2>
<h3>Serving the Assets</h3>
<p>To serve this file, we need a route and a controller.</p>
<p>First the route:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">map.<span style="color:#9900CC;">connect</span> <span style="color:#996600;color: blue;">'/asset/:path'</span>,
    <span style="color:#ff3333; font-weight:bold;">:controller</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#996600;color: blue;">'asset'</span>, <span style="color:#ff3333; font-weight:bold;">:action</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#996600;color: blue;">'serve_asset'</span>, <span style="color:#ff3333; font-weight:bold;">:path</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#006600; font-weight:bold;">/</span>.<span style="color:#006600; font-weight:bold;">*</span>.<span style="color:#006600; font-weight:bold;">&#40;</span>js<span style="color:#006600; font-weight:bold;">|</span>css<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">/</span></pre></div></div>

<p>We need to be careful here, since we&#8217;re going to be serving files directly out of our view hierarchy&#8211; make sure the route only picks up the javascript and CSS files.</p>
<p>The corresponding controller:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> AssetController <span style="color:#006600; font-weight:bold;">&amp;</span>lt; ApplicationController
  <span style="color:#9966CC; font-weight:bold;">def</span> serve_asset
    path = params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:path</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#CC0066; font-weight:bold;">format</span> = path.<span style="color:#CC0066; font-weight:bold;">sub</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">/</span>.<span style="color:#006600; font-weight:bold;">*</span>.<span style="color:#006600; font-weight:bold;">&#40;</span>w<span style="color:#006600; font-weight:bold;">+</span>$<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">/</span>, <span style="color:#996600;color: blue;">'1'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    respond_to <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>format<span style="color:#006600; font-weight:bold;">|</span>
      <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">js</span> <span style="color:#006600; font-weight:bold;">&#123;</span> render <span style="color:#ff3333; font-weight:bold;">:file</span>=<span style="color:#006600; font-weight:bold;">&amp;</span>gt;<span style="color:#996600;color: blue;">&quot;#{RAILS_ROOT}/app/views/#{path}&quot;</span><span style="color:#006600; font-weight:bold;">&#125;</span>
      <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">css</span> <span style="color:#006600; font-weight:bold;">&#123;</span> render<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:file</span>=<span style="color:#006600; font-weight:bold;">&amp;</span>gt;<span style="color:#996600;color: blue;">&quot;#{RAILS_ROOT}/app/views/#{path}&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#125;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Now the assets mentioned above are served as /assets/index.css and /assets/index.js.</p>
<h3>Including the Assets</h3>
<p>With this convention, we added code to our layout that includes these files automatically, but only if they exist. First, the additional controller code:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> AssetController <span style="color:#006600; font-weight:bold;">&amp;</span>lt; ApplicationController
  ...
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">include_asset</span><span style="color:#006600; font-weight:bold;">&#40;</span>rel_path<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#996600;color: blue;">''</span> <span style="color:#9966CC; font-weight:bold;">unless</span> AssetController.<span style="color:#9900CC;">asset_exists</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>rel_path<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">case</span> rel_path
      <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#006600; font-weight:bold;">/</span>.<span style="color:#9900CC;">js</span>$<span style="color:#006600; font-weight:bold;">/</span>
        <span style="color:#996600;color: blue;">&quot;&lt;script src=&quot;</span><span style="color:#006600; font-weight:bold;">/</span>asset<span style="color:#006600; font-weight:bold;">/</span><span style="color:#008000; font-style:italic;">#{rel_path}&quot; type=&quot;text/javascript&quot;&gt;&lt;!--mce:0--&gt;&lt;/script&gt;&quot;</span>
      <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#006600; font-weight:bold;">/</span>.<span style="color:#9900CC;">css</span>$<span style="color:#006600; font-weight:bold;">/</span>
        <span style="color:#996600;color: blue;">&quot;
&quot;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">asset_exists</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>rel_path<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#CC00FF; font-weight:bold;">FileTest</span>.<span style="color:#9900CC;">exists</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>RAILS_ROOT <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#996600;color: blue;">&quot;/app/views/#{rel_path}&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>And the code needed in the (Erector) layout:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">head <span style="color:#9966CC; font-weight:bold;">do</span>
  c = <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9966CC; font-weight:bold;">class</span>
  rawtext AssetController.<span style="color:#9900CC;">include_asset</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;color: blue;">&quot;#{c.name.underscore}.js&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  rawtext AssetController.<span style="color:#9900CC;">include_asset</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;color: blue;">&quot;#{c.name.underscore}.css&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Actually, since it&#8217;s Erector, the views are Ruby classes, so there is a hierarchy. These assets may be specific to any one of these:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">c = <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9966CC; font-weight:bold;">class</span>
<span style="color:#9966CC; font-weight:bold;">while</span> c != <span style="color:#CC00FF; font-weight:bold;">Object</span>
  rawtext AssetController.<span style="color:#9900CC;">include_asset</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;color: blue;">&quot;#{c.name.underscore}.js&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  rawtext AssetController.<span style="color:#9900CC;">include_asset</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;color: blue;">&quot;#{c.name.underscore}.css&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  c = c.<span style="color:#9900CC;">superclass</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<h2>Discussion</h2>
<p>Although some people will bristle at the proliferation of files, I have used this technique repeatedly over the last five years (in Java and PHP projects). I find it leads to sound, modular development. With Ruby, it&#8217;ll be pretty straightforward to concat the assets together later on, to reduce requests, or even embed the code directly in the served HTML files, if it&#8217;s small enough. It&#8217;s also convenient to add page caching in the controller, when the time comes. Adding</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  caches_page<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:serve_asset</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>copies all these files into public/assets (as they are accessed), which conveniently takes your mongrel (or whatever) out of the picture.</p>
<p>You might imagine this keeps you from organizing and structuring your CSS and Javascript; it doesn&#8217;t do that. It lowers the barier to using a &#8220;local&#8221; scope for the CSS and Javascript. It allows you to write page-specific CSS and Javascript, which if you&#8217;re developing code quickly, is a lifesaver. We have repeatedly opened a view-specific Javascript file, seen that it no longer applies to the code, and removed it&#8211; safely. It&#8217;s easy to edit scripts when you know they only effect one page. Without this, I tend to lump things together that don&#8217;t really belong, and it becomes hard to tease them apart later.</p>
<p>Thoughts?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2009/03/javascript-ajax/convenient-css-and-javascript-in-ruby-on-rails/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
