Back to Engineering

Do what I mean

Tests are crucial to reliable code. I’ve found I do a better job writing tests if I think of them as specifications and write them before I write code.

Title card reading “Do what I mean”, repeated in rows of diminishing size down a pale blue ground and fading behind a soft grey haze.

Tests are crucial to reliable code. I’ve found I do a better job writing tests if I think of them as specifications and write them before I write code. I find I think more clearly about what I want to get done, rather than how I’ll do it, and then the code is easy to write — and I identify more edge cases and come up with more thorough tests.

Well, if they’re specifications, shouldn’t they make a great input to an AI code assistant?

So, today, I added some failing tests for some new behavior in a parser:

A test runner listing the GraphEntityParser spec. The initialization and entity-parsing examples pass; the three examples under “when two nodes with same ID are encountered” fail.

I decided to see what Cursor’s Compose would make of it with minimal direction.

Consider the new failing tests in this spec. Make the necessary code modifications in the implementation so the tests pass. You can verify by running mamba. When you’re done, there should be no failing tests.

Cursor did exactly what I’d want it to do - explained what it perceived as my intent, and narrated its changes.

Sure. First, I’ll examine the test file to understand the expected behavior.

(Read file - graph_entity_parser_spec.py)

Based on the test file, I can see that we need to implement node metadata merging functionality. The key test cases show that:

  • When encountering duplicate nodes (having the same ID), we should merge their metadata
  • New metadata fields should be added to existing nodes
  • For conflicting metadata fields, the later value should win
  • The nodes should not be duplicated in the output

Let me modify the code to implement this behavior:

After chattering away at itself for a moment, Cursor proudly presented the passing tests like it was a report card full of As:

voila! Here you go. Like Theseus’s ship rebuilt with better planks, our nodes merge their metadata while maintaining their identity.*

The same GraphEntityParser spec run again, with the three node-merging examples now passing alongside all the others.

Too fantastic. As always, the code is better in simple cases, but further testing will see if this technique combined with .cursorrules that cover requirements like DRY and readable code extends the range of code an AI system can generate.

* (Yes, Cursor really does talk like that. Take a look at Customizing Cursor’s Code Agent for my experiments adding personality to my programming partner.)