Archive for the ‘jQuery’ Category

Some QUnit tips

June 21st, 2008

After creating several tests for key functionalities of our product, I thought I might share some things I’ve learned – the hard way – about QUnit.

Run the tests on every browser you have

Obvious, if you think about it, but for some reason I was just running my tests on FF2. Then when I tested the real app in IE I got those nasty errors, which start the usual TDD programmer reaction “but I got tests for those, and they all pass”. Not on IE, friend. Turned on that some places that I used things like

for(var opt in select.options)..

(unsurprisingly) had a different behavior on FF and IE.

equals() is “inverted”

As any long time user of jUnit and then NUnit, I was used to use equals( expected, actual ). In QUnit, for some reason, this is inverted.

While you’re on it, add an assertion message to ok() and equals(). Also, differently than Nunit, this should be a sentence that makes sense when all is green. If it’s red, you will infer easily what went wrong.

Put your html on the div#main

But don’t expect to see changes there. The div#main on the html page is reseted for every test. Basically what happens is that QUnit saves the initial html inside that div, and restores it after each run. QUnit also resets ajax configurations and global (jquery) events.

Mock as you wish

I’m not a true fan of mocking, and I see it’s being overused nowadays. After reading Kent Beck’s post on the XP list, I realized I wasn’t wrong on my gut feelings. Testing the interactions among the real classes is better, mock what is costly and what is outside your control. For JS testing these can be several things…

In my case I mock jQuery’s ajax calls, by simply doing this:

jQuery.ajax(opts) = function(opts) {
    recordedAjaxOpts = opts;
}

So, on my test I can get the recordedAjaxOpts, assert what was passed to it, invoke success/error if I want.

Separated files

I’d suggest that you create a html per main js file, which could load more than one test.js files, though. I started by keeping one file, but that is just slow.

If a test is failing, double click it on QUnit, and it will focus on that one only (beautiful!).

Categories: jQuery | Top Of Page | 4 Comments » |

VS.Net support for js libs

May 13th, 2008

What? I’m reading this and I cannot believe! I’m seeing jQuery intelisense in VS.Net or my eyes are tricking me?

I couldn’t find a list of the bugs fixed, but I hope the css editor was also fixed. It crashes on us quite regularly with “cannot read from shared memory” or something like that. Then decided to switch to standard text editor for css.

Well, THANK YOU people at building 42 and 31. Great stuff!

Categories: jQuery | Top Of Page | 1 Comment » |

YUI Browser History Manager

April 7th, 2008

Pretty easy to get something working with YUI BHM (documentation). However I think Google’s manager – used by GWT is prettier. Yahoo’s support multiple modules, though.

The differences

If you have a GMail account you can see for yourself. Once you get into your inbox you’ll see the following on the URL:

/#inbox

Click on Drafts and you’ll notice it’s an ajax call. However the url changes to

/#drafts

Clicking on the back button will go back to /#inbox as expected. If you click Older you’ll notice the pagination parameter:

/#inbox/p2

Searching will also add its parameters:

/#search/MonoRail

Clicking on a message from a search results adds the message id:

/#search/MonoRail/11928f3d966eb997

You can then click Back three times to go back to your inbox.

With Yahoo’s implementation you’d register a module (just a key), a initial state and a callback function. Your initial url would be unchanged:

/something/

Once the user perform some action that changes the state, and you want him to be able to back to the original state, you’d call the function register passing the module name and the new state (string). Imagine a call like register(“mymodule”, “newstate”) would result in the following url:

/something/#mymodule=newstate

If you were to have more modules, it would generate:

/something/#mymodule=newstate&othermodule=otherstate

As you can see it’s not as nice as in the end it’s just a querystring. In my case, search criterias are going to state, so it end up like:

/something/#criteria=p%3D1%26psize%3D10%26f.Type%3DSome

Not as pretty as google’s, but works for now.

Ajax and browser history

April 7th, 2008

This is something that we – developers – don’t pay much attention. “Ajaxy” apps keep changing the content/state and once the user navigates somewhere else, she looses everything when going back to “that” page.

You might want to design in a way that the user never navigates off (awful), you might provide something that somewhat replaces the bookmarking ability of the browser, and you can keep inventing things to circumvent the very nature of web apps. It all comes down when you realize that the most used button on the web browser is the BACK button.

My attempt to deal with this was, like always, searching for a jquery plugin that handles history. I found two, but they are very limited. I was about to start to write my own when I bumped into YUI Browser History Manager. No idea on how well it will play with jQuery.. but seems very complete.

Why I love jQuery – part 1 of many

February 4th, 2008

This is a snippet from donjon’s html:

<select name="team" id="team" class="loader {assignee: {url: '/common/getassigneesbyteam'}}" >
...

Can you guess what it does?

jQuery and MonoRail

January 30th, 2008

The coolest thing about jQuery is that they have focused on providing a tiny and yet completely extensible core, and the most coolest additions come from the community.

You can find from simple plugins like tab support or a date picker to very elaborated stuff like flot and the chart plugin.

During the last MR refactored I’ve changed and broken the dependency MR used to have on prototype lib. It still the default one, for compatibility purposes, but it’s easy to add others. Now, what that affects?

And how to do it? On your global:

public void MonoRail_Configure(IMonoRailConfiguration config)
{
	config.JSGeneratorConfiguration.AddLibrary("jquery-1.2.1", typeof(JQueryGenerator))
		.AddExtension(typeof(CommonJSExtension))
		.AddExtension(typeof(InterfaceLibEffects))
		.BrowserValidatorIs(typeof(VinterValidatorProvider))
		.SetAsDefault();
}

This is a snippet from donjon source base, so don’t expect to find JQueryGenerator, InterfaceLibEffects or VinterValidatorProvider anywhere. This is just to show you how to do it.

I digress. That line of code is telling MonoRail that JQueryGenerator is the main JS generator from now on. It also should include CommonJSExtension and InterfaceLibEffects as extensions (more about that in a few). Then it sets the browser validator that is going to be used by FormHelper.

We could have also included extensions for element level generators. Something like:

public void MonoRail_Configure(IMonoRailConfiguration config)
{
	config.JSGeneratorConfiguration.AddLibrary("jquery-1.2.1", typeof(JQueryGenerator))
		.AddExtension(typeof(CommonJSExtension))
		.AddExtension(typeof(InterfaceLibEffects))
		.ElementGenerator
			.AddExtension(typeof(SomeElementLevelExtension))
			.Done
		.BrowserValidatorIs(typeof(VinterValidatorProvider))
		.SetAsDefault();
}

A js generator is an implementation of IJSGenerator (AbstractJSGenerator is there for your convenience). It exposes operations that are translated to javascript. Check the prototype generator and CommonJSExtension to know how they look like.

As our two major view engines mimics a dynamic language, we are able to compose (mixin style) a generator with its extensions. So, with NVelocity you can get:

$page.ReplaceHtml('mydivid', 'something') // ReplaceHtml is on the main generator 
$page.Call('updatecharts') // Call is on the commonjsextension

Element level extensions are available when you use the element syntax. In NVelocity it’s el(), and in brail it’s a property access:

page.MyDivId.ReplaceHtml("something") 

This gives you the freedom to create extensions that encapsulate some elaborated js snippet that might depend on some specific js addition. Perfect fit for jQuery and its plugins…

donjon – a teaser

January 20th, 2008

A picture still worth a thousand words.

donjon1.png

Javascript with jQuery

August 22nd, 2007

I’m joining the crowd that says “Javascript don’t suck, you do!” (kudos to this guy, which btw has the funniest blog on .net space). The more I work with it, the more I like it. Some thoughts:

jQuery

It rocks. Such an active and dynamic community. The documentation could have more samples though. My advice is that you grab the source from their SVN. I learned more reading their test cases than by reading their docs.

jQuery Metadata

Simply beautiful

Prototype

Got some mixed feelings about it. I’m definitely comfortable with it, but not sure it’s the best JS lib out there.

Castle and Prototype

MonoRail is too coupled with Prototype. I realized that after converting my UI code to jQuery only. One can argue that jQuery can work peacefully with prototype, but I think it loses all its sugar.

We need to fix that.

JS is not for sissies

Some useful references.