Repository navigation
test: run every remaining driver-memory test on the SQL driver - #2104
Merged
Merged
Conversation
By the maintainer's ruling on #2092 (A), every test that ran on @objectstack/driver-memory moves to the SQL driver. These 19 files move with no case deleted or re-expressed: - each hand-built ObjectQL engine takes a driver-sqlite-wasm ':memory:' database and runs the engine's own syncSchemas() after create, the per-object syncSchema loop the runtime's boot runs (ObjectQL.create connects the datasource but emits no DDL); - decorative-field-sweep boots its kernel on DefaultDatasourcePlugin 'sqlite-wasm', the spelling case-creation-date already uses; - knowledge-deflection and sla-compliance-gauge drop the memory leg of their two-driver loop and keep the SQL leg they already had; - comments that justified the memory driver now describe what runs. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01P8mZuzuyZAHSrgQKmv6ASv
…that shape The rest of the #2092 conversion, where a case had to be judged rather than moved. Deleted, because their only subject was driver-memory's stored shape: - the four "stores no key for a column it was never given" preconditions (object-validation-predicates, flow-condition-totality, quote-contact-required-when, win-loss-capture); - quote-discount-ceiling "leaves a quote with no discount at all alone", whose business half the SQL block already pins ("admits a quote with a NULL discount"); - undeclared-key-probe's memory leg and its "memory no longer accepts it" case. Re-expressed on SQL: - sharing-seeding: the $nor refusal is asserted by its envelope (INVALID_FILTER / 400); driver-sql withholds the key from the message; - audit-stamp-readonly: each seeded deal gets its own account, because crm_account.name is unique and SQL enforces it; - quote-discount-ceiling: the line-default case pins the default 0, not the stored-key shape; - flow-variable-conditions: the class-1 precondition keeps its findOne null half and drops the sparse-column half, vacuous on SQL; - undeclared-key-probe: the convergence case is over the two SQL drivers. The absent-key shape stays covered by the evaluator sweeps (a record with no keys at all), which no driver change can reach. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01P8mZuzuyZAHSrgQKmv6ASv
Nothing in the repo imports it any more, and no kernel boots driver: 'memory'. @objectstack/cli and @objectstack/runtime still depend on it themselves, so it stays installed for them. The lockfile was regenerated by pnpm install: the only change is the importer entry. Changeset with empty frontmatter: tests only, nothing ships. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01P8mZuzuyZAHSrgQKmv6ASv
The note now says what was measured (one born-critical write, both drivers, with a direct-record control) and the cause the 18.0.0-next.0 upgrade recorded, instead of generalising from the one write. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01P8mZuzuyZAHSrgQKmv6ASv
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
This was referenced Oct 14, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #2092
Clause-②: no
What this does
The maintainer's ruling A on #2092 (comment 6166370777, verbatim: 「2092 内存测试全部换 sql」), which carries out the #2031 ruling 「就应该在 sql 上测试,作废内存驱动的测试」 (comment 6144864473): every test that ran on
@objectstack/driver-memorynow runs on the SQL driver. A case whose only subject was the memory driver's stored shape is deleted and named below. The app no longer listsdriver-memoryamong its own dependencies.Tests only, nothing ships. No
src/**change. The changeset has empty frontmatter.The harness (H2)
Two SQL shapes already existed in
test/, and each converted file moves onto whichever shape it already had. No new helper.hotcrmStack()/bootStackdefault todatabaseDriver: 'sqlite-wasm'. The twoDefaultDatasourcePlugin({ driver: 'memory' })kernels move to{ driver: 'sqlite-wasm', config: { filename: ':memory:' } }, the spellingcase-creation-date.test.tsalready uses.ObjectQL.createengine. It now getsnew SqliteWasmDriver({ filename: ':memory:' }), the driverdashboard-date-range-window,hook-org-inheritanceand others already construct inline.ObjectQL.createconnects the driver but emits no DDL, so each converted engine runsawait ql.syncSchemas()after create. That is the engine's own public method: the same per-objectdriver.syncSchema(table, obj)loop the runtime's boot runs (ObjectQLPlugin.syncRegisteredSchemas), over the registry's objects, with system fields already applied. It is one line per engine and cannot drift from the registry. The five pre-existing SQL legs that hand-callapplySystemFieldsandinitObjectsare left untouched.Driver used:
@objectstack/driver-sqlite-wasm(its SQL is@objectstack/driver-sql's), the one every existing SQL suite here uses.undeclared-key-probekeeps itssqlite(driver-sql on better-sqlite3) leg beside it.Files (before → after)
syncSchemas()driver: 'memory'driver: 'sqlite-wasm'The two de-looped files (
knowledge-deflection,sla-compliance-gauge) are mostly re-indentation;git diff -wshows the real change.Deleted: their only subject was the memory driver's stored shape (H3)
object-validation-predicates,flow-condition-totality,quote-contact-required-when,win-loss-capture: "stores no key for a column it was never given — the precondition". Each asserted'x' in stored === false, the absent key itself.quote-discount-ceiling› "leaves a quote with no discount at all alone": its business half is already pinned on SQL by "admits a quote with a NULL discount — the column-complete shape". What it added was'discount' in stored === false.undeclared-key-probe: thememoryleg of the half-1 matrix (5 runs), and "memory no longer accepts it — the permissive driver came into line". The premise assertion it also carried ("the line item does not declaretax") is still pinned by "the probe rests on a real asymmetry".knowledge-deflection› "the deflection measures over memory" andsla-compliance-gauge› "the compliance measure over memory": the memory leg of a two-driver loop (6 runs each). The same cases still run over sqlite.That is 23 fewer test runs (3676 → 3653 passed, 1 skipped both times).
Re-expressed on SQL (H3)
audit-stamp-readonly›seedOpportunity: each deal gets its own account.crm_account.nameis declaredunique: true(src/sales/objects/account.object.ts), SQL enforces it, and the memory driver never did. On SQL, two cases went red withDuplicateRecordError … on 'crm_account'because the fixture reused one name. The app is right to refuse that write. The readonly-strip assertions are unchanged.sharing-seeding› "a filter the driver cannot execute is refused loudly, not answered wrongly":.rejects.toThrow(/\$nor/)became.rejects.toMatchObject({ code: 'INVALID_FILTER', status: 400 }). driver-sql still refuses$norloudly, but it keeps the key out of the message (server log only, because the predicate is not marked author-written). The regex was pinning the memory driver's wording.quote-discount-ceiling› line case "… and it is NOT the sparse shape" → "… the field default is 0": the'discount' in storedassertion is dropped. The default0is kept.flow-variable-conditions› "findOne answers a miss with null — the precondition for class 1": keeps thefindOnemiss →nullhalf (true on SQL, and what the guard needs). It drops the sparse-column half,'status' in stored, which passes regardless on a column-complete driver.undeclared-key-probe› "so the three drivers DO agree" → "so the SQL drivers DO agree".No case went red because the app is wrong on SQL.
Measured while converting
sharing-seedingwas measured ondriver-memory17.1.0. Re-measured on sqlite-wasm 18.0.0-next.0, every one of the 9 rows answers the same, including the null-sensitive ones (!= "customer"and!(… == "customer")both return the null-typed row). All 10 rule witnesses pass on SQL. The docstring says so.flow-condition-totalityhad already stopped reaching the absent-key shape on 18.0.0-next.0, on both drivers (measured for one write; it matches chore(deps): upgrade the ObjectStack platform to 18.0.0-next.0 #2091's own note that on 18 the trigger'srecordis materialised over every declared field). I putcase_escalation_on_create's start condition back to its unguarded form and wrote a born-critical case through the realRecordChangeTrigger: no condition abort on memory or on sqlite-wasm. Control: the same flow handed a record withoutescalated_datedirectly aborts withNo such key: escalated_dateon both. So those cases pin "each flow runs end to end on the driver an install uses". The absent-key class is held by the evaluator sweeps ("answers on a record with no keys at all", "any single referenced key is the one that is missing"), which no driver change can reach. The docstring states this.syncSchemas()idiom (probe): an insert returns the full column-complete row. A second engine over the same driver (the "re-open the SAME store" legacy-row fixtures inquote-discount-ceiling/quote-contact-required-when) sees the stored row and adds its new column. AfindOnemiss answersnull.Dependency (H4)
Nothing imports
@objectstack/driver-memoryany more, and no kernel bootsdriver: 'memory'(git grep: 0 imports, 0 boots). The entry is gone frompackage.json(it was independencies, notdevDependencies), andpnpm installregeneratedpnpm-lock.yaml. The only lockfile change is the importer entry (3 lines).@objectstack/cliand@objectstack/runtimedepend ondriver-memorythemselves, so it stays installed for them.Suite time (H5)
Full
pnpm test, each under the shared verify lock (held the lockis the reading; a shared box, not an idle one):64003979(memory)2987e6c2(SQL)The whole-suite delta (+10%) is not the conversion. The same 28 files, run back to back, alternating, on the base tree and on this branch:
On these files SQL costs nothing measurable (mean 61.1s vs 59.4s). The full-suite readings differ by shared-box contention (
importtime rose 512s → 559s across all 179 files, most of which this PR does not touch), so H5's "the suite may grow" is not borne out.Gates (on
2b74e9f3, the final commit; each through the verify lock, exit code read before any pipe)pnpm validate:✓ Validation passedpnpm typecheck:tsc --noEmit, exit 0, no diagnostics.tsconfig.jsonincludestest/**/*;--listFileslists all 28 converted files.pnpm lint:18 suggestion(s), exit 0 (all metadata suggestions; this diff touches no metadata)pnpm lint:i18n-gate:✓ i18n lint gate: 0 i18n/missing-* issuespnpm hygiene:✓ source hygiene cleanpnpm hygiene:tokens:✓ source token ratchet cleanpnpm build:✓ Build completepnpm test:coverage(what CI runs; also the full suite on the final sha):Test Files 179 passed (179),Tests 3653 passed | 1 skipped (3654), coverageAll files | 95.18 | 86.74 | 96.61 | 99.22(stmts / branch / funcs / lines) against the floors 92 / 78 / 92 / 95. The coverage delta againstmainwas not measured (it needs a second 10-minute run). Coverage is scoped tosrc/*/objects/*.hook.ts. Of the 23 deleted runs, the only ones with app hooks bound areundeclared-key-probe's memory leg, whose two SQL legs boot the same kernel with the same hooks.Overlap
PR #2102 (#2016, draft) edits 2 lines of
test/flow-variable-conditions.test.ts: theboot([...])calls of twolead_conversioncases (lines 1137 and 1182), to register a callee flow. This PR's hunks in that file end near line 1000, so the two merge textually, and after the merge those cases boot on SQL through theboot()changed here. Whichever lands second mergesmain, and its CI runs them on SQL. Dependabot #2063 / #2064 touchpackage.json/pnpm-lock.yaml; the later one regenerates the lockfile.Acceptance notes
lead-duplicate-managementsaid "the engine test above is the proof" thehas()guards work. That proof leaned on the memory driver's absent keys. The pointer now names the no-keys sweep inobject-validation-predicates.test.ts.src/**comments that say "measured end-to-end on driver-memory" (for examplesrc/service/flows/case-escalation.flow.ts) are dated history and are left alone (nosrc/**change here).Generated by Claude Code