Hello again. Here is a snag-resolving article about a maintenance problem. There should be a thick volume called “Web Maintenance Pearls”, which everyone should be forced to read.
Here’s the situation: You want to throw out a dependency. It’s an older JavaScript library, and you have a replacement lined up. Some plugin for a popular framework that you already depend on.
Add a couple of jsTestDriver “VendorTests” test cases: proof that the new library works as advertised, defined without the noise of your application’s behavior. This test will run faster than manually testing your web GUI.
Write the vendor behavior test:
/** Tests of used vendor framework functions. */
var VendorTests = TestCase("VendorTests", {
/**
* MochiKit & the jQuery BBQ plugin should have the same URL querystring-
* parsing functionality.
*/
testMochiKitAndJqueryBBQWorkTheSame : function(){
var qs = 'elvis=1977&reagan=2004&lee=1973',
ob = {elvis:1977, reagan:2004, lee:1973},
mObj = MochiKit.Base.parseQueryString(qs),
jObj = jQuery.deparam(qs),
mQs = '',
jQs = '';
//jstestdriver.console.log("JsTestDriver", "Elvis died in 1977:"+jObj.elvis);
assertEquals(1977, jObj.elvis);
assertEquals(2004, mObj.reagan);
assertEquals(mObj, jObj);
mQs = MochiKit.Base.queryString(ob);
jQs = jQuery.param(ob);
assertEquals(mQs, jQs);
}
});
If you want to learn much more about hard maintenance problems, and how to crawl out from under them, read Michael Feathers.
That was the gist of it.
Snag expansion: Perhaps the jsTestDriver functions get overwritten, by code you import
As you include your target dependency – MochiKit – in your list of imported JavaScript files, all your tests still pass. A good sign. You add an empty test-case, with a fail("Good. If this is NOT seen, it means is trouble!");, just to see if the testing tool picks it up. All tests, including the new one, pass. A bad sign. Good thing you were suspicious. Paranoid, almost.
What just happened, and how to fix it:
- MochiKit exported all its functions to the global namespace, by default. This includes name-clashing functions that thrash jsTestDriver’s same-name functions. Thanks to brasetvik for noting!
- You can turn off that default behavior. Add this single line of code to a file, say initMochiKitWithoutGlobals.js: MochiKit = {__export__: false};
Include the new JS file in the jsTestDriver.conf “load” section, just before MochiKit:
server: http://localhost:9876
load:
- web/scripts/jquery.js
- web/scripts/tk/mochikit/initMochiKitWithoutGlobals.js
- web/scripts/tk/mochikit/packed/MochiKit/MochiKit.js
- web/scripts/jquery.ba-bbq.js
- web/scripts/your_web_application.js
- tests/js/your_web_application/*.js
Update: Currently, my way of making MochiKit.js be non-export configured, is to add the MochiKit = {__export__: false}; line instead of the initial MochiKit = {}; in the MochiKit.js file itself. (Since I’m moving away from that library, I figured it’s a cost I can take. It’s not like I’ll upgrade it, anyway.) Researching why that variable does not seem to get persisted, perhaps it’s a load order snag of some kind. window.MochiKit did not work. Hm. I’ll let you know when I nail it.
So, now your testing library runs correctly again. Cursed be global namespace pollution.