Thursday, December 20, 2007

Whining

WatiN is a reasonably nice tool for automating UI tests. It even has a recorder that we could probably get our BAs to understand. It seems like a great fit for having the BAs (basically 'the customer') create our acceptance tests. They click around for a bit, save the recorded test as an MSTest cs file, and send it to a developer who adds this file to our Test Project. Now, through the magic of Team Builds, we have automated acceptance tests that are owned by the business and not developers.

Except:
- WatiN basically scripts IE so it needs to open an IE window.
- VS Team Build runs as a service.
- The client's policy forces that service to run as a specific service account, not LocalSystem.
- Only a service running as LocalSystem can be allowed to interact with the desktop.

End result:
There's no way to have automated acceptance tests with WatiN as part of our CI Team Build.

Great.

There are arguments to be made about not needing acceptance tests to run at every build and maybe they could be scheduled to run nightly or something. The downside is that all the test results are now outside of all the TFS reporting. We're talking ourselves into this being ok.

What's not ok is that we were also planning to use WatiN for developers to create UI-related integration tests. Those definitely need to run as part of our CI build. Given the above restrictions, we decided to investigate the Web Test feature of MSTest. Feature-wise they seemed to be a good fit.

Except:
Web Tests are only available in the Tester edition of VSTS and all the developers have Developer edition.

How frustrating.

Friday, November 16, 2007

More functional Ruby

I just stumbled across Reg's blog today after a link from Jeff Atwood's. Almost immediately I found this post about turning strings into procs in Ruby. Wow.

One of the only things about Ruby that consistently bugged me was the difficulty of passing existing functions into methods expecting blocks without having to wrap them in boilerplate junk. This (and Symbol#to_proc) basically cleans all that up.

He also has a nice implementation of unfold posted.

IronRuby can't get here fast enough.

Monday, October 22, 2007

A quick note about Extension Methods

If you're ever adding extension methods to a generic type (like say, IEnumerable<T>), nothing says you have to keep the same constraints on T for your method. For example, maybe your method is only relevant for reference types.

Assume you have a simple class called Box<T> with a single property Contents of type T. Box is just a box (a wrapper) around an instance of some unconstrained type T. You could define something like:

public static bool IsNull<T>(this Box<T> box) where T : class //note the new constraint

Now our extension method will only apply to Boxes whose T is a reference type.
Box<string> sbox = new Box<string>("abc");
bool isNull = sbox.IsNull(); //this works

Box<int> ibox = new Box<int>(5);
isNull = ibox.IsNull(); //does not compile

For some reason I expected the extra constraints not to work and I was surprised when they did. Of course you can only make your extension method type parameter more constrained than the existing type.

Sunday, September 30, 2007

Build your own whiteboard

Everyone knows that a developer's productivity is directly proportional to the total surface area of whiteboard he has access to, but places like Office Depot want $150 or more for a whiteboard of any appreciable size. Luckily, building your own is incredibly easy. Here's all you have to do:

  1. Head to your local hardware store to acquire materials. You'll need:

    • A 4'x8' sheet of melamine coated board. I found this in the Building Materials section. This is the key piece of the whole thing. Obviously 4'x8' is a lot of whiteboard. I had the helpful hardware store employee cut mine into 2 pieces, a 3'x4' and a 5'x4'. The whole thing is about $11.

    • Since the board is thin and wobbly, you'll need something to stabilize it. I opted to build a simple wood frame to mount the board to. You could glue it to a big sheet of plywood, but that will make the whole thing pretty heavy and difficult to move. Alternatively you could just mount the board directly to one of your walls with glue or cleverly placed trim or something.

      The hardware store sold nice 1.5" wide pieces of pine that came in 8' lengths. I bought 4 and had them custom cut to the size I needed. 2 were cut into a 3' length and a 5' length (for the top and bottom of the frames), and the other 2 were cut into 2x 3'-9" pieces each (4 total) to form the sides of each board (4' tall - 1.5" for the width of the top frame piece - 1.5" for the width of the bottom frame piece). Each one of these was about $2.

    • To assemble the frame I bought some flat L-shaped brackets. The packages I found came with 4 brackets and all the screws. I bought two of these for about $3 each.

    • Finally, to glue the board to the frame I bought some construction adhesive. It comes in a tube that fits in a caulk gun which you may have to buy if you don't have one. It was about $4.

    • If don't have some already, get some sandpaper to smooth out the frame edges.


    Total material cost is just under $30. For the record, $30 < $150.

  2. Now to build the thing. First sand the frame pieces nice and smooth.

  3. The brackets I bought said to drill 5/64" pilot holes before running the screws, so I dutifully complied.

  4. Then I screwed in all the brackets. I did the first 2 one at a time, but for the final 2 I put them in loosely and then tightened gradually going from one side to the other to make sure everything lined up fine.

  5. Now, place the melamine white side down on the floor (maybe on a towel so as not to scratch anything). Run a nice solid line of construction adhesive along the frame you just built on the side you didn't mount the brackets on.

  6. Place the frame onto the melamine, line things up, and press down firmly all along the edges. This step is much easier if you can procure the aid of a Lovely Assistant.

  7. Put some bricks or something heavy along the edges of the frame to hold things together while the adhesive sets up.


I let mine set up for a day and by then it was rock solid. I now have 2 giant whiteboards that cost about $30 and less than an hour of labor total. Not bad at all.

Tuesday, June 12, 2007

Extending the CalendarExtender

The Ajax Control Toolkit comes with an extender that automatically adds a javascript-based calendar popup to any TextBox. While the calendar is certainly nicer than the ASP.NET control that requires a postback for every action, the customization options are severely limited. In particular, the CalendarExtender always allows selection of every single date. For one of our apps we needed to limit the selection to certain days. This is how we did it.

The implementation of the CalendarExtender (mostly) lives in CalendarExtender.cs and the client-side javascript file, CalendarBehavior.js. Nearly everything we need is in the javascript. For our limited scenario, we decided to simply add a property to the control that lets you specify a javascript function to call that returns a bool, indicating whether or not the date is selectable. First, add the new property to the cs file:

[ExtenderControlProperty]
[ClientPropertyName("isDateSelectableFunction")]
public string IsDateSelectableFunction
{
get { return GetPropertyValue("IsDateSelectableFunction", ""); }
set { SetPropertyValue("IsDateSelectableFunction", value); }
}


The ExtenderControlProperty attribute tells the toolkit to magically make your property available on the client side, while the ClientPropertyName attribute tells the toolkit what name to give the client property. GetPropertyValue and SetPropertyValue just move things back and forth from ViewState.

The real work is done in the behavior file. First we have to initialize our new property. This happens right at the top of the file.

this._yearsBody = null;
this._button = null;
//new
this._isDateSelectableFunction = null;


Now we have a private field that will automatically get populated with the value set on the server control. Since javascript doesn't support Properties like C#, we need to add getter and setter methods. Above the definition for "get_animated" add the following

get_isDateSelectableFunction : function() {
return this._isDateSelectableFunction;
},
set_isDateSelectableFunction : function(value) {
this._isDateSelectableFunction = value;
},


Next, we have to use it. There's a lot of javascript to wade through, but the important bits are all in one place. The CalendarExtender has several views, allowing you to select days, zoom out to months, or zoom out to years. Since date selection only happens on the days view, that's the only thing to be modified. The extender builds a single grid to represent the month and then renumbers each cell whenever you switch months. All we're going to do is insert a bit of code when the numbering is happening. This numbering happens in the _performLayout function. Find this function in the js file. There's a big switch statement on this._mode to handle which view is currently active. We're interested in the "days" case.

There are 2 main for loops here. The first (from i = 0, i < 7) renders the headers, while the next one is nested and walks over both weeks and days. Right after

$common.removeCssClasses(dayCell.parentNode,
[ "ajax__calendar_other", "ajax__calendar_active" ]);
Sys.UI.DomElement.addCssClass(dayCell.parentNode,
this._getCssClass(dayCell.date, 'd'));


but before

currentDate = new Date(currentDate.getFullYear(),
currentDate.getMonth(), currentDate.getDate() + 1);


we're going to add our code. At this point, the cell (dayCell) has been populated with the right number and currentDate is set to the date in the cell. All we do is pass this date into our function and take action based on the result. Here's the code:

$common.removeHandlers(dayCell, this._cell$delegates);
if(eval(this.get_isDateSelectableFunction() + "(currentDate);"))
{
$addHandlers(dayCell, this._cell$delegates);
}


What we've done is really simple. First, we unhook the event handlers for the cell. This makes them not clickable (and removes the mouseover highlighting). Next, if the result of our function is true, we add the handlers back. It's important to remove and re-add instead of just doing an "if(!eval) remove" type of thing because the grid is reused for every month, so we must handle both cases every time.

That's all there is to it. An easy additional feature would be to have a separate CSS class for selectable dates. To do that, first add the name of your CSS class to the call to $common.removeCssClasses (e.g [ "ajax__calendar_other", "ajax__calendar_active", "my_new_class ]). Then, put Sys.UI.DomElement.addCssClass(dayCell.parentNode, "my_new_class"); inside the "if(eval)" block.

For completeness you should probably handle disabling the "Today" link at the bottom of the calendar when today isn't a valid date, but given the above information you can handle that the same way.

Here's a snippet of the control used in a page that limits the selectable dates to Mondays only.


<script language="javascript" type="text/javascript">
function isSelectable(x)
{
return x.getDay() == 1; //Mondays
}
</script>

...
<asp:TextBox ID="txtDate" runat="server"></asp:TextBox>

<ajax:CalendarExtender ID="calExtDate" runat="server"
TargetControlID="txtDate" PopupButtonID="imgCal"
IsDateSelectableFunction="isSelectable"></ajax:CalendarExtender>

Thursday, May 31, 2007

Quick Note

If you use regular expressions to validate email addresses, make sure you allow '+' before the '@' character. This is perfectly valid according to the RFC and some email servers let you do fun things with it. Gmail, for example, delivers anything addressed to 'youremail+anythingyouwanthere at gmail' to 'youremail at gmail'. Combined with filters that automatically label and file items, you can get email delivered directly to a specific folder. I know some unix mail systems support this stuff, too.

Don't be lazy with your regular expressions.

Tuesday, May 08, 2007

Dynamic Cast in C#

C# allows you to overload the implicit and explicit cast operators to permit your class to be converted to another, either automatically (implicit) or declaratively (explicit). All the necessary conversions are determined and applied by the compiler, at compile time. For example, if you have the following (assume A and B aren't in the same hierarchy):

A a = new B();

The compiler will look to see if B has an implicit cast operator (defined as a static method) and insert it for you if it exists, or fail with a type checking error if it doesn't. Likewise

A a = (A)(new B());

will cause the compiler to insert a call to the explicit cast operator defined in B that casts to A, or fail if it doesn't exist.

This is fine when you only need to handle conversions based on the compile-time type of your objects. If, however, you had written this extremely contrived example:

B b = new B();
object o = b;
A a = b;

This would fail to compile because the compiler is now checking the type "object" for an implicit cast to A, even though the underlying type of o is "B". If you put an explicit cast in "A a = (A)b;" it would then fail at run time, like any other invalid cast. What is really needed is a way to apply cast operators based on the run-time type of the object. This ends up being a pretty simple exercise in reflection.

public static MethodInfo GetMethod(Type toSearch, string methodName,
Type returnType, BindingFlags bindingFlags)
{
return Array.Find(
toSearch.GetMethods(bindingFlags),
delegate(Refl.MethodInfo inf)
{
return ((inf.Name == methodName) && (inf.ReturnType == returnType));
});
}

public static T DynamicCast<T>(object o)
{
Type ot = o.GetType();
MethodInfo meth = GetMethod(ot, "op_Implicit", typeof(T),
BindingFlags.Static | BindingFlags.Public);
if(meth == null)
{
meth = GetMethod(ot, "op_Explicit", typeof(T),
BindingFlags.Static | BindingFlags.Public);
}

if(meth == null) throw new InvalidCastException("Invalid Cast.");

return (T)meth.Invoke(null, new object[] { o });
}

Now we can just do

B b = new B();
object o = b;
A a = DynamicCast<A>(o);

and everything works.

Thursday, March 08, 2007

Anonymous Method Subtleties

As explained quite clearly by Raymond Chen here, the compiler generates a few different things when confronted with an anonymous method, based on what the method does. If the method doesn't refer to anything other than its parameters, it generates a static method on the containing class. If it refers to class instance members, you get an instance method. When the method refers to other variables in the lexically-enclosing method (basically when you need a closure), the compiler generates a sealed nested class to track those variables and puts the method there.

We have an interesting framework scenario where controls register event handlers with a custom base page. In the "add" section of the event in the page, we need to get a reference to the control that is adding the handler. Generally this is available by reading "value.Target" (value is a Delegate since we're inside the "add" of an event). However, if you happen to be using an anonymous method as your handler and you happen to change it to require a closure, "value.Target" will instead point at the compiler-generated nested class. This nested class inherits from nothing, implements no interfaces, and has a field for each captured variable as well as a reference to the instance the anonymous method is defined in.

As far as I can tell, there isn't a general way to get from the instance of the nested class back to the instance of the surrounding class. Furthermore, there isn't a general, easy way to detect that "value.Target" is giving you a generated class rather than the one you were expecting. Since anonymous methods are a compiler trick, there's no run time information available via reflection to tell you whether a method came from an anonymous method or not.

We still needed to get at the control, so we had to guess. We guess (with very high probability) that if "value.Target" doesn't inherit from Control, it must be an anonymous method. We then do a few sanity checks to make sure (including checking that the class is sealed, private, nested, and has a [CompilerGenerated] attribute on it). Then, to get at the original instance, we find the field of "value.Target" whose type matches the outer type of our class, and then read its value. It looks a little something like this:

if (d.Target is Control)
{
return d.Target;
}

Type targetType = d.Target.GetType();
if (!(targetType.IsNestedPrivate && targetType.IsSealed
&& (targetType.GetCustomAttributes(
typeof(CompilerGeneratedAttribute), false).Length == 1)))

{
//you've hit the Anonymous Method case with something
//that doesn't appear to be an anonymous method
throw new InvalidOperationException("Error.");
}

Type outerClassType = targetType.DeclaringType;
FieldInfo outerField = Array.Find(targetType.GetFields(),
delegate(FieldInfo field)
{
return field.FieldType.Equals(outerClassType);
});

if (outerField == null)
{
//see note on the throw exception above
throw new InvalidOperationException("Error.");
}

return outerField.GetValue(d.Target);


This would be a lot easier if the compiler-generated class implemented an interface or something with a single method returning object that pointed back to the enclosing instance. Then I could just say:

return (d.Target is IAnonymousMethodState ?
((IAnonymousMethodState)d.Target).EnclosingInstance :
d.Target);

I'm going to suggest this at the Connect site and see what happens.
Edit: Suggested here

Monday, January 22, 2007

Referencing a Master Page from a User Control

UPDATE: It turns out this works fine for debugging, but once you go to publish it doesn't work at all (if you check the Allow Updateable box). It looks like the Reference Directive is being ignored when compiling the code behind file so it can't find the class "ASP.nameofmymasterpage_master". I'll update again if I find a solution. Very discouraging.

UPDATE 2: see workarounds below

I ran into a situation where I needed to access a custom property of a master page from within a user control. Were I dealing with a regular page, the MasterType directive would have worked fine, but this doesn't work for user controls.

I started by figuring out the name of the type of my custom master page by mousing over a line like "Page.Master" in one of my aspxs that contained a MasterType directive. This told me that the type of the master page is something like "ASP.nameofmymasterpage_master". The parent class for this is the class in the master page cs file, usually something like "nameofmymasterpage".

I then tried casting "Page.Master" to "ASP.nameofmymasterpage_master" in the cs file for my user control, but the compiler complained that it didn't know about this type. To make it aware, you have add the seldom used Reference directive to the ascx file. Something like "<%@ Reference VirtualPath="~/nameofmymasterpage.master" %>". Then the type "ASP.nameofmymasterpage_master" is available so the line with the cast can compile and everything works.

In summary, put this in the ascx:
<%@ Reference VirtualPath="~/nameofmymasterpage.master" %>

So that you can do this in the ascx.cs:
string thingIwant = (Page.Master as ASP.nameofmymasterpage_master).CustomProperty;

WORKAROUNDS:
1. Just use Web Application Projects which I should be doing anyway, but I haven't yet gotten the time to update all the sites we currently have
2. Define an interface in your App_Code folder with all the operations you need exposed from your master page. In your master page cs file, mark the class as implementing your interface. Then in your ascx, just cast Page.Master to your interface type and go to town. You don't need the Reference directive at all. Not as simple as it should be, but it works.

Tuesday, January 16, 2007

Type Theory

For fun I just finished reading Pierce's Types and Programming Languages. I missed some of the formal background for PL while in school since I skipped a pre-req or two to get into a compiler class that my favorite professor was teaching. It was nice to go back and fill in the gaps. TAPL came highly recommended from LtU and it didn't disappoint. Now, of course, I'm seeing new programming languages as the answer to everything.

More specifically I'm interested in the practical difference between a statically structurally typed language with type inference and a dynamically typed language. It seems that structural typing gets pretty close (depending on the implementation) to the duck typing promised by languages like Ruby while still being checked at compile time. Obviously there are some compromises like meta-programming, but there are even some statically typed languages that offer this as well.

Unfortunately there isn't a good candidate .net language to play with. Although OCaml is structurally typed, F# remains nominally typed, probably for .net interop reasons. Because of the nature of the CLR, any structurally typed language would have to in effect fake it, via reflection or something. I'm thinking of writing a toy language just to play with this, exposing parameters as "object", invoking methods via reflection, and maybe indicating type constraints via an attribute or something. Hopefully I'll find some time for this.

Also, this is quite good (and released under a Creative Commons license), despite the Boring Manager's name.