@danceroutine/tango-testing 1.1.1 → 1.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -1
- package/dist/mocks/MockQuerySetResult.d.ts +2 -1
- package/dist/mocks/aQuerySet.d.ts +1 -1
- package/dist/mocks/index.js +1 -1
- package/dist/{mocks-BkwkXQQt.js → mocks-JCG0Cdwf.js} +3 -2
- package/dist/mocks-JCG0Cdwf.js.map +1 -0
- package/package.json +6 -6
- package/dist/mocks-BkwkXQQt.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { aDBClient } from "./aDBClient-W6eXsK3X.js";
|
|
2
|
-
import { aManager, aQueryExecutor, aQueryResult, aQuerySet, aRequestContext, mocks_exports } from "./mocks-
|
|
2
|
+
import { aManager, aQueryExecutor, aQueryResult, aQuerySet, aRequestContext, mocks_exports } from "./mocks-JCG0Cdwf.js";
|
|
3
3
|
import { ModelDataFactory, factories_exports } from "./factories-Cl_CAzbj.js";
|
|
4
4
|
import { assertions, assertions_exports } from "./assertions-CCFZ53Y-.js";
|
|
5
5
|
import { AppProcessHarness, Dialect, HarnessStrategyRegistry, ResetMode, TestHarness, aTangoConfig, anIntegrationHarness, applyAndVerifyMigrations, assertMigrationPlan, conformance_exports, createQuerySetFixture, domain_exports, expectQueryResult, integration_exports, introspectSchema, migrations_exports, runDialectConformanceSuite, runtime_exports, seedTable, setupTestTangoRuntime, smoke_exports } from "./integration-BrJw6NzG.js";
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { QuerySet } from '@danceroutine/tango-orm';
|
|
2
2
|
/**
|
|
3
|
+
* @deprecated Use QuerySet instead.
|
|
3
4
|
* Legacy alias for query-set test doubles.
|
|
4
5
|
*/
|
|
5
|
-
export type MockQuerySetResult<TModel extends Record<string, unknown
|
|
6
|
+
export type MockQuerySetResult<TModel extends Record<string, unknown>, TResult extends Record<string, unknown> = TModel> = QuerySet<TModel, TResult>;
|
|
@@ -5,4 +5,4 @@ import type { QuerySet } from '@danceroutine/tango-orm';
|
|
|
5
5
|
* All methods are wrapped in `vi.fn()` so they can be asserted on directly
|
|
6
6
|
* without an additional `vi.mocked()` call.
|
|
7
7
|
*/
|
|
8
|
-
export declare function aQuerySet<TModel extends Record<string, unknown
|
|
8
|
+
export declare function aQuerySet<TModel extends Record<string, unknown>, TResult extends Record<string, unknown> = TModel>(overrides?: Partial<QuerySet<TModel, TResult>>): QuerySet<TModel, TResult>;
|
package/dist/mocks/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { aDBClient } from "../aDBClient-W6eXsK3X.js";
|
|
2
|
-
import { aManager, aQueryExecutor, aQueryResult, aQuerySet, aRequestContext } from "../mocks-
|
|
2
|
+
import { aManager, aQueryExecutor, aQueryResult, aQuerySet, aRequestContext } from "../mocks-JCG0Cdwf.js";
|
|
3
3
|
|
|
4
4
|
export { aDBClient, aManager, aQueryExecutor, aQueryResult, aQuerySet, aRequestContext };
|
|
@@ -41,7 +41,8 @@ function aQuerySet(overrides = {}) {
|
|
|
41
41
|
const orderByImpl = overrides.orderBy ?? ((..._tokens) => queryset);
|
|
42
42
|
const limitImpl = overrides.limit ?? ((_n) => queryset);
|
|
43
43
|
const offsetImpl = overrides.offset ?? ((_n) => queryset);
|
|
44
|
-
const
|
|
44
|
+
const defaultSelect = (_cols) => queryset;
|
|
45
|
+
const selectImpl = overrides.select ?? defaultSelect;
|
|
45
46
|
const selectRelatedImpl = overrides.selectRelated ?? ((..._rels) => queryset);
|
|
46
47
|
const prefetchRelatedImpl = overrides.prefetchRelated ?? ((..._rels) => queryset);
|
|
47
48
|
const fetchImpl = overrides.fetch ?? (async (_shape) => aQueryResult());
|
|
@@ -133,4 +134,4 @@ __export(mocks_exports, {
|
|
|
133
134
|
|
|
134
135
|
//#endregion
|
|
135
136
|
export { aManager, aQueryExecutor, aQueryResult, aQuerySet, aRequestContext, mocks_exports };
|
|
136
|
-
//# sourceMappingURL=mocks-
|
|
137
|
+
//# sourceMappingURL=mocks-JCG0Cdwf.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mocks-JCG0Cdwf.js","names":["overrides: Partial<QueryResult<TModel>>","overrides: QueryExecutorOverrides<TModel>","meta: TableMeta","overrides: Partial<QuerySet<TModel, TResult>>","filterImpl: QuerySet<TModel, TResult>['filter']","excludeImpl: QuerySet<TModel, TResult>['exclude']","orderByImpl: QuerySet<TModel, TResult>['orderBy']","limitImpl: QuerySet<TModel, TResult>['limit']","offsetImpl: QuerySet<TModel, TResult>['offset']","_cols: readonly (keyof TModel)[]","selectRelatedImpl: QuerySet<TModel, TResult>['selectRelated']","prefetchRelatedImpl: QuerySet<TModel, TResult>['prefetchRelated']","fetchImpl: QuerySet<TModel, TResult>['fetch']","_shape?: ((r: TResult) => Out) | { parse: (r: TResult) => Out }","fetchOneImpl: QuerySet<TModel, TResult>['fetchOne']","countImpl: QuerySet<TModel, TResult>['count']","existsImpl: QuerySet<TModel, TResult>['exists']","input: Parameters<QuerySet<TModel, TResult>['filter']>[0]","input: Parameters<QuerySet<TModel, TResult>['exclude']>[0]","n: number","cols: Parameters<QuerySet<TModel, TResult>['select']>[0]","overrides: ManagerOverrides<TModel>","id: ModelId","input: Partial<TModel>","_id: ModelId","patch: Partial<TModel>","inputs: Partial<TModel>[]","optionsOrMethod: RequestContextFixtureOptions<TUser, TContext> | string","urlArg?: string","bodyArg?: unknown","resolvedOptions: RequestContextFixtureOptions<TUser, TContext>","resolvedHeaders: HeadersInit | undefined","req: Request","currentUser: TUser | null"],"sources":["../src/mocks/aQueryResult.ts","../src/mocks/aQueryExecutor.ts","../src/mocks/aQuerySet.ts","../src/mocks/aManager.ts","../src/mocks/aRequestContext.ts","../src/mocks/index.ts"],"sourcesContent":["import type { QueryResult } from '@danceroutine/tango-orm/query';\n\n/**\n * Create a query-result test value with optional overrides.\n */\nexport function aQueryResult<TModel>(overrides: Partial<QueryResult<TModel>> = {}): QueryResult<TModel> {\n return {\n results: [] as TModel[],\n nextCursor: null,\n ...overrides,\n };\n}\n","import { vi } from 'vitest';\nimport type { QueryExecutor } from '@danceroutine/tango-orm';\nimport type { Dialect, TableMeta } from '@danceroutine/tango-orm/query';\nimport { aDBClient } from './aDBClient';\n\nexport type QueryExecutorOverrides<TModel extends Record<string, unknown>> = {\n dialect?: Dialect;\n meta?: TableMeta;\n query?: (sql: string, params?: readonly unknown[]) => Promise<{ rows: unknown[] }>;\n run?: QueryExecutor<TModel>['run'];\n};\n\n/**\n * Create a minimal `QueryExecutor` test double for `QuerySet` tests.\n */\nexport function aQueryExecutor<TModel extends Record<string, unknown>>(\n overrides: QueryExecutorOverrides<TModel> = {}\n): QueryExecutor<TModel> {\n const dialect = overrides.dialect ?? 'postgres';\n const meta: TableMeta = overrides.meta ?? { table: 'mock_table', pk: 'id', columns: {} };\n const run = overrides.run ?? vi.fn(async () => [] as TModel[]);\n const client = aDBClient(overrides.query ? { query: overrides.query } : {});\n\n return { meta, client, dialect, run };\n}\n","import { vi } from 'vitest';\nimport type { QuerySet } from '@danceroutine/tango-orm';\nimport { QuerySet as QuerySetClass } from '@danceroutine/tango-orm';\nimport { aQueryResult } from './aQueryResult';\nimport { aQueryExecutor } from './aQueryExecutor';\n\n/**\n * Create a chainable query-set test double with optional behavior overrides.\n *\n * All methods are wrapped in `vi.fn()` so they can be asserted on directly\n * without an additional `vi.mocked()` call.\n */\nexport function aQuerySet<TModel extends Record<string, unknown>, TResult extends Record<string, unknown> = TModel>(\n overrides: Partial<QuerySet<TModel, TResult>> = {}\n): QuerySet<TModel, TResult> {\n const queryset = new QuerySetClass<TModel, TResult>(aQueryExecutor<TModel>());\n const filterImpl: QuerySet<TModel, TResult>['filter'] = overrides.filter ?? ((_input) => queryset);\n const excludeImpl: QuerySet<TModel, TResult>['exclude'] = overrides.exclude ?? ((_input) => queryset);\n const orderByImpl: QuerySet<TModel, TResult>['orderBy'] = overrides.orderBy ?? ((..._tokens) => queryset);\n const limitImpl: QuerySet<TModel, TResult>['limit'] = overrides.limit ?? ((_n) => queryset);\n const offsetImpl: QuerySet<TModel, TResult>['offset'] = overrides.offset ?? ((_n) => queryset);\n const defaultSelect = ((_cols: readonly (keyof TModel)[]) => queryset) as unknown as QuerySet<\n TModel,\n TResult\n >['select'];\n const selectImpl = overrides.select ?? defaultSelect;\n const selectRelatedImpl: QuerySet<TModel, TResult>['selectRelated'] =\n overrides.selectRelated ?? ((..._rels) => queryset);\n const prefetchRelatedImpl: QuerySet<TModel, TResult>['prefetchRelated'] =\n overrides.prefetchRelated ?? ((..._rels) => queryset);\n const fetchImpl: QuerySet<TModel, TResult>['fetch'] =\n overrides.fetch ??\n (async <Out = TResult>(_shape?: ((r: TResult) => Out) | { parse: (r: TResult) => Out }) => aQueryResult<Out>());\n const fetchOneImpl: QuerySet<TModel, TResult>['fetchOne'] =\n overrides.fetchOne ??\n (async <Out = TResult>(_shape?: ((r: TResult) => Out) | { parse: (r: TResult) => Out }) => null as Out | null);\n const countImpl: QuerySet<TModel, TResult>['count'] = overrides.count ?? (async () => 0);\n const existsImpl: QuerySet<TModel, TResult>['exists'] = overrides.exists ?? (async () => false);\n\n queryset.filter = vi.fn((input: Parameters<QuerySet<TModel, TResult>['filter']>[0]) =>\n filterImpl(input)\n ) as QuerySet<TModel, TResult>['filter'];\n queryset.exclude = vi.fn((input: Parameters<QuerySet<TModel, TResult>['exclude']>[0]) =>\n excludeImpl(input)\n ) as QuerySet<TModel, TResult>['exclude'];\n queryset.orderBy = vi.fn((...tokens: Parameters<QuerySet<TModel, TResult>['orderBy']>) =>\n orderByImpl(...tokens)\n ) as QuerySet<TModel, TResult>['orderBy'];\n queryset.limit = vi.fn((n: number) => limitImpl(n)) as QuerySet<TModel, TResult>['limit'];\n queryset.offset = vi.fn((n: number) => offsetImpl(n)) as QuerySet<TModel, TResult>['offset'];\n queryset.select = vi.fn((cols: Parameters<QuerySet<TModel, TResult>['select']>[0]) =>\n selectImpl(cols)\n ) as unknown as QuerySet<TModel, TResult>['select'];\n queryset.selectRelated = vi.fn((...rels: Parameters<QuerySet<TModel, TResult>['selectRelated']>) =>\n selectRelatedImpl(...rels)\n ) as QuerySet<TModel, TResult>['selectRelated'];\n queryset.prefetchRelated = vi.fn((...rels: Parameters<QuerySet<TModel, TResult>['prefetchRelated']>) =>\n prefetchRelatedImpl(...rels)\n ) as QuerySet<TModel, TResult>['prefetchRelated'];\n queryset.fetch = vi.fn(fetchImpl) as unknown as QuerySet<TModel, TResult>['fetch'];\n queryset.fetchOne = vi.fn(fetchOneImpl) as unknown as QuerySet<TModel, TResult>['fetchOne'];\n queryset.count = vi.fn(() => countImpl()) as QuerySet<TModel, TResult>['count'];\n queryset.exists = vi.fn(() => existsImpl()) as QuerySet<TModel, TResult>['exists'];\n\n return queryset;\n}\n","import { vi } from 'vitest';\nimport type { ManagerLike, QuerySet } from '@danceroutine/tango-orm';\nimport type { TableMeta } from '@danceroutine/tango-orm/query';\nimport { aQuerySet } from './aQuerySet';\n\nexport type ManagerOverrides<TModel extends Record<string, unknown>> = {\n meta?: TableMeta;\n querySet?: QuerySet<TModel>;\n query?: ManagerLike<TModel>['query'];\n findById?: ManagerLike<TModel>['findById'];\n getOrThrow?: ManagerLike<TModel>['getOrThrow'];\n create?: ManagerLike<TModel>['create'];\n update?: ManagerLike<TModel>['update'];\n delete?: ManagerLike<TModel>['delete'];\n bulkCreate?: ManagerLike<TModel>['bulkCreate'];\n};\n\n/**\n * Create a manager-shaped test double for resource and service tests.\n */\nexport function aManager<TModel extends Record<string, unknown>>(\n overrides: ManagerOverrides<TModel> = {}\n): ManagerLike<TModel> {\n const meta = overrides.meta ?? { table: 'mock_table', pk: 'id', columns: {} };\n const querySet = overrides.querySet ?? aQuerySet<TModel>();\n type ModelId = TModel[keyof TModel];\n\n const queryImpl = overrides.query ?? (() => querySet);\n const findByIdImpl = overrides.findById ?? (async () => null as TModel | null);\n const getOrThrowImpl =\n overrides.getOrThrow ??\n (async (id: ModelId) => {\n const record = await findByIdImpl(id);\n if (!record) {\n throw new Error(`No ${meta.table} record found for ${String(meta.pk)}=${String(id)}.`);\n }\n return record;\n });\n const createImpl = overrides.create ?? (async (input: Partial<TModel>) => input as TModel);\n const updateImpl = overrides.update ?? (async (_id: ModelId, patch: Partial<TModel>) => patch as TModel);\n const deleteImpl = overrides.delete ?? (async (_id: ModelId) => {});\n const bulkCreateImpl = overrides.bulkCreate ?? (async (inputs: Partial<TModel>[]) => inputs as TModel[]);\n\n return {\n meta,\n query: vi.fn(() => queryImpl()),\n findById: vi.fn((id: ModelId) => findByIdImpl(id)),\n getOrThrow: vi.fn((id: ModelId) => getOrThrowImpl(id)),\n create: vi.fn((input: Partial<TModel>) => createImpl(input)),\n update: vi.fn((id: ModelId, patch: Partial<TModel>) => updateImpl(id, patch)),\n delete: vi.fn((id: ModelId) => deleteImpl(id)),\n bulkCreate: vi.fn((inputs: Partial<TModel>[]) => bulkCreateImpl(inputs)),\n };\n}\n","// Import through the package subpath so fixtures stay aligned with the public nominal type.\nimport { RequestContext, type BaseUser } from '@danceroutine/tango-resources/context';\n\ntype RequestContextFactory<TUser, TContext extends RequestContextLike<TUser>> = (\n request: Request,\n user: TUser | null\n) => TContext;\n\ntype RequestContextLike<TUser> = {\n request: Request;\n user: TUser | null;\n params: Record<string, string>;\n};\n\nexport type RequestContextFixtureOptions<\n TUser = BaseUser,\n TContext extends RequestContextLike<TUser> = RequestContext<TUser>,\n> = {\n method?: string;\n url?: string;\n body?: unknown;\n user?: TUser | null;\n params?: Record<string, string>;\n headers?: HeadersInit;\n contextFactory?: RequestContextFactory<TUser, TContext>;\n};\n\n/**\n * Create a RequestContext fixture with optional method/url/body/user/params.\n */\nexport function aRequestContext<TUser = BaseUser, TContext extends RequestContextLike<TUser> = RequestContext<TUser>>(\n method: string,\n url: string,\n body?: unknown\n): TContext;\nexport function aRequestContext<TUser = BaseUser, TContext extends RequestContextLike<TUser> = RequestContext<TUser>>(\n options?: RequestContextFixtureOptions<TUser, TContext>\n): TContext;\nexport function aRequestContext<TUser = BaseUser, TContext extends RequestContextLike<TUser> = RequestContext<TUser>>(\n optionsOrMethod: RequestContextFixtureOptions<TUser, TContext> | string = {},\n urlArg?: string,\n bodyArg?: unknown\n): TContext {\n const resolvedOptions: RequestContextFixtureOptions<TUser, TContext> =\n typeof optionsOrMethod === 'string'\n ? {\n method: optionsOrMethod,\n url: urlArg,\n body: bodyArg,\n }\n : optionsOrMethod;\n const {\n method = 'GET',\n url = 'https://example.test',\n body,\n user = null,\n params = {},\n headers,\n contextFactory,\n } = resolvedOptions;\n\n const resolvedHeaders: HeadersInit | undefined =\n body === undefined ? headers : { 'content-type': 'application/json', ...headers };\n\n const request = new Request(url, {\n method,\n headers: resolvedHeaders,\n body: body === undefined ? undefined : JSON.stringify(body),\n });\n const createContext =\n contextFactory ?? ((req: Request, currentUser: TUser | null) => RequestContext.create<TUser>(req, currentUser));\n const context = createContext(request, user) as TContext;\n context.params = params;\n return context;\n}\n","/**\n * Domain boundary barrel: centralizes this subdomain's public contract.\n */\n\nexport { aDBClient } from './aDBClient';\nexport { aManager } from './aManager';\nexport { aQueryResult } from './aQueryResult';\nexport { aQuerySet } from './aQuerySet';\nexport { aRequestContext } from './aRequestContext';\nexport { aQueryExecutor } from './aQueryExecutor';\nexport type { QueryExecutorOverrides } from './aQueryExecutor';\nexport type { ManagerOverrides } from './aManager';\nexport type { DBClient } from './DBClient';\nexport type { MockQuerySetResult } from './MockQuerySetResult';\nexport type { RequestContextFixtureOptions } from './aRequestContext';\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@danceroutine/tango-testing",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.3",
|
|
4
4
|
"description": "Testing utilities for Tango",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -52,11 +52,11 @@
|
|
|
52
52
|
"directory": "packages/testing"
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
|
-
"@danceroutine/tango-config": "1.1.
|
|
56
|
-
"@danceroutine/tango-
|
|
57
|
-
"@danceroutine/tango-
|
|
58
|
-
"@danceroutine/tango-
|
|
59
|
-
"@danceroutine/tango-
|
|
55
|
+
"@danceroutine/tango-config": "1.1.3",
|
|
56
|
+
"@danceroutine/tango-migrations": "1.1.3",
|
|
57
|
+
"@danceroutine/tango-core": "1.1.3",
|
|
58
|
+
"@danceroutine/tango-resources": "1.1.3",
|
|
59
|
+
"@danceroutine/tango-orm": "1.1.3"
|
|
60
60
|
},
|
|
61
61
|
"peerDependencies": {
|
|
62
62
|
"@types/express": "^5.0.0",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mocks-BkwkXQQt.js","names":["overrides: Partial<QueryResult<TModel>>","overrides: QueryExecutorOverrides<TModel>","meta: TableMeta","overrides: Partial<QuerySet<TModel>>","filterImpl: QuerySet<TModel>['filter']","excludeImpl: QuerySet<TModel>['exclude']","orderByImpl: QuerySet<TModel>['orderBy']","limitImpl: QuerySet<TModel>['limit']","offsetImpl: QuerySet<TModel>['offset']","selectImpl: QuerySet<TModel>['select']","selectRelatedImpl: QuerySet<TModel>['selectRelated']","prefetchRelatedImpl: QuerySet<TModel>['prefetchRelated']","fetchImpl: QuerySet<TModel>['fetch']","_shape?: ((r: TModel) => Out) | { parse: (r: TModel) => Out }","fetchOneImpl: QuerySet<TModel>['fetchOne']","countImpl: QuerySet<TModel>['count']","existsImpl: QuerySet<TModel>['exists']","input: Parameters<QuerySet<TModel>['filter']>[0]","input: Parameters<QuerySet<TModel>['exclude']>[0]","n: number","cols: Parameters<QuerySet<TModel>['select']>[0]","overrides: ManagerOverrides<TModel>","id: ModelId","input: Partial<TModel>","_id: ModelId","patch: Partial<TModel>","inputs: Partial<TModel>[]","optionsOrMethod: RequestContextFixtureOptions<TUser, TContext> | string","urlArg?: string","bodyArg?: unknown","resolvedOptions: RequestContextFixtureOptions<TUser, TContext>","resolvedHeaders: HeadersInit | undefined","req: Request","currentUser: TUser | null"],"sources":["../src/mocks/aQueryResult.ts","../src/mocks/aQueryExecutor.ts","../src/mocks/aQuerySet.ts","../src/mocks/aManager.ts","../src/mocks/aRequestContext.ts","../src/mocks/index.ts"],"sourcesContent":["import type { QueryResult } from '@danceroutine/tango-orm/query';\n\n/**\n * Create a query-result test value with optional overrides.\n */\nexport function aQueryResult<TModel>(overrides: Partial<QueryResult<TModel>> = {}): QueryResult<TModel> {\n return {\n results: [] as TModel[],\n nextCursor: null,\n ...overrides,\n };\n}\n","import { vi } from 'vitest';\nimport type { QueryExecutor } from '@danceroutine/tango-orm';\nimport type { Dialect, TableMeta } from '@danceroutine/tango-orm/query';\nimport { aDBClient } from './aDBClient';\n\nexport type QueryExecutorOverrides<TModel extends Record<string, unknown>> = {\n dialect?: Dialect;\n meta?: TableMeta;\n query?: (sql: string, params?: readonly unknown[]) => Promise<{ rows: unknown[] }>;\n run?: QueryExecutor<TModel>['run'];\n};\n\n/**\n * Create a minimal `QueryExecutor` test double for `QuerySet` tests.\n */\nexport function aQueryExecutor<TModel extends Record<string, unknown>>(\n overrides: QueryExecutorOverrides<TModel> = {}\n): QueryExecutor<TModel> {\n const dialect = overrides.dialect ?? 'postgres';\n const meta: TableMeta = overrides.meta ?? { table: 'mock_table', pk: 'id', columns: {} };\n const run = overrides.run ?? vi.fn(async () => [] as TModel[]);\n const client = aDBClient(overrides.query ? { query: overrides.query } : {});\n\n return { meta, client, dialect, run };\n}\n","import { vi } from 'vitest';\nimport type { QuerySet } from '@danceroutine/tango-orm';\nimport { QuerySet as QuerySetClass } from '@danceroutine/tango-orm';\nimport { aQueryResult } from './aQueryResult';\nimport { aQueryExecutor } from './aQueryExecutor';\n\n/**\n * Create a chainable query-set test double with optional behavior overrides.\n *\n * All methods are wrapped in `vi.fn()` so they can be asserted on directly\n * without an additional `vi.mocked()` call.\n */\nexport function aQuerySet<TModel extends Record<string, unknown>>(\n overrides: Partial<QuerySet<TModel>> = {}\n): QuerySet<TModel> {\n const queryset = new QuerySetClass<TModel>(aQueryExecutor<TModel>());\n const filterImpl: QuerySet<TModel>['filter'] = overrides.filter ?? ((_input) => queryset);\n const excludeImpl: QuerySet<TModel>['exclude'] = overrides.exclude ?? ((_input) => queryset);\n const orderByImpl: QuerySet<TModel>['orderBy'] = overrides.orderBy ?? ((..._tokens) => queryset);\n const limitImpl: QuerySet<TModel>['limit'] = overrides.limit ?? ((_n) => queryset);\n const offsetImpl: QuerySet<TModel>['offset'] = overrides.offset ?? ((_n) => queryset);\n const selectImpl: QuerySet<TModel>['select'] = overrides.select ?? ((_cols) => queryset);\n const selectRelatedImpl: QuerySet<TModel>['selectRelated'] = overrides.selectRelated ?? ((..._rels) => queryset);\n const prefetchRelatedImpl: QuerySet<TModel>['prefetchRelated'] =\n overrides.prefetchRelated ?? ((..._rels) => queryset);\n const fetchImpl: QuerySet<TModel>['fetch'] =\n overrides.fetch ??\n (async <Out = TModel>(_shape?: ((r: TModel) => Out) | { parse: (r: TModel) => Out }) => aQueryResult<Out>());\n const fetchOneImpl: QuerySet<TModel>['fetchOne'] =\n overrides.fetchOne ??\n (async <Out = TModel>(_shape?: ((r: TModel) => Out) | { parse: (r: TModel) => Out }) => null as Out | null);\n const countImpl: QuerySet<TModel>['count'] = overrides.count ?? (async () => 0);\n const existsImpl: QuerySet<TModel>['exists'] = overrides.exists ?? (async () => false);\n\n queryset.filter = vi.fn((input: Parameters<QuerySet<TModel>['filter']>[0]) =>\n filterImpl(input)\n ) as QuerySet<TModel>['filter'];\n queryset.exclude = vi.fn((input: Parameters<QuerySet<TModel>['exclude']>[0]) =>\n excludeImpl(input)\n ) as QuerySet<TModel>['exclude'];\n queryset.orderBy = vi.fn((...tokens: Parameters<QuerySet<TModel>['orderBy']>) =>\n orderByImpl(...tokens)\n ) as QuerySet<TModel>['orderBy'];\n queryset.limit = vi.fn((n: number) => limitImpl(n)) as QuerySet<TModel>['limit'];\n queryset.offset = vi.fn((n: number) => offsetImpl(n)) as QuerySet<TModel>['offset'];\n queryset.select = vi.fn((cols: Parameters<QuerySet<TModel>['select']>[0]) =>\n selectImpl(cols)\n ) as QuerySet<TModel>['select'];\n queryset.selectRelated = vi.fn((...rels: Parameters<QuerySet<TModel>['selectRelated']>) =>\n selectRelatedImpl(...rels)\n ) as QuerySet<TModel>['selectRelated'];\n queryset.prefetchRelated = vi.fn((...rels: Parameters<QuerySet<TModel>['prefetchRelated']>) =>\n prefetchRelatedImpl(...rels)\n ) as QuerySet<TModel>['prefetchRelated'];\n queryset.fetch = vi.fn(fetchImpl) as QuerySet<TModel>['fetch'];\n queryset.fetchOne = vi.fn(fetchOneImpl) as QuerySet<TModel>['fetchOne'];\n queryset.count = vi.fn(() => countImpl()) as QuerySet<TModel>['count'];\n queryset.exists = vi.fn(() => existsImpl()) as QuerySet<TModel>['exists'];\n\n return queryset;\n}\n","import { vi } from 'vitest';\nimport type { ManagerLike, QuerySet } from '@danceroutine/tango-orm';\nimport type { TableMeta } from '@danceroutine/tango-orm/query';\nimport { aQuerySet } from './aQuerySet';\n\nexport type ManagerOverrides<TModel extends Record<string, unknown>> = {\n meta?: TableMeta;\n querySet?: QuerySet<TModel>;\n query?: ManagerLike<TModel>['query'];\n findById?: ManagerLike<TModel>['findById'];\n getOrThrow?: ManagerLike<TModel>['getOrThrow'];\n create?: ManagerLike<TModel>['create'];\n update?: ManagerLike<TModel>['update'];\n delete?: ManagerLike<TModel>['delete'];\n bulkCreate?: ManagerLike<TModel>['bulkCreate'];\n};\n\n/**\n * Create a manager-shaped test double for resource and service tests.\n */\nexport function aManager<TModel extends Record<string, unknown>>(\n overrides: ManagerOverrides<TModel> = {}\n): ManagerLike<TModel> {\n const meta = overrides.meta ?? { table: 'mock_table', pk: 'id', columns: {} };\n const querySet = overrides.querySet ?? aQuerySet<TModel>();\n type ModelId = TModel[keyof TModel];\n\n const queryImpl = overrides.query ?? (() => querySet);\n const findByIdImpl = overrides.findById ?? (async () => null as TModel | null);\n const getOrThrowImpl =\n overrides.getOrThrow ??\n (async (id: ModelId) => {\n const record = await findByIdImpl(id);\n if (!record) {\n throw new Error(`No ${meta.table} record found for ${String(meta.pk)}=${String(id)}.`);\n }\n return record;\n });\n const createImpl = overrides.create ?? (async (input: Partial<TModel>) => input as TModel);\n const updateImpl = overrides.update ?? (async (_id: ModelId, patch: Partial<TModel>) => patch as TModel);\n const deleteImpl = overrides.delete ?? (async (_id: ModelId) => {});\n const bulkCreateImpl = overrides.bulkCreate ?? (async (inputs: Partial<TModel>[]) => inputs as TModel[]);\n\n return {\n meta,\n query: vi.fn(() => queryImpl()),\n findById: vi.fn((id: ModelId) => findByIdImpl(id)),\n getOrThrow: vi.fn((id: ModelId) => getOrThrowImpl(id)),\n create: vi.fn((input: Partial<TModel>) => createImpl(input)),\n update: vi.fn((id: ModelId, patch: Partial<TModel>) => updateImpl(id, patch)),\n delete: vi.fn((id: ModelId) => deleteImpl(id)),\n bulkCreate: vi.fn((inputs: Partial<TModel>[]) => bulkCreateImpl(inputs)),\n };\n}\n","// Import through the package subpath so fixtures stay aligned with the public nominal type.\nimport { RequestContext, type BaseUser } from '@danceroutine/tango-resources/context';\n\ntype RequestContextFactory<TUser, TContext extends RequestContextLike<TUser>> = (\n request: Request,\n user: TUser | null\n) => TContext;\n\ntype RequestContextLike<TUser> = {\n request: Request;\n user: TUser | null;\n params: Record<string, string>;\n};\n\nexport type RequestContextFixtureOptions<\n TUser = BaseUser,\n TContext extends RequestContextLike<TUser> = RequestContext<TUser>,\n> = {\n method?: string;\n url?: string;\n body?: unknown;\n user?: TUser | null;\n params?: Record<string, string>;\n headers?: HeadersInit;\n contextFactory?: RequestContextFactory<TUser, TContext>;\n};\n\n/**\n * Create a RequestContext fixture with optional method/url/body/user/params.\n */\nexport function aRequestContext<TUser = BaseUser, TContext extends RequestContextLike<TUser> = RequestContext<TUser>>(\n method: string,\n url: string,\n body?: unknown\n): TContext;\nexport function aRequestContext<TUser = BaseUser, TContext extends RequestContextLike<TUser> = RequestContext<TUser>>(\n options?: RequestContextFixtureOptions<TUser, TContext>\n): TContext;\nexport function aRequestContext<TUser = BaseUser, TContext extends RequestContextLike<TUser> = RequestContext<TUser>>(\n optionsOrMethod: RequestContextFixtureOptions<TUser, TContext> | string = {},\n urlArg?: string,\n bodyArg?: unknown\n): TContext {\n const resolvedOptions: RequestContextFixtureOptions<TUser, TContext> =\n typeof optionsOrMethod === 'string'\n ? {\n method: optionsOrMethod,\n url: urlArg,\n body: bodyArg,\n }\n : optionsOrMethod;\n const {\n method = 'GET',\n url = 'https://example.test',\n body,\n user = null,\n params = {},\n headers,\n contextFactory,\n } = resolvedOptions;\n\n const resolvedHeaders: HeadersInit | undefined =\n body === undefined ? headers : { 'content-type': 'application/json', ...headers };\n\n const request = new Request(url, {\n method,\n headers: resolvedHeaders,\n body: body === undefined ? undefined : JSON.stringify(body),\n });\n const createContext =\n contextFactory ?? ((req: Request, currentUser: TUser | null) => RequestContext.create<TUser>(req, currentUser));\n const context = createContext(request, user) as TContext;\n context.params = params;\n return context;\n}\n","/**\n * Domain boundary barrel: centralizes this subdomain's public contract.\n */\n\nexport { aDBClient } from './aDBClient';\nexport { aManager } from './aManager';\nexport { aQueryResult } from './aQueryResult';\nexport { aQuerySet } from './aQuerySet';\nexport { aRequestContext } from './aRequestContext';\nexport { aQueryExecutor } from './aQueryExecutor';\nexport type { QueryExecutorOverrides } from './aQueryExecutor';\nexport type { ManagerOverrides } from './aManager';\nexport type { DBClient } from './DBClient';\nexport type { MockQuerySetResult } from './MockQuerySetResult';\nexport type { RequestContextFixtureOptions } from './aRequestContext';\n"],"mappings":"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"}
|