<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>Pawel Pabich's blog</title>
        <link>http://www.pabich.eu/blog/Default.aspx</link>
        <description>Keep it simple but not simpler</description>
        <language>en-AU</language>
        <copyright>Pawel Pabich</copyright>
        <generator>Subtext Version 2.5.0.3</generator>
        <image>
            <title>Pawel Pabich's blog</title>
            <url>http://www.pabich.eu/blog/images/RSS2Image.gif</url>
            <link>http://www.pabich.eu/blog/Default.aspx</link>
            <width>77</width>
            <height>60</height>
        </image>
        <item>
            <title>RubyMine is a real gem</title>
            <link>http://www.pabich.eu/blog/archive/2010/08/26/RubyMine-is-a-real-gem.aspx</link>
            <description>&lt;p&gt;Today I had to fix a piece of custom code inside of &lt;a href="http://blog.duc.as/2010/08/25/a-day-in-the-life-of-a-metro-veloper/feed/"&gt;&lt;strong&gt;Redmine&lt;/strong&gt;&lt;/a&gt;. I have very little experience with Ruby on Rails but I was able to get the app up and running with a debugger attached within 15 minutes. &lt;/p&gt;  &lt;p&gt;I downloaded the latest version of &lt;a href="http://confluence.jetbrains.net/display/RUBYDEV/RubyMine+EAP"&gt;&lt;strong&gt;RubyMine 2.5 EAP&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;,&lt;/strong&gt; installed it, pointed it to the folder with the app, selected production configuration and hit Debug. &lt;a href="http://www.jetbrains.com/ruby/"&gt;&lt;strong&gt;RubyMine&lt;/strong&gt;&lt;/a&gt; analysed my Ruby setup and popped up a window with a notification that I’m missing some gems and the IDE can download and install them for me. I hit Ok and 5 minutes later I was debugging the app. Ruby on Rails experience on Windows is far from being perfect but &lt;a href="http://www.jetbrains.com/ruby/"&gt;&lt;strong&gt;RubyMine&lt;/strong&gt;&lt;/a&gt; is simply awesome.&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:03326406-c245-46f3-95a3-0cd608ac7f7f" class="wlWriterEditableSmartContent"&gt;Tags: &lt;a href="http://www.pabich.eu/blog/tags/Ruby/default.aspx" rel="tag"&gt;Ruby&lt;/a&gt;, &lt;a href="http://www.pabich.eu/blog/tags/RubyMine/default.aspx" rel="tag"&gt;RubyMine&lt;/a&gt;, &lt;a href="http://www.pabich.eu/blog/tags/Debugging/default.aspx" rel="tag"&gt;Debugging&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.pabich.eu/blog/aggbug/146.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Pawel Pabich</dc:creator>
            <guid>http://www.pabich.eu/blog/archive/2010/08/26/RubyMine-is-a-real-gem.aspx</guid>
            <pubDate>Thu, 26 Aug 2010 13:28:39 GMT</pubDate>
            <comments>http://www.pabich.eu/blog/archive/2010/08/26/RubyMine-is-a-real-gem.aspx#feedback</comments>
            <wfw:commentRss>http://www.pabich.eu/blog/comments/commentRss/146.aspx</wfw:commentRss>
            <trackback:ping>http://www.pabich.eu/blog/services/trackbacks/146.aspx</trackback:ping>
        </item>
        <item>
            <title>Java Script unit testing with YUI Test and Jack mocking framework</title>
            <link>http://www.pabich.eu/blog/archive/2010/07/22/Java-Script-unit-testing-with-YUI-Test-and-Jack-mocking.aspx</link>
            <description>&lt;p&gt;I strongly believe in unit testing and recently I spent a bit of time trying to apply this technique to Java Script code. &lt;/p&gt;  &lt;p&gt;The first problem that I had to solve was which framework to use. From what I’ve read it looks like &lt;a href="http://code.google.com/p/jsspec/"&gt;&lt;strong&gt;JSSpec&lt;/strong&gt;&lt;/a&gt;, &lt;a href="http://docs.jquery.com/QUnit"&gt;&lt;strong&gt;qUnit&lt;/strong&gt;&lt;/a&gt; and &lt;a href="http://developer.yahoo.com/yui/3/test/"&gt;&lt;strong&gt;YUI Test&lt;/strong&gt;&lt;/a&gt; get most of the attention nowadays. YUI is the most mature from them and offers by far the most functionality out of the box. On the other hand it is the most complex one to setup but still the whole process takes only a few copy/paste clicks. At the end of the day I decided to go with YUI Test because I wanted to check if I really need its rich capabilities.&lt;/p&gt;  &lt;p&gt;In C# world to make unit testing easy we use mocking frameworks. In Java Script world mocking frameworks are not needed because Java Script is a dynamic language and every method/object can be overwritten at any time at runtime. Still mocking might take a bit of effort because you have to keep the original method somewhere around to put it back to where it was at the end of a test. Otherwise you end up with state that is shared between tests which is a bad thing. &lt;a href="http://boss.bekk.no/display/BOSS/Jack"&gt;&lt;strong&gt;Jack&lt;/strong&gt;&lt;/a&gt; is a mocking framework that helps solve this problem. It’s not perfect but it is good enough for what I wanted to do.&lt;/p&gt;  &lt;p&gt;Enough introduction, let’s start with the story that I’ve implemented. The link to the complete source code is located at the bottom of this post.&lt;/p&gt;  &lt;p&gt;There is a simple form and we have to write client side validation logic for it. The rules are as follows:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The user can select either one or more predefined reasons or can provide a custom reason. The user can not use both. &lt;/li&gt;    &lt;li&gt;If the form validation succeeds then the user gets a popup with “Correct” message &lt;/li&gt;    &lt;li&gt;If the form validation fails then the user gets a popup with “Wrong” message. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;This is how the form looks like:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.pabich.eu/blog/images/www_pabich_eu/blog/WindowsLiveWriter/JavaScriptunittestingwithYUITestandJackm_144D5/image_6.png" rel="lightbox"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.pabich.eu/blog/images/www_pabich_eu/blog/WindowsLiveWriter/JavaScriptunittestingwithYUITestandJackm_144D5/image_thumb_2.png" width="407" height="333" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;and this is the HTML behind it: &lt;/p&gt;  &lt;pre class="code"&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;html &lt;/span&gt;&lt;span style="color: red"&gt;xmlns&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;="http://www.w3.org/1999/xhtml"&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;head&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;title&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;title&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;script &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;="Scripts/Form.js" &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;="text/javascript"&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;script &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;="text/javascript"
    &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;head&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;body&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;form &lt;/span&gt;&lt;span style="color: red"&gt;method&lt;/span&gt;&lt;span style="color: blue"&gt;="post" &lt;/span&gt;&lt;span style="color: red"&gt;action&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;=""&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;p&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;Why did you decided to submit this form?&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;p&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;fieldset&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;&amp;gt;
            &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;legend&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;Reasons&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;legend&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;&amp;gt;
            &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;ul&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;&amp;gt;
                &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;&amp;gt;
                    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;label &lt;/span&gt;&lt;span style="color: red"&gt;for&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;="dontKnowReason"&amp;gt;
                    &lt;/span&gt;I don't know:
                    &lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;label&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;&amp;gt;
                    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;input &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;="checkbox" &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;="dontKnowReason" 
                    &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;="dontKnowReason" /&amp;gt;                    
                &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;&amp;gt;
                &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;&amp;gt;
                    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;label &lt;/span&gt;&lt;span style="color: red"&gt;for&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;="likeTheFormReason"&amp;gt;
                    &lt;/span&gt;I like the form:
                    &lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;label&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;&amp;gt;
                    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;input &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;="checkbox" &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;="likeTheFormReason" 
                    &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;="likeTheFormReason" /&amp;gt;                    
                &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;&amp;gt;
                &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;&amp;gt;
                    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;label &lt;/span&gt;&lt;span style="color: red"&gt;for&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;="wasToldReason"&amp;gt;
                    &lt;/span&gt;Someone told me to do so:
                    &lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;label&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;&amp;gt;
                    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;input &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;="checkbox" &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;="wasToldReason" 
                    &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;="wasToldReason" /&amp;gt;                    
                &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;&amp;gt;        
                &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;&amp;gt;
                    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;label &lt;/span&gt;&lt;span style="color: red"&gt;for&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;="customReason"&amp;gt;
                    &lt;/span&gt;Other reason:
                    &lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;label&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;&amp;gt;
                    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;input &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;="text" &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;="customReason" 
                    &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;="customReason" /&amp;gt;                    
                &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;&amp;gt;                                              
            &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;ul&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;&amp;gt;            
        &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;fieldset&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;input &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;="submit" &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;="Submit" /&amp;gt;    
    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;form&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;&amp;gt;

    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;script &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;="text/javascript"&amp;gt;

        &lt;/span&gt;$(&lt;span style="color: blue"&gt;function &lt;/span&gt;() {
            JSUnitTesting.init();
        });
       
    &lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;body&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;html&lt;/span&gt;&lt;/font&gt;&lt;span style="color: blue"&gt;&lt;font size="1"&gt;&amp;gt;&lt;/font&gt;

&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;To be able to run the unit tests we have to have an HTML page that simply loads all required Java Script code and executes it. &lt;/p&gt;

&lt;pre class="code"&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;&amp;lt;!&lt;/span&gt;&lt;span style="color: maroon"&gt;DOCTYPE &lt;/span&gt;&lt;span style="color: red"&gt;html PUBLIC &lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;"-//W3C//DTD XHTML 1.0 Transitional//EN" 
          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;html &lt;/span&gt;&lt;span style="color: red"&gt;xmlns&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;="http://www.w3.org/1999/xhtml" &amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;head&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;title&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;Untitled Page&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;title&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;&amp;gt;

    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;link &lt;/span&gt;&lt;span style="color: red"&gt;rel&lt;/span&gt;&lt;span style="color: blue"&gt;="stylesheet" &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;="text/css" 
    &lt;/span&gt;&lt;span style="color: red"&gt;href&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;="http://developer.yahoo.com/yui/3/assets/yui.css"/&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;link &lt;/span&gt;&lt;span style="color: red"&gt;rel&lt;/span&gt;&lt;span style="color: blue"&gt;="stylesheet" &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;="text/css" 
    &lt;/span&gt;&lt;span style="color: red"&gt;href&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;="http://yui.yahooapis.com/3.1.1/build/cssfonts/fonts-min.css"/&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;script &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;="http://yui.yahooapis.com/3.1.1/build/yui/yui-min.js" 
    &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;="text/javascript" &amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;script &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;="Scripts/jack.js" &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;="text/javascript" &amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;script &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;="Scripts/Form.js" &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;="text/javascript" &amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;script &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;="Scripts/UnitTests.js" &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;="text/javascript" &amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;head&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;body &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;="yui3-skin-sam  yui-skin-sam"&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;="testLogger"&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;div&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;&amp;gt; 
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;body&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;html&lt;/span&gt;&lt;/font&gt;&lt;span style="color: blue"&gt;&lt;font size="1"&gt;&amp;gt;&lt;/font&gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;As you can see the HTML page is very simple. It loads a few files that belong to YUI framework, then it loads code under test from &lt;strong&gt;Form.js&lt;/strong&gt; and the actual unit tests from &lt;strong&gt;UnitTests.js&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Below is the content of &lt;strong&gt;UnitTest.js&lt;/strong&gt; file. &lt;/p&gt;

&lt;p&gt;&lt;font size="1"&gt;&lt;span style="color: #006400"&gt;/// &amp;lt;reference path="jack.js" /&amp;gt; 
      &lt;br /&gt;

      &lt;br /&gt;&lt;/span&gt;JST = JSUnitTesting; 

    &lt;br /&gt;

    &lt;br /&gt;YUI().use(&lt;span style="color: maroon"&gt;"node"&lt;/span&gt;, &lt;span style="color: maroon"&gt;"console"&lt;/span&gt;, &lt;span style="color: maroon"&gt;"test"&lt;/span&gt;, &lt;span style="color: blue"&gt;function &lt;/span&gt;(Y) { 

    &lt;br /&gt;

    &lt;br /&gt;    &lt;span style="color: blue"&gt;var &lt;/span&gt;validation_tests = &lt;span style="color: blue"&gt;new &lt;/span&gt;Y.Test.Case({ 

    &lt;br /&gt;

    &lt;br /&gt;        name: &lt;span style="color: maroon"&gt;"Validation tests"&lt;/span&gt;, 

    &lt;br /&gt;

    &lt;br /&gt;       &lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: maroon"&gt;"validation should fail when both custom and 
      &lt;br /&gt;        "predefined reasons are selected"&lt;/span&gt;: &lt;span style="color: blue"&gt;function &lt;/span&gt;() { 

    &lt;br /&gt;

    &lt;br /&gt;            &lt;span style="color: blue"&gt;var &lt;/span&gt;reasons = [&lt;span style="color: blue"&gt;true&lt;/span&gt;, &lt;span style="color: blue"&gt;false&lt;/span&gt;, &lt;span style="color: blue"&gt;true&lt;/span&gt;]; 

    &lt;br /&gt;            &lt;span style="color: blue"&gt;var &lt;/span&gt;result = JST.validate(reasons, &lt;span style="color: maroon"&gt;"content"&lt;/span&gt;); 

    &lt;br /&gt;

    &lt;br /&gt;            Y.Assert.isFalse(result); 

    &lt;br /&gt;        }, 

    &lt;br /&gt;

    &lt;br /&gt;        &lt;span style="color: maroon"&gt;"validation should succeed when only custom reason is selected"&lt;/span&gt;: &lt;span style="color: blue"&gt;function &lt;/span&gt;() { 

    &lt;br /&gt;

    &lt;br /&gt;            &lt;span style="color: blue"&gt;var &lt;/span&gt;reasons = [&lt;span style="color: blue"&gt;false&lt;/span&gt;, &lt;span style="color: blue"&gt;false&lt;/span&gt;, &lt;span style="color: blue"&gt;false&lt;/span&gt;]; 

    &lt;br /&gt;            &lt;span style="color: blue"&gt;var &lt;/span&gt;result = JST.validate(reasons, &lt;span style="color: maroon"&gt;"content"&lt;/span&gt;); 

    &lt;br /&gt;

    &lt;br /&gt;            Y.Assert.isTrue(result); 

    &lt;br /&gt;        }, 

    &lt;br /&gt;

    &lt;br /&gt;        &lt;span style="color: maroon"&gt;"validation should fail when none of the reasons is selected"&lt;/span&gt;: &lt;span style="color: blue"&gt;function &lt;/span&gt;() { 

    &lt;br /&gt;

    &lt;br /&gt;            &lt;span style="color: blue"&gt;var &lt;/span&gt;reasons = [&lt;span style="color: blue"&gt;false&lt;/span&gt;, &lt;span style="color: blue"&gt;false&lt;/span&gt;, &lt;span style="color: blue"&gt;false&lt;/span&gt;]; 

    &lt;br /&gt;            &lt;span style="color: blue"&gt;var &lt;/span&gt;result = JST.validate(reasons, &lt;span style="color: maroon"&gt;""&lt;/span&gt;); 

    &lt;br /&gt;

    &lt;br /&gt;            Y.Assert.isFalse(result); 

    &lt;br /&gt;        }, 

    &lt;br /&gt;

    &lt;br /&gt;        &lt;span style="color: maroon"&gt;"validation should succeed when only predefined reasons are selected"&lt;/span&gt;: &lt;span style="color: blue"&gt;function &lt;/span&gt;() { 

    &lt;br /&gt;

    &lt;br /&gt;            &lt;span style="color: blue"&gt;var &lt;/span&gt;reasons = [&lt;span style="color: blue"&gt;true&lt;/span&gt;, &lt;span style="color: blue"&gt;true&lt;/span&gt;, &lt;span style="color: blue"&gt;true&lt;/span&gt;]; 

    &lt;br /&gt;            &lt;span style="color: blue"&gt;var &lt;/span&gt;result = JST.validate(reasons, &lt;span style="color: maroon"&gt;""&lt;/span&gt;); 

    &lt;br /&gt;

    &lt;br /&gt;            Y.Assert.isTrue(result); 

    &lt;br /&gt;        } 

    &lt;br /&gt;    }); 

    &lt;br /&gt;

    &lt;br /&gt;    &lt;span style="color: blue"&gt;var &lt;/span&gt;submission_tests = &lt;span style="color: blue"&gt;new &lt;/span&gt;Y.Test.Case({ 

    &lt;br /&gt;

    &lt;br /&gt;        name: &lt;span style="color: maroon"&gt;"Submission tests"&lt;/span&gt;, 

    &lt;br /&gt;

    &lt;br /&gt;        &lt;span style="color: maroon"&gt;"confirmation should be shown to the user when validation passes and form is about to be submitted"&lt;/span&gt;: &lt;span style="color: blue"&gt;function &lt;/span&gt;() { 

    &lt;br /&gt;

    &lt;br /&gt;            jack(&lt;span style="color: blue"&gt;function &lt;/span&gt;() { 

    &lt;br /&gt;

    &lt;br /&gt;                jack.expect(&lt;span style="color: maroon"&gt;"JST.getCustomReason"&lt;/span&gt;).atLeast(0).returnValue(&lt;span style="color: blue"&gt;null&lt;/span&gt;); 

    &lt;br /&gt;                jack.expect(&lt;span style="color: maroon"&gt;"JST.getPredefinedReasons"&lt;/span&gt;).atLeast(0).returnValue(&lt;span style="color: blue"&gt;null&lt;/span&gt;); 

    &lt;br /&gt;                jack.expect(&lt;span style="color: maroon"&gt;"JST.validate"&lt;/span&gt;).atLeast(0).returnValue(&lt;span style="color: blue"&gt;true&lt;/span&gt;); 

    &lt;br /&gt;                jack.expect(&lt;span style="color: maroon"&gt;"JST.notify"&lt;/span&gt;).once().mock(&lt;span style="color: blue"&gt;function &lt;/span&gt;(arg) { 

    &lt;br /&gt;                    Y.Assert.areNotEqual(arg.indexOf(&lt;span style="color: maroon"&gt;"Correct"&lt;/span&gt;), -1); 

    &lt;br /&gt;                }); 

    &lt;br /&gt;               &lt;br /&gt;                JST.submitForm(); 

    &lt;br /&gt;            }); 

    &lt;br /&gt;        } 

    &lt;br /&gt;    }); 

    &lt;br /&gt;

    &lt;br /&gt;    &lt;span style="color: blue"&gt;var &lt;/span&gt;console = &lt;span style="color: blue"&gt;new &lt;/span&gt;Y.Console({ 

    &lt;br /&gt;        verbose: &lt;span style="color: blue"&gt;true&lt;/span&gt;, 

    &lt;br /&gt;        newestOnTop: &lt;span style="color: blue"&gt;false&lt;/span&gt;, 

    &lt;br /&gt;        style: &lt;span style="color: maroon"&gt;"block"&lt;/span&gt;, 

    &lt;br /&gt;        height:&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: maroon"&gt;"500px" 
      &lt;br /&gt;    &lt;/span&gt;}); 

    &lt;br /&gt;

    &lt;br /&gt;    console.render(&lt;span style="color: maroon"&gt;'#testLogger'&lt;/span&gt;); 

    &lt;br /&gt;

    &lt;br /&gt;    Y.Test.Runner.add(validation_tests); 

    &lt;br /&gt;    Y.Test.Runner.add(submission_tests); 

    &lt;br /&gt;    Y.Test.Runner.run(); 

    &lt;br /&gt;});&lt;/font&gt; &lt;/p&gt;

&lt;p&gt;and the end result in a web browser:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.pabich.eu/blog/images/www_pabich_eu/blog/WindowsLiveWriter/JavaScriptunittestingwithYUITestandJackm_144D5/image_4.png" rel="lightbox"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="image" border="0" alt="image" src="http://www.pabich.eu/blog/images/www_pabich_eu/blog/WindowsLiveWriter/JavaScriptunittestingwithYUITestandJackm_144D5/image_thumb_1.png" width="288" height="467" /&gt;&lt;/a&gt; 

  &lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;The only thing that requires explanation here is the difference between Validation and Submission tests. The &lt;strong&gt;validate&lt;/strong&gt; method is a standalone method that does not have any dependencies hence its unit testing is very simple and boils down to passing different sets of input parameters and asserting the correct results. &lt;/p&gt;

&lt;p&gt;The unit testing of the &lt;strong&gt;submitForm&lt;/strong&gt; method on the other hand is not that simple because the method relies on &lt;strong&gt;getPredefinedReasons&lt;/strong&gt; and &lt;strong&gt;getCustomReason&lt;/strong&gt; methods that grab data from the DOM and &lt;strong&gt;validate&lt;/strong&gt; method that ensures that the user provided data is valid. We are not interested in the way those methods work while unit testing &lt;strong&gt;submitForm&lt;/strong&gt; method. They actually gets in the way. What we need to do is to mock them and focus on making sure the &lt;strong&gt;submitForm &lt;/strong&gt;method shows correct messages to the user. &lt;/p&gt;

&lt;p&gt;The mocking framework takes care of that. All we have to do is create an anonymous method that encapsulate all our mocking logic. The mocking framework will make sure that once the test is done the global state gets rolled back to where it was before the test was executed. The way Jack is designed reminds me of &lt;strong&gt;using&lt;/strong&gt; and &lt;strong&gt;IDisposable&lt;/strong&gt; in C#.&lt;/p&gt;

&lt;p&gt;As you can see the jQuery based code is encapsulated into getXXX methods which makes easy to mock them. Some people don’t mock jQuery and instead try to recreate enough DOM elements on the test page to satisfy the tests. I don’t like this approach because changes to either HTML or jQuery might force us to change the unit tests which makes them brittle. It is like using L2S in a unit test. It’s not a unit test, it is an integration test. Other approach I’ve seen is to mock jQuery methods one by one. This is a slightly better approach but still changes to jQuery queries can break the tests. It is like trying to mock a sequence of Linq extension methods. It’s way easier to mock the whole method that simply encapsulates the query.&lt;/p&gt;

&lt;p&gt;If this was a C# code then getXXX methods would be defined on some kind of repository and validate method would belong to a validation component. Both of them would be injected to the main logic that handles the form submission. If this was an ASP.NET MVC app that would be a controller. It was not my intention to structure the code in this way but that’s what I ended up with writing the tests first.&lt;/p&gt;

&lt;p&gt;You might wonder why I haven’t shown the actual code yet. Well, I did it on purpose. The unit tests should be enough to understand what the client side code does and what its desired behaviour is. If this is still not clear then it means that either the code is not structured properly or that the names are not descriptive enough.&lt;/p&gt;

&lt;p&gt;And that would be it. The last thing to do is to show the actual code: &lt;/p&gt;

&lt;pre class="code"&gt;&lt;font size="1"&gt;JSUnitTesting = {

    getPredefinedReasons: &lt;span style="color: blue"&gt;function &lt;/span&gt;() {
        &lt;span style="color: blue"&gt;var &lt;/span&gt;values = [];
        $(&lt;span style="color: maroon"&gt;"input[type='checkbox']"&lt;/span&gt;).each(&lt;span style="color: blue"&gt;function &lt;/span&gt;() {
            values.push($(&lt;span style="color: blue"&gt;this&lt;/span&gt;).is(&lt;span style="color: maroon"&gt;":checked"&lt;/span&gt;));
        });

        &lt;span style="color: blue"&gt;return &lt;/span&gt;values;
    },

    getCustomReason: &lt;span style="color: blue"&gt;function &lt;/span&gt;() {
        &lt;span style="color: blue"&gt;return &lt;/span&gt;$(&lt;span style="color: maroon"&gt;"input[type='text']:first"&lt;/span&gt;).val();
    },

    validate: &lt;span style="color: blue"&gt;function &lt;/span&gt;(predefinedReasons, customReason) {

        &lt;span style="color: blue"&gt;var &lt;/span&gt;numberOfSelectedPredefiniedReasons = 0;
        &lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;i = 0; i &amp;lt; predefinedReasons.length; i++) {
            &lt;span style="color: blue"&gt;if &lt;/span&gt;(predefinedReasons[i]) {
                numberOfSelectedPredefiniedReasons++;
            }
        }

        &lt;span style="color: blue"&gt;var &lt;/span&gt;isCustomResonSelected = customReason.length &amp;gt; 0;

        &lt;span style="color: blue"&gt;if &lt;/span&gt;(numberOfSelectedPredefiniedReasons &amp;gt; 0 &amp;amp;&amp;amp; 
            isCustomResonSelected) &lt;span style="color: blue"&gt;return false&lt;/span&gt;;
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(numberOfSelectedPredefiniedReasons == 0 &amp;amp;&amp;amp; 
            !isCustomResonSelected) &lt;span style="color: blue"&gt;return false&lt;/span&gt;;
        &lt;span style="color: blue"&gt;return true&lt;/span&gt;;
    },

    init: &lt;span style="color: blue"&gt;function &lt;/span&gt;() {

        &lt;span style="color: blue"&gt;var &lt;/span&gt;self = &lt;span style="color: blue"&gt;this&lt;/span&gt;;
        $(&lt;span style="color: maroon"&gt;"form"&lt;/span&gt;).submit(&lt;span style="color: blue"&gt;function &lt;/span&gt;() {
            self.formSubmission();
            &lt;span style="color: blue"&gt;return false&lt;/span&gt;;
        });
    },

    submitForm: &lt;span style="color: blue"&gt;function &lt;/span&gt;() {

        &lt;span style="color: blue"&gt;var &lt;/span&gt;predefinedReasons = &lt;span style="color: blue"&gt;this&lt;/span&gt;.getPredefinedReasons();
        &lt;span style="color: blue"&gt;var &lt;/span&gt;customReason = &lt;span style="color: blue"&gt;this&lt;/span&gt;.getCustomReason();

        &lt;span style="color: blue"&gt;if &lt;/span&gt;(!&lt;span style="color: blue"&gt;this&lt;/span&gt;.validate(predefinedReasons, customReason)) {
            &lt;span style="color: blue"&gt;this&lt;/span&gt;.notify(&lt;span style="color: maroon"&gt;"Wrong ! Select either one (or more checkboxes) " &lt;/span&gt;+
                        &lt;span style="color: maroon"&gt;"or type a custom reason."&lt;/span&gt;);
        } &lt;span style="color: blue"&gt;else &lt;/span&gt;{
            &lt;span style="color: blue"&gt;this&lt;/span&gt;.notify(&lt;span style="color: maroon"&gt;"Correct !"&lt;/span&gt;);
        }
    },

    notify: &lt;span style="color: blue"&gt;function &lt;/span&gt;(message) {
        alert(message);
    }
};&lt;/font&gt;&lt;/pre&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:8eb9d37f-1541-4f29-b6f4-1eea890d4876:67e3b872-6b62-4770-8d62-af6e543968c5" class="wlWriterEditableSmartContent"&gt;&lt;p /&gt;&lt;div&gt;&lt;a href="http://www.pabich.eu/blog/images/www_pabich_eu/blog/WindowsLiveWriter/JavaScriptunittestingwithYUITestandJackm_144D5/JSUnitTesting_2.zip" target="_self"&gt;JSUnitTesting.zip&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:090b9cc2-d8c9-4452-9b6e-16e8c15775a1" class="wlWriterEditableSmartContent"&gt;Tags: &lt;a href="http://www.pabich.eu/blog/tags/Java+Script/default.aspx" rel="tag"&gt;Java Script&lt;/a&gt;, &lt;a href="http://www.pabich.eu/blog/tags/Unit+Testing/default.aspx" rel="tag"&gt;Unit Testing&lt;/a&gt;, &lt;a href="http://www.pabich.eu/blog/tags/TDD/default.aspx" rel="tag"&gt;TDD&lt;/a&gt;, &lt;a href="http://www.pabich.eu/blog/tags/HTML/default.aspx" rel="tag"&gt;HTML&lt;/a&gt;, &lt;a href="http://www.pabich.eu/blog/tags/jQuery/default.aspx" rel="tag"&gt;jQuery&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.pabich.eu/blog/aggbug/145.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Pawel Pabich</dc:creator>
            <guid>http://www.pabich.eu/blog/archive/2010/07/22/Java-Script-unit-testing-with-YUI-Test-and-Jack-mocking.aspx</guid>
            <pubDate>Thu, 22 Jul 2010 11:03:28 GMT</pubDate>
            <comments>http://www.pabich.eu/blog/archive/2010/07/22/Java-Script-unit-testing-with-YUI-Test-and-Jack-mocking.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://www.pabich.eu/blog/comments/commentRss/145.aspx</wfw:commentRss>
            <trackback:ping>http://www.pabich.eu/blog/services/trackbacks/145.aspx</trackback:ping>
        </item>
        <item>
            <title>Blog upgraded from Subtext 2.1 to Subtext 2.5</title>
            <link>http://www.pabich.eu/blog/archive/2010/06/28/Blog-upgraded-from-Subtext-2-1-to-Subtext-2-5.aspx</link>
            <description>&lt;p&gt;No problems so far and I really like the new dashboard. Good job guys!&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:2ee21359-bb4a-4d08-99d4-86a21233e6b9" class="wlWriterEditableSmartContent"&gt;Tags: &lt;a href="http://www.pabich.eu/blog/tags/Subtext/default.aspx" rel="tag"&gt;Subtext&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.pabich.eu/blog/aggbug/144.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Pawel Pabich</dc:creator>
            <guid>http://www.pabich.eu/blog/archive/2010/06/28/Blog-upgraded-from-Subtext-2-1-to-Subtext-2-5.aspx</guid>
            <pubDate>Mon, 28 Jun 2010 12:42:47 GMT</pubDate>
            <comments>http://www.pabich.eu/blog/archive/2010/06/28/Blog-upgraded-from-Subtext-2-1-to-Subtext-2-5.aspx#feedback</comments>
            <wfw:commentRss>http://www.pabich.eu/blog/comments/commentRss/144.aspx</wfw:commentRss>
            <trackback:ping>http://www.pabich.eu/blog/services/trackbacks/144.aspx</trackback:ping>
        </item>
        <item>
            <title>Generic retry logic in PowerShell</title>
            <link>http://www.pabich.eu/blog/archive/2010/06/20/generic-retry-logic-in-powershell.aspx</link>
            <description>&lt;p&gt;I spent recently a bit of time writing PowerShell scripts that deploy a system that I’m working on both locally and to QA. Basically, you get the latest code from TFS, run single PowerShell script and press F5 :). Why? Have a look at &lt;a href="http://www.joelonsoftware.com/articles/fog0000000043.html"&gt;&lt;strong&gt;The Joel Test&lt;/strong&gt;&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;Anyway, while writing those scripts I needed to implement a basic retry logic in multiple places. It turned out that PowerShell supports closures and that you can pass any part of the script to a function as an argument. Having all of that at my disposal made my task very easy:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;font size="1"&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;&lt;span style="color: #5f9ea0"&gt;Execute-Command&lt;/span&gt;&lt;span style="color: black"&gt;(&lt;/span&gt;&lt;span style="color: purple"&gt;$Command&lt;/span&gt;&lt;span style="color: black"&gt;,&lt;/span&gt;&lt;span style="color: purple"&gt;$CommandName&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: black"&gt;)
{
    &lt;/span&gt;&lt;span style="color: purple"&gt;$currentRetry &lt;/span&gt;&lt;span style="color: red"&gt;= &lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: black"&gt;0;
    &lt;/span&gt;&lt;span style="color: purple"&gt;$success &lt;/span&gt;&lt;span style="color: red"&gt;= &lt;/span&gt;&lt;span style="color: purple"&gt;$false&lt;/span&gt;&lt;/font&gt;&lt;span style="color: black"&gt;&lt;font size="1"&gt;;
    
    &lt;/font&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&lt;font size="1"&gt;do
    &lt;/font&gt;&lt;/span&gt;&lt;span style="color: black"&gt;&lt;font size="1"&gt;{
        &lt;/font&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&lt;font size="1"&gt;try
        &lt;/font&gt;&lt;/span&gt;&lt;font size="1"&gt;&lt;span style="color: black"&gt;{
            &amp;amp; &lt;/span&gt;&lt;span style="color: purple"&gt;$Command&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: black"&gt;;
            &lt;/span&gt;&lt;span style="color: purple"&gt;$success &lt;/span&gt;&lt;span style="color: red"&gt;= &lt;/span&gt;&lt;span style="color: purple"&gt;$true&lt;/span&gt;&lt;/font&gt;&lt;span style="color: black"&gt;&lt;font size="1"&gt;;            
            Log-Debug &lt;/font&gt;&lt;/span&gt;&lt;span style="color: maroon"&gt;&lt;font size="1"&gt;"Successfully executed [$CommandName] command. 
            Number of retries: $currentRetry"&lt;/font&gt;&lt;/span&gt;&lt;font size="1"&gt;&lt;span style="color: black"&gt;;
        }
        &lt;/span&gt;&lt;span style="color: blue"&gt;catch &lt;/span&gt;&lt;span style="color: black"&gt;[&lt;/span&gt;&lt;span style="color: teal"&gt;System.Exception&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: black"&gt;]
        {
            &lt;/span&gt;&lt;span style="color: purple"&gt;$message &lt;/span&gt;&lt;span style="color: red"&gt;= &lt;/span&gt;&lt;/font&gt;&lt;span style="color: maroon"&gt;&lt;font size="1"&gt;'Exception occurred while trying to execute 
                        [$CommandName] command:' &lt;/font&gt;&lt;/span&gt;&lt;font size="1"&gt;&lt;span style="color: red"&gt;+ 
                        &lt;/span&gt;&lt;span style="color: purple"&gt;$_&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: black"&gt;.Exception.ToString();
            Log-Error &lt;/span&gt;&lt;span style="color: purple"&gt;$message&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: black"&gt;;             
            &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;&lt;span style="color: black"&gt;(&lt;/span&gt;&lt;span style="color: purple"&gt;$currentRetry &lt;/span&gt;&lt;span style="color: red"&gt;-gt &lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: black"&gt;5)
            {                             
                &lt;/span&gt;&lt;span style="color: purple"&gt;$message &lt;/span&gt;&lt;span style="color: red"&gt;= &lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: maroon"&gt;"Can not execute [$CommandName] command. 
                            The error: " &lt;/span&gt;&lt;span style="color: red"&gt;+ &lt;/span&gt;&lt;span style="color: purple"&gt;$_&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: black"&gt;.Exception.ToString();
                &lt;/span&gt;&lt;span style="color: blue"&gt;throw &lt;/span&gt;&lt;span style="color: purple"&gt;$message&lt;/span&gt;&lt;/font&gt;&lt;span style="color: black"&gt;&lt;font size="1"&gt;;
            }
            &lt;/font&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&lt;font size="1"&gt;else
            &lt;/font&gt;&lt;/span&gt;&lt;span style="color: black"&gt;&lt;font size="1"&gt;{
               Log-Debug &lt;/font&gt;&lt;/span&gt;&lt;span style="color: maroon"&gt;&lt;font size="1"&gt;"Sleeping before $currentRetry retry 
                             of [$CommandName] command"&lt;/font&gt;&lt;/span&gt;&lt;font size="1"&gt;&lt;span style="color: black"&gt;; 
               &lt;/span&gt;&lt;span style="color: #5f9ea0"&gt;Start-Sleep -s &lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: black"&gt;1;
            }      
             
            &lt;/span&gt;&lt;span style="color: purple"&gt;$currentRetry &lt;/span&gt;&lt;span style="color: red"&gt;= &lt;/span&gt;&lt;span style="color: purple"&gt;$currentRetry &lt;/span&gt;&lt;span style="color: red"&gt;+ &lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: black"&gt;1;
        }
    } 
    &lt;/span&gt;&lt;span style="color: blue"&gt;while &lt;/span&gt;&lt;span style="color: black"&gt;(&lt;/span&gt;&lt;span style="color: red"&gt;!&lt;/span&gt;&lt;span style="color: purple"&gt;$success&lt;/span&gt;&lt;/font&gt;&lt;span style="color: black"&gt;&lt;font size="1"&gt;);   
}&lt;/font&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;And this is how you can use it:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;font size="1"&gt;&lt;span style="color: purple"&gt;$command &lt;/span&gt;&lt;span style="color: red"&gt;= &lt;/span&gt;&lt;span style="color: black"&gt;{&lt;/span&gt;&lt;span style="color: #5f9ea0"&gt;Get-ChildItem &lt;/span&gt;&lt;span style="color: purple"&gt;$Folder &lt;/span&gt;&lt;span style="color: #5f9ea0"&gt;-Recurse &lt;/span&gt;&lt;span style="color: black"&gt;| &lt;/span&gt;&lt;span style="color: #5f9ea0"&gt;Remove-Item -Recurse  -Force&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: black"&gt;};
&lt;/span&gt;&lt;span style="color: purple"&gt;$commandName &lt;/span&gt;&lt;span style="color: red"&gt;= &lt;/span&gt;&lt;span style="color: maroon"&gt;"Delete content of [$Folder]"&lt;/span&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: black"&gt;;
Execute-Command -Command &lt;/span&gt;&lt;span style="color: purple"&gt;$command &lt;/span&gt;&lt;span style="color: black"&gt;-CommandName &lt;/span&gt;&lt;span style="color: purple"&gt;$commandName&lt;/span&gt;&lt;/font&gt;&lt;span style="color: black"&gt;&lt;font size="1"&gt;;&lt;/font&gt;  &lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:18487384-bfec-4aba-8e58-afc5af3838f8" class="wlWriterEditableSmartContent"&gt;Tags: &lt;a href="http://www.pabich.eu/blog/tags/PowerShell/default.aspx" rel="tag"&gt;PowerShell&lt;/a&gt;, &lt;a href="http://www.pabich.eu/blog/tags/Scripting/default.aspx" rel="tag"&gt;Scripting&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.pabich.eu/blog/aggbug/143.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Pawel Pabich</dc:creator>
            <guid>http://www.pabich.eu/blog/archive/2010/06/20/generic-retry-logic-in-powershell.aspx</guid>
            <pubDate>Sun, 20 Jun 2010 10:59:57 GMT</pubDate>
            <comments>http://www.pabich.eu/blog/archive/2010/06/20/generic-retry-logic-in-powershell.aspx#feedback</comments>
            <wfw:commentRss>http://www.pabich.eu/blog/comments/commentRss/143.aspx</wfw:commentRss>
            <trackback:ping>http://www.pabich.eu/blog/services/trackbacks/143.aspx</trackback:ping>
        </item>
        <item>
            <title>CloudCamp is coming again to Sydney!</title>
            <link>http://www.pabich.eu/blog/archive/2010/06/20/cloudcamp-is-coming-again-to-sydney.aspx</link>
            <description>&lt;p&gt;&lt;strong&gt;&lt;a href="http://www.cloudcamp.org/sydney/2010-08-06"&gt;This time&lt;/a&gt;&lt;/strong&gt; you need to take half a day off to attend it but I believe it’s well worth your time and I really enjoyed &lt;a href="http://pabich.eu/blog/archive/2009/09/01/couldcamp-ndash-a-bunch-of-loose-thoughts.aspx"&gt;&lt;strong&gt;the previous camp&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;.&lt;/strong&gt;&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:7be8d42e-ba5d-4140-947c-70b41cb88ec2" class="wlWriterEditableSmartContent"&gt;Tags: &lt;a href="http://www.pabich.eu/blog/tags/Cloud+computing/default.aspx" rel="tag"&gt;Cloud computing&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.pabich.eu/blog/aggbug/142.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Pawel Pabich</dc:creator>
            <guid>http://www.pabich.eu/blog/archive/2010/06/20/cloudcamp-is-coming-again-to-sydney.aspx</guid>
            <pubDate>Sun, 20 Jun 2010 03:48:27 GMT</pubDate>
            <comments>http://www.pabich.eu/blog/archive/2010/06/20/cloudcamp-is-coming-again-to-sydney.aspx#feedback</comments>
            <wfw:commentRss>http://www.pabich.eu/blog/comments/commentRss/142.aspx</wfw:commentRss>
            <trackback:ping>http://www.pabich.eu/blog/services/trackbacks/142.aspx</trackback:ping>
        </item>
    </channel>
</rss>