<?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>Olle Jonsson&#039;s blog &#187; Javascript</title>
	<atom:link href="http://ollehost.dk/blog/tag/javascript/feed/" rel="self" type="application/rss+xml" />
	<link>http://ollehost.dk/blog</link>
	<description></description>
	<lastBuildDate>Tue, 22 May 2012 20:28:14 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Workstyle: Add vendor tests before using new library code</title>
		<link>http://ollehost.dk/blog/2010/08/03/workstyle-add-vendor-tests-before-using-new-library-code/</link>
		<comments>http://ollehost.dk/blog/2010/08/03/workstyle-add-vendor-tests-before-using-new-library-code/#comments</comments>
		<pubDate>Tue, 03 Aug 2010 09:19:05 +0000</pubDate>
		<dc:creator>olleolleolle</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[jstestdriver]]></category>
		<category><![CDATA[legacy]]></category>
		<category><![CDATA[maintenance]]></category>

		<guid isPermaLink="false">http://ollehost.dk/blog/?p=809</guid>
		<description><![CDATA[Hello again. Here is a snag-resolving article about a maintenance problem. There should be a thick volume called &#8220;Web Maintenance Pearls&#8221;, which everyone should be forced to read. Here&#8217;s the situation: You want to throw out a dependency. It&#8217;s an &#8230; <a href="http://ollehost.dk/blog/2010/08/03/workstyle-add-vendor-tests-before-using-new-library-code/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Hello again. Here is a snag-resolving article about a maintenance problem. There should be a thick volume called &#8220;Web Maintenance Pearls&#8221;, which everyone should be forced to read.</p>
<p>Here&#8217;s the situation: You want to <strong>throw out a dependency</strong>. It&#8217;s an older JavaScript library, and <strong>you have a replacement lined up</strong>. Some plugin for a popular framework that you already depend on.</p>
<p>Add a couple of <a href="http://code.google.com/p/js-test-driver/wiki/GettingStarted" title="Getting started with jsTestDriver">jsTestDriver</a> <strong>&#8220;VendorTests&#8221; test cases</strong>: proof that the new library works as advertised, defined without the noise of your application&#8217;s behavior. This test will run faster than manually testing your web GUI.</p>
<p>Write the vendor behavior test:</p>
<pre><code>
/** Tests of used vendor framework functions. */
var VendorTests = TestCase("VendorTests", {

    /**
     * MochiKit &#038; the jQuery BBQ plugin should have the same URL querystring-
     * parsing functionality.
     */
    testMochiKitAndJqueryBBQWorkTheSame : function(){
        var qs = 'elvis=1977&#038;reagan=2004&#038;lee=1973',
            ob = {elvis:1977, reagan:2004, lee:1973},
            mObj = MochiKit.Base.parseQueryString(qs),
            jObj = jQuery.deparam(qs),
            mQs = '',
            jQs = '';

        //jstestdriver.console.log("JsTestDriver", "Elvis died in 1977:"+jObj.elvis);
        assertEquals(1977, jObj.elvis);
        assertEquals(2004, mObj.reagan);
        assertEquals(mObj, jObj);

        mQs = MochiKit.Base.queryString(ob);
        jQs = jQuery.param(ob);
        assertEquals(mQs, jQs);
    }
});
</code></pre>
<p>If you want to learn much more about hard maintenance problems, and how to crawl out from under them, <a href="http://www.michaelfeathers.com/">read Michael Feathers</a>.</p>
<p>That was the gist of it.</p>
<p><strong>Snag expansion: Perhaps the jsTestDriver functions get overwritten, by code you import</strong></p>
<p>As you include your target dependency &#8211; MochiKit &#8211; in your list of imported JavaScript files, all your tests still pass. A good sign. You add an empty test-case, with a <tt>fail("Good. If this is NOT seen, it means is trouble!");</tt>, just to see if the testing tool picks it up. All tests, including the new one, pass. A bad sign. <em>Good thing you were suspicious. Paranoid, almost.</em></p>
<p>What just happened, and how to fix it:</p>
<ul>
<li>MochiKit exported all its functions to the global namespace, by default. This includes name-clashing functions that thrash jsTestDriver&#8217;s same-name functions. <em>Thanks to <a href="http://stackoverflow.com/users/230253/alex-brasetvik">brasetvik</a> for noting!</em></li>
<li>You can turn off that default behavior. Add this single line of code to a file, say <tt>initMochiKitWithoutGlobals.js</tt>: <tt>MochiKit = {__export__: false};</tt></li>
<li><del datetime="2010-08-03T09:29:27+00:00">Include the new JS file in the <tt>jsTestDriver.conf</tt> &#8220;load&#8221; section, just before MochiKit:</del></li>
</ul>
<pre><code>
<del datetime="2010-08-03T09:29:27+00:00">server: http://localhost:9876

load:
  - web/scripts/jquery.js
  - web/scripts/tk/mochikit/initMochiKitWithoutGlobals.js
  - web/scripts/tk/mochikit/packed/MochiKit/MochiKit.js
  - web/scripts/jquery.ba-bbq.js
  - web/scripts/your_web_application.js
  - tests/js/your_web_application/*.js
</del></code>
</pre>
<p><strong>Update</strong>: Currently, my way of making MochiKit.js be non-export configured, is to add the <tt>MochiKit = {__export__: false};</tt> line instead of the initial <tt>MochiKit = {};</tt> in the <tt>MochiKit.js</tt> file itself. (Since I&#8217;m moving away from that library, I figured it&#8217;s a cost I can take. It&#8217;s not like I&#8217;ll upgrade it, anyway.) Researching why that variable does not seem to get persisted, perhaps it&#8217;s a load order snag of some kind. <tt>window.MochiKit</tt> did not work. Hm. I&#8217;ll let you know when I nail it.</p>
<p>So, now your testing library runs correctly again. <strong>Cursed be global namespace pollution.</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://ollehost.dk/blog/2010/08/03/workstyle-add-vendor-tests-before-using-new-library-code/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Upcoming meetup poster: active redesigning and customizing</title>
		<link>http://ollehost.dk/blog/2010/05/26/upcoming-meetup-on-active-redesigning-and-customizing-poster/</link>
		<comments>http://ollehost.dk/blog/2010/05/26/upcoming-meetup-on-active-redesigning-and-customizing-poster/#comments</comments>
		<pubDate>Wed, 26 May 2010 20:01:23 +0000</pubDate>
		<dc:creator>olleolleolle</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[meetup]]></category>

		<guid isPermaLink="false">http://ollehost.dk/blog/?p=759</guid>
		<description><![CDATA[Indulge me. I allowed myself to make a little poster. Öresund JavaScript Meetup #10 on June 14, in Malmö, at Hypergene&#8217;s offices. I guess there are a couple of things wrong with it. The date and time are lacking. Monday &#8230; <a href="http://ollehost.dk/blog/2010/05/26/upcoming-meetup-on-active-redesigning-and-customizing-poster/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://ollehost.dk/blog/wp-content/uploads/orejs.jpg"><img src="http://ollehost.dk/blog/wp-content/uploads/orejs-300x225.jpg" alt="Prettify your web apps" title="Oresund JS meetup #10 poster" width="300" height="225" class="alignleft size-medium wp-image-765" /></a></p>
<p>Indulge me. I allowed myself to make a little poster.</p>
<p><a href='http://ollehost.dk/blog/wp-content/uploads/OresundJavaScriptMeetup10.pdf'>Öresund JavaScript Meetup #10</a> on June 14, in Malmö, at Hypergene&#8217;s offices.</p>
<p>I guess there are a couple of things wrong with it. The date and time are lacking. Monday June 14. At 19.00. The URL says those things. (But people looking at a poster can&#8217;t click it.)</p>
<p><a href="http://www.improving-visualisation.org/vis/id=235">These guys would disapprove.</a></p>
<p>Update: Now, I went and added that stuff. </p>
<p>Still, the workshop will be great.</p>
]]></content:encoded>
			<wfw:commentRss>http://ollehost.dk/blog/2010/05/26/upcoming-meetup-on-active-redesigning-and-customizing-poster/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Change ID of a Component in ExtJS</title>
		<link>http://ollehost.dk/blog/2010/04/07/ext-componentmgr-all-changekey/</link>
		<comments>http://ollehost.dk/blog/2010/04/07/ext-componentmgr-all-changekey/#comments</comments>
		<pubDate>Wed, 07 Apr 2010 12:05:51 +0000</pubDate>
		<dc:creator>olleolleolle</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[extjs]]></category>

		<guid isPermaLink="false">http://ollehost.dk/blog/2010/04/07/ext-componentmgr-all-changekey/</guid>
		<description><![CDATA[ExtJS: The Component manager instance&#8217;s all collection does not let you change an ID of a component. Let&#8217;s say&#8230; you wanted to, anyway. Add this: Ext.ComponentMgr.all.changeKey = function(oldkey, newkey) { var comp = this.map[oldkey]; var index = this.indexOfKey(oldkey); this.keys[index] = &#8230; <a href="http://ollehost.dk/blog/2010/04/07/ext-componentmgr-all-changekey/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.extjs.com/">ExtJS</a>: The Component manager instance&#8217;s <code>all</code> collection does not let you change an ID of a component.</p>
<p>Let&#8217;s say&#8230; you wanted to, anyway. Add this:</p>
<pre><code>Ext.ComponentMgr.all.changeKey = function(oldkey, newkey) {
    var comp = this.map[oldkey];
    var index = this.indexOfKey(oldkey);
    this.keys[index] = newkey;
    this.map[newkey] = comp;
    delete this.map[oldkey];
};
</code></pre>
<p>Is there anything really wrong with this approach?</p>
]]></content:encoded>
			<wfw:commentRss>http://ollehost.dk/blog/2010/04/07/ext-componentmgr-all-changekey/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>7th Öresund JavaScript Meetup (and the next)</title>
		<link>http://ollehost.dk/blog/2010/01/21/7th-oresund-javascript-meetup-and-the-next/</link>
		<comments>http://ollehost.dk/blog/2010/01/21/7th-oresund-javascript-meetup-and-the-next/#comments</comments>
		<pubDate>Thu, 21 Jan 2010 12:54:17 +0000</pubDate>
		<dc:creator>olleolleolle</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[meetup]]></category>

		<guid isPermaLink="false">http://ollehost.dk/blog/2010/01/21/7th-oresund-javascript-meetup-and-the-next/</guid>
		<description><![CDATA[So that was the 7th meetup about JavaScript. We learnt stuff about extending Chrome, that WebKit browser. Mark Wubben taught us. Thanks, Mark! You provided much more than a glorified walkthrough of the extant documentation, you gave us insight into &#8230; <a href="http://ollehost.dk/blog/2010/01/21/7th-oresund-javascript-meetup-and-the-next/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>So that was the 7th meetup about JavaScript. We learnt stuff about extending Chrome, that WebKit browser. Mark Wubben taught us.</p>
<p>Thanks, Mark! You provided much more than a glorified walkthrough of the extant documentation, you gave us insight into how the workflow feels, and how a finished product can look.</p>
<p>That went well.</p>
<p>When one participant muttered &#8220;Anyone interested in&#8230; pizza?&#8221; we trudged throught the snow to Drottningtorget, around ten Open Source enthusiasts had gathered for the bi-weekly MOSIG social event. Yep, that&#8217;s short for Malmö Open Source Interest Group. Affectionately known as &#8220;Linux pizza&#8221;.</p>
<p><a href="http://www.meetup.com/The-Oresund-JavaScript-Meetup/calendar/12380885/" title="Meetup page">Next meetup date, in Copenhagen, is at 23&#8242;s headquarters in Vesterbro.</a> </p>
]]></content:encoded>
			<wfw:commentRss>http://ollehost.dk/blog/2010/01/21/7th-oresund-javascript-meetup-and-the-next/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>4th Øresund JavaScript Meetup report</title>
		<link>http://ollehost.dk/blog/2009/10/23/4th-%c3%b8resund-javascript-meetup-report/</link>
		<comments>http://ollehost.dk/blog/2009/10/23/4th-%c3%b8resund-javascript-meetup-report/#comments</comments>
		<pubDate>Fri, 23 Oct 2009 07:05:38 +0000</pubDate>
		<dc:creator>olleolleolle</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[event]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[malmö]]></category>
		<category><![CDATA[meetup]]></category>

		<guid isPermaLink="false">http://ollehost.dk/blog/2009/10/23/4th-%c3%b8resund-javascript-meetup-report/</guid>
		<description><![CDATA[The 4th Øresund JavaScript Meetup was just held at Hypergene&#8216;s Malmö offices, yesterday night. Eight brave souls made the journey to Malmö C and came to Hypergene&#8217;s quite fancy offices. After a little pizza snack and introductory conversation, we repaired &#8230; <a href="http://ollehost.dk/blog/2009/10/23/4th-%c3%b8resund-javascript-meetup-report/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>The 4th <a href="http://www.meetup.com/The-Oresund-JavaScript-Meetup/">Øresund JavaScript Meetup</a> was just held at <a href="http://www.hypergene.se/">Hypergene</a>&#8216;s Malmö offices, yesterday night. Eight brave souls made the journey to Malmö C and came to Hypergene&#8217;s quite fancy offices. After a little pizza snack and introductory conversation, we repaired to a meeting room. Networking was in full swing, in at least three languages, when Jacob announced that he&#8217;d run his introductory <a href="http://visionmedia.github.com/jspec/">JSpec</a> presentation.</p>
<p>It turns out that JSpec is a <a title="Behaviour-Driven Development" href="http://behaviour-driven.org/">BDD</a> specification tool, which uses some Ruby to run its specs. The syntax was a mix of Ruby and JavaScript in the same file. </p>
<p><a href="http://mankzblog.wordpress.com/">Mats Bryntse</a> had quit his job to make an <a href="http://extjs.com">ExtJS</a> web app, and he&#8217;ll be on his way to San Francisco in a few months. The app he made, <a href="http://www.ext-scheduler.com/">Ext.ux.Scheduler</a> is impressive.</p>
<p>Later, I got fiddly. Programming languages had come up in conversation. <a href="http://www.scala-lang.org/">Scala</a>! <a href="http://clojure.org/">Clojure</a>! <a href="http://www.erlang.org/">Erlang</a>! <a href="http://caml.inria.fr/ocaml/">OCaml</a>! So, I installed a few of them. We deciphered a bit of Scala, and tried it out. Quite entrancing, getting it to run, when four people stand around and shout suggestions. The Erlang Eclipse extension Erlide was hastily installed, but we ran out of time before we got anything done with it. And the title of the meetup is &#8220;Öresund JavaScript Meetup&#8221;. The irony was not lost on us. </p>
<p>&#8220;It&#8217;s dead easy to make Erlang web backends!&#8221;, I later exclaimed. &#8220;Can I quote you on that?&#8221; <a href="http://dlade.net/">David</a> retorted.</p>
<p>So, there&#8217;s my challenge. Using <a href="http://erlyweb.org/">ErlyWeb</a>, <a href="http://code.google.com/p/mochiweb/">MochiWeb</a>, and others, and perhaps <a href="http://noss.github.com/2009/04/04/mnesia-sucks-not.html">Mnesia</a> (the database), I&#8217;ll have to work hard until the next meetup to get an environment running &#8211; and make a web application.</p>
<p>Speaking of the next meetup, David, who&#8217;s working for streaming outfit <a href="http://xstream.dk/">XStream</a> in Copenhagen, will try and convince his people that a JavaScript Meetup is just what they need to host, so we&#8217;ll probably be in Copenhagen next time.</p>
<p>What&#8217;s more? There were shoutouts to the <a href="http://www.meetup.com/copenhagenphp/">Copenhagen PHP Meetup</a>, and talk about coding dojos. </p>
]]></content:encoded>
			<wfw:commentRss>http://ollehost.dk/blog/2009/10/23/4th-%c3%b8resund-javascript-meetup-report/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Oresund JavaScript Meetup tonight</title>
		<link>http://ollehost.dk/blog/2009/03/26/oresund-javascript-meetup-tonight/</link>
		<comments>http://ollehost.dk/blog/2009/03/26/oresund-javascript-meetup-tonight/#comments</comments>
		<pubDate>Thu, 26 Mar 2009 10:03:45 +0000</pubDate>
		<dc:creator>olleolleolle</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[event]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[oresund]]></category>

		<guid isPermaLink="false">http://ollehost.dk/blog/2009/03/26/oresund-javascript-meetup-tonight/</guid>
		<description><![CDATA[Quoth the Öresund JS meetup locally here: 18.00 - 18.15 Arrive, have some free pizza and soda 18.15 - 18.30 Introduction of members and talk about the future of the group 18.30 - 18.40 Mats Bryntse - How "global" are &#8230; <a href="http://ollehost.dk/blog/2009/03/26/oresund-javascript-meetup-tonight/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Quoth the <a href="http://www.meetup.com/The-Oresund-JavaScript-Meetup/">Öresund JS meetup</a> locally here:</p>
<pre>
18.00 - 18.15 Arrive, have some free pizza and soda
18.15 - 18.30 Introduction of members and talk about the future of the group
18.30 - 18.40 Mats Bryntse - How "global" are the modern Ajax frameworks
18.50 - 19.10 Olle Jonsson - Building a Dojo application using Bespin (by Mozilla Labs)
19.10 - 19-20 Fredric Berling - "Hello world" with ExtJS
----------------------------------------------------------------
</pre>
<p>It&#8217;s tonight. Wanna come? I go from Malmö after work.</p>
<p>So, my title there, it&#8217;s a bit off, I&#8217;m going to show you how to become a Bespin hacker. What steps to take. Where to fix things. (Since there&#8217;s an ample list of things to fix &#8211; as in every healthy FOSS project.)</p>
]]></content:encoded>
			<wfw:commentRss>http://ollehost.dk/blog/2009/03/26/oresund-javascript-meetup-tonight/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Hackmeetup on Javascript mini-report: RFID on Rhino</title>
		<link>http://ollehost.dk/blog/2008/07/25/hackmeetup-on-javascript-mini-report-rfid-on-rhino/</link>
		<comments>http://ollehost.dk/blog/2008/07/25/hackmeetup-on-javascript-mini-report-rfid-on-rhino/#comments</comments>
		<pubDate>Fri, 25 Jul 2008 05:30:28 +0000</pubDate>
		<dc:creator>olleolleolle</dc:creator>
				<category><![CDATA[Events]]></category>
		<category><![CDATA[event]]></category>
		<category><![CDATA[hackmeetup]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[rfid]]></category>
		<category><![CDATA[rhino]]></category>
		<category><![CDATA[ubicomp]]></category>

		<guid isPermaLink="false">http://ollehost.dk/blog/?p=421</guid>
		<description><![CDATA[This past Tuesday, we ran another Hackmeetup. Same great location, same great time. Mark ran a talk about Typography on the Web for an audience of three. For the hardware experimentation session, Carl had left, so it was Mark, me, &#8230; <a href="http://ollehost.dk/blog/2008/07/25/hackmeetup-on-javascript-mini-report-rfid-on-rhino/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This past Tuesday, we ran another <a href="http://hackmeetup.ollehost.dk">Hackmeetup</a>. Same great location, same great time. </p>
<p><a href="http://novemberborn.net">Mark</a> ran a talk about <a href="http://www.singularity08.com/speakers/mark-wubben/">Typography on the Web</a> for an audience of three. </p>
<p>For the hardware experimentation session, Carl had left, so it was Mark, me, and <a href="http://dlade.net">David</a>, and we all worked on the same project. Mark had brought a USB-connected RFID reader of the <a href="http://www.phidgets.com/">Phidgets</a> brand, and the idea: Use <a href="http://mozilla.org/rhino/">Rhino</a> to wrap the Phidgets Java API to the RFID reader in a JavaScript, so we could&#8230; script the thing.</p>
<p><strong>Update</strong>: <a href="http://code.google.com/p/physical-js/">Physical.js</a> is the software we wrote, now published under MIT license. </p>
<p>We printed out the Javadocs for the API, and began laughing at some of the names: <code>getLEDOn()</code>, <code>getAntennaOn()</code>. Then we whiteboard-sessioned up some simpler, JS-idiomatic names, and had our wishlist. Almost cheating: Rhino has <code>__defineGetter__</code> and <code>__defineSetter__</code>. Then we scrambled to find out how Rhino&#8217;s Java-adapting mechanism really worked. Great fun! Mark was the only one with the Phidgets hardware and software platform installed, so he was typing what me and David sent to him. </p>
<p>Prototyping with Rhino is quick. Soon, we were able to read the RFID card that Mark brought, and also a keychain fob I had with me. When we had 30 minutes until the trains went, Mark said: Let&#8217;s also hook it up to chat Jabber! He installed an <a href="http://www.igniterealtime.org/projects/openfire/">OpenFire</a> XMPP server on his machine, created a &#8220;rfid&#8221; account, and had it send a message onTagEnter and onTagLeave (enter/leave sounds better than gain/loss: we&#8217;re web developers&#8230;). Then he took an extra step and made chat commands to enable/disable the LED and antenna.  </p>
<p>We cheered. We&#8217;d done it all.</p>
<p><b>Conclusion</b>: Working on the same project is very productive. This was the first time we had a theme, two speakers, a dropped talk, and gotten stuff Done and Ready and the end of the night. Also: snacks. Healthier snacks are better, so next time, let&#8217;s up the ante.</p>
]]></content:encoded>
			<wfw:commentRss>http://ollehost.dk/blog/2008/07/25/hackmeetup-on-javascript-mini-report-rfid-on-rhino/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Crosscheck wheel spin</title>
		<link>http://ollehost.dk/blog/2007/10/05/crosscheck-wheel-spin/</link>
		<comments>http://ollehost.dk/blog/2007/10/05/crosscheck-wheel-spin/#comments</comments>
		<pubDate>Fri, 05 Oct 2007 21:00:23 +0000</pubDate>
		<dc:creator>olleolleolle</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[copenhagenrb]]></category>
		<category><![CDATA[crosscheck]]></category>

		<guid isPermaLink="false">http://ollehost.dk/blog/?p=362</guid>
		<description><![CDATA[At the last meeting with Copenhagen.rb, I said I&#8217;d test out Crosscheck &#8211; a JavaScript testing framework, suited for continuous integration or command-line testing. I had just tried getting it to run, following the slightly outdated Add Event tutorial. At &#8230; <a href="http://ollehost.dk/blog/2007/10/05/crosscheck-wheel-spin/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>At the last meeting with Copenhagen.rb, I said I&#8217;d test out <a href="http://www.thefrontside.net/crosscheck">Crosscheck</a> &#8211; a JavaScript testing framework, suited for continuous integration or command-line testing.</p>
<p>I had just tried getting it to run, following the slightly outdated <a href="https://dev.thefrontside.net/crosscheck/wiki/AddEventTutorial">Add Event tutorial</a>. At last I got it to work, but I had to actually read the text, not just paste the examples. Better grab the example source code than read the slightly-outdated docs.</p>
<p>Tonight I have tested it in a little more real setting: I had a hunch of how I would be able to do a filtering function that worked like in Quicksilver or Textmate. A case-insensitive, very inclusive search that just narrows down based on the sequence of the characters, not on their immediate order. (Did that make sense?)</p>
<p>Expressed as a positive test case: &#8220;jy8&#8243; should match &#8220;Jyri is happy to be 8 years of age&#8221;.</p>
<p>Anyway, I thought I could construct a regex on the fly, somehow. I itched to try. And I wanted to try it using tests along the way.</p>
<p>So, I entered the first, simplest case I could think of: equality. A list of one element should return only a single-element array. That was simple to do, so I could take on the next (that I could think of). And the rest was just implementation, until I hit something I had to test in Firebug.</p>
<p>The cool thing was that my experimentation was over as soon as I&#8217;d answered the question I had. Focus, the programmer&#8217;s holy grail. The promise of focus, at least. We&#8217;ll see about how that holds up in practice.</p>
<p>Here is the quite redundant, stupid list of test cases that I accumulated while trying things on:</p>
<pre><code>
crosscheck.onSetup(function(){
    crosscheck.load("scripts/quicksilverSearch.js");
});
crosscheck.addTest({
    testShouldFindSameMatchingString : function () {
        var outPut = quicksilverMatch('johnny', ['johnny']);
        var exp = ['johnny'];
        assertEquals( exp[0], outPut[0],
            'The same word could not be found in the simple array. Shame.' );
    },
    testShouldNotFindANonMatchingString : function () {
        var outPut = quicksilverMatch('jx', ['johnny']);
        assertTrue( outPut.length == 0, 'The word jx was found in johnny?! Shame.' );
    },
    testShouldMatchAllOnFirstLetter : function() {
        var outPut = quicksilverMatch('jo', ['johnny', 'jools', 'june']);
        assertTrue( outPut.length == 2,
            'Unable to match with indexOf on the first two letters. Shame.' );
    },
    testShouldMatchAcrossWords : function() {
        var outPut = quicksilverMatch('jy', ['jyri', 'johnny', 'june']);
        assertTrue( outPut.length == 2,
            'Unable to match across words. Shame.' );
    },
    testShouldMatchAcrossWordsCaseInsensitively : function() {
        var outPut = quicksilverMatch('jy8', ['Jyri 8 years', 'Johnny turns 8', 'june']);
        assertTrue( outPut.length == 2,
            'Unable to match case-ins. across words. Shame.' );
    }
});
</code></pre>
<p>So, the first thing that gets done before execution of each test case: load my script. That is specified in <code>crosscheck.onSetup</code>.</p>
<p>The least interesting part of this is my resulting code. After pulling it through JSLint and mulling over it a couple more times, it just shrunk. Which is the end goal of testing, I guess: to have me own as little code as possible. (We&#8217;ll come back to that.)</p>
<pre><code>
/**
 * "Quicksilver" filter search: returns an array of the haystack elements that
 * match case-insensitively the given term.
 * 2007-10-05, Olle
 */
function quicksilverMatch(term, haystack) {
    var matches = [];
    var straw; // The individual piece of hay
    // "t.*e.*r.*m" regular expression for loose matching
    var re = new RegExp(term.split("").join('.*'), "i");
    for (var idx = 0, len = haystack.length; idx < len; ++idx) {
        straw = haystack[idx];
        // Direct match inside word? Or: a case-ins. loose match
        if (straw.indexOf(term) > -1 || re.test(straw)) {
            matches.push(straw);
        }
    }
    return matches;
}
</code></pre>
<p>The take-home piece I got from this sitting was how to run Crosscheck. I created a wrapper shell script that I christened &#8220;crosschecka&#8221;, where I set my target browsers (&#8220;hosts&#8221;) and paths:</p>
<pre><code>
#!/bin/bash
#
# Run the crosscheck jar on given test path, or default
#
# We run on Firefox 1.5 and IE6: moz-1.8:ie-6
#
# Author: olle, 2007-09-26

CROSSCHECK_JAR=/Users/olle/lib/crosscheck-0.2.1/crosscheck.jar
# Colon-separated. Possible values are moz-1.7:moz-1.8:ie-6
HOSTS_TO_CHECK=moz-1.8:ie-6    

# Our test path is tests/eosweb/js, relative to the web app root
if [[ $1 == '' ]]; then
{
    java -jar $CROSSCHECK_JAR -hosts=$HOSTS_TO_CHECK tests/eosweb/js
    exit 0;
}
else
{
    java -jar $CROSSCHECK_JAR -hosts=$HOSTS_TO_CHECK $1
    exit 0;
}
fi
</code></pre>
<p>(I never got the file test in the else clause right, so I let Crosscheck complain for me.) The Rails-type win here is having a pre-set default, so I never have to think about it.</p>
<p>Thought: Maybe this whole testing thing is a way to get me to reduce the scope of my methods? To be testable, they have to be decomposed to parts that are cheap to test. </p>
<p>I said I&#8217;d come back to owning less code: now that I know these things about the behaviour of my code, do you think I should revisit and sharpen up my test-cases? For one thing, some of them might not even hit right. The first one, it seems very weak and situationally dependent. </p>
<p>Would you go back and change such stuff? Or delete such cases?</p>
]]></content:encoded>
			<wfw:commentRss>http://ollehost.dk/blog/2007/10/05/crosscheck-wheel-spin/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

