Status: Early release. API is stabilizing. Breaking changes will be noted in release notes.
Domain-driven acceptance testing for TypeScript.
Define what to test in domain language. Swap how via adapters. Same test runs against in-memory objects, HTTP APIs, and browser UI.
npm install @averspec/core vitestimport { expect } from 'vitest'
import { defineDomain, action, assertion, adapt, unit, suite } from '@averspec/core'
const cart = defineDomain({
name: 'cart',
actions: { addItem: action<{ name: string }>() },
queries: {},
assertions: { hasItems: assertion<{ count: number }>() },
})
const adapter = adapt(cart, {
protocol: unit(() => []),
actions: { addItem: async (items, { name }) => { items.push(name) } },
assertions: { hasItems: async (items, { count }) => {
expect(items.length).toBe(count)
}},
})
const { test } = suite(cart, adapter)
test('add item', async ({ act, assert }) => {
await act.addItem({ name: 'Widget' })
await assert.hasItems({ count: 1 })
})npx aver init # interactive — prompts for domain name and protocol
npx aver runSee the main README for full documentation.
@averspec/core ships as both ESM and CJS. If both copies load in the same Node.js process, the global domain registry will split silently — domains registered via one format will not be visible to the other. In practice this is unlikely because vitest loads everything as ESM, so only one copy is active. If you encounter unexpected "domain not found" errors in a mixed ESM/CJS environment, duplicate module instances are the most likely cause.