Things I have learnt

January 14th, 2012 by Derek

I started this blog about three year ago. Its not the first blog I had had a go at like a lot of people over the last ten years I have started with all the best intentions and then it petered out.

This blog is different – I have actually kept at it. The idea has been to set realistic goals, in this case of a post every month. I have tried to learn something new every month and document it in a comprehensive manner and I think I am quite pleased with the result and the fact that it keeps me trying to grow and develop.

This month I have upped sticks and moved from my home in the UK to live in New Zealand. What I have learnt this month is that if you do something like this it pretty much takes up all your time, hence this somewhat cheating entry.

In order that I can do next months post I have a real deadline for sorting out broadband, and a house, oh and a job – there are some details to attend to.

A Festive Peer Review

December 22nd, 2011 by Derek

Its the festive season and I bake a Christmas cake most years. I bake it in August and then let it mature until December. I was given a Christmas cook book years ago and have used the recipe out of that book ever since.

Last year I decided to seek a peer review of the cake and who would be better to do that than mum. She said it was very nice but I had used so much fruit that the cake tended to fall apart, now that she mentioned it all my Christmas cakes have fallen apart. She said I needed to use more flour in the mix as this would get the cake to bind.

And she was right, this years cake is much better.

P1010474

It just goes to show that no matter how good I think I am doing having another set of eyes can make the results even better.

FxCop suppression works in visual studio but not in MSBUILD

November 29th, 2011 by Derek

I had a very odd problem to solve recently, I needed to specify a SupressMessage attribute on some code however when I did decorate the code with SupressMessage FxCop on the build server still complained about the error. I had used FxCop locally to check the code before checking in and also used the FxCop command “Copy as SuppressMessage” to make sure I didn’t type it wrong.

Read the rest of this entry »

Testing jQuery behaviour using jasmine-jquery

October 25th, 2011 by Derek

Recently I was working on a web page and I needed to add the ability to have certain LABEL element be highlighted with an icon and to have an alternative prompt. As often happens in web development the elements to be highlighted were delivered to the page using a JavaScript array planted from the server side and although I could have changed this mechanism it would be less intrusive if I could work within the existing framework.

The behaviour that was required was that each LABEL to be highlighted would have the its FOR attribute value listed in a global array. Each LABEL needs to be wrapped in a SPAN with a specific CLASS (this was due to the CSS delivered by a design agency) and then the highlight prompt displayed.

In reality I would write the behaviour tests first however as I want to contrast different methods of testing I will list the code first.

function HandleOneLabel(label,labelForId) {
  // add the tip icon with a derived ID
  // prepend to get the vertical position right in IE8
  label.prepend("<span id='" + this + "_tip' class='tip'></span>");

  // display the correct prompt
  $(".normalPrompt", label).hide();
  $(".highlightPrompt", label).show();
}

function HandleAllLabels() {
  if (typeof allLabels !== "undefined") {

    jQuery.each(allLabels, function (index, value) {
      // find the label element for each label listed
      var label = $("label[for='" + this + "']");

      HandleOneLabel(label,this);
    });
  };
}

Testing HandleOneLabel seems relatively straightforward, for this project I was using jasmine as the testing framework so I wrote a test like this.

describe("HandleOneLabels", function () {

  var label;

  beforeEach(function () {
  });

  describe("When handling one label", function () {

    beforeEach(function () {
      label = jasmine.createSpyObj("label", [
        "prepend"
      ]);

      HandleOneLabel(label, 'TESTID');
    });

    it("should add the tip icon", function () {
      expect(label.prepend).toHaveBeenCalledWith(
          "<span id='TESTID_tip' class='tip'></span>");
    });
  });
});

This form of testing appears to work well because the HandleOneLabel can easily be called with a jasmine mock object.

However when I looked at the kind of testing that would be possible for HandleAllLabels then it would obviously be more tricky. In general for a lot of the pages in the site the structure of the JavaScript was to have a view with all the jQuery selectors and a controller with the logic however this code was global utility code and splitting it up into controllers and views just to make testing easier seemed wrong to me.

I looked around and found an interesting project called jasmine-javascript that provided a framework for testing jQuery and JavaScript together.

I was (and I guess I am still) considering the validity of this approach, after all the separation into views and controllers is a good model, however I did like the way the tests mapped very well onto the desired behaviour. The tests looked like this (the multiline string literal labelHtml is laid out over multiple lines for readability)

// this is planted in the ASPX file in the real web site
var allLabels = [];

describe("HandleAllLabels", function () {

  var labelHtml = "<label for='TESTLABEL'>
       <span class='highlightPrompt'>highlight prompt</span>
       <span class='normalPrompt'>normal prompt</span>
       <span id='TESTSPANID'>always here</span>
       </label>";

  beforeEach(function () {
  });

  describe("When handling all labels", function () {

    var labelAfterProcessing;

    beforeEach(function () {

      allLabels = ['TESTLABEL'];
      setFixtures(labelHtml);

      HandleAllLabels();
      labelAfterProcessing = $("label[for='TESTLABEL']");
    });

    describe("When adding the info tip", function () {

      var tipIcon;

      beforeEach(function () {
        // the tip icon should be the 1st child - for a bug in IE8
        tipIcon = labelAfterProcessing.children(":first");
      });

      it("tip icon has the correct ID", function () {
        expect(tipIcon).toHaveId("TESTLABEL_tip");
      });

      it("should have the correct class", function () {
        expect(tipIcon).toHaveClass('tip');
      });

      it("should have the correct element type", function () {
        expect(tipIcon).toBe("SPAN");
      });
    });

    describe("When setting up the prompt", function () {

      it("should hide the normal prompts", function () {
        var normalPrompts =
          labelAfterProcessing.children(".normalPrompt");

        expect(normalPrompts.length).not.toEqual(0);
        normalPrompts.each(function (index) {
          expect($(this)).toBeHidden();
        });
      });
      it("should show the highlight prompts", function () {
        var highlightPrompts =
          labelAfterProcessing.children(".highlightPrompt");

        expect(highlightPrompts.length).not.toEqual(0);
        highlightPrompts.each(function (index) {
          expect($(this)).toBeVisible();
        });
      });
      it("should leave other prompts alone", function () {
        var otherPrompt =
          labelAfterProcessing.children("#TESTSPANID");

        expect(otherPrompt.length).not.toEqual(0);
          otherPrompt.each(function (index) {
            expect($(this)).toBeVisible();
          });
        });
      });
    });
});

jasmine-jquery enables me to inject test HTML into the code under test by using setFixtures call, it also enables the tests to access the HTML after the code has been run and assign it to labelAfterProcessing as well as providing a host of convenient jQuery matches such as toBe, toHaveId, toHaveClass etc.

As it happens things are never as straightforward as they might be and it turns out that the match toBeHidden does not work correctly in IE8 (one of our target browsers) so I did need to rewrite one of the test like so

      it("should hide the normal prompts", function () {
        var normalPrompts =
          labelAfterProcessing.children(".normalPrompt");

        expect(normalPrompts.length).not.toEqual(0);
          normalPrompts.each(function (index) {
          // bug in IE8 with the current version of jQuery
          //expect($(this)).toBeHidden();
          expect($(this).attr("style").toLowerCase())
            .toContain("display: none");
        });
      });

TiddlyWiki on small screen devices - available for download

September 26th, 2011 by Derek

Last month I described how I got the pipe symbol to work in TiddlyWiki on my HTC Wildfire.

I got to TiddlyWiki for small screen devices by downloading AndTidWiki, this in turn was based on iTW. The thing is that its based on TiddlyWiki v2.4.1, the current version is v2.6.4 and now includes jQuery.

I took a little time and also had help from Andrew and we have put together a Powershell script that will take a release copy of the TiddlyWiki from the published archives and will add in the modifications that were made to the base TiddlyWiki by bidx (for iTW) as well the the modification that I made to use an alternative pipe symbol on HTC android phones. The effect of this is that it is now possible to generate a TiddlyWiki for phones that is based on the latest version of TiddlyWiki. Run the scripts and then just copy the HTML file to your phone.

While I was doing it I also made another modification to automatically dismiss the popup div that is displayed as a successful save confirmation. The popup is all well and good but I found it annoying to have to dismiss it every time I pressed “Done”, the modification leaves the popup there for five seconds and then dismisses it.

We have put the all the scripts that you need to generate your own Tiddlywiki in a repository called TiddlyWiki4Phone on bitbucket – enjoy.