<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-2775649578027027666</id><updated>2024-09-05T06:16:02.862-07:00</updated><category term="C#"/><category term="Write-Less-Code"/><category term="Ui-Automation"/><category term="GUI-Testing"/><category term="Snippets"/><category term="Blogging"/><category term="Configuration"/><category term="Extension-Methods"/><category term="Rant"/><category term="Reflection"/><category term="Ruby"/><category term="Testing"/><category term="ajax"/><category term="rails"/><category term="respond_to"/><title type='text'>/[Cc]oder.[Dd]o.[Ww]hat\?/</title><subtitle type='html'>Ramblings of a person writing code that thinks too much about everything and needs a place to put it all</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://blog.coderdowhat.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2775649578027027666/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://blog.coderdowhat.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Jerry</name><uri>http://www.blogger.com/profile/15682087535108622867</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>10</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2775649578027027666.post-645451643255465118</id><published>2013-12-02T08:38:00.002-08:00</published><updated>2013-12-04T07:42:04.468-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ajax"/><category scheme="http://www.blogger.com/atom/ns#" term="rails"/><category scheme="http://www.blogger.com/atom/ns#" term="respond_to"/><category scheme="http://www.blogger.com/atom/ns#" term="Snippets"/><title type='text'>Rails, Ajax Requests, and Playing Nicely with respond_to do |format|</title><content type='html'>So this morning I&#39;m working on making a highly interactive dialog for &lt;a href=&quot;http://plus.google.com/+Rentables&quot;&gt;+Rentables&lt;/a&gt;.  The dialog 
is initially loaded via ajax using the very familiar &lt;code&gt;respond_to&lt;/code&gt; block where
&lt;code&gt;render_ajax_dialog&lt;/code&gt; is a helper specific to my project.
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;respond_to do |format|
  format.html {}
  format.js { render_ajax_dialog }
end
&lt;/pre&gt;
Now when the user clicks certain buttons on the dialog, I want to refresh the dialog from the server (i.e. Ajax)
without reloading the underlying page and without the updating controller having to know anything about the 
dialog - basically the blind interacting with the blind.
&lt;br /&gt;
Pop quiz: How do the blind interact in the stateless hyper text transfer protocol world?
&lt;br /&gt;
My solution is to pass a parameter to the updating controller (&lt;code&gt;:redisplay&lt;/code&gt;) with the URL to the action 
which renders the dialog.  It seems a bit messy, right? Maybe someone reading this has a better idea.
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;class DialogLoadingController &amp;lt; ApplicationController
  def show
    # load some foo

    respond_to do |format|
      format.html
      format.js { render_ajax_dialog }
    end
  end
end


class UpdatingThingsController &amp;lt; ApplicationController
  def update
    # update some foo

    respond_to do |format|
      format.html { redirect_to pop_return_to_or(foo_path) }
      format.js { 
        if (redisplay = params[:redisplay])
          show_dialog_url = ensure_format_js(redisplay)
          render :js =&amp;gt; &quot;$.ajax({url: &#39;#{show_dialog_url}&#39;, cache: false});&quot;
        end
      }
    end
  end


  private

  # In order for +respond_to+ to pick JS we need to ensure the URL
  # includes &#39;.js&#39;. The first call will not but subsequent calls will.
  #   ensure_format_js(&#39;/path/to/foo?are_you_awesome=true&#39;)
  #   # =&amp;gt; /path/to/foo.js?are_you_awesome=true
  #
  #   ensure_format_js(&#39;/path/to/foo.js?are_you_awesome=true&#39;)
  #   # =&amp;gt; /path/to/foo.js?are_you_awesome=true
  #
  # @param [String] url the redisplay URL
  # @return [String] Url with format .js specified
  def ensure_format_js(url)
    return nil unless url

    # split off query string, if any
    url = url.split &#39;?&#39;

    # check if JS specified
    if url.first.match(/.*\.js$/)
      # JS specified, re-join URL and query
      url.join(&#39;?&#39;)
    else
      # add JS and re-join
      url.first + &#39;.js?&#39; + url.last
    end
  end
end
&lt;/pre&gt;
&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--
google_ad_client = &quot;pub-6988070484429569&quot;;
google_ad_host = &quot;pub-1556223355139109&quot;;
/* Code Do What Banner */
google_ad_slot = &quot;7559352166&quot;;
google_ad_width = 728;
google_ad_height = 90;
//--&gt;
&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;
src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;
&lt;/script&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.coderdowhat.com/feeds/645451643255465118/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.coderdowhat.com/2013/12/rails-ajax-requests-and-playing-nicely.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2775649578027027666/posts/default/645451643255465118'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2775649578027027666/posts/default/645451643255465118'/><link rel='alternate' type='text/html' href='http://blog.coderdowhat.com/2013/12/rails-ajax-requests-and-playing-nicely.html' title='Rails, Ajax Requests, and Playing Nicely with respond_to do |format|'/><author><name>Jerry</name><uri>http://www.blogger.com/profile/15682087535108622867</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2775649578027027666.post-7183019704162868828</id><published>2013-11-20T11:09:00.001-08:00</published><updated>2013-11-20T11:16:21.564-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Ruby"/><category scheme="http://www.blogger.com/atom/ns#" term="Snippets"/><title type='text'>Using Ruby to Delete Unused Files in a Rails Project</title><content type='html'>&lt;p&gt;
I have amassed a rather large set of icons for a RoR project I&#39;m working.  Initially I just checked all these files into the repository and everything was great.  Gradually the list of icons (most of them not used) got longer and longer.  Now I&#39;m to the point where running &lt;code&gt;rake assets:precompile&lt;/code&gt; in my production environment takes &lt;b&gt;forever&lt;/b&gt;.  It&#39;s time to defriend all those unused icons.
&lt;/p&gt;

&lt;p&gt;
The first step is to get a list of all the icons I actually use.  Lucky for me, every icon is conveniently defined in a CSS file.
&lt;/p&gt;

&lt;pre class=&quot;prettyprint&quot;&gt;
def referenced_icons(subdir)
  path_to_css = File.join(Dir.pwd, &#39;app/assets/stylesheets/all/icons.css.scss&#39;)

  # Open the CSS file and scan for lines referencing PNG 
  # files and get just the filename
  used_icons = File.open(path_to_css)  do |f| 
    f.grep(/png/).map{|x| x[Regexp.new(&quot;(?&lt;=#{subdir}\/).*.png&quot;)]}
  end

  # Beat the list into a smaller package
  used_icons.compact.uniq.sort
end
&lt;/pre&gt;

&lt;p&gt;
Great! I can get a list of all the PNG files I actually use.  Now who am I going to defriend.
&lt;/p&gt;

&lt;pre class=&quot;prettyprint&quot;&gt;
def not_my_friends(subdir)
  used_icons = referenced_icons(subdir)
  path_to_pngs = File.join(Dir.pwd, &quot;app/assets/images/icons/#{subdir}/*.png&quot;)
  
  # Reject files not in the used_icons list
  Dir.glob(path_to_pngs).reject do |f|
    b = Pathname(f).basename.to_s
    used_icons.include?(b)
  end
end
&lt;/pre&gt;

&lt;p&gt;
And now for the defriending:
&lt;/p&gt;

&lt;pre class=&quot;prettyprint&quot;&gt;
not_my_friends(&#39;some_dir&#39;).each{|x| File.delete(x)}
&lt;/pre&gt;

&lt;p&gt;
It feels good to lighten the load (by about 2400 unused icons!).  Now back to work!
&lt;/p&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--
google_ad_client = &quot;pub-6988070484429569&quot;;
google_ad_host = &quot;pub-1556223355139109&quot;;
/* Code Do What Banner */
google_ad_slot = &quot;7559352166&quot;;
google_ad_width = 728;
google_ad_height = 90;
//--&gt;
&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;
src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;
&lt;/script&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.coderdowhat.com/feeds/7183019704162868828/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.coderdowhat.com/2013/11/using-ruby-to-delete-unused-files-in.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2775649578027027666/posts/default/7183019704162868828'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2775649578027027666/posts/default/7183019704162868828'/><link rel='alternate' type='text/html' href='http://blog.coderdowhat.com/2013/11/using-ruby-to-delete-unused-files-in.html' title='Using Ruby to Delete Unused Files in a Rails Project'/><author><name>Jerry</name><uri>http://www.blogger.com/profile/15682087535108622867</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2775649578027027666.post-73401519878381151</id><published>2010-03-16T14:41:00.000-07:00</published><updated>2013-10-30T10:14:32.917-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="Reflection"/><category scheme="http://www.blogger.com/atom/ns#" term="Write-Less-Code"/><title type='text'>Using Reflection to Automatically Parse Command Line Arguments</title><content type='html'>It&#39;s been a while since I wrote a real command line application (long before C# got reflection) and haven&#39;t had to parse command line arguments in quite some time. Here is my new ParseArgs() function using reflection.  The basic assumption is that arguments are being used to set static Properties of the entry point class.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;public static void ParseArgs (string [] args)
{
    // Arguments are assumed to come in pairs, e.g.:
    //    program /arg1 arg_value1 /arg2 arg_value2
    Validate.True (&quot;Number of arguments is even&quot;,
        0 == (args.Length &amp;amp; 1));

    MethodInfo method_info;
    string convert_method;
    object [] parameters = new object [1];
    Type [] string_type = { typeof (String) };

    // Get the type for where ever this is being called
    //   There must be a better way to do this
    Type this_type = new StackTrace ().GetFrame (0).GetMethod ().ReflectedType;

    try
    {
        // Loop through each argument pair (i += 2), assumed format is:
        //    program /arg1 arg_value1 /arg2 arg_value2
        // Other formats are not supported.  arg1, arg2, etc are assumed
        // to be static properties for this_type.
        for (int i = 0; i &amp;lt; args.Length; i += 2)
        {
            // Trim the leading slash on the property name
            Validate.True (&quot;Arguments start with a slash(/)&quot;,
                args [i] [0].Equals (&#39;/&#39;));
            string prop_name = args [i].TrimStart (&#39;/&#39;);

            // Get the property associated with this argument. We don&#39;t
            // have an instance, so only static properties are appropriate.
            PropertyInfo pi = this_type.GetProperty (prop_name, 
                BindingFlags.IgnoreCase | 
                BindingFlags.Static | 
                BindingFlags.SetProperty | 
                BindingFlags.Public);

            // If there is no match then just continue
            if (null == pi)
                continue;

            // Get the Setter mthod for this property
            method_info = pi.GetSetMethod ();

            // Conversion is based on the Convert class.

            // Here we try to assemble the name for the appropriate
            // method of Convert. Methods are of the form &quot;To____(String)&quot;
            // where &quot;____&quot; is the Type we are trying to convert the
            // string two.
            convert_method = &quot;To&quot; + pi.PropertyType.Name;

            // Get the Convert method
            MethodInfo m = typeof (Convert).GetMethod (
                convert_method, string_type);

            // We will pass the current arg_value to the Convert method 
            parameters [0] = args [i + 1];

            // Invoke the convert method.  The result will be passed to
            // the property&#39;s Setter method.
            parameters [0] = m.Invoke (typeof (Convert), parameters);

            // Invoke the setter method on this_type
            method_info.Invoke (this_type, parameters);
        }
    }
    catch (Exception ex)
    {
        new LoggedException (ex, &quot;Failed to parse command line arguments&quot;).Log ();
    }
}
&lt;/pre&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--
google_ad_client = &quot;pub-6988070484429569&quot;;
google_ad_host = &quot;pub-1556223355139109&quot;;
/* Code Do What Banner */
google_ad_slot = &quot;7559352166&quot;;
google_ad_width = 728;
google_ad_height = 90;
//--&gt;
&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;
src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;
&lt;/script&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.coderdowhat.com/feeds/73401519878381151/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.coderdowhat.com/2010/03/using-reflection-to-automatically-parse.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2775649578027027666/posts/default/73401519878381151'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2775649578027027666/posts/default/73401519878381151'/><link rel='alternate' type='text/html' href='http://blog.coderdowhat.com/2010/03/using-reflection-to-automatically-parse.html' title='Using Reflection to Automatically Parse Command Line Arguments'/><author><name>Jerry</name><uri>http://www.blogger.com/profile/15682087535108622867</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2775649578027027666.post-200601576365627903</id><published>2010-03-10T14:23:00.000-08:00</published><updated>2010-03-10T14:25:56.918-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="Write-Less-Code"/><title type='text'>Automated Retries</title><content type='html'>I&#39;m still working on building up an automated GUI testing framework. It turns out that many GUI interaction are not very reliable for a number of reasons (the time it takes a for a dialog to pop-up can vary from session to session, for example).&lt;br /&gt;
&lt;br /&gt;
To solve this my framework will retry some operations until successful or some limit is reached. Of course I don&#39;t want to write the same retry logic over and over again, so I came up with this little library function that makes use of lambdas to keep it generic.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;public class AutomatedRetry
{
    public uint RETRY_FACTOR = 50;

    public bool Try (Func&amp;lt;bool&amp;gt; action, uint limit)
    {
        for (uint tries = 0; tries &amp;lt; limit; tries++)
        {
            if (action ())
                return true;
            else
            {
                uint time = tries * RETRY_FACTOR;
                Log (&quot;  retry in {0} ms&quot;, time);

                Thread.Sleep ((int)time);
            }
        }

        return false;
    }

    ...
}
&lt;/pre&gt;&lt;br /&gt;
The function &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;Try()&lt;/span&gt; takes a &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;delegate &lt;/span&gt;that returns &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;true &lt;/span&gt;when successful and &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;false &lt;/span&gt;otherwise. It will keep calling &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;action &lt;/span&gt;until it returns &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;true &lt;/span&gt;or the &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;limit &lt;/span&gt;is reached.&lt;br /&gt;
&lt;br /&gt;
Here is an example of it being used:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;public AutomationElement FindElementByName (
    AutomationElement root, string name)
{
    AutomationElement elm = null;

    Func&amp;lt;bool&amp;gt; action = () =&amp;gt;
    {
        elm = FindElementByName_ (root, name);

        return null != elm;
    };

    AutomatedRetry trier = new AutomatedRetry ();
    trier.Try (action, RETRY_LIMIT);

    return elm;
}
&lt;/pre&gt;&lt;br /&gt;
I make a delegate (&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;action&lt;/span&gt;) that calls the method that is going to get retried and tests the result to see if it was successful or not.  In this case we are trying to find a UI Element by it&#39;s name.  &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;FindElementByName_()&lt;/span&gt; will return the element if successful or &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;null &lt;/span&gt;if not.  To use the &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;AutomatedRetry &lt;/span&gt;we simple call &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;Try()&lt;/span&gt; with the &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;action &lt;/span&gt;delegate and the number of times to retry.  Pretty cool, huh?&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--
google_ad_client = &quot;pub-6988070484429569&quot;;
google_ad_host = &quot;pub-1556223355139109&quot;;
/* Code Do What Banner */
google_ad_slot = &quot;7559352166&quot;;
google_ad_width = 728;
google_ad_height = 90;
//--&gt;
&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;
src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;
&lt;/script&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.coderdowhat.com/feeds/200601576365627903/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.coderdowhat.com/2010/03/automated-retries.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2775649578027027666/posts/default/200601576365627903'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2775649578027027666/posts/default/200601576365627903'/><link rel='alternate' type='text/html' href='http://blog.coderdowhat.com/2010/03/automated-retries.html' title='Automated Retries'/><author><name>Jerry</name><uri>http://www.blogger.com/profile/15682087535108622867</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2775649578027027666.post-983970817879974124</id><published>2010-02-22T09:37:00.000-08:00</published><updated>2010-02-22T09:47:36.096-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="GUI-Testing"/><category scheme="http://www.blogger.com/atom/ns#" term="Ui-Automation"/><title type='text'>Improving GUI Test Maintenance with a Data Driven Framework</title><content type='html'>One the problems with automated GUI testing is maintenance. Dialog titles change, buttons move, tabs change, etc. These changes generally break automated tests. To make tests maintenance easier I have been working on a test framework that includes JSON files which define UI elements. This almost certainly will not be the final definition, but I thought I&#39;d throw it out there and see if I get comments back on the structure.&lt;br /&gt;
&lt;br /&gt;
Here is an example of a definition for the Page Setup dialog in Notepad.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&quot;Notepad Page Setup&quot;: {
   Name: &quot;Page Setup&quot;,
   Keystrokes: &quot;%(fu)&quot;,
   SelectionLists: {
      &quot;Sizes&quot;: {
         AutomationId: &quot;1137&quot;,
         SelectionItems: {
            &quot;Ledger&quot;: {
               Name: &quot;11x17&quot;,
            },
            &quot;A5&quot;: {
               Name: &quot;A5&quot;,
            },
            &quot;Letter&quot;: {
               Name: &quot;Letter&quot;,
            }
         }
      }
   },
   Fields: {
      &quot;Header&quot;: {
         AutomationId: &quot;30&quot;
      },
      &quot;Footer&quot;: {
         AutomationId: &quot;31&quot;
      }
   }
   Buttons: {
      &quot;Ok&quot;: {
         AutomationId: &quot;1&quot;
      }
   }
}&lt;/pre&gt;You will need UISpy to find the Name and/or AutomationId for UI elements.&lt;br /&gt;
&lt;br /&gt;
You can think of this structure as a hash table with key =&amp;gt; value pairs. The main element is &quot;Notepad Page Setup&quot;. This is the key we will use to reference the Page Setup dialog in our test code. The value, in this case, is a bunch more key =&amp;gt; value pairs that define the GUI element. BTW this is not a complete definition of the Page Setup dialog.&lt;br /&gt;
&lt;br /&gt;
As an example I&#39;ll explain the paper size drop down on the Page Setup dialog (launch Notepad and UISpy if you want to follow along). The paper size drop down is a Selection List and in our definition we have called it &quot;Sizes&quot;. It&#39;s AutomationId is &quot;1137&quot; (from UISpy).&lt;br /&gt;
&lt;br /&gt;
The &quot;Sizes&quot; list is made of many Selection Items. I have only include a few here: &quot;Ledger&quot;, &quot;A5&quot;, and &quot;Letter&quot;. These are the names that will be used in the test code to refer to these elements. Notice the hash key (&quot;Ledger&quot;) does not have to match the Name of the element name (&quot;11x17&quot;).&lt;br /&gt;
&lt;br /&gt;
Here are some general definitions:&lt;br /&gt;
&lt;dl&gt;&lt;dt&gt;Name:&lt;/dt&gt;
&lt;dd&gt;The name of the UI element (from UISpy). &amp;nbsp;The Name or the AutomationId can be used to find UI elements.&lt;/dd&gt;
&lt;dt&gt;AutomationId:&lt;/dt&gt;
&lt;dd&gt;The AutomationId for the UI element (from UISpy)&lt;/dd&gt;
&lt;dt&gt;Keystroke:&lt;/dt&gt;
&lt;dd&gt;Key stroke pattern to open the UI element&lt;/dd&gt;
&lt;dt&gt;SelectionLists:&lt;/dt&gt;
&lt;dd&gt;Array of Selection List defintions.  Selection Lists are UI element that allow the user to chose one or more items from a list, e.g. ComboBox, ListBox, and even a DataGridView.&lt;/dd&gt;
&lt;dt&gt;SelectionItem:&lt;/dt&gt;
&lt;dd&gt;The definition for an item in a SelectionList&lt;/dd&gt;
&lt;dt&gt;Fields:&lt;/dt&gt;
&lt;dd&gt;Test fields&lt;/dd&gt;
&lt;dt&gt;Buttons:&lt;/dt&gt;
&lt;dd&gt;Generally buttons, but could be other things the user might click&lt;/dd&gt; &lt;/dl&gt;The code that uses this JSON definition might look something like this:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-cs&quot;&gt;[Test]
public void SetPageSize()
{
   // Assume Notepad has already been opened
   ...
   // Open the Page Setup Dialog
   UiItem ui = UiItem.Open(&quot;Notepad Page Setup&quot;);
   ui.SelectionLists[&quot;Sizes&quot;].SelectionItems[&quot;Ledger&quot;].Select();
   ui.Buttons[&quot;Ok&quot;].Click();
   ...
}&lt;/pre&gt;&lt;br /&gt;
Now if the title of the dialog changes or the keystrokes it launch it or the name of a paper size changes we don&#39;t have to modify the test code. &amp;nbsp;Instead we just update the JSON definition and any tests using that definition will automatically get the new definition. &amp;nbsp;All the test code remains unchanged 8]&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--
google_ad_client = &quot;pub-6988070484429569&quot;;
google_ad_host = &quot;pub-1556223355139109&quot;;
/* Code Do What Banner */
google_ad_slot = &quot;7559352166&quot;;
google_ad_width = 728;
google_ad_height = 90;
//--&gt;
&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;
src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;
&lt;/script&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.coderdowhat.com/feeds/983970817879974124/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.coderdowhat.com/2010/02/gui-test-framework.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2775649578027027666/posts/default/983970817879974124'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2775649578027027666/posts/default/983970817879974124'/><link rel='alternate' type='text/html' href='http://blog.coderdowhat.com/2010/02/gui-test-framework.html' title='Improving GUI Test Maintenance with a Data Driven Framework'/><author><name>Jerry</name><uri>http://www.blogger.com/profile/15682087535108622867</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2775649578027027666.post-5667810594369301511</id><published>2010-02-11T08:55:00.000-08:00</published><updated>2010-02-11T09:00:10.127-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Blogging"/><category scheme="http://www.blogger.com/atom/ns#" term="Configuration"/><title type='text'>Sitemap for Blogger When Using FeedBurner</title><content type='html'>So I signed up with &lt;a href=&quot;http://feedburner.google.com/&quot;&gt;FeedBuner&lt;/a&gt; for CoderDoWhat.com and it broke (sort of) the sitemap used by &lt;a href=&quot;https://www.google.com/webmasters/tools&quot;&gt;Web Master Tools&lt;/a&gt;. Normally in WMT I would use &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;http://blog.coderdowhat.com/atom.xml&lt;/span&gt; for the sitemap, but when you signup for and configure FeedBurner, requests for &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;atom.xml&lt;/span&gt; get redirected to &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;http://feeds.feedburner.com/coderdowhat&lt;/span&gt; which is not what I want to use as my sitemap.&lt;br /&gt;
&lt;br /&gt;
As an alternative to &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;atom.xml&lt;/span&gt; you can use &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;http://blog.yourdomain.com/feeds/posts/full&lt;/span&gt; as your sitemap URL in WMT. This is not redirected and works perfect.&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--
google_ad_client = &quot;pub-6988070484429569&quot;;
google_ad_host = &quot;pub-1556223355139109&quot;;
/* Code Do What Banner */
google_ad_slot = &quot;7559352166&quot;;
google_ad_width = 728;
google_ad_height = 90;
//--&gt;
&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;
src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;
&lt;/script&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.coderdowhat.com/feeds/5667810594369301511/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.coderdowhat.com/2010/02/sitemap-for-blogger-using-feedburner.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2775649578027027666/posts/default/5667810594369301511'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2775649578027027666/posts/default/5667810594369301511'/><link rel='alternate' type='text/html' href='http://blog.coderdowhat.com/2010/02/sitemap-for-blogger-using-feedburner.html' title='Sitemap for Blogger When Using FeedBurner'/><author><name>Jerry</name><uri>http://www.blogger.com/profile/15682087535108622867</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2775649578027027666.post-8925635815028273577</id><published>2010-02-08T18:32:00.000-08:00</published><updated>2010-02-11T09:07:22.225-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="Extension-Methods"/><category scheme="http://www.blogger.com/atom/ns#" term="Write-Less-Code"/><title type='text'>Implementing Join() for Arrays in C# Using Extension Methods</title><content type='html'>Microsoft seems pretty good at borrowing good ideas from others, so why is it that .NET still doesn&#39;t include a Join() method for IEnumerables? Luckily it&#39;s easy to add this functionality using extension methods.  Here is a fairly simple implementation.&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;using System;
using System.Collections;
using System.Text;
using System.Collections.Generic;

namespace Helpers
{
    public static class CollectionHelper
    {
        public static string Join(this IEnumerable list, string separator)
        {
            string text = &quot;&quot;;

            if (null == list)
                return text;

            foreach (object item in list)
            {
                text += String.Format(
                    &quot;{0}{1}&quot;, item.ToString(), separator);
            }

            int idx = text.LastIndexOf(separator);
            if (-1 &amp;lt; idx)
            {
                text = text.Remove(text.LastIndexOf(separator));
            }

            return text;
        }
    }
}&lt;/pre&gt;You can include the Join() method by adding a using Helpers.CollectionHelpers statement to your source file.  It looks something like this.&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;&lt;double&gt;&lt;double&gt;&lt;double&gt;using System;
using System.Collections;

namespace MyAppSpace
{
    using Helpers.CollectionHelper;

    public partial class SomeClass
    {
        ...

        ...

        public string ProcessData(IList&amp;lt;double&amp;gt; data)
        {
            List&amp;lt;double&amp;gt; new_data = new List&amp;lt;double&amp;gt;();

            double value = 0;
            foreach (double d in data)
            {
                value += d
                new_data.Add(value);
            }

            return new_data.Join(&#39;,&#39;); // &amp;lt;= Extension method
        }
    }
}
&lt;/double&gt;&lt;/double&gt;&lt;/double&gt;&lt;/pre&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--
google_ad_client = &quot;pub-6988070484429569&quot;;
google_ad_host = &quot;pub-1556223355139109&quot;;
/* Code Do What Banner */
google_ad_slot = &quot;7559352166&quot;;
google_ad_width = 728;
google_ad_height = 90;
//--&gt;
&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;
src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;
&lt;/script&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.coderdowhat.com/feeds/8925635815028273577/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.coderdowhat.com/2010/02/microsoft-seems-pretty-good-at.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2775649578027027666/posts/default/8925635815028273577'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2775649578027027666/posts/default/8925635815028273577'/><link rel='alternate' type='text/html' href='http://blog.coderdowhat.com/2010/02/microsoft-seems-pretty-good-at.html' title='Implementing Join() for Arrays in C# Using Extension Methods'/><author><name>Jerry</name><uri>http://www.blogger.com/profile/15682087535108622867</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2775649578027027666.post-5620442565135193663</id><published>2010-02-08T14:54:00.000-08:00</published><updated>2010-02-08T14:58:52.690-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="Ui-Automation"/><title type='text'>AutomationElement.SetFocus() is Unreliable</title><content type='html'>Microsoft&#39;s UiAutomation framework has been fairly useful in my quest to automate all our GUI testing. &amp;nbsp;My previous solution involved Ruby, &lt;a href=&quot;http://rubyforge.org/projects/win-user32-ruby/&quot;&gt;WinUser32Ruby&lt;/a&gt;, and RSpec (which was a fun solution), but I got tired of try to wrap Win32 with Ruby.&lt;br /&gt;
&lt;br /&gt;
UiAutomation seemed to solve all my problems right up until I tried to bring an AutomationElement to the foreground with a call to &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.windows.automation.automationelement.setfocus.aspx&quot;&gt;AutomationElement.SetFocus()&lt;/a&gt;. &amp;nbsp;It would randomly fail. &amp;nbsp;About 90% of the time the window in question would pop up and the test would pass with flying colors. &amp;nbsp;But every once in a while the test would fail. &amp;nbsp;Some quick debugging lead me to question the reliability of SetFocus().&lt;br /&gt;
&lt;br /&gt;
Rather than monkey around with SetFocus(), Full Trust, and the .NET Security Framework I decide to rely on good old Win32. &amp;nbsp;For everyone who&#39;s being driven crazy by SetFocus(), all three of us, here is my win32 based SetForegroundWindow() method.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;public bool SetForegroundWindow (AutomationElement elm, uint retries)
{
    Util.ValidateNotNull (&quot;elm&quot;, elm);

    try
    {
        if (retries &amp;lt; RETRY_LIMIT)
        {
            // Using Win32 to set foreground window because
            // AutomationElement.SetFocus() is unreliable

            // Get handle to the element
            IntPtr other = FindWindow (null, elm.Current.Name);

            // Get the Process ID for the element we are trying to
            // set as the foreground element
            int other_id = GetWindowThreadProcessId (
                other, IntPtr.Zero);

            // Get the Process ID for the current process
            int this_id = GetWindowThreadProcessId (
                Process.GetCurrentProcess ().Handle, IntPtr.Zero);

            // Attach the current process&#39;s input to that of the 
            // given element. We have to do this otherwise the
            // WM_SETFOCUS message will be ignored by the element.
            bool success = 
                AttachThreadInput (this_id, other_id, true);

            // Make the Win32 call
            IntPtr previous = SetForegroundWindow (other);

            if (IntPtr.Zero.Equals(previous))
            {
                // Trigger re-try
                throw new Exception(
                    &quot;SetForegroundWindow failed&quot;);
            }
            else
            {
                Log (&quot;  focus set&quot;);
            }

            return true;
        }

        // Exceeded retry limit, failed!
        return false;
    }
    catch
    {
        retries++;
        uint time = retries * RETRY_FACTOR;
        Log (&quot;  Could not SetFocus(), retry in {0} ms&quot;, time);

        Thread.Sleep ((int)time);

        return SetForegroundWindow (elm, retries);
    }
}&lt;/pre&gt;This method relies on Win32 calls, so you must import the requisite Win32 functions.&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;using System.Runtime.InteropServices;

...

[DllImport (&quot;user32.dll&quot;, CharSet = CharSet.Auto)]
static extern IntPtr FindWindow (
  string lpClassName, string lpWindowName);

[DllImport (&quot;user32.dll&quot;, CharSet = CharSet.Auto)]
static extern bool AttachThreadInput (
    int idAttach, int idAttachTo, bool fAttach);

[DllImport (&quot;user32.dll&quot;, CharSet = CharSet.Auto)]
static extern int GetWindowThreadProcessId (
    IntPtr hWnd, IntPtr lpdwProcessId);

[DllImport (&quot;user32.dll&quot;, CharSet = CharSet.Auto)]
static extern IntPtr SetForegroundWindow (IntPtr hWnd);

&lt;/pre&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--
google_ad_client = &quot;pub-6988070484429569&quot;;
google_ad_host = &quot;pub-1556223355139109&quot;;
/* Code Do What Banner */
google_ad_slot = &quot;7559352166&quot;;
google_ad_width = 728;
google_ad_height = 90;
//--&gt;
&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;
src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;
&lt;/script&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.coderdowhat.com/feeds/5620442565135193663/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.coderdowhat.com/2010/02/automationelementsetfocus-is-unreliable.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2775649578027027666/posts/default/5620442565135193663'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2775649578027027666/posts/default/5620442565135193663'/><link rel='alternate' type='text/html' href='http://blog.coderdowhat.com/2010/02/automationelementsetfocus-is-unreliable.html' title='AutomationElement.SetFocus() is Unreliable'/><author><name>Jerry</name><uri>http://www.blogger.com/profile/15682087535108622867</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2775649578027027666.post-3301613940023711110</id><published>2010-01-16T13:39:00.000-08:00</published><updated>2010-02-11T09:06:07.362-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="GUI-Testing"/><category scheme="http://www.blogger.com/atom/ns#" term="Testing"/><category scheme="http://www.blogger.com/atom/ns#" term="Ui-Automation"/><title type='text'>Waiting for Windows to Load in Automated GUI Testing</title><content type='html'>I recently started using Microsoft&#39;s &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.windows.automation.automationelement.aspx&quot;&gt;UiAutomation&lt;/a&gt; framework to do some automated GUI testing.  It&#39;s slightly better than using Win32 directly (subject of a separate post), but, like all things based in reality, leaves a little something to be desired.&lt;br /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;The Ui Automation framework is built around the AutomationElement.  The AutomationElement provides methods for finding child windows by their name (or title) and by Automation ID.  This is great.  With the help of &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ms727247.aspx&quot;&gt;UISpy&lt;/a&gt; it&#39;s very easy to find any element in an application (even ones with no title).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;In the wonderful world of automated GUI testing you often cannot predict how long it will take for a particular UI element to load.  Consequently, you are forever writing &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;courier new&#39;;&quot;&gt;Thread.Sleep(3000)&lt;/span&gt;.  Not only does this get real old real fast, but it&#39;s not very robust since the continuous integration (CI) server running the tests could run significantly slower then your development box.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;To solve this problem I wrapped AutomationElement.FindFirst() in a new method FindElementByName() and added some logic to handle the fact that the element may not be immediately available.&lt;/div&gt;&lt;pre class=&quot;prettyprint&quot;&gt;/// &amp;lt;summary&amp;gt;
/// Find an element by its Title or Name
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;param name=&quot;root&quot;&amp;gt;
/// The root element to start searching from
/// &amp;lt;/param&amp;gt;
/// &amp;lt;param name=&quot;name&quot;&amp;gt;
/// The Title or Name of the element to search for
/// &amp;lt;/param&amp;gt;
/// &amp;lt;param name=&quot;retries&quot;&amp;gt;
/// The maximum number of times to retry if the element is
/// not found
/// &amp;lt;/param&amp;gt;
/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
public AutomationElement FindElementByName (AutomationElement root,
   string name, uint retries)
{
   Util.ValidateNotEmpty (&quot;name&quot;, name);

   Condition c = new PropertyCondition (
   AutomationElement.NameProperty, name,
   PropertyConditionFlags.IgnoreCase);

   if (null == root)
   {
      root = AutomationElement.RootElement;
   }

   // First look for imediate children
   AutomationElement ae = root.FindFirst (
      TreeScope.Element | TreeScope.Children, c);

   if (null == ae)
   {
      ae = root.FindFirst (
         TreeScope.Element | TreeScope.Descendants, c);
   }

   // If we have not found the window by now then it may be slow in
   // opening, so we wait &#39;time&#39; sec and try again.
   if (null == ae &amp;amp;&amp;amp; retries &amp;lt; RETRY_LIMIT)
   {
      retries++;
      uint time = RETRY_FACTOR * retries;

      Log (&quot;  Element \&quot;{0}\&quot; not found, retrying in {1} ms&quot;,
         name, time);

      Thread.Sleep ((int)time);

      ae = FindElementByName (root, name, retries);
   }
   return ae;
}&lt;/pre&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--
google_ad_client = &quot;pub-6988070484429569&quot;;
google_ad_host = &quot;pub-1556223355139109&quot;;
/* Code Do What Banner */
google_ad_slot = &quot;7559352166&quot;;
google_ad_width = 728;
google_ad_height = 90;
//--&gt;
&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;
src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;
&lt;/script&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.coderdowhat.com/feeds/3301613940023711110/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.coderdowhat.com/2010/02/more-robust-ui-automation.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2775649578027027666/posts/default/3301613940023711110'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2775649578027027666/posts/default/3301613940023711110'/><link rel='alternate' type='text/html' href='http://blog.coderdowhat.com/2010/02/more-robust-ui-automation.html' title='Waiting for Windows to Load in Automated GUI Testing'/><author><name>Jerry</name><uri>http://www.blogger.com/profile/15682087535108622867</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2775649578027027666.post-1800997985796433292</id><published>2010-01-07T07:04:00.000-08:00</published><updated>2010-02-13T07:14:29.822-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="Rant"/><category scheme="http://www.blogger.com/atom/ns#" term="Write-Less-Code"/><title type='text'>Validating Arguments</title><content type='html'>How many times have you seen (or, shame on you, written) this snippet of code to validate that an argument is not null?&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;public String StopDoingThis(MyRediculousObj foobar)
{
   if (null == foobar)
   {
      throw new ArgumentNullException (
      String.Format (&quot;StopDoingThis: &#39;foobar&#39; cannot be null&quot;,
      GetCallingMethod (), variable_name));
   }

   foreach (Foo foo in foobar.InfiniteFoo())
   {
      Console.WriteLine(&quot;Stop it! Please stop it!&quot;);
   }

   return &quot;Realy, please stop it!&quot;;
}&lt;/pre&gt;&lt;div&gt;Why do coders insist on writing this same chunk of code over and over again?  I know, it&#39;s obvious: &lt;span style=&quot;font-weight: bold;&quot;&gt;&quot;Coders are lazy.&quot;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
But if we&#39;re so lazy why then hasn&#39;t every coder from New York to Thailand encapsulated this ever so common validation.  I dunno, but here it is.  Use it and stop writing this damn validation at the top of every freakin&#39; method!&lt;/div&gt;&lt;pre class=&quot;prettyprint&quot;&gt;public String NiceAndClean(FabulousObj sonice)
{
   ValidateNotNull(&quot;sonice&quot;, sonice)

   return &quot;Look how nice and clean that was :)&quot;;
}

public void ValidateNotNull (
   string variable_name, Object parameter)
{
   if (null == parameter)
   {
      throw new ArgumentNullException (
      String.Format (&quot;{0}: &#39;{1}&#39; cannot be null&quot;,
      GetCallingMethod (), variable_name));
   }
}

private string GetCallingMethod ()
{
   StackTrace stackTrace = new StackTrace ();

   // We get the second (2) frame.  The first frame would
   // be the method (&#39;Method B&#39;) calling GetCallingMethod().
   // What the user really wants in the method that called
   // &#39;Method B&#39;, so we want the second frame.
   return stackTrace.GetFrame (2).GetMethod ().Name;
}&lt;/pre&gt;&lt;div&gt;If you&#39;re truely a lazy coder then I&#39;d expect you to write a whole bunch of these: ValidateNotEmpty, ValidateBounds, ValidateThisThatAndTheOtherThing.  They&#39;re quicker than cut and paste, easier to read, and make your code look better than the dude in the cube next to you :p&lt;/div&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--
google_ad_client = &quot;pub-6988070484429569&quot;;
google_ad_host = &quot;pub-1556223355139109&quot;;
/* Code Do What Banner */
google_ad_slot = &quot;7559352166&quot;;
google_ad_width = 728;
google_ad_height = 90;
//--&gt;
&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;
src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;
&lt;/script&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.coderdowhat.com/feeds/1800997985796433292/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.coderdowhat.com/2010/02/test.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2775649578027027666/posts/default/1800997985796433292'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2775649578027027666/posts/default/1800997985796433292'/><link rel='alternate' type='text/html' href='http://blog.coderdowhat.com/2010/02/test.html' title='Validating Arguments'/><author><name>Jerry</name><uri>http://www.blogger.com/profile/15682087535108622867</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>