@elench/testkit 0.1.27 → 0.1.28
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 +6 -3
- package/lib/bundler/index.mjs +32 -3
- package/lib/bundler/index.test.mjs +61 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -109,11 +109,12 @@ const suite = defineHttpSuite(({ rawReq }) => {
|
|
|
109
109
|
rawReq("GET", "/health");
|
|
110
110
|
});
|
|
111
111
|
|
|
112
|
-
export
|
|
113
|
-
export const setup = suite.setup;
|
|
114
|
-
export default suite.exec;
|
|
112
|
+
export default suite;
|
|
115
113
|
```
|
|
116
114
|
|
|
115
|
+
`testkit` suite files should default-export the suite object returned by
|
|
116
|
+
`defineHttpSuite(...)` or `defineDalSuite(...)`.
|
|
117
|
+
|
|
117
118
|
Named HTTP profiles live in `testkit.setup.ts` and can be referenced by name:
|
|
118
119
|
|
|
119
120
|
```ts
|
|
@@ -132,6 +133,8 @@ import { defineDalSuite } from "@elench/testkit";
|
|
|
132
133
|
const suite = defineDalSuite(({ db }) => {
|
|
133
134
|
db.query("select 1");
|
|
134
135
|
});
|
|
136
|
+
|
|
137
|
+
export default suite;
|
|
135
138
|
```
|
|
136
139
|
|
|
137
140
|
Low-level runtime primitives remain available:
|
package/lib/bundler/index.mjs
CHANGED
|
@@ -119,8 +119,37 @@ registerRepoSetup(null);
|
|
|
119
119
|
import { registerRepoSetup } from "@elench/testkit/setup";
|
|
120
120
|
import * as suiteModule from ${sourceImport};
|
|
121
121
|
${setupRegistration}
|
|
122
|
-
|
|
123
|
-
export const
|
|
124
|
-
export
|
|
122
|
+
const suite = normalizeTestkitSuite(suiteModule);
|
|
123
|
+
export const options = suite.options;
|
|
124
|
+
export function setup(...args) {
|
|
125
|
+
return suite.setup(...args);
|
|
126
|
+
}
|
|
127
|
+
export default function exec(...args) {
|
|
128
|
+
return suite.exec(...args);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function normalizeTestkitSuite(module) {
|
|
132
|
+
const candidate = module?.default;
|
|
133
|
+
if (!candidate || typeof candidate !== "object") {
|
|
134
|
+
throw new Error(
|
|
135
|
+
"testkit suite files must default-export the suite object returned by defineHttpSuite(...) or defineDalSuite(...). Example: export default defineHttpSuite(...) or const suite = defineHttpSuite(...); export default suite;"
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
if (typeof candidate.exec !== "function") {
|
|
139
|
+
throw new Error(
|
|
140
|
+
"testkit suite default export must expose an exec(setupData) function"
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const setupFn = typeof candidate["setup"] === "function"
|
|
145
|
+
? (...args) => candidate.setup(...args)
|
|
146
|
+
: () => null;
|
|
147
|
+
|
|
148
|
+
return {
|
|
149
|
+
options: candidate["options"],
|
|
150
|
+
setup: setupFn,
|
|
151
|
+
exec: (...args) => candidate.exec(...args),
|
|
152
|
+
};
|
|
153
|
+
}
|
|
125
154
|
`;
|
|
126
155
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import fs from "fs";
|
|
2
2
|
import os from "os";
|
|
3
3
|
import path from "path";
|
|
4
|
+
import { pathToFileURL } from "url";
|
|
4
5
|
import { afterEach, describe, expect, it } from "vitest";
|
|
5
6
|
import { bundleK6File } from "./index.mjs";
|
|
6
7
|
|
|
@@ -29,9 +30,7 @@ describe("runtime bundler", () => {
|
|
|
29
30
|
' "has status": (body) => typeof body.status === "string",',
|
|
30
31
|
" });",
|
|
31
32
|
"});",
|
|
32
|
-
"export
|
|
33
|
-
"export const setup = suite.setup;",
|
|
34
|
-
"export default suite.exec;",
|
|
33
|
+
"export default suite;",
|
|
35
34
|
"",
|
|
36
35
|
].join("\n")
|
|
37
36
|
);
|
|
@@ -60,9 +59,7 @@ describe("runtime bundler", () => {
|
|
|
60
59
|
"const suite = defineDalSuite(({ db }) => {",
|
|
61
60
|
' db.query("SELECT 1");',
|
|
62
61
|
"});",
|
|
63
|
-
"export
|
|
64
|
-
"export const setup = suite.setup;",
|
|
65
|
-
"export default suite.exec;",
|
|
62
|
+
"export default suite;",
|
|
66
63
|
"",
|
|
67
64
|
].join("\n")
|
|
68
65
|
);
|
|
@@ -77,4 +74,62 @@ describe("runtime bundler", () => {
|
|
|
77
74
|
expect(bundled).toContain("defineDalSuite");
|
|
78
75
|
expect(bundled).toContain('import sql from "k6/x/sql"');
|
|
79
76
|
});
|
|
77
|
+
|
|
78
|
+
it("normalizes a default-exported suite object with no setup override", async () => {
|
|
79
|
+
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "testkit-bundle-"));
|
|
80
|
+
cleanups.push(() => fs.rmSync(tmpDir, { force: true, recursive: true }));
|
|
81
|
+
|
|
82
|
+
const sourceFile = path.join(tmpDir, "no-setup.js");
|
|
83
|
+
fs.writeFileSync(
|
|
84
|
+
sourceFile,
|
|
85
|
+
[
|
|
86
|
+
"const suite = {",
|
|
87
|
+
" options: { vus: 1, iterations: 1 },",
|
|
88
|
+
" exec() {",
|
|
89
|
+
" return 'ok';",
|
|
90
|
+
" },",
|
|
91
|
+
"};",
|
|
92
|
+
"export default suite;",
|
|
93
|
+
"",
|
|
94
|
+
].join("\n")
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
const bundledFile = await bundleK6File({
|
|
98
|
+
productDir: tmpDir,
|
|
99
|
+
serviceName: "api",
|
|
100
|
+
sourceFile,
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
const bundled = await import(`${pathToFileURL(bundledFile).href}?v=${Date.now()}`);
|
|
104
|
+
expect(typeof bundled.setup).toBe("function");
|
|
105
|
+
expect(bundled.setup()).toBeNull();
|
|
106
|
+
expect(typeof bundled.default).toBe("function");
|
|
107
|
+
expect(bundled.default()).toBe("ok");
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it("throws a clear error when the default export is not a suite object", async () => {
|
|
111
|
+
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "testkit-bundle-"));
|
|
112
|
+
cleanups.push(() => fs.rmSync(tmpDir, { force: true, recursive: true }));
|
|
113
|
+
|
|
114
|
+
const sourceFile = path.join(tmpDir, "legacy-shape.js");
|
|
115
|
+
fs.writeFileSync(
|
|
116
|
+
sourceFile,
|
|
117
|
+
[
|
|
118
|
+
"export default function exec() {",
|
|
119
|
+
" return 'legacy';",
|
|
120
|
+
"}",
|
|
121
|
+
"",
|
|
122
|
+
].join("\n")
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
const bundledFile = await bundleK6File({
|
|
126
|
+
productDir: tmpDir,
|
|
127
|
+
serviceName: "api",
|
|
128
|
+
sourceFile,
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
await expect(
|
|
132
|
+
import(`${pathToFileURL(bundledFile).href}?v=${Date.now()}`)
|
|
133
|
+
).rejects.toThrow(/default-export the suite object/);
|
|
134
|
+
});
|
|
80
135
|
});
|