/** * LINEAGE PRODUCTIZATION — persistent shadow writer, independent coverage * observer, additive ancestry surface. * * Three properties this suite exists to hold: * the product never depends on lineage; * the observer never trusts the writer; * the ancestry surface never invents history it does not have. */ const svc = require('../../src/services/snapshotService'); const mode = require('../../src/services/lineageWriteMode'); const coverage = require('../../src/services/lineageCoverage'); const ancestry = require('../../src/services/read/readAncestry'); const retention = require('../../src/services/retentionService'); const ENV = mode.ENV_VAR; const setPersistent = (v) => { if (v === null) delete process.env[ENV]; else process.env[ENV] = v; }; afterEach(() => setPersistent(null)); /* ─────────────────────────── WRITE MODE ─────────────────────────── */ describe('write mode — three modes, one evaluator', () => { test('unset -> OFF, nothing enabled', () => { setPersistent(null); expect(mode.evaluate().mode).toBe(mode.WRITE_MODE.OFF); expect(mode.isEnabled('mlb')).toBe(false); }); test('PERSISTENT_SHADOW writes without any lease', () => { setPersistent('mlb'); const e = mode.evaluate(); expect(e.mode).toBe(mode.WRITE_MODE.PERSISTENT_SHADOW); expect(mode.isEnabled('mlb')).toBe(true); // No lease is involved, and none is required. expect(e.canary_sports).toEqual([]); expect(mode.modeFor('mlb')).toBe(mode.WRITE_MODE.PERSISTENT_SHADOW); }); test('a sport outside the allowlist fails closed, and takes the whole list with it', () => { setPersistent('wnba'); expect(mode.evaluate().persistent_invalid_reason).toBe('INVALID_SPORT_NOT_PERSISTABLE'); expect(mode.isEnabled('wnba')).toBe(false); setPersistent('mlb,wnba'); // Keeping the valid half would enable a subset nobody asked for on its own. expect(mode.isEnabled('mlb')).toBe(false); }); test('the allowlist is the canary\'s, not a second one', () => { const canary = require('../../src/services/lineageCanaryConfig'); expect(mode.PERSISTABLE_SPORTS).toBe(canary.LEASABLE_SPORTS); }); test('another sport cannot become enabled by accident', () => { setPersistent('mlb'); for (const s of ['wnba', 'nba', 'soccer', '']) expect(mode.isEnabled(s)).toBe(false); }); test('status and gate come from the SAME evaluator', () => { setPersistent('mlb'); const st = mode.state(); expect(st.mode).toBe(mode.evaluate().mode); expect(st.effective_sports).toEqual(mode.evaluate().sports); expect(st.authority).toBe('NON_AUTHORITATIVE'); }); test('rollback ON -> OFF disables future writes and touches nothing else', () => { setPersistent('mlb'); expect(mode.isEnabled('mlb')).toBe(true); setPersistent(null); expect(mode.isEnabled('mlb')).toBe(false); expect(mode.evaluate().mode).toBe(mode.WRITE_MODE.OFF); }); }); describe('canary and persistent are DIFFERENT modes', () => { test('an ambiguous configuration fails closed rather than double-enabling', () => { // The two instructions disagree about WHEN WRITING STOPS. We cannot know // which the operator meant, so the sport writes nothing. const e = mode.evaluate.call(null); const fake = { lease_state: 'ACTIVE', effective_active_sports: ['mlb'], }; jest.isolateModules(() => { jest.doMock('../../src/services/lineageCanaryConfig', () => ({ LEASABLE_SPORTS: ['mlb'], evaluate: () => fake, })); const m2 = require('../../src/services/lineageWriteMode'); process.env[m2.ENV_VAR] = 'mlb'; const ev = m2.evaluate(); expect(ev.conflict).toBe(m2.CONFLICT.SPORT_IN_BOTH_MODES); expect(ev.conflict_sports).toEqual(['mlb']); expect(ev.mode).toBe(m2.WRITE_MODE.OFF); expect(m2.isEnabled('mlb')).toBe(false); delete process.env[m2.ENV_VAR]; }); expect(e).toBeDefined(); }); test('a lease alone still enables, with the canary contract untouched', () => { jest.isolateModules(() => { jest.doMock('../../src/services/lineageCanaryConfig', () => ({ LEASABLE_SPORTS: ['mlb'], evaluate: () => ({ lease_state: 'ACTIVE', effective_active_sports: ['mlb'] }), })); const m2 = require('../../src/services/lineageWriteMode'); delete process.env[m2.ENV_VAR]; expect(m2.evaluate().mode).toBe(m2.WRITE_MODE.CANARY_LEASED); expect(m2.isEnabled('mlb')).toBe(true); }); }); test('an EXPIRED lease enables nothing — dynamic expiry is preserved', () => { jest.isolateModules(() => { jest.doMock('../../src/services/lineageCanaryConfig', () => ({ LEASABLE_SPORTS: ['mlb'], evaluate: () => ({ lease_state: 'EXPIRED', effective_active_sports: [] }), })); const m2 = require('../../src/services/lineageWriteMode'); delete process.env[m2.ENV_VAR]; expect(m2.isEnabled('mlb')).toBe(false); expect(m2.evaluate().mode).toBe(m2.WRITE_MODE.OFF); }); }); }); /* ────────────────── FAILURE ISOLATION (the product first) ────────────────── */ describe('lineage failure can never reach authoritative product truth', () => { // HERMETIC. Injecting `retention` activates pipeline paths the other snapshot // tests never reach, and several resolve a real Supabase client when the // environment offers one. Blanking the credentials makes every database // dependency a no-op, so this measures the ISOLATION PROPERTY and not the // network. Restored afterwards so no other suite inherits it. const SUPA_KEYS = ['SUPABASE_URL', 'SUPABASE_SERVICE_ROLE_KEY', 'SUPABASE_SERVICE_KEY', 'SUPABASE_ANON_KEY']; const saved = {}; beforeAll(() => { for (const k of SUPA_KEYS) { saved[k] = process.env[k]; delete process.env[k]; } }); afterAll(() => { for (const k of SUPA_KEYS) { if (saved[k] === undefined) delete process.env[k]; else process.env[k] = saved[k]; } }); const memCache = () => { const store = {}; return { store, cacheGet: async (k) => (k in store ? store[k] : null), cacheSet: async (k, v) => { store[k] = v; } }; }; const sampleProps = [{ player: 'Aaron Judge', stat_type: 'total_bases', line: 1.5, over_odds: -115, under_odds: -105, book: 'draftkings' }]; const grades = [{ player: 'Aaron Judge', stat_type: 'total_bases', line: 1.5, direction: 'over', grade: 'A+', confidence: 80 }]; const deps = (cache, extra = {}) => ({ getOdds: async () => ({ sport: 'mlb', props: sampleProps, provider: 'propline' }), // Fires the retention hook the real grader fires. Without it the collector // stays empty, `persistedRows` stays null and the lineage gate is never // reached — which would make every assertion below vacuously true. gradeAndCacheSlate: async (_s, _p, opts) => { if (typeof opts.onGraded === 'function') { opts.onGraded( { player: 'Aaron Judge', stat_type: 'total_bases', line: 1.5, book: 'draftkings', game_time: '2026-08-31T23:05:00Z', game_date: '2026-08-31', canonical_event_id: 'mlb:gamepk:999001', }, [ { player: 'Aaron Judge', stat_type: 'total_bases', line: 1.5, direction: 'over', grade: 'A+', confidence: 80 }, { player: 'Aaron Judge', stat_type: 'total_bases', line: 1.5, direction: 'under', grade: 'D', confidence: 40 }, ], ); } await opts.cacheSet('grades:x', { grades }); return { written: true, count: 1 }; }, resolveStats: async () => ({ found: false }), classify: require('../../src/services/archetypeService').classify, cacheGet: cache.cacheGet, cacheSet: cache.cacheSet, now: () => '2026-08-31T01:00:00Z', nowMs: () => 1000, ...extra, }); test('a throwing lineage commit leaves the slate published and the run ok', async () => { setPersistent('mlb'); const cache = memCache(); // The counter is the point. Without it this test passes when the lineage // path is never entered at all, which asserts nothing about isolation. let commits = 0; const r = await svc.runSnapshot('mlb', deps(cache, { retention: { persist: async () => ({ attempted: 1, written: 1 }), commitPublication: async () => { commits += 1; throw new Error('lineage exploded'); }, rowsFromSides: retention.rowsFromSides, createCollector: retention.createCollector, newSnapshotId: retention.newSnapshotId, }, })); expect(commits).toBe(1); // the failure really happened expect(r.status).toBe('ok'); // and the run still completed // The authoritative product write happened regardless... expect(cache.store['snapshot:mlb:latest']).toBeTruthy(); // ...and so did every step AFTER the lineage block. This is what separates // "the slate was already written" from "the exception was contained". expect(cache.store['grades:mlb']).toBeTruthy(); }); test('a throwing lineage commit does not stop the Ledger write', async () => { setPersistent('mlb'); const cache = memCache(); const ledgerCalls = []; let commits = 0; await svc.runSnapshot('mlb', deps(cache, { retention: { persist: async () => ({ attempted: 1, written: 1 }), commitPublication: async () => { commits += 1; throw new Error('lineage exploded'); }, rowsFromSides: retention.rowsFromSides, createCollector: retention.createCollector, newSnapshotId: retention.newSnapshotId, }, ledger: { recordPipelineGrades: async (...a) => { ledgerCalls.push(a); return { written: 1 }; }, captureClosing: async () => ({}), }, })); expect(commits).toBe(1); expect(ledgerCalls.length).toBe(1); // read_id linkage is absent, never guessed. expect(ledgerCalls[0][3].lineageIndex).toBeNull(); }); test('with the mode OFF no lineage commit is attempted at all', async () => { setPersistent(null); const cache = memCache(); let commits = 0; await svc.runSnapshot('mlb', deps(cache, { retention: { persist: async () => ({ attempted: 1, written: 1 }), commitPublication: async () => { commits += 1; return { published: 0, candidates: 0 }; }, rowsFromSides: retention.rowsFromSides, createCollector: retention.createCollector, newSnapshotId: retention.newSnapshotId, }, })); expect(commits).toBe(0); }); }); /* ─────────────── PARTIAL-LINEAGE ATOMICITY (no half actions) ─────────────── */ describe('a failed lineage attempt writes no half action', () => { test('a throwing family lookup leaves every row completely blank', async () => { const rows = [ { sport: 'mlb', game_date: '2026-08-31', player_key: 'a b', stat: 'hits', side: 'over', line: 0.5, published: true }, { sport: 'mlb', game_date: '2026-08-31', player_key: 'c d', stat: 'hits', side: 'over', line: 0.5, published: true }, ]; const out = await retention.attachLineage(rows, { fetchExisting: async () => { throw new Error('boom'); } }); expect(out.error).toMatch(/boom/); for (const r of rows) { expect(retention.isValidLineageAction(r)).toBe(false); for (const k of retention.LINEAGE_KEYS) expect(r[k]).toBeNull(); } // The natural key stamped before the lookup is cleared too — it is family // identity, and a failed attempt has no claim to it. expect(rows[0].read_natural_key).toBeNull(); expect(out.incomplete_cleared).toBe(2); }); }); /* ───────────── INDEPENDENT COVERAGE OBSERVER (never trust the writer) ───────────── */ describe('coverage observer', () => { const row = (o) => ({ sport: 'mlb', game_date: '2026-08-31', player_key: 'aaron judge', stat: 'hits', side: 'over', line: 0.5, published: true, ...o, }); const action = (o) => ({ read_id: 'r1', read_natural_key: 'k', lineage_action: 'ORIGIN', claim_digest: 'd', revision_ordinal: 0, lineage_state: 's', lineage_version: 'lin@1', claim_schema_version: 'claim@1', digest_algorithm_version: 'sha256-json-sorted@1', ...o, }); test('THE DENOMINATOR IGNORES lineage_action — the property, not the spelling', () => { const base = [row({ player_key: 'a' }), row({ player_key: 'b' })]; const withLineage = base.map((r) => ({ ...r, ...action({ read_natural_key: r.player_key }) })); const without = base.map((r) => ({ ...r })); // Same rows, opposite lineage state, identical expectation. expect(coverage.expectedKeys(withLineage).keys.size).toBe(coverage.expectedKeys(without).keys.size); expect([...coverage.expectedKeys(withLineage).keys].sort()) .toEqual([...coverage.expectedKeys(without).keys].sort()); }); test('unpublished rows are not expected to have lineage', () => { expect(coverage.expectedKeys([row({ published: false })]).keys.size).toBe(0); expect(coverage.expectedKeys([row({ published: null })]).keys.size).toBe(0); }); test('a row with no derivable identity is counted, not silently dropped', () => { const e = coverage.expectedKeys([row({ player_key: '' })]); expect(e.keys.size).toBe(0); expect(e.unkeyable_rows).toBe(1); }); test('WRITER NEVER RAN: full slate, zero lineage -> MISSING_COVERAGE', () => { const a = coverage.auditRows([row({ player_key: 'a' }), row({ player_key: 'b' })]); expect(a.expected_keys).toBe(2); expect(a.covered_keys).toBe(0); expect(a.health).toBe(coverage.HEALTH.MISSING_COVERAGE); }); test('zero expected and zero written are DIFFERENT answers', () => { const none = coverage.auditRows([row({ published: false })]); expect(none.health).toBe(coverage.HEALTH.NO_ELIGIBLE_CLAIMS); expect(none.health).not.toBe(coverage.HEALTH.MISSING_COVERAGE); }); test('partial coverage is detected', () => { const rows = [ { ...row({ player_key: 'a' }), ...action({ read_natural_key: 'mlb|2026-08-31|a|hits|over|0.500000' }) }, row({ player_key: 'b' }), ]; const a = coverage.auditRows(rows); expect(a.health).toBe(coverage.HEALTH.PARTIAL_COVERAGE); expect(a.missing_keys).toBe(1); expect(a.coverage_pct).toBe(50); }); test('full coverage is HEALTHY', () => { const rows = ['a', 'b'].map((p) => ({ ...row({ player_key: p }), ...action({ read_natural_key: `mlb|2026-08-31|${p}|hits|over|0.500000`, read_id: `r-${p}` }), })); const a = coverage.auditRows(rows); expect(a.health).toBe(coverage.HEALTH.HEALTHY); expect(a.coverage_pct).toBe(100); expect(a.missing_keys).toBe(0); expect(a.extra_keys).toBe(0); }); test('an invalid partial action is INVALID_GRAPH, never counted as covered', () => { const partial = { ...row({ player_key: 'a' }), read_natural_key: 'k', read_id: 'r' }; // 2 of 9 const a = coverage.auditRows([partial]); expect(a.invalid_partial_actions).toBe(1); expect(a.covered_keys).toBe(0); expect(a.health).toBe(coverage.HEALTH.INVALID_GRAPH); }); test('extra lineage — covered but never expected — is a defect', () => { const rows = [{ ...row({ published: false, player_key: 'a' }), ...action({ read_natural_key: 'ghost' }) }]; const a = coverage.auditRows(rows); expect(a.expected_keys).toBe(0); expect(a.extra_keys).toBe(1); expect(a.health).toBe(coverage.HEALTH.INVALID_GRAPH); }); test('a forked chain is a graph defect', () => { const k = 'mlb|2026-08-31|a|hits|over|0.500000'; const rows = [ { ...row({ player_key: 'a' }), ...action({ read_natural_key: k, revision_ordinal: 0 }) }, { ...row({ player_key: 'a' }), ...action({ read_natural_key: k, revision_ordinal: 0 }) }, ]; const a = coverage.auditRows(rows); expect(a.graph_defects).toBeGreaterThan(0); expect(a.health).toBe(coverage.HEALTH.INVALID_GRAPH); }); test('the observer\'s valid-action fields match the writer\'s, without importing it', () => { expect([...coverage.VALID_ACTION_FIELDS].sort()) .toEqual([...retention.VALID_LINEAGE_ACTION_FIELDS].sort()); }); test('a cohort spanning two game_dates is audited whole, not one slice', () => { // The real 2026-08-31 03:00Z shape: a late slot spanning midnight ET. Rows // from BOTH dates are eligible and both must be counted, or a date slice // with no lineage stays invisible behind a HEALTHY verdict. const mk = (d, p, covered) => ({ sport: 'mlb', game_date: d, player_key: p, stat: 'hits', side: 'over', line: 0.5, published: true, ...(covered ? { read_id: `r-${p}`, read_natural_key: `mlb|${d}|${p}|hits|over|0.500000`, lineage_action: 'ORIGIN', claim_digest: 'd', revision_ordinal: 0, lineage_state: 's', lineage_version: 'lin@1', claim_schema_version: 'claim@1', digest_algorithm_version: 'sha256-json-sorted@1', } : {}), }); const a = coverage.auditRows([mk('2026-08-31', 'a', true), mk('2026-08-30', 'b', false)]); expect(a.expected_keys).toBe(2); expect(a.covered_keys).toBe(1); expect(a.health).toBe(coverage.HEALTH.PARTIAL_COVERAGE); }); test('an unavailable audit is not a coverage claim', () => { expect(coverage.classify({ audit_available: false })).toBe(coverage.HEALTH.AUDIT_UNAVAILABLE); }); }); /* ───────────────────────── ADDITIVE ANCESTRY ───────────────────────── */ describe('ancestry surface tells the truth about what it has', () => { const A = ancestry.ANCESTRY_STATE; const act = (o) => ({ id: 1, read_id: 'r1', read_natural_key: 'k', lineage_action: 'ORIGIN', claim_digest: 'd0', revision_ordinal: 0, lineage_state: 'PUBLISHED', lineage_version: 'lin@1', claim_schema_version: 'claim@1', digest_algorithm_version: 'sha256-json-sorted@1', publication_id: 'p1', ...o, }); test('a row lineage never ran for is LEGACY_UNVERIFIED, and nothing is synthesized', () => { const out = ancestry.classifyAncestry([{ id: 1, publication_id: null, grade: 'B' }]); expect(out.state).toBe(A.LEGACY_UNVERIFIED); expect(out.revisions).toEqual([]); expect(out.read_id).toBeUndefined(); }); test('a row lineage RAN for but did not complete is LINEAGE_UNAVAILABLE, not legacy', () => { // This is the shape of the 1,119 historical partial rows. const out = ancestry.classifyAncestry([{ id: 1, publication_id: 'p1', read_natural_key: 'k' }]); expect(out.state).toBe(A.LINEAGE_UNAVAILABLE); expect(out.state).not.toBe(A.LEGACY_UNVERIFIED); }); test('a partial row is never elected as an ancestry head', () => { const out = ancestry.classifyAncestry([ { id: 1, publication_id: 'p1', read_natural_key: 'k', read_id: 'r1' }, ]); expect(out.state).toBe(A.LINEAGE_UNAVAILABLE); expect(out.current).toBeUndefined(); }); test('ORIGIN alone reads as a one-entry chronology', () => { const out = ancestry.classifyAncestry([act({})]); expect(out.state).toBe(A.LINEAGE_AVAILABLE); expect(out.revision_count).toBe(0); expect(out.original.action).toBe('ORIGIN'); expect(out.current.action).toBe('ORIGIN'); expect(out.authority).toBe('NON_AUTHORITATIVE'); }); test('REVISION ancestry names the exact parent and order', () => { const out = ancestry.classifyAncestry([ act({ id: 1, revision_ordinal: 0, lineage_action: 'ORIGIN' }), act({ id: 2, revision_ordinal: 1, lineage_action: 'REVISION', supersedes_id: 1, claim_digest: 'd1', change_type: 'MIXED_CHANGE' }), ]); expect(out.state).toBe(A.LINEAGE_AVAILABLE); expect(out.revision_count).toBe(1); expect(out.current.revision_ordinal).toBe(1); expect(out.current.supersedes_row_id).toBe(1); expect(out.current.change_type).toBe('MIXED_CHANGE'); }); test('RECAPTURE is reported as a recapture, never as a revision', () => { const out = ancestry.classifyAncestry([ act({ id: 1, lineage_action: 'ORIGIN', revision_ordinal: 0 }), act({ id: 2, lineage_action: 'RECAPTURE', revision_ordinal: 0, recaptures_id: 1 }), ]); expect(out.state).toBe(A.LINEAGE_AVAILABLE); expect(out.revision_count).toBe(0); expect(out.recapture_count).toBe(1); expect(out.recaptures[0].action).toBe('RECAPTURE'); }); test('a broken chain REFUSES rather than electing a head', () => { const out = ancestry.classifyAncestry([ act({ id: 1, lineage_action: 'ORIGIN', revision_ordinal: 0 }), act({ id: 2, lineage_action: 'REVISION', revision_ordinal: 1, supersedes_id: 999 }), ]); expect(out.state).toBe(A.INVALID_LINEAGE); expect(out.revisions).toEqual([]); }); test('two read_ids under one natural key is INVALID_LINEAGE', () => { const out = ancestry.classifyAncestry([act({ id: 1, read_id: 'r1' }), act({ id: 2, read_id: 'r2' })]); expect(out.state).toBe(A.INVALID_LINEAGE); }); test('the projection carries only what lineage knows', () => { const p = ancestry.project({ ...act({}), p_win: 0.6, grade: 'A', locked_odds: '-110', outcome: 'hit' }); for (const forbidden of ['p_win', 'grade', 'locked_odds', 'outcome', 'projection']) { expect(p[forbidden]).toBeUndefined(); } expect(p.read_id).toBe('r1'); expect(p.claim_digest).toBe('d0'); }); test('a valid chain with a stamped-but-unrecorded sibling discloses the hole', () => { // The production shape: one good ORIGIN plus a later publication that was // attempted and never recorded. The chain stays valid and the partial row // stays out of it, but the answer must not claim the chronology is whole. const out = ancestry.classifyAncestry([ act({ id: 1, publication_id: 'p1' }), { id: 2, publication_id: 'p2', read_natural_key: 'k' }, ]); expect(out.state).toBe(A.LINEAGE_AVAILABLE); expect(out.revisions).toHaveLength(1); expect(out.revisions[0].snapshot_row_id).toBe(1); // the partial is excluded expect(out.chronology_complete).toBe(false); expect(out.unrecorded_publications).toBe(1); }); test('a chain with no unrecorded siblings is complete', () => { const out = ancestry.classifyAncestry([act({ id: 1, publication_id: 'p1' })]); expect(out.chronology_complete).toBe(true); expect(out.unrecorded_publications).toBe(0); }); test('nothing found is NOT_FOUND, which is not an absence of lineage', () => { expect(ancestry.classifyAncestry([]).state).toBe(A.NOT_FOUND); }); }); /* ────────────────────── PRESERVATION ────────────────────── */ describe('this tranche changes nothing it was told not to', () => { const fs = require('fs'); const path = require('path'); const ROOT = path.resolve(__dirname, '..', '..'); test('the grade-shift badge is untouched — no lineage anywhere near it', () => { for (const f of ['src/routes/ledger.js', 'src/routes/profiles.js']) { const src = fs.readFileSync(path.join(ROOT, f), 'utf8'); expect(src).toMatch(/revised_from_grade/); expect(src).not.toMatch(/lineage|read_id/); } }); test('retention identity and its collision counter are unchanged', () => { expect(retention.RETENTION_CONFLICT.split(',')).toEqual( ['snapshot_id', 'game_id', 'canonical_event_id', 'player_key', 'stat', 'line', 'side']); const dup = [ { snapshot_id: 's', game_id: 'g', canonical_event_id: 'e', player_key: 'a', stat: 'hits', line: 0.5, side: 'over' }, { snapshot_id: 's', game_id: 'g', canonical_event_id: 'e', player_key: 'a', stat: 'hits', line: 0.5, side: 'over' }, ]; expect(retention.expectedMaterialization(dup).collision_count).toBe(1); }); test('participant identity guards are unchanged', () => { const pid = require('../../src/services/model/participantIdentity'); const a = pid.auditParticipantIdentity([ { canonical_event_id: 'e', mlb_person_id: 1, player_key: 'x' }, { canonical_event_id: 'e', mlb_person_id: 1, player_key: 'y' }, ]); expect(a.participant_identity_split_count).toBe(1); expect(pid.semanticPlayerKey({ player: 'Mickey Gasper', mlb_person_id: 681508, canonical_player_name: 'Mickey Gasper' }).canonical).toBe(true); }); test('the ancestry surface writes nothing', () => { const src = fs.readFileSync(path.join(ROOT, 'src/services/read/readAncestry.js'), 'utf8') .replace(/\/\*[\s\S]*?\*\//g, '').replace(/^\s*\/\/.*$/gm, ''); for (const verb of ['.insert(', '.update(', '.upsert(', '.delete(']) { expect(src).not.toContain(verb); } }); test('the coverage observer writes nothing', () => { const src = fs.readFileSync(path.join(ROOT, 'src/services/lineageCoverage.js'), 'utf8') .replace(/\/\*[\s\S]*?\*\//g, '').replace(/^\s*\/\/.*$/gm, ''); for (const verb of ['.insert(', '.update(', '.upsert(', '.delete(']) { expect(src).not.toContain(verb); } }); });