cf-bun-mocks 0.2.0 → 0.3.0
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/README.md +27 -56
- package/package.json +1 -1
- package/src/d1.ts +5 -5
- package/src/workers.ts +17 -22
package/README.md
CHANGED
|
@@ -109,77 +109,52 @@ const response = await worker.fetch(request, env);
|
|
|
109
109
|
|
|
110
110
|
## Workers Environment
|
|
111
111
|
|
|
112
|
-
For testing
|
|
112
|
+
For testing code that imports from `cloudflare:workers`, use `useWorkersMock()` to mock the module and set up test environments:
|
|
113
113
|
|
|
114
114
|
```typescript
|
|
115
115
|
import { describe, test, expect } from "bun:test";
|
|
116
|
-
import {
|
|
117
|
-
import type { Env } from "./worker";
|
|
116
|
+
import { useWorkersMock, D1Mock } from "cf-bun-mocks";
|
|
118
117
|
|
|
119
|
-
describe("
|
|
120
|
-
const { env } =
|
|
121
|
-
|
|
122
|
-
|
|
118
|
+
describe("worker with module imports", () => {
|
|
119
|
+
const { env } = useWorkersMock(() => ({
|
|
120
|
+
env: {
|
|
121
|
+
DB: new D1Mock(":memory:"),
|
|
122
|
+
API_KEY: "test-key",
|
|
123
|
+
},
|
|
123
124
|
}));
|
|
124
125
|
|
|
125
|
-
test("uses
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
expect(
|
|
126
|
+
test("uses mocked environment", async () => {
|
|
127
|
+
const { env } = await import("cloudflare:workers");
|
|
128
|
+
expect(env.DB).toBeDefined();
|
|
129
|
+
expect(env.API_KEY).toBe("test-key");
|
|
129
130
|
});
|
|
130
131
|
});
|
|
131
132
|
```
|
|
132
133
|
|
|
133
|
-
|
|
134
|
+
The mock environment is reset before each test with the values from your factory function.
|
|
134
135
|
|
|
135
|
-
|
|
136
|
+
### Manual Injection (Alternative)
|
|
136
137
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
```typescript
|
|
140
|
-
// test-setup.ts
|
|
141
|
-
import { setupWorkersMock } from "cf-bun-mocks";
|
|
142
|
-
|
|
143
|
-
// Set up module mocks before any test files load
|
|
144
|
-
await setupWorkersMock();
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
Then run tests with preload:
|
|
148
|
-
|
|
149
|
-
```bash
|
|
150
|
-
bun test --preload ./test-setup.ts
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
Or configure it in `bunfig.toml`:
|
|
154
|
-
|
|
155
|
-
```toml
|
|
156
|
-
[test]
|
|
157
|
-
preload = ["./test-setup.ts"]
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
Then use in your tests:
|
|
138
|
+
If you're not using `cloudflare:workers` imports, you can pass the environment directly to your worker:
|
|
161
139
|
|
|
162
140
|
```typescript
|
|
163
141
|
import { describe, test, expect } from "bun:test";
|
|
164
|
-
import {
|
|
142
|
+
import { D1Mock } from "cf-bun-mocks";
|
|
143
|
+
import type { Env } from "./worker";
|
|
165
144
|
|
|
166
|
-
describe("worker
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
145
|
+
describe("my worker", () => {
|
|
146
|
+
test("uses test environment", async () => {
|
|
147
|
+
const env: Env = {
|
|
148
|
+
DB: new D1Mock(":memory:"),
|
|
149
|
+
MY_SECRET: "test-secret",
|
|
150
|
+
};
|
|
171
151
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
const { env } = await import("cloudflare:workers");
|
|
175
|
-
expect(env.DB).toBeDefined();
|
|
176
|
-
expect(env.API_KEY).toBe("test-key");
|
|
152
|
+
const response = await worker.fetch(request, env);
|
|
153
|
+
expect(response.status).toBe(200);
|
|
177
154
|
});
|
|
178
155
|
});
|
|
179
156
|
```
|
|
180
157
|
|
|
181
|
-
> **Note**: `setupWorkersMock` uses Bun's `mock.module()` function. Module mocks must be set up before any imports happen. See [Bun's test lifecycle docs](https://bun.com/docs/test/lifecycle#global-setup-and-teardown) for preload details and [Bun's mocking docs](https://bun.sh/docs/test/mocking) for more on module mocking.
|
|
182
|
-
|
|
183
158
|
## API
|
|
184
159
|
|
|
185
160
|
### `D1Mock`
|
|
@@ -196,13 +171,9 @@ Implements the full `D1Database` interface from `@cloudflare/workers-types`:
|
|
|
196
171
|
|
|
197
172
|
Creates an in-memory D1Mock and runs all `.sql` migration files from the specified directory in sorted order.
|
|
198
173
|
|
|
199
|
-
### `
|
|
200
|
-
|
|
201
|
-
Updates the global workers mock environment for each test. Must be used with `setupWorkersMock()`.
|
|
202
|
-
|
|
203
|
-
### `setupWorkersMock<TEnv>(createMock?: () => WorkersModuleMock<TEnv> | Promise<WorkersModuleMock<TEnv>>)`
|
|
174
|
+
### `useWorkersMock<TEnv>(createMock: () => Partial<{ env: TEnv }> | Promise<Partial<{ env: TEnv }>>)`
|
|
204
175
|
|
|
205
|
-
|
|
176
|
+
Mocks the `cloudflare:workers` module and sets up test environments. Returns a mock object with an `env` property that gets updated before each test with values from the factory function. Uses Bun's `mock.module()` internally.
|
|
206
177
|
|
|
207
178
|
## Requirements
|
|
208
179
|
|
package/package.json
CHANGED
package/src/d1.ts
CHANGED
|
@@ -110,7 +110,7 @@ class D1DatabaseSessionMock implements D1DatabaseSession {
|
|
|
110
110
|
}
|
|
111
111
|
|
|
112
112
|
export class D1Mock implements D1Database {
|
|
113
|
-
|
|
113
|
+
db: Database;
|
|
114
114
|
|
|
115
115
|
constructor(
|
|
116
116
|
filename?: string,
|
|
@@ -124,11 +124,11 @@ export class D1Mock implements D1Database {
|
|
|
124
124
|
strict?: boolean;
|
|
125
125
|
}
|
|
126
126
|
) {
|
|
127
|
-
this
|
|
127
|
+
this.db = new Database(filename, options);
|
|
128
128
|
}
|
|
129
129
|
|
|
130
130
|
prepare(query: string): D1PreparedStatement {
|
|
131
|
-
const stmt = this
|
|
131
|
+
const stmt = this.db.prepare(query);
|
|
132
132
|
return new D1PreparedStatementMock(stmt);
|
|
133
133
|
}
|
|
134
134
|
|
|
@@ -148,7 +148,7 @@ export class D1Mock implements D1Database {
|
|
|
148
148
|
async exec(query: string): Promise<D1ExecResult> {
|
|
149
149
|
const start = performance.now();
|
|
150
150
|
try {
|
|
151
|
-
const { changes: count } = this
|
|
151
|
+
const { changes: count } = this.db.run(query);
|
|
152
152
|
const duration = performance.now() - start;
|
|
153
153
|
return {
|
|
154
154
|
count,
|
|
@@ -170,7 +170,7 @@ export class D1Mock implements D1Database {
|
|
|
170
170
|
}
|
|
171
171
|
|
|
172
172
|
async dump(): Promise<ArrayBuffer> {
|
|
173
|
-
const serialized = this
|
|
173
|
+
const serialized = this.db.serialize();
|
|
174
174
|
const buffer = serialized.buffer;
|
|
175
175
|
if (buffer instanceof SharedArrayBuffer) {
|
|
176
176
|
const newBuffer = new ArrayBuffer(buffer.byteLength);
|
package/src/workers.ts
CHANGED
|
@@ -1,33 +1,28 @@
|
|
|
1
1
|
/// <reference types="@cloudflare/workers-types" />
|
|
2
|
-
import { beforeEach, mock, afterAll } from "bun:test";
|
|
2
|
+
import { beforeEach, mock, afterAll, beforeAll } from "bun:test";
|
|
3
3
|
|
|
4
|
-
type WorkersModuleMock<TEnv extends Cloudflare.Env = Cloudflare.Env> =
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
type WorkersModuleMock<TEnv extends Partial<Cloudflare.Env> = Cloudflare.Env> =
|
|
5
|
+
{
|
|
6
|
+
env: TEnv;
|
|
7
|
+
};
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
export function useWorkersMock<
|
|
10
|
+
TEnv extends Partial<Cloudflare.Env> = Cloudflare.Env
|
|
11
|
+
>(createMock: () => Bun.MaybePromise<Partial<WorkersModuleMock<TEnv>>>) {
|
|
12
|
+
const moduleMock: WorkersModuleMock<TEnv> = { env: {} as TEnv };
|
|
9
13
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
if (createMock) {
|
|
14
|
-
moduleMock = await createMock();
|
|
15
|
-
}
|
|
16
|
-
mock.module("cloudflare:workers", () => moduleMock);
|
|
17
|
-
}
|
|
14
|
+
beforeAll(() => {
|
|
15
|
+
mock.module("cloudflare:workers", () => moduleMock);
|
|
16
|
+
});
|
|
18
17
|
|
|
19
|
-
export function useWorkersEnv<TEnv extends Cloudflare.Env = Cloudflare.Env>(
|
|
20
|
-
createEnv: () => Bun.MaybePromise<Partial<TEnv>>
|
|
21
|
-
) {
|
|
22
18
|
beforeEach(async () => {
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
delete (moduleMock.env as any)[key];
|
|
26
|
-
}
|
|
27
|
-
Object.assign(moduleMock.env, env);
|
|
19
|
+
const mock = await createMock();
|
|
20
|
+
Object.assign(moduleMock.env, mock.env);
|
|
28
21
|
});
|
|
29
22
|
|
|
30
23
|
afterAll(() => {
|
|
31
|
-
|
|
24
|
+
mock.restore();
|
|
32
25
|
});
|
|
26
|
+
|
|
27
|
+
return moduleMock;
|
|
33
28
|
}
|