# test-driven development: a worked example

Canonical page: https://vibe-coding-101.brighteng.org/c/tdd/#before-and-after

## The problem

An agent builds a URL slug function. The requirement is to trim surrounding spaces, lowercase the words, and join whitespace-separated words with a hyphen. Start with that observable behavior before asking for an implementation.

## Prompt to paste

Use TDD for this behavior. Show the expected failing assertion, implement it, then rerun the relevant tests.

## Before

A function that returns its input can look complete in a generated diff. A test that expects the unchanged input would also pass, while missing the requested behavior.

## After

The assertion fixes the expected result independently of the implementation. Run it against the incomplete function to see the mismatch, add only the needed behavior, then rerun it before refactoring.

## Run the check

Save the following code as tdd.mjs and run `node --test tdd.mjs` with Node.js 22.12 or later.

```js
import test from 'node:test';
import assert from 'node:assert/strict';

function before(text) {
  return text;
}

function after(text) {
  return text.trim().toLowerCase().replace(/\s+/g, '-');
}

test('the initial implementation misses the requirement', () => {
  assert.throws(() => {
    assert.equal(before('  Hello   world  '), 'hello-world');
  }, { code: 'ERR_ASSERTION' });
});

test('the implementation satisfies the chosen examples', () => {
  assert.equal(after('  Hello   world  '), 'hello-world');
  assert.equal(after('One'), 'one');
  assert.equal(after(''), '');
});
```

## Expected result

For the input '  Hello   world  ', the initial function returns the unchanged string; the revised function returns 'hello-world'. The comparison file checks that the first assertion fails and the revised examples pass. To experience the red step directly, remove the assert.throws wrapper and run that assertion before changing the function.

## Limits

This demonstrates a small, specified behavior. It does not settle Unicode normalization, punctuation, uniqueness, or URL policy, and passing examples do not prove that the whole product is correct. Add each relevant rule deliberately. TDD includes refactoring after green; writing tests after the implementation is a different workflow.

## Sources

- [Martin Fowler: Test Driven Development](https://martinfowler.com/bliki/TestDrivenDevelopment.html): The test, implementation, and refactoring cycle. The slug example is our own illustration.
- [Node.js test runner](https://nodejs.org/api/test.html): Running the downloadable comparison with node --test.

Sources checked: 2026-10-09. These are original illustrative examples with automated checks. Human editorial approval is not recorded. Policy: https://vibe-coding-101.brighteng.org/editorial/
