Skip to content

Commit 2a8c150

Browse files
committed
test(driver-memory): type the aggregation conformance query instead of erasing it
The query-options-erasure ratchet (#4918) went red: the new aggregation suite added 3 counted sites (242 -> 245) by casting `queryFor(c) as any` at each of its three call sites — the two doors of the data face plus the never-answers- null property row. Typed rather than exempted. `queryFor` now declares `DriverQuery` as its return type (import-reachable from `@objectstack/spec/contracts`, the same type `MemoryDriver.find` takes), so all three arguments are checked by `tsc` and no call site needs a cast. The `as unknown as` spelling would have been wrong here: every case in this file is deliberately ON contract — the whole point is that the standard's own vocabulary reaches the driver — so there is no bypassed contract to name. The baseline is NOT raised: the count returns to the 242 ceiling. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NuzQE844ut8m8vypXcdBYD
1 parent e470ac1 commit 2a8c150

1 file changed

Lines changed: 14 additions & 5 deletions

File tree

packages/drivers/driver-memory/src/memory-aggregation-conformance.test.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,13 +69,22 @@
6969
import { describe, it, expect, beforeEach } from 'vitest';
7070
import { AGGREGATION_CASES, AGGREGATION_ROWS } from '@objectstack/spec/data';
7171
import type { AggregationCase, Cube } from '@objectstack/spec/data';
72+
import type { DriverQuery } from '@objectstack/spec/contracts';
7273
import { InMemoryDriver } from './memory-driver.js';
7374
import { MemoryAnalyticsService } from './memory-analytics.js';
7475

7576
const TABLE = 'conformance_agg';
7677

77-
/** The case as the `DriverQuery` shape both doors consume. */
78-
const queryFor = (c: AggregationCase) => ({
78+
/**
79+
* The case as the `DriverQuery` shape both doors consume.
80+
*
81+
* [#4918] The return type is DECLARED rather than left to inference and erased
82+
* at each call site. Every case here is deliberately ON contract — the whole
83+
* point of the file is that the standard's own vocabulary reaches the driver —
84+
* so there is nothing for an `as any` to bypass, and typing it puts the two
85+
* doors' argument under `tsc` instead of exempting it.
86+
*/
87+
const queryFor = (c: AggregationCase): DriverQuery => ({
7988
aggregations: [{ function: c.function, ...(c.field ? { field: c.field } : {}), alias: 'n' }],
8089
// [#6401] A case carrying `groupByAlias` is sent as the STRUCTURED node, so
8190
// the face receives the union member that declares `alias`. Without this the
@@ -140,7 +149,7 @@ describe('[#6814] InMemoryDriver — aggregate vocabulary conformance', () => {
140149

141150
for (const c of AGGREGATION_CASES) {
142151
it(`find(): ${c.name}`, async () => {
143-
const rows = await driver.find(TABLE, queryFor(c) as any);
152+
const rows = await driver.find(TABLE, queryFor(c));
144153
expect(actualFor(c, rows as any[]), c.note ?? c.name).toEqual(expectedFor(c));
145154
});
146155

@@ -151,7 +160,7 @@ describe('[#6814] InMemoryDriver — aggregate vocabulary conformance', () => {
151160
* stand for the other.
152161
*/
153162
it(`aggregate(AST): ${c.name}`, async () => {
154-
const rows = await driver.aggregate(TABLE, queryFor(c) as any);
163+
const rows = await driver.aggregate(TABLE, queryFor(c));
155164
expect(actualFor(c, rows as any[]), c.note ?? c.name).toEqual(expectedFor(c));
156165
});
157166
}
@@ -165,7 +174,7 @@ describe('[#6814] InMemoryDriver — aggregate vocabulary conformance', () => {
165174
*/
166175
it('never answers null for a declared aggregate function', async () => {
167176
for (const c of AGGREGATION_CASES) {
168-
const rows = await driver.find(TABLE, queryFor(c) as any);
177+
const rows = await driver.find(TABLE, queryFor(c));
169178
for (const row of rows as any[]) {
170179
expect(row.n, `${c.name} — a declared function resolving null is the #6814 defect`).not.toBeNull();
171180
expect(typeof row.n, c.name).toBe('number');

0 commit comments

Comments
 (0)