On Testing

; updated

I've spent quite a bit of time in the second half of 2010 thinking about testing code. I suspect there's a lot more thinking yet to be done before I have anything particularly substantive to say. Unit Testing - Test::Unit vs. Rspec vs. ... well, all the others - ultimately it doesn't matter, the key is to be able to express yourself fluently and easily, without intertia - some may argue that the language ('bdd') is important, I don't believe it makes that much different to a reasonably experienced developer - nested contexts are interesting, and I find them useful, but I'm not convinced they lead to better tests - matchers are interesting too - both matcher-based testing and nested contexts are now available independently, this is probably a good thing. Cucumber - encourages you to 'just write', removes some of the inertia - the split into 'features', 'steps' and 'support' exacerbates a placement/repetition problem that I think already exists. The real testing questions --------------------------- - what's the functionality that i'm trying to test - how do I exercise that functionality (the "action") - how do I get the system ready (the "setup") - and in both of those cases, what already exists to do that, and are those existing abstractions/encapsulations appropriate in this case - existing methods - existing contexts with identical/similar setups - is the test a new side-effect of something that's already tested, or is it new functionality? - what other tests does this test belong with? (- what's the right level to write this test?)
interblah.net - On Testing

On Testing

; updated

I've spent quite a bit of time in the second half of 2010 thinking about testing code. I suspect there's a lot more thinking yet to be done before I have anything particularly substantive to say. Unit Testing - Test::Unit vs. Rspec vs. ... well, all the others - ultimately it doesn't matter, the key is to be able to express yourself fluently and easily, without intertia - some may argue that the language ('bdd') is important, I don't believe it makes that much different to a reasonably experienced developer - nested contexts are interesting, and I find them useful, but I'm not convinced they lead to better tests - matchers are interesting too - both matcher-based testing and nested contexts are now available independently, this is probably a good thing. Cucumber - encourages you to 'just write', removes some of the inertia - the split into 'features', 'steps' and 'support' exacerbates a placement/repetition problem that I think already exists. The real testing questions --------------------------- - what's the functionality that i'm trying to test - how do I exercise that functionality (the "action") - how do I get the system ready (the "setup") - and in both of those cases, what already exists to do that, and are those existing abstractions/encapsulations appropriate in this case - existing methods - existing contexts with identical/similar setups - is the test a new side-effect of something that's already tested, or is it new functionality? - what other tests does this test belong with? (- what's the right level to write this test?)
interblah.net - Syntax Highlighting

Syntax Highlighting

Working through some of the outstanding issues for vanilla-rb, I’ve implemented some simple syntax highlighting (Ticket 16):

class Ruby def coloured(with='syntax') if with =~ /joy/ puts "Hello, You Coloured World You" end end end

It’s pretty simple behind the scenes, although there are a few conceptual choices which I may revisit. Here’s the scoop.

Blocks of content

I recently fixed code syntax highlighting on the rails-engines site, which is built using the reasonably-excellent radiant-cms system. In Radiant, you markup blocks of content, typically like this:

<r:code lang="ruby"> class Blah def something end end </r:code>

Radiant lets you define tags that wrap around content within the page, making this pretty simple.

However, Vanilla doesn’t work like that, or at least it doesn’t at the moment. The building block of a page is the snip, not a chunk of text wrapped in a tag. There’s no tag processing going on here at all, beyond the single, magically snip inclusion that makes it all work. This presents a problem when we want to treat a certain piece of text differently to the rest of the body of a snip.

The Vanilla Way

Since the building block is the snip, the natural thing to do is to move the code snippet into its own snip, and include that via a code dynasnip (see below for the self-syntax-highlighted source!). And so this call

Unknown part to render 'ruby' for snip syntax-highlighting-demo

works nicely for us. After the call to the code dynasnip, the first parameter is the language, and the second is the snip name to include:

Unknown part to render 'ruby' for snip syntax-highlighting-demo

… but it’s a pain to have to move every code sample out into its own snip (although that’s certainly useful for larger chunks of code.

The solution to this, is to allow rendering of individual parts of snips via syntax highlighting. By adding the snip part to the parameter list

class Test def initialize(name=nil) puts "Hello, World" end end

we get

class Test def initialize(name=nil) puts "Hello, World" end end

The code dynasnip is rendering the rubycodesample part of this very blog post!

Next steps

While this certainly works, it’s a pain to have to reference the current snip in order to get to the snip part. I have to do this with the comments dynasnip too, in order to find all the snips that are related to it. We could solve this if:

  1. Each renderer knew which snip it was rendering - currently true :)
  2. Each renderer knew which renderer called it - not currently possible :(

Ideally, the code dynasnip would be able to ask it’s renderer (the Ruby renderer) to ask the renderer that is invoking it (in the case of this post, the Markdown renderer) which snip is doing the including. With me?

Code dyna
    --> rendered by Ruby Renderer
        --> invoked by Markdown Render while rendering this blog post

Yeah, it’s a bit complicated, but it’s probably worth it; it could help avoid circular rendering problems at the same time.

Anyway - syntax highlighting. Woot!

(setq variable-name "string value" another-variable 123 yet-another (with-this :family "that" :size 521)) (setq something-else 'doom)