@xivdyetools/test-utils 1.0.1 → 1.0.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/auth/jwt.d.ts.map +1 -1
- package/dist/auth/jwt.js +3 -2
- package/dist/auth/jwt.js.map +1 -1
- package/dist/cloudflare/d1.d.ts +66 -22
- package/dist/cloudflare/d1.d.ts.map +1 -1
- package/dist/cloudflare/d1.js +71 -5
- package/dist/cloudflare/d1.js.map +1 -1
- package/dist/factories/index.d.ts +2 -2
- package/dist/factories/index.d.ts.map +1 -1
- package/dist/factories/index.js +4 -3
- package/dist/factories/index.js.map +1 -1
- package/dist/factories/vote.d.ts +4 -1
- package/dist/factories/vote.d.ts.map +1 -1
- package/dist/factories/vote.js +6 -4
- package/dist/factories/vote.js.map +1 -1
- package/dist/utils/counters.d.ts +30 -6
- package/dist/utils/counters.d.ts.map +1 -1
- package/dist/utils/counters.js +50 -8
- package/dist/utils/counters.js.map +1 -1
- package/package.json +5 -5
package/dist/auth/jwt.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["../../src/auth/jwt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAIH;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,wBAAwB;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,eAAe;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,8BAA8B;IAC9B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,6BAA6B;IAC7B,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,cAAe,SAAQ,cAAc;IACpD,iCAAiC;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,kCAAkC;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,aAAa;IACb,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,cAAc,EACvB,gBAAgB,SAAO,EACvB,MAAM,SAA6B,GAClC,OAAO,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["../../src/auth/jwt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAIH;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,wBAAwB;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,eAAe;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,8BAA8B;IAC9B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,6BAA6B;IAC7B,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,cAAe,SAAQ,cAAc;IACpD,iCAAiC;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,kCAAkC;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,aAAa;IACb,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,cAAc,EACvB,gBAAgB,SAAO,EACvB,MAAM,SAA6B,GAClC,OAAO,CAAC,MAAM,CAAC,CAgCjB;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,cAAiD,GACzD,OAAO,CAAC,MAAM,CAAC,CAGjB;AAED;;;;;;;GAOG;AACH,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,cAAc,EACvB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,CAAC,CAIjB"}
|
package/dist/auth/jwt.js
CHANGED
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
* });
|
|
23
23
|
* ```
|
|
24
24
|
*/
|
|
25
|
-
import { base64UrlEncode } from '../utils/crypto.js';
|
|
25
|
+
import { base64UrlEncode, base64UrlEncodeBytes } from '../utils/crypto.js';
|
|
26
26
|
/**
|
|
27
27
|
* Creates a valid JWT for testing
|
|
28
28
|
*
|
|
@@ -47,7 +47,8 @@ export async function createTestJWT(secret, payload, expiresInSeconds = 3600, is
|
|
|
47
47
|
const signatureInput = `${encodedHeader}.${encodedPayload}`;
|
|
48
48
|
const key = await crypto.subtle.importKey('raw', encoder.encode(secret), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);
|
|
49
49
|
const signature = await crypto.subtle.sign('HMAC', key, encoder.encode(signatureInput));
|
|
50
|
-
|
|
50
|
+
// Use base64UrlEncodeBytes for binary signature data to avoid UTF-8 encoding issues
|
|
51
|
+
const encodedSignature = base64UrlEncodeBytes(new Uint8Array(signature));
|
|
51
52
|
return `${encodedHeader}.${encodedPayload}.${encodedSignature}`;
|
|
52
53
|
}
|
|
53
54
|
/**
|
package/dist/auth/jwt.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jwt.js","sourceRoot":"","sources":["../../src/auth/jwt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"jwt.js","sourceRoot":"","sources":["../../src/auth/jwt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AA4B3E;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAAc,EACd,OAAuB,EACvB,gBAAgB,GAAG,IAAI,EACvB,MAAM,GAAG,0BAA0B;IAEnC,MAAM,MAAM,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;IAC5C,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IAE1C,MAAM,WAAW,GAAmB;QAClC,GAAG,OAAO;QACV,GAAG,EAAE,GAAG;QACR,GAAG,EAAE,GAAG,GAAG,gBAAgB;QAC3B,GAAG,EAAE,MAAM;KACZ,CAAC;IAEF,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;IAElC,MAAM,aAAa,GAAG,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IAC9D,MAAM,cAAc,GAAG,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC;IAEpE,MAAM,cAAc,GAAG,GAAG,aAAa,IAAI,cAAc,EAAE,CAAC;IAE5D,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CACvC,KAAK,EACL,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EACtB,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,EACjC,KAAK,EACL,CAAC,MAAM,CAAC,CACT,CAAC;IAEF,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC;IAExF,oFAAoF;IACpF,MAAM,gBAAgB,GAAG,oBAAoB,CAAC,IAAI,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC;IAEzE,OAAO,GAAG,aAAa,IAAI,cAAc,IAAI,gBAAgB,EAAE,CAAC;AAClE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,MAAc,EACd,UAA0B,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE;IAE1D,uCAAuC;IACvC,OAAO,aAAa,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC;AAC/C,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,MAAc,EACd,OAAuB,EACvB,YAAoB;IAEpB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IAC1C,MAAM,gBAAgB,GAAG,YAAY,GAAG,GAAG,CAAC;IAC5C,OAAO,aAAa,CAAC,MAAM,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;AAC1D,CAAC"}
|
package/dist/cloudflare/d1.d.ts
CHANGED
|
@@ -8,11 +8,15 @@
|
|
|
8
8
|
* ```typescript
|
|
9
9
|
* const db = createMockD1Database();
|
|
10
10
|
*
|
|
11
|
-
* // Setup mock responses
|
|
11
|
+
* // Setup mock responses using regex patterns (TEST-DESIGN-002)
|
|
12
|
+
* // Use /^\s*SELECT/i to anchor to start and be case-insensitive
|
|
12
13
|
* db._setupMock((query, bindings) => {
|
|
13
|
-
* if (
|
|
14
|
+
* if (/^\s*SELECT/i.test(query) && query.includes('presets')) {
|
|
14
15
|
* return [{ id: 'preset-1', name: 'Test Preset' }];
|
|
15
16
|
* }
|
|
17
|
+
* if (/^\s*INSERT/i.test(query)) {
|
|
18
|
+
* return { meta: { changes: 1, last_row_id: 1 } };
|
|
19
|
+
* }
|
|
16
20
|
* return null;
|
|
17
21
|
* });
|
|
18
22
|
*
|
|
@@ -34,26 +38,26 @@ export type QueryMockFn = (query: string, bindings: unknown[]) => unknown;
|
|
|
34
38
|
/**
|
|
35
39
|
* Mock D1 prepared statement interface
|
|
36
40
|
*/
|
|
41
|
+
/**
|
|
42
|
+
* D1 result type - matches Cloudflare's D1Result<T>
|
|
43
|
+
*/
|
|
44
|
+
export interface D1Result<T = unknown> {
|
|
45
|
+
results: T[];
|
|
46
|
+
success: true;
|
|
47
|
+
meta: D1Meta;
|
|
48
|
+
}
|
|
37
49
|
export interface MockD1PreparedStatement {
|
|
38
50
|
bind: (...values: unknown[]) => MockD1PreparedStatement;
|
|
39
51
|
first: <T = unknown>() => Promise<T | null>;
|
|
40
|
-
all: <T = unknown>() => Promise<
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}>;
|
|
45
|
-
run: () => Promise<{
|
|
46
|
-
success: boolean;
|
|
47
|
-
meta: {
|
|
48
|
-
changes: number;
|
|
49
|
-
duration: number;
|
|
50
|
-
last_row_id: number;
|
|
51
|
-
};
|
|
52
|
-
}>;
|
|
53
|
-
raw: <T = unknown[]>() => Promise<T[]>;
|
|
52
|
+
all: <T = unknown>() => Promise<D1Result<T>>;
|
|
53
|
+
run: <T = unknown>() => Promise<D1Result<T>>;
|
|
54
|
+
raw: <T = unknown[]>(options?: {
|
|
55
|
+
columnNames?: boolean;
|
|
56
|
+
}) => Promise<T>;
|
|
54
57
|
}
|
|
55
58
|
/**
|
|
56
|
-
* D1 result metadata
|
|
59
|
+
* D1 result metadata - matches Cloudflare's D1Meta type
|
|
60
|
+
* Includes index signature to match Record<string, unknown> requirement
|
|
57
61
|
*/
|
|
58
62
|
interface D1Meta {
|
|
59
63
|
duration: number;
|
|
@@ -61,22 +65,37 @@ interface D1Meta {
|
|
|
61
65
|
last_row_id: number;
|
|
62
66
|
rows_read: number;
|
|
63
67
|
rows_written: number;
|
|
68
|
+
size_after: number;
|
|
69
|
+
changed_db: boolean;
|
|
70
|
+
[key: string]: unknown;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Mock D1 database session (returned by withSession)
|
|
74
|
+
* Mimics D1DatabaseSession which has similar methods to D1Database
|
|
75
|
+
*/
|
|
76
|
+
export interface MockD1DatabaseSession {
|
|
77
|
+
prepare: (query: string) => MockD1PreparedStatement;
|
|
78
|
+
batch: <T = unknown>(statements: MockD1PreparedStatement[]) => Promise<D1Result<T>[]>;
|
|
79
|
+
exec: (query: string) => Promise<{
|
|
80
|
+
count: number;
|
|
81
|
+
duration: number;
|
|
82
|
+
}>;
|
|
83
|
+
/** Get constraint string for this session */
|
|
84
|
+
getBookmark: () => string;
|
|
64
85
|
}
|
|
65
86
|
/**
|
|
66
87
|
* Extended mock D1 database with test helpers
|
|
67
88
|
*/
|
|
68
89
|
export interface MockD1Database {
|
|
69
90
|
prepare: (query: string) => MockD1PreparedStatement;
|
|
70
|
-
batch: <T = unknown>(statements: MockD1PreparedStatement[]) => Promise<
|
|
71
|
-
results: T[];
|
|
72
|
-
success: boolean;
|
|
73
|
-
meta: D1Meta;
|
|
74
|
-
}>>;
|
|
91
|
+
batch: <T = unknown>(statements: MockD1PreparedStatement[]) => Promise<D1Result<T>[]>;
|
|
75
92
|
exec: (query: string) => Promise<{
|
|
76
93
|
count: number;
|
|
77
94
|
duration: number;
|
|
78
95
|
}>;
|
|
79
96
|
dump: () => Promise<ArrayBuffer>;
|
|
97
|
+
/** Start a session - returns a session object with same query methods */
|
|
98
|
+
withSession: (constraintOrBookmark?: string) => MockD1DatabaseSession;
|
|
80
99
|
/** Array of all queries executed (for assertions) */
|
|
81
100
|
_queries: string[];
|
|
82
101
|
/** Array of all binding arrays passed to queries */
|
|
@@ -87,6 +106,11 @@ export interface MockD1Database {
|
|
|
87
106
|
_reset: () => void;
|
|
88
107
|
/** Current mock function (if any) */
|
|
89
108
|
_mockFn?: QueryMockFn;
|
|
109
|
+
/**
|
|
110
|
+
* Set the ban status for ban-check middleware tests
|
|
111
|
+
* @param isBanned - true to simulate banned user, false or undefined for not banned
|
|
112
|
+
*/
|
|
113
|
+
_setBanStatus: (isBanned: boolean) => void;
|
|
90
114
|
}
|
|
91
115
|
/**
|
|
92
116
|
* Creates a mock D1 database for testing
|
|
@@ -97,5 +121,25 @@ export interface MockD1Database {
|
|
|
97
121
|
* @returns A mock D1 database that can be cast to D1Database
|
|
98
122
|
*/
|
|
99
123
|
export declare function createMockD1Database(): MockD1Database;
|
|
124
|
+
/**
|
|
125
|
+
* Creates a mock D1 database pre-cast as D1Database
|
|
126
|
+
*
|
|
127
|
+
* Use this when you need to pass the mock to code expecting D1Database.
|
|
128
|
+
* The mock still supports all testing helpers via type assertion:
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* ```typescript
|
|
132
|
+
* const db = createMockD1();
|
|
133
|
+
* // Use as D1Database
|
|
134
|
+
* someFunction(db);
|
|
135
|
+
*
|
|
136
|
+
* // Access testing helpers via assertion
|
|
137
|
+
* (db as unknown as MockD1Database)._queries;
|
|
138
|
+
* (db as unknown as MockD1Database)._setupMock(...);
|
|
139
|
+
* ```
|
|
140
|
+
*
|
|
141
|
+
* @returns A D1Database-typed mock
|
|
142
|
+
*/
|
|
143
|
+
export declare function createMockD1(): D1Database;
|
|
100
144
|
export {};
|
|
101
145
|
//# sourceMappingURL=d1.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"d1.d.ts","sourceRoot":"","sources":["../../src/cloudflare/d1.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"d1.d.ts","sourceRoot":"","sources":["../../src/cloudflare/d1.ts"],"names":[],"mappings":"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"}
|
package/dist/cloudflare/d1.js
CHANGED
|
@@ -8,11 +8,15 @@
|
|
|
8
8
|
* ```typescript
|
|
9
9
|
* const db = createMockD1Database();
|
|
10
10
|
*
|
|
11
|
-
* // Setup mock responses
|
|
11
|
+
* // Setup mock responses using regex patterns (TEST-DESIGN-002)
|
|
12
|
+
* // Use /^\s*SELECT/i to anchor to start and be case-insensitive
|
|
12
13
|
* db._setupMock((query, bindings) => {
|
|
13
|
-
* if (
|
|
14
|
+
* if (/^\s*SELECT/i.test(query) && query.includes('presets')) {
|
|
14
15
|
* return [{ id: 'preset-1', name: 'Test Preset' }];
|
|
15
16
|
* }
|
|
17
|
+
* if (/^\s*INSERT/i.test(query)) {
|
|
18
|
+
* return { meta: { changes: 1, last_row_id: 1 } };
|
|
19
|
+
* }
|
|
16
20
|
* return null;
|
|
17
21
|
* });
|
|
18
22
|
*
|
|
@@ -39,12 +43,15 @@ export function createMockD1Database() {
|
|
|
39
43
|
const queries = [];
|
|
40
44
|
const bindings = [];
|
|
41
45
|
let mockFn;
|
|
46
|
+
let banStatus;
|
|
42
47
|
const createDefaultMeta = () => ({
|
|
43
48
|
duration: 0,
|
|
44
49
|
changes: 0,
|
|
45
50
|
last_row_id: 0,
|
|
46
51
|
rows_read: 0,
|
|
47
52
|
rows_written: 0,
|
|
53
|
+
size_after: 0,
|
|
54
|
+
changed_db: false,
|
|
48
55
|
});
|
|
49
56
|
const createStatement = (query) => {
|
|
50
57
|
let boundValues = [];
|
|
@@ -56,6 +63,15 @@ export function createMockD1Database() {
|
|
|
56
63
|
},
|
|
57
64
|
first: async () => {
|
|
58
65
|
queries.push(query);
|
|
66
|
+
// Special handling for banned_users queries to prevent false ban detection
|
|
67
|
+
// Use _setBanStatus(true) to simulate a banned user in tests
|
|
68
|
+
if (query.includes('banned_users')) {
|
|
69
|
+
if (banStatus === true) {
|
|
70
|
+
return { 1: 1 }; // User is banned
|
|
71
|
+
}
|
|
72
|
+
// Default: user not banned (don't call mockFn to avoid side effects)
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
59
75
|
if (mockFn) {
|
|
60
76
|
const result = mockFn(query, boundValues);
|
|
61
77
|
// If result is an array, return first element
|
|
@@ -89,11 +105,12 @@ export function createMockD1Database() {
|
|
|
89
105
|
}
|
|
90
106
|
}
|
|
91
107
|
return {
|
|
108
|
+
results: [],
|
|
92
109
|
success: true,
|
|
93
|
-
meta: { changes: 1,
|
|
110
|
+
meta: { ...createDefaultMeta(), changes: 1, rows_written: 1, last_row_id: 1, changed_db: true },
|
|
94
111
|
};
|
|
95
112
|
},
|
|
96
|
-
raw: async () => {
|
|
113
|
+
raw: async (_options) => {
|
|
97
114
|
queries.push(query);
|
|
98
115
|
if (mockFn) {
|
|
99
116
|
const result = mockFn(query, boundValues);
|
|
@@ -112,7 +129,8 @@ export function createMockD1Database() {
|
|
|
112
129
|
};
|
|
113
130
|
return statement;
|
|
114
131
|
};
|
|
115
|
-
|
|
132
|
+
// Create the mock database object
|
|
133
|
+
const mockDb = {
|
|
116
134
|
prepare: createStatement,
|
|
117
135
|
batch: async (statements) => {
|
|
118
136
|
const results = [];
|
|
@@ -130,6 +148,27 @@ export function createMockD1Database() {
|
|
|
130
148
|
dump: async () => {
|
|
131
149
|
return new ArrayBuffer(0);
|
|
132
150
|
},
|
|
151
|
+
// withSession returns a session object with the same query methods
|
|
152
|
+
// In real D1, this creates a transaction-like session for consistency
|
|
153
|
+
withSession: (constraintOrBookmark) => {
|
|
154
|
+
// Return a session object that shares the same query tracking
|
|
155
|
+
return {
|
|
156
|
+
prepare: createStatement,
|
|
157
|
+
batch: async (statements) => {
|
|
158
|
+
const results = [];
|
|
159
|
+
for (const stmt of statements) {
|
|
160
|
+
await stmt.run();
|
|
161
|
+
results.push({ results: [], success: true, meta: createDefaultMeta() });
|
|
162
|
+
}
|
|
163
|
+
return results;
|
|
164
|
+
},
|
|
165
|
+
exec: async (query) => {
|
|
166
|
+
queries.push(query);
|
|
167
|
+
return { count: 1, duration: 0 };
|
|
168
|
+
},
|
|
169
|
+
getBookmark: () => constraintOrBookmark ?? 'mock-bookmark',
|
|
170
|
+
};
|
|
171
|
+
},
|
|
133
172
|
_queries: queries,
|
|
134
173
|
_bindings: bindings,
|
|
135
174
|
_setupMock: (fn) => {
|
|
@@ -139,10 +178,37 @@ export function createMockD1Database() {
|
|
|
139
178
|
queries.length = 0;
|
|
140
179
|
bindings.length = 0;
|
|
141
180
|
mockFn = undefined;
|
|
181
|
+
banStatus = undefined;
|
|
142
182
|
},
|
|
143
183
|
get _mockFn() {
|
|
144
184
|
return mockFn;
|
|
145
185
|
},
|
|
186
|
+
_setBanStatus: (isBanned) => {
|
|
187
|
+
banStatus = isBanned;
|
|
188
|
+
},
|
|
146
189
|
};
|
|
190
|
+
return mockDb;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Creates a mock D1 database pre-cast as D1Database
|
|
194
|
+
*
|
|
195
|
+
* Use this when you need to pass the mock to code expecting D1Database.
|
|
196
|
+
* The mock still supports all testing helpers via type assertion:
|
|
197
|
+
*
|
|
198
|
+
* @example
|
|
199
|
+
* ```typescript
|
|
200
|
+
* const db = createMockD1();
|
|
201
|
+
* // Use as D1Database
|
|
202
|
+
* someFunction(db);
|
|
203
|
+
*
|
|
204
|
+
* // Access testing helpers via assertion
|
|
205
|
+
* (db as unknown as MockD1Database)._queries;
|
|
206
|
+
* (db as unknown as MockD1Database)._setupMock(...);
|
|
207
|
+
* ```
|
|
208
|
+
*
|
|
209
|
+
* @returns A D1Database-typed mock
|
|
210
|
+
*/
|
|
211
|
+
export function createMockD1() {
|
|
212
|
+
return createMockD1Database();
|
|
147
213
|
}
|
|
148
214
|
//# sourceMappingURL=d1.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"d1.js","sourceRoot":"","sources":["../../src/cloudflare/d1.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"d1.js","sourceRoot":"","sources":["../../src/cloudflare/d1.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAyFH;;;;;;;GAOG;AACH,MAAM,UAAU,oBAAoB;IAClC,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,QAAQ,GAAgB,EAAE,CAAC;IACjC,IAAI,MAA+B,CAAC;IACpC,IAAI,SAA8B,CAAC;IAEnC,MAAM,iBAAiB,GAAG,GAAW,EAAE,CAAC,CAAC;QACvC,QAAQ,EAAE,CAAC;QACX,OAAO,EAAE,CAAC;QACV,WAAW,EAAE,CAAC;QACd,SAAS,EAAE,CAAC;QACZ,YAAY,EAAE,CAAC;QACf,UAAU,EAAE,CAAC;QACb,UAAU,EAAE,KAAK;KAClB,CAAC,CAAC;IAEH,MAAM,eAAe,GAAG,CAAC,KAAa,EAA2B,EAAE;QACjE,IAAI,WAAW,GAAc,EAAE,CAAC;QAEhC,MAAM,SAAS,GAA4B;YACzC,IAAI,EAAE,CAAC,GAAG,MAAiB,EAAE,EAAE;gBAC7B,WAAW,GAAG,MAAM,CAAC;gBACrB,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBACtB,OAAO,SAAS,CAAC;YACnB,CAAC;YAED,KAAK,EAAE,KAAK,IAAiB,EAAE;gBAC7B,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBACpB,2EAA2E;gBAC3E,6DAA6D;gBAC7D,IAAI,KAAK,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;oBACnC,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;wBACvB,OAAO,EAAE,CAAC,EAAE,CAAC,EAAO,CAAC,CAAC,iBAAiB;oBACzC,CAAC;oBACD,qEAAqE;oBACrE,OAAO,IAAI,CAAC;gBACd,CAAC;gBACD,IAAI,MAAM,EAAE,CAAC;oBACX,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;oBAC1C,8CAA8C;oBAC9C,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;wBAC1B,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,CAAa,CAAC;oBACzC,CAAC;oBACD,OAAO,MAAkB,CAAC;gBAC5B,CAAC;gBACD,OAAO,IAAI,CAAC;YACd,CAAC;YAED,GAAG,EAAE,KAAK,IAAuC,EAAE;gBACjD,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBACpB,IAAI,MAAM,EAAE,CAAC;oBACX,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;oBAC1C,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;wBAC1B,OAAO,EAAE,OAAO,EAAE,MAAa,EAAE,OAAO,EAAE,IAAa,EAAE,IAAI,EAAE,iBAAiB,EAAE,EAAE,CAAC;oBACvF,CAAC;oBACD,2CAA2C;oBAC3C,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;wBACzC,OAAO,EAAE,OAAO,EAAE,CAAC,MAAM,CAAQ,EAAE,OAAO,EAAE,IAAa,EAAE,IAAI,EAAE,iBAAiB,EAAE,EAAE,CAAC;oBACzF,CAAC;gBACH,CAAC;gBACD,OAAO,EAAE,OAAO,EAAE,EAAS,EAAE,OAAO,EAAE,IAAa,EAAE,IAAI,EAAE,iBAAiB,EAAE,EAAE,CAAC;YACnF,CAAC;YAED,GAAG,EAAE,KAAK,IAAuC,EAAE;gBACjD,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBACpB,IAAI,MAAM,EAAE,CAAC;oBACX,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;oBAC1C,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,IAAI,MAAM,EAAE,CAAC;wBAC7D,OAAO,MAAqB,CAAC;oBAC/B,CAAC;gBACH,CAAC;gBACD,OAAO;oBACL,OAAO,EAAE,EAAS;oBAClB,OAAO,EAAE,IAAa;oBACtB,IAAI,EAAE,EAAE,GAAG,iBAAiB,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE;iBAChG,CAAC;YACJ,CAAC;YAED,GAAG,EAAE,KAAK,EAAiB,QAAoC,EAAc,EAAE;gBAC7E,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBACpB,IAAI,MAAM,EAAE,CAAC;oBACX,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;oBAC1C,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;wBAC1B,sCAAsC;wBACtC,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;4BACxB,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;gCAC5C,OAAO,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;4BAC5B,CAAC;4BACD,OAAO,GAAG,CAAC;wBACb,CAAC,CAAM,CAAC;oBACV,CAAC;gBACH,CAAC;gBACD,OAAO,EAAO,CAAC;YACjB,CAAC;SACF,CAAC;QAEF,OAAO,SAAS,CAAC;IACnB,CAAC,CAAC;IAEF,kCAAkC;IAClC,MAAM,MAAM,GAAmB;QAC7B,OAAO,EAAE,eAAe;QAExB,KAAK,EAAE,KAAK,EAAe,UAAqC,EAA0B,EAAE;YAC1F,MAAM,OAAO,GAAkB,EAAE,CAAC;YAClC,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;gBAC9B,sCAAsC;gBACtC,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC;gBACjB,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,EAAS,EAAE,OAAO,EAAE,IAAa,EAAE,IAAI,EAAE,iBAAiB,EAAE,EAAE,CAAC,CAAC;YAC1F,CAAC;YACD,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,IAAI,EAAE,KAAK,EAAE,KAAa,EAAE,EAAE;YAC5B,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACpB,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;QACnC,CAAC;QAED,IAAI,EAAE,KAAK,IAAI,EAAE;YACf,OAAO,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC;QAC5B,CAAC;QAED,mEAAmE;QACnE,sEAAsE;QACtE,WAAW,EAAE,CAAC,oBAA6B,EAAyB,EAAE;YACpE,8DAA8D;YAC9D,OAAO;gBACL,OAAO,EAAE,eAAe;gBACxB,KAAK,EAAE,KAAK,EAAe,UAAqC,EAA0B,EAAE;oBAC1F,MAAM,OAAO,GAAkB,EAAE,CAAC;oBAClC,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;wBAC9B,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC;wBACjB,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,EAAS,EAAE,OAAO,EAAE,IAAa,EAAE,IAAI,EAAE,iBAAiB,EAAE,EAAE,CAAC,CAAC;oBAC1F,CAAC;oBACD,OAAO,OAAO,CAAC;gBACjB,CAAC;gBACD,IAAI,EAAE,KAAK,EAAE,KAAa,EAAE,EAAE;oBAC5B,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;oBACpB,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;gBACnC,CAAC;gBACD,WAAW,EAAE,GAAG,EAAE,CAAC,oBAAoB,IAAI,eAAe;aAC3D,CAAC;QACJ,CAAC;QAED,QAAQ,EAAE,OAAO;QACjB,SAAS,EAAE,QAAQ;QAEnB,UAAU,EAAE,CAAC,EAAe,EAAE,EAAE;YAC9B,MAAM,GAAG,EAAE,CAAC;QACd,CAAC;QAED,MAAM,EAAE,GAAG,EAAE;YACX,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;YACnB,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;YACpB,MAAM,GAAG,SAAS,CAAC;YACnB,SAAS,GAAG,SAAS,CAAC;QACxB,CAAC;QAED,IAAI,OAAO;YACT,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,aAAa,EAAE,CAAC,QAAiB,EAAE,EAAE;YACnC,SAAS,GAAG,QAAQ,CAAC;QACvB,CAAC;KACF,CAAC;IAEF,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,YAAY;IAC1B,OAAO,oBAAoB,EAA2B,CAAC;AACzD,CAAC"}
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
* Domain object factories for testing
|
|
3
3
|
*
|
|
4
4
|
* Provides factory functions to create mock domain objects
|
|
5
|
-
* with sensible defaults and
|
|
5
|
+
* with sensible defaults and random IDs (TEST-DESIGN-001).
|
|
6
6
|
*/
|
|
7
7
|
export * from './preset.js';
|
|
8
8
|
export * from './category.js';
|
|
9
9
|
export * from './vote.js';
|
|
10
10
|
export * from './user.js';
|
|
11
11
|
export * from './dye.js';
|
|
12
|
-
export { resetCounters, resetCounter, getCounterValue } from '../utils/counters.js';
|
|
12
|
+
export { randomId, randomStringId, resetCounters, resetCounter, getCounterValue, } from '../utils/counters.js';
|
|
13
13
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/factories/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/factories/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AAIzB,OAAO,EACL,QAAQ,EACR,cAAc,EACd,aAAa,EACb,YAAY,EACZ,eAAe,GAChB,MAAM,sBAAsB,CAAC"}
|
package/dist/factories/index.js
CHANGED
|
@@ -2,13 +2,14 @@
|
|
|
2
2
|
* Domain object factories for testing
|
|
3
3
|
*
|
|
4
4
|
* Provides factory functions to create mock domain objects
|
|
5
|
-
* with sensible defaults and
|
|
5
|
+
* with sensible defaults and random IDs (TEST-DESIGN-001).
|
|
6
6
|
*/
|
|
7
7
|
export * from './preset.js';
|
|
8
8
|
export * from './category.js';
|
|
9
9
|
export * from './vote.js';
|
|
10
10
|
export * from './user.js';
|
|
11
11
|
export * from './dye.js';
|
|
12
|
-
// Re-export
|
|
13
|
-
|
|
12
|
+
// Re-export ID utilities for test setup
|
|
13
|
+
// TEST-DESIGN-001: randomId and randomStringId are the recommended functions for parallel-safe tests
|
|
14
|
+
export { randomId, randomStringId, resetCounters, resetCounter, getCounterValue, } from '../utils/counters.js';
|
|
14
15
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/factories/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AAEzB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/factories/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AAEzB,wCAAwC;AACxC,qGAAqG;AACrG,OAAO,EACL,QAAQ,EACR,cAAc,EACd,aAAa,EACb,YAAY,EACZ,eAAe,GAChB,MAAM,sBAAsB,CAAC"}
|
package/dist/factories/vote.d.ts
CHANGED
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
* Vote factory functions for testing
|
|
3
3
|
*
|
|
4
4
|
* Provides functions to create mock votes.
|
|
5
|
+
* TEST-DESIGN-001: Uses random IDs for parallel test safety.
|
|
5
6
|
*
|
|
6
7
|
* @example
|
|
7
8
|
* ```typescript
|
|
8
|
-
* const vote = createMockVote({ preset_id: 'preset-
|
|
9
|
+
* const vote = createMockVote({ preset_id: 'preset-xyz' });
|
|
9
10
|
* const votes = createMockVotes(5, { user_discord_id: '123' });
|
|
10
11
|
* ```
|
|
11
12
|
*/
|
|
@@ -20,6 +21,8 @@ export interface VoteRow {
|
|
|
20
21
|
/**
|
|
21
22
|
* Creates a mock vote row
|
|
22
23
|
*
|
|
24
|
+
* TEST-DESIGN-001: Uses random preset IDs for parallel test safety.
|
|
25
|
+
*
|
|
23
26
|
* @param overrides - Optional overrides for the default values
|
|
24
27
|
* @returns A VoteRow object
|
|
25
28
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vote.d.ts","sourceRoot":"","sources":["../../src/factories/vote.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"vote.d.ts","sourceRoot":"","sources":["../../src/factories/vote.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH;;GAEG;AACH,MAAM,WAAW,OAAO;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,GAAE,OAAO,CAAC,OAAO,CAAM,GAAG,OAAO,CAO3E;AAED;;GAEG;AACH,eAAO,MAAM,cAAc,0BAAoB,CAAC;AAEhD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,EACb,SAAS,GAAE,OAAO,CAAC,OAAO,CAAM,GAC/B,OAAO,EAAE,CAEX;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,GAChB,OAAO,EAAE,CAOX;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EAAE,GAClB,OAAO,EAAE,CAOX"}
|
package/dist/factories/vote.js
CHANGED
|
@@ -2,24 +2,26 @@
|
|
|
2
2
|
* Vote factory functions for testing
|
|
3
3
|
*
|
|
4
4
|
* Provides functions to create mock votes.
|
|
5
|
+
* TEST-DESIGN-001: Uses random IDs for parallel test safety.
|
|
5
6
|
*
|
|
6
7
|
* @example
|
|
7
8
|
* ```typescript
|
|
8
|
-
* const vote = createMockVote({ preset_id: 'preset-
|
|
9
|
+
* const vote = createMockVote({ preset_id: 'preset-xyz' });
|
|
9
10
|
* const votes = createMockVotes(5, { user_discord_id: '123' });
|
|
10
11
|
* ```
|
|
11
12
|
*/
|
|
12
|
-
import {
|
|
13
|
+
import { randomStringId } from '../utils/counters.js';
|
|
13
14
|
/**
|
|
14
15
|
* Creates a mock vote row
|
|
15
16
|
*
|
|
17
|
+
* TEST-DESIGN-001: Uses random preset IDs for parallel test safety.
|
|
18
|
+
*
|
|
16
19
|
* @param overrides - Optional overrides for the default values
|
|
17
20
|
* @returns A VoteRow object
|
|
18
21
|
*/
|
|
19
22
|
export function createMockVoteRow(overrides = {}) {
|
|
20
|
-
const voteNum = nextId('vote');
|
|
21
23
|
return {
|
|
22
|
-
preset_id:
|
|
24
|
+
preset_id: randomStringId('preset'),
|
|
23
25
|
user_discord_id: '123456789',
|
|
24
26
|
created_at: new Date().toISOString(),
|
|
25
27
|
...overrides,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vote.js","sourceRoot":"","sources":["../../src/factories/vote.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"vote.js","sourceRoot":"","sources":["../../src/factories/vote.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAWtD;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAAC,YAA8B,EAAE;IAChE,OAAO;QACL,SAAS,EAAE,cAAc,CAAC,QAAQ,CAAC;QACnC,eAAe,EAAE,WAAW;QAC5B,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACpC,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,iBAAiB,CAAC;AAEhD;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAC7B,KAAa,EACb,YAA8B,EAAE;IAEhC,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC,CAAC;AAC3E,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAClC,QAAgB,EAChB,SAAiB;IAEjB,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAChD,iBAAiB,CAAC;QAChB,SAAS,EAAE,QAAQ;QACnB,eAAe,EAAE,QAAQ,CAAC,GAAG,CAAC,EAAE;KACjC,CAAC,CACH,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CACjC,MAAc,EACd,SAAmB;IAEnB,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAChC,iBAAiB,CAAC;QAChB,SAAS,EAAE,QAAQ;QACnB,eAAe,EAAE,MAAM;KACxB,CAAC,CACH,CAAC;AACJ,CAAC"}
|
package/dist/utils/counters.d.ts
CHANGED
|
@@ -1,19 +1,43 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* ID generation utilities for test factories
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* TEST-DESIGN-001: Uses random IDs to prevent race conditions in parallel test execution.
|
|
5
|
+
* Sequential counters are kept for backward compatibility but random IDs are now the default.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* // Recommended: Random IDs (safe for parallel tests)
|
|
10
|
+
* const id = randomStringId('preset'); // 'preset-a7x9k2m'
|
|
11
|
+
*
|
|
12
|
+
* // Legacy: Sequential IDs (call resetCounters() in beforeEach for isolation)
|
|
13
|
+
* const seqId = nextStringId('preset'); // 'preset-1'
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Generate a random numeric ID
|
|
18
|
+
* TEST-DESIGN-001: Safe for parallel test execution
|
|
19
|
+
* @returns A random positive integer
|
|
20
|
+
*/
|
|
21
|
+
export declare function randomId(): number;
|
|
22
|
+
/**
|
|
23
|
+
* Generate a random string ID with prefix
|
|
24
|
+
* TEST-DESIGN-001: Safe for parallel test execution
|
|
25
|
+
* @param prefix - The ID prefix (e.g., 'preset', 'category')
|
|
26
|
+
* @returns A string ID like 'preset-a7x9k2m'
|
|
6
27
|
*/
|
|
28
|
+
export declare function randomStringId(prefix: string): string;
|
|
7
29
|
/**
|
|
8
|
-
* Get the next value for a named counter
|
|
30
|
+
* Get the next value for a named counter (legacy)
|
|
31
|
+
* @deprecated Use randomId() for parallel-safe ID generation
|
|
9
32
|
* @param name - The counter name (e.g., 'preset', 'category')
|
|
10
33
|
* @returns The next sequential value
|
|
11
34
|
*/
|
|
12
35
|
export declare function nextId(name: string): number;
|
|
13
36
|
/**
|
|
14
|
-
* Get a string ID with prefix
|
|
37
|
+
* Get a string ID with prefix (legacy)
|
|
38
|
+
* TEST-DESIGN-001: Now uses random IDs by default for parallel-safe execution
|
|
15
39
|
* @param prefix - The ID prefix (e.g., 'preset', 'category')
|
|
16
|
-
* @returns A string ID like 'preset-
|
|
40
|
+
* @returns A string ID like 'preset-a7x9k2m'
|
|
17
41
|
*/
|
|
18
42
|
export declare function nextStringId(prefix: string): string;
|
|
19
43
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"counters.d.ts","sourceRoot":"","sources":["../../src/utils/counters.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"counters.d.ts","sourceRoot":"","sources":["../../src/utils/counters.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAmBH;;;;GAIG;AACH,wBAAgB,QAAQ,IAAI,MAAM,CAEjC;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAErD;AAED;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAM3C;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAGnD;AAED;;;GAGG;AACH,wBAAgB,aAAa,IAAI,IAAI,CAIpC;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAE/C;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEpD"}
|
package/dist/utils/counters.js
CHANGED
|
@@ -1,13 +1,53 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* ID generation utilities for test factories
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* TEST-DESIGN-001: Uses random IDs to prevent race conditions in parallel test execution.
|
|
5
|
+
* Sequential counters are kept for backward compatibility but random IDs are now the default.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* // Recommended: Random IDs (safe for parallel tests)
|
|
10
|
+
* const id = randomStringId('preset'); // 'preset-a7x9k2m'
|
|
11
|
+
*
|
|
12
|
+
* // Legacy: Sequential IDs (call resetCounters() in beforeEach for isolation)
|
|
13
|
+
* const seqId = nextStringId('preset'); // 'preset-1'
|
|
14
|
+
* ```
|
|
6
15
|
*/
|
|
7
|
-
// Counter storage
|
|
16
|
+
// Counter storage (legacy, for backward compatibility)
|
|
8
17
|
const counters = {};
|
|
9
18
|
/**
|
|
10
|
-
*
|
|
19
|
+
* Generate a random alphanumeric string
|
|
20
|
+
* @param length - Length of the random string (default: 8)
|
|
21
|
+
* @returns Random alphanumeric string
|
|
22
|
+
*/
|
|
23
|
+
function randomAlphanumeric(length = 8) {
|
|
24
|
+
const chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
|
25
|
+
let result = '';
|
|
26
|
+
for (let i = 0; i < length; i++) {
|
|
27
|
+
result += chars.charAt(Math.floor(Math.random() * chars.length));
|
|
28
|
+
}
|
|
29
|
+
return result;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Generate a random numeric ID
|
|
33
|
+
* TEST-DESIGN-001: Safe for parallel test execution
|
|
34
|
+
* @returns A random positive integer
|
|
35
|
+
*/
|
|
36
|
+
export function randomId() {
|
|
37
|
+
return Math.floor(Math.random() * 900000000) + 100000000; // 9-digit number
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Generate a random string ID with prefix
|
|
41
|
+
* TEST-DESIGN-001: Safe for parallel test execution
|
|
42
|
+
* @param prefix - The ID prefix (e.g., 'preset', 'category')
|
|
43
|
+
* @returns A string ID like 'preset-a7x9k2m'
|
|
44
|
+
*/
|
|
45
|
+
export function randomStringId(prefix) {
|
|
46
|
+
return `${prefix}-${randomAlphanumeric(8)}`;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Get the next value for a named counter (legacy)
|
|
50
|
+
* @deprecated Use randomId() for parallel-safe ID generation
|
|
11
51
|
* @param name - The counter name (e.g., 'preset', 'category')
|
|
12
52
|
* @returns The next sequential value
|
|
13
53
|
*/
|
|
@@ -19,12 +59,14 @@ export function nextId(name) {
|
|
|
19
59
|
return counters[name];
|
|
20
60
|
}
|
|
21
61
|
/**
|
|
22
|
-
* Get a string ID with prefix
|
|
62
|
+
* Get a string ID with prefix (legacy)
|
|
63
|
+
* TEST-DESIGN-001: Now uses random IDs by default for parallel-safe execution
|
|
23
64
|
* @param prefix - The ID prefix (e.g., 'preset', 'category')
|
|
24
|
-
* @returns A string ID like 'preset-
|
|
65
|
+
* @returns A string ID like 'preset-a7x9k2m'
|
|
25
66
|
*/
|
|
26
67
|
export function nextStringId(prefix) {
|
|
27
|
-
|
|
68
|
+
// TEST-DESIGN-001: Use random IDs by default for parallel test safety
|
|
69
|
+
return randomStringId(prefix);
|
|
28
70
|
}
|
|
29
71
|
/**
|
|
30
72
|
* Reset all counters to zero
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"counters.js","sourceRoot":"","sources":["../../src/utils/counters.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"counters.js","sourceRoot":"","sources":["../../src/utils/counters.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,uDAAuD;AACvD,MAAM,QAAQ,GAA2B,EAAE,CAAC;AAE5C;;;;GAIG;AACH,SAAS,kBAAkB,CAAC,SAAiB,CAAC;IAC5C,MAAM,KAAK,GAAG,sCAAsC,CAAC;IACrD,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;IACnE,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,QAAQ;IACtB,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,SAAS,CAAC,GAAG,SAAS,CAAC,CAAC,iBAAiB;AAC7E,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,MAAc;IAC3C,OAAO,GAAG,MAAM,IAAI,kBAAkB,CAAC,CAAC,CAAC,EAAE,CAAC;AAC9C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,MAAM,CAAC,IAAY;IACjC,IAAI,CAAC,CAAC,IAAI,IAAI,QAAQ,CAAC,EAAE,CAAC;QACxB,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;IACD,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;IACjB,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC;AACxB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,MAAc;IACzC,sEAAsE;IACtE,OAAO,cAAc,CAAC,MAAM,CAAC,CAAC;AAChC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa;IAC3B,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC;IACvB,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC;AACxB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xivdyetools/test-utils",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "Shared testing utilities for the xivdyetools ecosystem",
|
|
5
5
|
"author": "XIV Dye Tools",
|
|
6
6
|
"license": "MIT",
|
|
@@ -60,15 +60,15 @@
|
|
|
60
60
|
}
|
|
61
61
|
},
|
|
62
62
|
"dependencies": {
|
|
63
|
-
"@xivdyetools/types": "^1.
|
|
63
|
+
"@xivdyetools/types": "^1.1.1"
|
|
64
64
|
},
|
|
65
65
|
"devDependencies": {
|
|
66
66
|
"@cloudflare/workers-types": "^4.20241205.0",
|
|
67
67
|
"@testing-library/dom": "^10.0.0",
|
|
68
|
-
"@vitest/coverage-v8": "^
|
|
68
|
+
"@vitest/coverage-v8": "^4.0.15",
|
|
69
69
|
"rimraf": "^5.0.5",
|
|
70
|
-
"typescript": "^5.3
|
|
71
|
-
"vitest": "^
|
|
70
|
+
"typescript": "^5.9.3",
|
|
71
|
+
"vitest": "^4.0.15"
|
|
72
72
|
},
|
|
73
73
|
"engines": {
|
|
74
74
|
"node": ">=18.0.0"
|