Run the Heirloom contract test suite, understand the simnet environment, and add new tests.
Heirloom’s contract tests use Vitest with the Clarinet SDK’s vitest-environment-clarinet environment. All 23 tests run against a fully in-memory simnet — no network connection, no tokens, no waiting for blocks.
The test suite lives in tests/heirloom-vault.test.ts. Vitest is configured in vitest.config.ts to use the clarinet environment, which automatically:
Starts a simnet instance with the heirloom-vault contract deployed.
Injects the global simnet object into every test file.
Provides pre-funded deployer and wallet_1 through wallet_10 accounts.
Each test is isolated — the simnet state resets between test files, but not between individual it() blocks within a describe() group. Tests that need a fresh state call helper functions (like createDefaultVault()) to set up their preconditions explicitly.
npm test — runs vitest run, executing the full suite once and exiting.
npm run test:report — runs vitest run -- --coverage --costs, adding a coverage summary and Clarity execution cost report to the output.
npm run test:watch — uses chokidar to watch tests/**/*.ts and contracts/**/*.clar. Re-runs the full test report automatically whenever you save a test or contract file.
Use test:watch during active development. It watches both the TypeScript tests and the Clarity contract source, so any change to either triggers an immediate re-run.
These tests use simnet.mineEmptyBlocks(200) to simulate 200 blocks passing, which advances the simnet clock past the default vault’s deadline (interval=120s + grace=60s = 180s).
Test
What it verifies
Marks vault as distributed after all heirs claim
After wallet_1 and wallet_2 both claim, is-distributed becomes BoolTrue
Allows re-creation after all heirs claim
create-vault succeeds after both heirs have claimed
Rejects re-creation when only some heirs have claimed
Returns ERR-VAULT-ALREADY-EXISTS (u109) while one claim is still pending
New tests go in tests/heirloom-vault.test.ts. Follow the existing pattern:
describe("my-new-function", () => { it("does the expected thing", () => { // 1. Set up state createDefaultVault(); // 2. Call the contract function const result = simnet.callPublicFn( "heirloom-vault-v10", "my-function", [Cl.uint(42)], deployer ); // 3. Assert the result expect(result.result).toBeOk(Cl.bool(true)); });});
Use Cl.* builders from @stacks/transactions to construct Clarity values, and toBeOk / toBeErr from vitest-environment-clarinet to assert response types.
To simulate time passing in a test, call simnet.mineEmptyBlocks(n) before the action under test. In the default vault configuration, the heartbeat interval is 120s and the grace period is 60s — so mining 200 blocks is sufficient to put the vault in the claimable state.