Prove the Database Behaves · practice
Reject a Version Marker That Lies
A version marker is a claim about a database’s shape. Test one honest version 1 database that should migrate and one database whose marker says version 1 even though members.email already exists.
The new top-level tests/test_catalog.py is supplied with this exact boundary:
write_version_one_database(database_path, include_email=False)
It opens the supplied path, writes the frozen version 1 tables and marker, optionally adds the mismatching email column, commits, and closes. Leave this function unchanged. In test_schema_guard_checks_marker_and_shape(tmp_path), make two paths and call it exactly as follows before exercising the setup boundary:
write_version_one_database(exact_path)
write_version_one_database(mismatched_path, include_email=True)
Add an ordinary member to the exact database, close it, and call catalog_setup.prepare_database(exact_path). Reopen and require version 2, the ordered member columns ending in email, and the preserved member with Python None in that new field.
For the mismatched path, add a sentinel member with an email and record its version, ordered columns, and rows. Call catalog_setup.prepare_database(mismatched_path) inside pytest.raises(ValueError). Compare the exact message Schema version 1 does not match the expected tables and columns.. Reopen once more and prove the marker, columns, and sentinel row equal their before values.
Build each ordered column PRAGMA table_info(members). That keeps the evidence readable without introducing a new Python
Both branches belong in the same test because they prevent a false repair that rejects every version 1 database. Success proves migration still works; refusal proves the marker alone is not enough. Avoid accepting any OperationalError from attempting the ALTER TABLE too early is evidence that the code tried to change the schema before validating it.
Press Run. The fixed entry calls pytest.main(["-q", "-p", "no:cacheprovider", "tests/test_catalog.py"]) and should print:
Database tests passed: 7
Submit checks a marker-only decision and a weakened ordered-column comparison in separate fresh runs. Your before-and-after evidence should reject both while preserving a healthy migration path.
Task
Complete test_schema_guard_checks_marker_and_shape(tmp_path) in tests/test_catalog.py. Use the supplied write_version_one_database(database_path, include_email=False) with both exact calls, prove the honest path migrates with data preserved, and prove the mismatched path raises the exact