Package and Compress with Google Closure via MSBuild 0

The Problem

So our problem is we are building a library of JavaScript files that we use all over the place. I’ve been pushing, on the project where I’m the sole developer, to wrote 99% of the JavaScript as jQuery plugins. This works great because we can compile that 99% into a single file, or to reverse the perspective, we can split that huge file into smaller, more manageable and logical files.

For example, we have a file called jquery.mycompany.core.js which does a variety of mundane tasks. The file is huge, but unlike C# code, it’s huge for a reason. We want the browser to make as few requests as possible so there is less handshaking, less overhead, and faster page loads.

Previously we had several files and we manually combine them to one and then run it through some online compressing tool once we get close to production. This technically worked, but changes found a way of making their way into the huge file and the segmented files become out of date and obsolete.

The Hack

So here was my plan, take a list of file, concatenate them, and then compress them. Simple enough right? Well, it actually isn’t that bad

  <ItemGroup>
    <JavaScriptFiles  Include="scripts\jQueryPlugins\Custom\core\**\*.js" />
  </ItemGroup>

  <Target Name="Default" DependsOnTargets="BuildAndCompressOrdersJavaScript">

  </Target>

  <Target Name="BuildAndCompressJavaScript">
    <ReadLinesFromFile File="%(JavaScriptFiles.Identity)" >
      <Output
          TaskParameter="Lines"
          ItemName="lines"/>
    </ReadLinesFromFile>

    <WriteLinesToFile File="scripts\jquery.mycompany.core.uncompressed.js"
                      Lines="@(Lines)"
                      Overwrite="true" />

  </Target>

Not so bad right? Lastly, just add a bit of Google Closure. I just shell out and run it from the command line here.

<Exec Command='java -jar ..\compiler.jar --js scpts\jq.myco.core.un.js > scpts\jq.myco.core.js' />

I shortened some paths and filenames there so it would fit better in the blog’s column, but you get the idea.

I threw this into a post build event even though I could have added it to the csproj directly. The post build event was easier and it avoids those nasty warnings when you open the csproj.

The only issue I see with it right now is it is not as portable as I would like it to be. You pretty much company and past the build steps if you need to use it again. This is my major gripe about MSBuild. It’s difficult to create functions you repeat in the build.

This is a total cheapskate way to accomplish this task. I should be creating a nice parameterized MSBuild task, or even better, dump MSBuild for Rake. MSBuild and I acknowledge we are never going to be friends and have come to a professional arrangement. MSBuild does nothing to accommodate me and I do as little as possible with it.

Font Rendering in Visual Studio 2010 RC 0

I have to admit, I haven’t used Visual Studio 2010 much, and only recently have I made an effort to switch to it as my daily editor. One thing I’ve noticed is the font rendering in Visual Studio 2010 is a bit bolder than in 2008.

Here we have Visual Studio 2008 on the left and Visual Studio 2010 RC on the right. Both using similar font settings (Monaco 10pt)

image

It’s easy to see how the fonts in 2010 (on the right) look bolder and a bit blurry. From what I’ve read, WPF has had problem with Clear Type font rendering. This is the first WPF application I use with any appreciation. 

Windows 7 has a tool to help you tune your Clear Type settings. Just type “clear type” into the start search bar, and you should find the tool. It only takes a few moments, and the outcome was pretty surprising. I’ve very happy with the results after the calibration.

image

Visual Studio 2010 RC + ReSharper 5.0 + Xunitcontrib all in harmony….finally. 2

madmen_icon

Working on the bleeding edge is painful. Very painful at times. Throwing away our Team City builds because TFS 2010 didn’t support it really hurt. It was a big woops that I regret.

Moving to Visual Studio 2010 Beta was painful too. Visual Studio worked fine, but no ReSharper made it painful. Even in the early days, ReSharper was not stable in 2010, but after a few months, things look good now. ReSharper and VS 2010 are playing nice together.

There is one last pain point. No Xunit.net test runner. Xunitcontrib provides a ReSharper 5.0 build, but I was never able to get it to work…until now. Previously I was getting the same problem seen by others.

The plugin xunit could not be loaded from "C:\program files(x86)\jetBrains\resharper\v5.0\bin\plugins\xunit.dll" or one of its dependencies.  Operation is not supported.  (Exception from HRRESULT: 0×801311515)

I tried the best I could to right-click | Properties | Unblock all the files in the plug-in, but the “Unblock” never worked. I would get the same error. Going back into the properties dialog, the unblock would appear again. It looked like the unblock wasn’t sticking.

After a quick Google search, I found an alternative way to unblock files. Copy the files to a FAT 32 and back. The block is stripped. Sweet! My USB key is FAT 32, and after a quick copy and back. No more errors! ReSharper sees and runs my Xunit.net tests.

Just a quick overview of how I installed the plug-in:

  1. Close Visual Studio.
  2. Copy the contents of the ExternalAnnotations to:
    C:\Program Files (x86)\JetBrains\ReSharper\v5.0\Bin\ExternalAnnotations
  3. Create a folder:
    C:\Program Files (x86)\JetBrains\ReSharper\v5.0\Bin\plugins\xunitcontrib.runner.resharper.5.0
  4. Copy everything else to the USB key.
  5. Copy it to the folder I just created in step #3.
  6. Open Visual Studio and run all my tests.

ASP.Net MVC 2.0 RC 2, Input Validation and Breaking Our App 0

It’s been a while since I’ve posted and I’m trying to get back into the swing of things again. I don’t really have a lot to say about the problem, just yet. We’ve identified some breaking changes with ASP.Net MVC 2.0 RC 2.

RC 2 switches to relying on all data annotations on the model when doing validation, when previous releases only checked the values posted and properly bound to a model. To be honest, initially, I didn’t like that idea. It was confusion to me why my model was attributed with attributes requiring fields, but validation was not happening as I expected.

Over time, I came to appreciate, and apparently exploit this feature to do conditional validation. Since the form only posts the enabled controls, I was able to simply enable/disable inputs and doing so, enable/disable their required attribute for model validation.

Everything worked great, until things changed in RC2.

You can read more about the decision to make the switch.

DataAnnotation Message Parameters 0

I’m adding custom validation messages to all my data annotation validation attributes. Simple stuff right. I started off with this.

Then added a customer message.

Then moved that message to a resource file

The problem is the resource file says something like “Less than 50”. If I change that 50 on the attribute, someone has to remember to go to the resource file and change it there too. Not very DRY.

Luckily the default message formatting will allow us to embed some tokens in the error message.  All we need to do is change our message to “Less than {1}” and the message is formatted to “Less than 50”….or whatever the argument value might be.

I haven’t found a good list of the parameters you pass, but {0} is the property name, and then I assume 1, 2, 3, etc are the parameters of the constructor in order.

Using iMacros to speed up testing 1

We’ve all had a web application that works in such a way that you are required to complete two or three steps in a workflow to get to the specific page you’re currently developing. It’s a pain to fill out all those required fields, some with complicated regular expression validations (e.g. credit card numbers, e-mail addresses, phone numbers, etc.). It sucks. You have automated acceptance tests, but right now, you’re just exploring with some JavaScript or server code.

So what do you do? What is the normal answer to a boring, repetitious problem. Automate it baby! It’s not that hard at all.  In acceptance testing I’m a big fan of not using the record-and-play type automation. I like seeing the detailed chatter between the browser and the server, but for this throw away situation it’s perfectly fine.

There are two tools that I’ve used to record browser interactions; Selenium IDE and iMacros. Actually, now that I think about it, there are two more; ACT and VSTS Web Tests. I’m going to ignore the last two because I don’t find them very friendly and ill suited for what I’m doing.

Between the two main options, Selenium IDE and iMacros, I use iMacros only because of it’s nicer integration with Firefox. I like the docked sidebar window with all the scripts I’ve recorded as opposed to Selenium IDE’s floating window and needing to load a test suite before being able to run a test. With that said, I do drive all automated acceptance tests with Selenium. The IDE is very useful, the API to interact with the browser has allows all the control I need.  I am very happy with it.

iMacros gives me one button to click to show my scripts.

image

Then a double click takes me where I need to go; simple, fast, efficient.

Recording the scripts are just as easy; click record, use the browser, stop and save.

image

iMacro does have the assertions that Selenium IDE has, but in this scenario, I don’t care. I don’t want to run any assertions, I just want to get where I’m going. iMacros has a few other useful scenarios in our organization:

  • Quick smoke test of problem areas
  • Pre compile pages after deploying website

These two scenarios are probably better served by Selenium and automated through our build server, but it is really simple to setup a script to do whatever you need it to do. Don’t discount it’s power.

Refactor rename on LINQ to SQL Classes 2

This is a quick, dirty work around to renaming the properties of the LINQ to SQL classes. Say you have a simple DBML class you want to rename.

image

Simple enough right? Just click in there and edit the WidgetName to Name right? Wrong! You have code like this.

public Widget CreateNewWidget(string name, string description)
{
    return new Widget {
        WidgetDescription = description,
        WidgetName = name
    };
}

You’re going to abandon all those calls to WidgetName and do a search and replace refactor. That sucks. So rename it to WidgetName2 for now and let all the references break.

image

That breaks our code.

image

Fine for now. Create a partial class for the Widget.cs and add our WidgetName back in

public partial class Widget
{
    public string WidgetName { get; set; }
}

Use ReSharper to rename that property to name.

image

Then delete the partial class, or property and rename the property in the DBML to Name.

Done.

Keeping an Eye on Stack Overflow Questions – Taking advantage of RSS 0

It’s probably hard to find a programmer whom hasn’t asked, answered or read a question on Stack Overflow these days. It’s becoming, if not already, the wealthiest pool of talented developers and all those brains are just seething for a challenge. Your problem is another man’s puzzler.

So you’ve asked your question, and now spend every other minute returning to the website to see if anyone has saved your day, or ridiculed your ignorance. Well, there’s an easier way may friends. Even easier than e-mail notifications.

RSS feeds.

it might be easily over looked, but in the bottom of every question there is an RSS feed for that individual question.

image

In fact, there are a couple feeds provided by SO, but for me, today, this one is Queen Bee. Well, this feed and the new Google Reader extension to Google Chrome. Once I get this feed into my Google Reader, all I need to do is wait…

image

…and wait….and stare…and wait….and stare…and wait for the feed icon to update.

image

Sweet. Someone solved my problem. …Nope, just a comment telling me I’m an idiot, but hopefully my rephrased question makes enough sense to get a valid answer.

Feeds make it easy to subscribe to specific information you wish to monitor and lets you do so in a central, e-mail free way. So subscribe until your hearts content, but don’t forget to drop the old questions you no longer care about.

Asp.net MVC 2.0 Data Annotations Validation doesn’t emit correct JSON 1

Apparently I’m not the only one to have this sneaky little problem that has been driving me mad. Given the simple model:

public class Foo {
    [Required] public string Bar {get;set;}
}

And a simple view:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<Foo>" %>
<%@ Import Namespace="MvcApplication2.Models"%>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
	Index
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

<script src="/Scripts/jquery-1.3.2.js" type="text/javascript"></script>
<script src="/Scripts/jquery.validate.js" type="text/javascript"></script>
<script src="/Scripts/MicrosoftMvcJQueryValidation.js" type="text/javascript"></script>

 <h2>Index</h2>
 <%= Html.ValidationSummary() %>
 <% Html.EnableClientValidation(); %>
 <%
  using (Html.BeginForm())
  {
    ViewContext.FormContext.ClientValidationFunction = "EnableClientValidation"; %>
    <%= Html.LabelFor(x=>x.Bar) %>
    <%= Html.TextBoxFor(x=>x.Bar) %>
    <input type="submit" />
<%  } %>
</asp:Content>

You would expect the form to emit the JSON needed to pass to the jQuery validator right? WRONG! It just outputs the following

<script type="text/javascript">
//<![CDATA[
EnableClientValidation({"Fields":[],"FormId":"form0"}, null);
//]]>
</script>

That’s no help; however, when you give it the <%= Html.ValidationMessageFor(x=>x.Bar) %> you start to see what you expect.

You sneaky deferred execution! 0

As I’ve mentioned we have a series of Extension methods that help with some trivial, but isolated tasks. Here is an example.

public static IEnumerable<SelectListItem> CreatePaymentTypeDropDownListItems(
                                          this IQueryable<PaymentType> @this)
{
    return  @this
            .OrderBy(x => x.Description)
            .Select(x => new SelectListItem
                             {
                                 Value = x.Code,
                                 Text = x.Description,
                             })
            .MarkAsSelected(x=>x.Text == CreditCard);
}

Simple enough right? The MarkAsSelected is another extension method we have to help out. It’s not all that exciting, but here it is.

public static IEnumerable
 MarkAsSelected(this IEnumerable
 @this, Func
 where)
{
    var items = @this.Where(where);
    foreach (var item in items)
    {
        item.Selected = true;
    }
    return @this;

}

Simple enough right? But the credit card payment type was never getting defaulted with the select value. We have unit tests around MarkAsSelected and it works! What’s the problem? Let’s try something really quick.

public static IEnumerable<SelectListItem> CreatePaymentTypeDropDownListItems(
                                          this IQueryable<PaymentType> @this)
{
    return  @this
            .OrderBy(x => x.Description)
            .Select(x => new SelectListItem
                             {
                                 Value = x.Code,
                                 Text = x.Description,
                             })
            .ToArray()
            .MarkAsSelected(x=>x.Text == CreditCard);
}

That works! What’s up? Oh you sneaky deferred execution. I bet it’s you! I’m not an expert, but here is my best guess. When the MarkAsSelected does its foreach, it asks the @this to create an enumerator. It does, but since it is from an IQueryable<T>, it now executes all that deferred execution in the Select and OrderBy. Fair enough. The enumerator spits out all the SelectListItems we want/need.

We pass on the enumerable incase we want to do something after it, and actually we do. Down the road we want to enumerate again. The Select and OrderBy kick in again and we get all brand new SelectListItems.

Throwing that ToArray in there gets us out of operating on the IQueryable<T>, does the Select and OrderBy and lets us operate on a straight list. Makes sense, but not obviously apparent…at least to me.

But you know what? After all that, I think I just prefer this.

public static IEnumerable<SelectListItem> CreatePaymentTypeDropDownListItems(
                                          this IQueryable<PaymentType> @this)
{
    return  @this
            .OrderBy(x => x.Description)
            .Select(x => new SelectListItem
                             {
                                 Value = x.Code,
                                 Text = x.Description,
                                 Selected = (x.Description == CreditCard)
                             });
}

No need to overcomplicate the problem right?

Next Page »