@specific.dev/spectest 0.109.0 → 0.109.1
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/helper-tracking.js
CHANGED
|
@@ -83,9 +83,11 @@ function invokeHelper(kind, name, member, fn, receiver, callArgs) {
|
|
|
83
83
|
};
|
|
84
84
|
let result;
|
|
85
85
|
try {
|
|
86
|
+
// Reading a callable proxy's `.apply` can bind directly to its raw client
|
|
87
|
+
// and bypass instrumentation (SQL does this). Invoke the proxy itself.
|
|
86
88
|
result = recording.run(() => kind === "fake"
|
|
87
|
-
? runUninstrumented(() =>
|
|
88
|
-
:
|
|
89
|
+
? runUninstrumented(() => Reflect.apply(fn, receiver, args))
|
|
90
|
+
: Reflect.apply(fn, receiver, args));
|
|
89
91
|
}
|
|
90
92
|
catch (error) {
|
|
91
93
|
return fail(error);
|
package/package.json
CHANGED
|
@@ -3,6 +3,7 @@ import { annotate } from "./annotate.js";
|
|
|
3
3
|
import { expect as assertValue, type ServiceHandlesFor, type Wrapped } from "./index.js";
|
|
4
4
|
import { readRaw, readTag, wrap } from "./inspect.js";
|
|
5
5
|
import { trackHelpers } from "./helper-tracking.js";
|
|
6
|
+
import { SQL } from "./sql.js";
|
|
6
7
|
import {
|
|
7
8
|
recordHttp, recordWait, recorderEventCount, recorderMarkChildren, recorderTruncate,
|
|
8
9
|
startRecording, stopRecording,
|
|
@@ -175,6 +176,41 @@ test("live objects, callable clients, function properties and receivers survive"
|
|
|
175
176
|
expect<unknown>(readRaw(helper.latest.call({...raw, subject: "Other"}))).toEqual({subject: "Other"});
|
|
176
177
|
});
|
|
177
178
|
|
|
179
|
+
test("a tracked SQL client keeps tagged queries and attached methods instrumented", async () => {
|
|
180
|
+
const client = new SQL("sqlite://:memory:", { label: "db" });
|
|
181
|
+
const helper = trackHelpers("service", "db", { client });
|
|
182
|
+
startRecording();
|
|
183
|
+
try {
|
|
184
|
+
const rows = await helper.client<{ id: number }>`SELECT ${7} AS id`;
|
|
185
|
+
assertValue(rows.transform("ids", (rows) => Array.from(rows, (row) => row.id))).toEqual([7]);
|
|
186
|
+
const other = await helper.client.unsafe<{ id: number }>("SELECT ? AS id", [8]);
|
|
187
|
+
assertValue(other[0]!.id).toBe(8);
|
|
188
|
+
const events = stopRecording();
|
|
189
|
+
expect(events.map((event) => event.kind)).toEqual(["db", "assertion", "db", "assertion"]);
|
|
190
|
+
expect(events[0]).toMatchObject({ service: "db", query: "SELECT $1 AS id", params: [7], rows: [{ id: 7 }] });
|
|
191
|
+
expect(events[1]).toMatchObject({ sourceSeq: events[0]!.seq, path: ["<ids>"] });
|
|
192
|
+
expect(events[2]).toMatchObject({ service: "db", query: "SELECT ? AS id", params: [8], rows: [{ id: 8 }] });
|
|
193
|
+
expect(events[3]).toMatchObject({ sourceSeq: events[2]!.seq, path: ["0", "id"] });
|
|
194
|
+
} finally {
|
|
195
|
+
await helper.client.close!();
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
test("a tracked SQL client preserves query failure diagnostics", async () => {
|
|
200
|
+
const client = new SQL("sqlite://:memory:", { label: "db" });
|
|
201
|
+
const helper = trackHelpers("service", "db", { client });
|
|
202
|
+
startRecording();
|
|
203
|
+
try {
|
|
204
|
+
await expect(helper.client`SELECT * FROM missing_table`).rejects.toThrow("no such table");
|
|
205
|
+
const events = stopRecording();
|
|
206
|
+
expect(events).toHaveLength(1);
|
|
207
|
+
expect(events[0]).toMatchObject({ kind: "db", service: "db", query: "SELECT * FROM missing_table",
|
|
208
|
+
error: expect.stringContaining("no such table") });
|
|
209
|
+
} finally {
|
|
210
|
+
await helper.client.close!();
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
|
|
178
214
|
test("setup/eval unwrap annotated returns without recording", async () => {
|
|
179
215
|
const scope = createInstrumentationScope(false);
|
|
180
216
|
const helper = trackHelpers("service", "mail", { latest: () => annotate({subject: "Invoice"}, "email") });
|
package/src/helper-tracking.ts
CHANGED
|
@@ -93,9 +93,11 @@ function invokeHelper(
|
|
|
93
93
|
};
|
|
94
94
|
let result: unknown;
|
|
95
95
|
try {
|
|
96
|
+
// Reading a callable proxy's `.apply` can bind directly to its raw client
|
|
97
|
+
// and bypass instrumentation (SQL does this). Invoke the proxy itself.
|
|
96
98
|
result = recording.run(() => kind === "fake"
|
|
97
|
-
? runUninstrumented(() =>
|
|
98
|
-
:
|
|
99
|
+
? runUninstrumented(() => Reflect.apply(fn, receiver, args))
|
|
100
|
+
: Reflect.apply(fn, receiver, args));
|
|
99
101
|
} catch (error) {
|
|
100
102
|
return fail(error);
|
|
101
103
|
}
|