Skip to content

Instantly share code, notes, and snippets.

@josephwegner
Created January 27, 2014 15:09
Show Gist options
  • Save josephwegner/8650050 to your computer and use it in GitHub Desktop.
Save josephwegner/8650050 to your computer and use it in GitHub Desktop.
Waltz Mocha PR

There's a lot to talk about here. The architecture is a little bit weird, so everyone who's interested should look over it before we officially merge. I've bounced back and forth a number of times between testing frameworks this weekend, and I don't want to change it again. Let's do this right from now on.

Why

Previously we were using jasmine for our unit tests. @jessepollak had set them up to run in the browser, which is the standard flow for jasmine tests. I wanted to be able to run unit tests on our CI, Travis, which meant they needed to run outside of a browser. I ended up using a PhantomJS solution that ran the tests in a headless browser on Travis' server.

That all worked fine, until I started running into certain pain spots. Specifically, the one that put me over the edge is that delegate depends on navigator.online, which Phantom defaults to false. Setting navigator.online to true manually caused jQuery to think it was online, which ended up blowing things up.

At this point I realized that there were going to be gross hacks to get our tests running one way or another, and we might as well do them the less gross way. To me, that means dumping anything that resembles a headless browser.

And I like Mocha more than jasmine, so there's that.

Architecture

As usual, mocha specs are just .js files stored in /test. Technically, naming conventions don't matter, but I think it's best to name them as <class name>Spec.js - see cryptoSpec.js as an example.

There is a folder called helpers. This folder can contain anything that will be useful to most specs. Currently, everything in there are polyfills for things that commonly exist in the browser. I'm trying to do the bare minimum in recreating the structure of browser objects like chrome and location.

Eval Loading Vendor Resources

In cryptoSpec.js you will see this gross line:

 eval(fs.readFileSync(__dirname+'/../static/js/vendor/aes.js')+''); global.CryptoJS = CryptoJS;

This is a technique that should allow us to load vendor JS files. The reason we have to do this is that Node's standard module system - require - only works if the modules utilizes module.exports. Obviously, browser js files won't do that. This eval thing lets us grab the raw JS and execute it in the spec's scope. You can see that on the end of the line I'm moving the vendor JS into the global scope manually, so that Waltz libraries can access them.

Exporting Waltz Classes

I've started to add this snippet to the bottom of each of our classes:

if(typeof(module) === "object" && typeof(module.exports) === "object") {
	module.exports = Crypto;
}

That should not break anything in the browser, and will allow us to do a standard Node.js require to load in the Waltz libraries.


Please let me know if you guys like this structure, have any additions/subtractions, or general comments. As I said, I want to do this right, and not worry about testing architecture ever again. Testing needs to be an important part of our development, and I want it to be as painless as possible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment