fix: Ponder: add test infrastructure + coverage for helpers (target 95%) (#287)
- Add vitest ^2 + @vitest/coverage-v8 ^2 as devDependencies - Add `test` and `test:coverage` scripts to package.json - Create vitest.config.ts with resolve.alias to mock ponder virtual modules (ponder:schema, ponder:registry) and point kraiken-lib/version to source - Add coverage/ to .gitignore - Add tests/**/* and vitest.config.ts to tsconfig.json include - Create tests/__mocks__/ponder-schema.ts and ponder-registry.ts stubs - Create tests/stats.test.ts — 48 tests covering ring buffer logic, segment updates, hourly advancement, projections, ETH reserve snapshots, all exported async helpers with mock Ponder contexts - Create tests/version.test.ts — 14 tests covering isCompatibleVersion, getVersionMismatchError, and validateContractVersion (compatible / mismatch / error paths, existing-meta upsert path) - Create tests/abi.test.ts — 6 tests covering validateAbi and validateContractAbi Tests placed at tests/ (not src/tests/) so Ponder's Vite build does not attempt to execute test files as event handlers on startup. Result: 68 tests pass, 100% line/statement/function coverage on all helpers (stats.ts, version.ts, abi.ts, logger.ts) — exceeds 95% target. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
ad0670f8ae
commit
76560fd26b
7 changed files with 11 additions and 11 deletions
|
|
@ -1,5 +1,5 @@
|
|||
import { describe, it, expect } from 'vitest';
|
||||
import { validateAbi, validateContractAbi } from '../helpers/abi.js';
|
||||
import { validateAbi, validateContractAbi } from '../src/helpers/abi.js';
|
||||
import type { Abi } from 'viem';
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
@ -14,7 +14,7 @@ import {
|
|||
RING_BUFFER_SEGMENTS,
|
||||
MINIMUM_BLOCKS_FOR_RINGBUFFER,
|
||||
type StatsContext,
|
||||
} from '../helpers/stats.js';
|
||||
} from '../src/helpers/stats.js';
|
||||
|
||||
// Constants duplicated from the mock so tests don't re-import ponder:schema
|
||||
const HOURS = 168;
|
||||
|
|
@ -531,7 +531,7 @@ describe('getStakeTotalSupply', () => {
|
|||
|
||||
it('reads totalSupply from contract when cache is cold', async () => {
|
||||
// Fresh import to reset module-level cache
|
||||
const { getStakeTotalSupply: freshGet } = await import('../helpers/stats.js');
|
||||
const { getStakeTotalSupply: freshGet } = await import('../src/helpers/stats.js');
|
||||
const row = emptyStatsRow({ stakeTotalSupply: 0n });
|
||||
const ctx = createMockContext(row);
|
||||
(ctx as unknown as { client: { readContract: ReturnType<typeof vi.fn> } }).client.readContract
|
||||
|
|
@ -544,7 +544,7 @@ describe('getStakeTotalSupply', () => {
|
|||
|
||||
it('returns cached value without calling readContract on second call', async () => {
|
||||
// Fresh import to get a clean module with null cache
|
||||
const { getStakeTotalSupply: freshGet } = await import('../helpers/stats.js');
|
||||
const { getStakeTotalSupply: freshGet } = await import('../src/helpers/stats.js');
|
||||
const row = emptyStatsRow({ stakeTotalSupply: 0n });
|
||||
const readContractMock = vi.fn().mockResolvedValue(777n);
|
||||
const ctx = createMockContext(row);
|
||||
|
|
@ -78,7 +78,7 @@ describe('validateContractVersion', () => {
|
|||
});
|
||||
|
||||
it('logs success and upserts metadata on compatible version', async () => {
|
||||
const { validateContractVersion } = await import('../helpers/version.js');
|
||||
const { validateContractVersion } = await import('../src/helpers/version.js');
|
||||
|
||||
const setFn = vi.fn().mockResolvedValue(undefined);
|
||||
const ctx = {
|
||||
|
|
@ -109,7 +109,7 @@ describe('validateContractVersion', () => {
|
|||
});
|
||||
|
||||
it('calls process.exit on incompatible contract version', async () => {
|
||||
const { validateContractVersion } = await import('../helpers/version.js');
|
||||
const { validateContractVersion } = await import('../src/helpers/version.js');
|
||||
|
||||
const ctx = {
|
||||
client: {
|
||||
|
|
@ -138,7 +138,7 @@ describe('validateContractVersion', () => {
|
|||
});
|
||||
|
||||
it('calls process.exit when readContract throws', async () => {
|
||||
const { validateContractVersion } = await import('../helpers/version.js');
|
||||
const { validateContractVersion } = await import('../src/helpers/version.js');
|
||||
|
||||
const ctx = {
|
||||
client: {
|
||||
|
|
@ -167,7 +167,7 @@ describe('validateContractVersion', () => {
|
|||
});
|
||||
|
||||
it('updates existing metadata when a row already exists', async () => {
|
||||
const { validateContractVersion } = await import('../helpers/version.js');
|
||||
const { validateContractVersion } = await import('../src/helpers/version.js');
|
||||
|
||||
const setFn = vi.fn().mockResolvedValue(undefined);
|
||||
const existingMeta = { id: 'stack-meta', contractVersion: 1 };
|
||||
|
|
@ -20,6 +20,6 @@
|
|||
"ponder/virtual": ["./node_modules/ponder/src/types.d.ts"]
|
||||
}
|
||||
},
|
||||
"include": ["src/**/*", "ponder.config.ts", "ponder.schema.ts", "ponder-env.d.ts", "vitest.config.ts"],
|
||||
"include": ["src/**/*", "tests/**/*", "ponder.config.ts", "ponder.schema.ts", "ponder-env.d.ts", "vitest.config.ts"],
|
||||
"exclude": ["node_modules", ".ponder"]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@ export default defineConfig({
|
|||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
'ponder:schema': resolve(rootDir, 'src/tests/__mocks__/ponder-schema.ts'),
|
||||
'ponder:registry': resolve(rootDir, 'src/tests/__mocks__/ponder-registry.ts'),
|
||||
'ponder:schema': resolve(rootDir, 'tests/__mocks__/ponder-schema.ts'),
|
||||
'ponder:registry': resolve(rootDir, 'tests/__mocks__/ponder-registry.ts'),
|
||||
'kraiken-lib/version': resolve(rootDir, '../../kraiken-lib/src/version.ts'),
|
||||
},
|
||||
},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue