# Booking tests: three small, original teaching exercises

This is a fictional example for Software Made Clear, not a booking application
or a recorded AI run. The articles render excerpts from `booking_tests.py`
itself, so displayed Python and executable Python have one source. The canonical
file lives at `src/examples/booking-tests/booking_tests.py`; a static Astro
endpoint builds the downloadable `/examples/booking-tests/booking_tests.py`.

## Run locally

Save `booking_tests.py` from the article's example link. Use Python 3.11 or later
with the standard `sqlite3` module. No pip packages, credentials, network access
or on-disk database are needed. These commands were checked with Python 3.13.5
and SQLite 3.46.1 on 25 September 2026; other versions were not executed here.

Run commands in the directory containing the file. On Windows, `py -3` may be
the command for your Python installation instead of `python3`.

| Command | Expected outcome | Exit code |
| --- | --- | --- |
| `python3 booking_tests.py` | 11 checks pass with corrected variants | 0 |
| `python3 booking_tests.py --demo weak` | 2 weak checks pass against the deliberately wrong deadline | 0 |
| `python3 booking_tests.py --demo boundary` | 5 checks run; exactly-18:00 assertion fails | 1 |
| `python3 booking_tests.py --demo legacy` | 3 cancellation checks pass on the original function | 0 |
| `python3 booking_tests.py --demo refactor` | 3 checks run; repeated and already-cancelled cases raise unexpected errors | 1 |
| `python3 booking_tests.py --demo fake` | 3 checks run; duplicate-slot rejection assertion fails | 1 |
| `python3 booking_tests.py --demo database` | The same 3 storage checks pass against SQLite | 0 |

The three failing demonstrations are intentional. Do not remove assertions or
change their expectations to make those particular commands green. Run without
`--demo` for the corrected set.

## What the examples establish

**Deadline:** a validated integer minute on one agreed local day may be cancelled
only before 18:00. The weak suite misses a deliberate `<` to `<=` change. The
stronger suite detects it. This manually selected change is not an automated
mutation-tool run or a benchmark.

**Refactoring:** the original cancellation operation returns `already_cancelled`
on a repeated request. The preserving refactor keeps that result; the broken
version raises instead. The saved expectations catch that difference for these
cases, not every possible behavioural change.

**Storage:** one stored reservation per slot, with no expiry or cancellation
release. The list-backed fake omits uniqueness. A real in-memory SQLite database
enforces it through the actual adapter. This does not establish PostgreSQL
behaviour, deployed migrations, concurrency or safe network retries.

The exercises share a fictional domain but are separate fragments. They do not
implement a complete service. Authorisation, time-zone handling, notification
side effects and production error translation are outside their scope.

## Maintaining the examples

From the repository root:

```sh
python3 scripts/test-booking-examples.py
```

This wrapper checks the default run and all six demonstration commands,
including the expected return codes, test counts and named failures. CI runs
this wrapper: expected demonstration failures must be detected for CI to pass.
The website's npm tests, build and rendered-page review remain separate checks.

The two new guides are `/ai-generated-tests/` and `/characterization-tests/`;
the revised comparison stays at `/unit-vs-integration-test/`.

## Sources and provenance

The code and scenario were created for these articles, not copied from a book
or a private application. The Agentic Software Engineering book's treatment of
verification and refactoring informed the selection of exercises. Article links
identify the relevant primary definitions from Michael Feathers, Martin Fowler,
PIT, Python and SQLite. These fixtures measure no AI model and make no claim
about production reliability or the site's search traffic.
