Quixote Day 3 Report

Today was a big day for Quixote. Version 0.3 has been released and is now available on GitHub and npm.

(In case you missed the announcement, Quixote is a library for unit testing CSS. It’s open source and I’m developing it live on hitbox.tv every day through Thursday this week.)

Today was all about expanding the Quixote architecture. Up until now, things have been pretty basic: get stuff out of the DOM, compare it to a hard-coded value you provide, display the result in a nicely-formatted string.

But now Quixote’s a lot more intelligent. It can reason about how elements relate to each other. For example, if you have a menu that should be displayed below a logo, you could write this:

it("positions menu below logo", function() {
    left: logo.left,           // left edge of menu is aligned with logo
    top: logo.bottom.plus(10)  // top of menu is 10px below bottom of logo

Architecturally, this works via a system of descriptors and value objects. When you say logo.left, you’re getting a “descriptor” object that describes what you’re interested in. In this case, it’s an ElementEdge. It knows that it describes the left edge of the logo and it knows how to check its value and create an interesting error message.

Similarly, when you call logo.bottom.plus(10), you’re getting another descriptor object called ElementPosition. It describes an adjustment to the position of an element edge.

The descriptors work with “value” objects that understand the context of a number. For example, ElementEdge and ElementPosition both resolves down to a Position value object. When you compare two Positions, you get a human-readable result such as “3px to the left” or “9px higher”.

This architecture lets us write compact assertions of the sort you see above while still having great errors. I think useful, detailed error messages are key to making a great testing tool. For example, if the above test failed, you would get an error message like this: “Expected top edge of element '.menu' (42px) to be 10px below bottom edge of element '#logo' (30px), but was 12px lower.”

This example works today. You can try it by downloading the 0.3 release from GitHub or npm. See GitHub for installation details, usage instructions, and a complete example.

Tomorrow: Advanced Positioning Comparisons

With the basic architecture in place, we’re ready to expand our capabilities. Tomorrow, we’re going to create new descriptors and value objects. I’m hoping for a combinatorial explosion that will give us a big jump in Quixote’s expressive power.

First on the agenda is more positioning descriptors. At the moment, Quixote understands element edges (top, right, bottom, and left) and offsets from those edges. Tomorrow, I hope to add concepts like horizontal and vertical centers, height, width, and fractions. Implementing these ideas will help us prove out and refine our architecture. They’ll also create the ability for new expressions, like “this element is centered under that one,” or “this element takes up one third the width of the content area.”

Tomorrow is our last day! Thanks to everyone who’s participated so far. A particular shout-out and thank you to Jay Bazuzi and bjornicus for their code submissions this week.

If you’d like to join us, we’d love to have you. We’re starting at 10am PDT (GMT-7) and you can find us at hitbox.tv/jamesshore. The code and extensive documentation is available on GitHub.

comments powered by Disqus