@flink-app/test-utils 1.0.0 → 2.0.0-alpha.101
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/CHANGELOG.md +177 -0
- package/dist/ai/conversation.d.ts +27 -0
- package/dist/ai/conversation.js +30 -0
- package/dist/ai/index.d.ts +4 -0
- package/dist/ai/index.js +20 -0
- package/dist/ai/mockContext.d.ts +16 -0
- package/dist/ai/mockContext.js +39 -0
- package/dist/ai/mockLLMAdapter.d.ts +90 -0
- package/dist/ai/mockLLMAdapter.js +252 -0
- package/dist/ai/mockTool.d.ts +64 -0
- package/dist/ai/mockTool.js +133 -0
- package/dist/http.d.ts +2 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/mocks.d.ts +14 -1
- package/dist/mocks.js +17 -0
- package/dist/requestContext.d.ts +22 -0
- package/dist/requestContext.js +86 -0
- package/package.json +9 -5
- package/spec/ai/conversation.spec.ts +280 -0
- package/spec/ai/mockLLMAdapter.spec.ts +533 -0
- package/spec/ai/mockTool.spec.ts +313 -0
- package/spec/support/jasmine.json +7 -0
- package/src/ai/conversation.ts +54 -0
- package/src/ai/index.ts +4 -0
- package/src/ai/mockContext.ts +41 -0
- package/src/ai/mockLLMAdapter.ts +238 -0
- package/src/ai/mockTool.ts +135 -0
- package/src/http.ts +3 -3
- package/src/index.ts +2 -0
- package/src/mocks.ts +21 -1
- package/src/requestContext.ts +44 -0
- package/tsconfig.dist.json +4 -0
- package/tsconfig.json +6 -5
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { FlinkTool, FlinkToolProps } from "@flink-app/flink/ai";
|
|
3
|
+
export interface MockToolConfig<Input, Output> {
|
|
4
|
+
name: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
inputSchema: z.ZodType<Input>;
|
|
7
|
+
outputSchema?: z.ZodType<Output>;
|
|
8
|
+
response?: Output;
|
|
9
|
+
error?: {
|
|
10
|
+
error: string;
|
|
11
|
+
code?: string;
|
|
12
|
+
};
|
|
13
|
+
fn?: FlinkTool<any, Input, Output>;
|
|
14
|
+
permissions?: FlinkToolProps["permissions"];
|
|
15
|
+
}
|
|
16
|
+
export interface MockToolInvocation<Input> {
|
|
17
|
+
input: Input;
|
|
18
|
+
user?: any;
|
|
19
|
+
}
|
|
20
|
+
export interface MockToolResult<Input, Output> {
|
|
21
|
+
props: FlinkToolProps;
|
|
22
|
+
fn: FlinkTool<any, Input, Output>;
|
|
23
|
+
invocations: MockToolInvocation<Input>[];
|
|
24
|
+
getLastInvocation(): MockToolInvocation<Input> | undefined;
|
|
25
|
+
reset(): void;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Creates a mock tool with tracking and canned responses
|
|
29
|
+
*
|
|
30
|
+
* Features:
|
|
31
|
+
* - Simple canned responses
|
|
32
|
+
* - Error simulation
|
|
33
|
+
* - Custom function support
|
|
34
|
+
* - Automatic invocation tracking
|
|
35
|
+
* - Validation helpers
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* // Simple canned response
|
|
39
|
+
* const weatherTool = mockTool({
|
|
40
|
+
* name: "get_weather",
|
|
41
|
+
* inputSchema: z.object({ city: z.string() }),
|
|
42
|
+
* response: { temperature: 22, conditions: "sunny" }
|
|
43
|
+
* });
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* // Custom function with tracking
|
|
47
|
+
* const calculatorTool = mockTool({
|
|
48
|
+
* name: "calculate",
|
|
49
|
+
* inputSchema: z.object({ a: z.number(), b: z.number() }),
|
|
50
|
+
* fn: async ({ input }) => ({
|
|
51
|
+
* success: true,
|
|
52
|
+
* data: { result: input.a + input.b }
|
|
53
|
+
* })
|
|
54
|
+
* });
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* // Error simulation
|
|
58
|
+
* const failingTool = mockTool({
|
|
59
|
+
* name: "fail",
|
|
60
|
+
* inputSchema: z.object({}),
|
|
61
|
+
* error: { error: "Tool failed", code: "MOCK_ERROR" }
|
|
62
|
+
* });
|
|
63
|
+
*/
|
|
64
|
+
export declare function mockTool<Input = any, Output = any>(config: MockToolConfig<Input, Output>): MockToolResult<Input, Output>;
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
13
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
+
function step(op) {
|
|
16
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
18
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
+
switch (op[0]) {
|
|
21
|
+
case 0: case 1: t = op; break;
|
|
22
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
+
default:
|
|
26
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
+
if (t[2]) _.ops.pop();
|
|
31
|
+
_.trys.pop(); continue;
|
|
32
|
+
}
|
|
33
|
+
op = body.call(thisArg, _);
|
|
34
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.mockTool = mockTool;
|
|
40
|
+
/**
|
|
41
|
+
* Creates a mock tool with tracking and canned responses
|
|
42
|
+
*
|
|
43
|
+
* Features:
|
|
44
|
+
* - Simple canned responses
|
|
45
|
+
* - Error simulation
|
|
46
|
+
* - Custom function support
|
|
47
|
+
* - Automatic invocation tracking
|
|
48
|
+
* - Validation helpers
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* // Simple canned response
|
|
52
|
+
* const weatherTool = mockTool({
|
|
53
|
+
* name: "get_weather",
|
|
54
|
+
* inputSchema: z.object({ city: z.string() }),
|
|
55
|
+
* response: { temperature: 22, conditions: "sunny" }
|
|
56
|
+
* });
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* // Custom function with tracking
|
|
60
|
+
* const calculatorTool = mockTool({
|
|
61
|
+
* name: "calculate",
|
|
62
|
+
* inputSchema: z.object({ a: z.number(), b: z.number() }),
|
|
63
|
+
* fn: async ({ input }) => ({
|
|
64
|
+
* success: true,
|
|
65
|
+
* data: { result: input.a + input.b }
|
|
66
|
+
* })
|
|
67
|
+
* });
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* // Error simulation
|
|
71
|
+
* const failingTool = mockTool({
|
|
72
|
+
* name: "fail",
|
|
73
|
+
* inputSchema: z.object({}),
|
|
74
|
+
* error: { error: "Tool failed", code: "MOCK_ERROR" }
|
|
75
|
+
* });
|
|
76
|
+
*/
|
|
77
|
+
function mockTool(config) {
|
|
78
|
+
var _this = this;
|
|
79
|
+
var invocations = [];
|
|
80
|
+
// Create the tool props
|
|
81
|
+
var props = {
|
|
82
|
+
id: config.name,
|
|
83
|
+
description: config.description || "Mock tool: ".concat(config.name),
|
|
84
|
+
inputSchema: config.inputSchema,
|
|
85
|
+
outputSchema: config.outputSchema,
|
|
86
|
+
permissions: config.permissions,
|
|
87
|
+
};
|
|
88
|
+
// Create the tool function with invocation tracking
|
|
89
|
+
var fn = function (_a) { return __awaiter(_this, [_a], void 0, function (_b) {
|
|
90
|
+
var input = _b.input, ctx = _b.ctx, user = _b.user;
|
|
91
|
+
return __generator(this, function (_c) {
|
|
92
|
+
// Track invocation
|
|
93
|
+
invocations.push({ input: input, user: user });
|
|
94
|
+
// If custom function provided, use it
|
|
95
|
+
if (config.fn) {
|
|
96
|
+
return [2 /*return*/, config.fn({ input: input, ctx: ctx, user: user })];
|
|
97
|
+
}
|
|
98
|
+
// If error configured, return error
|
|
99
|
+
if (config.error) {
|
|
100
|
+
return [2 /*return*/, {
|
|
101
|
+
success: false,
|
|
102
|
+
error: config.error.error,
|
|
103
|
+
code: config.error.code,
|
|
104
|
+
}];
|
|
105
|
+
}
|
|
106
|
+
// If response configured, return success with data
|
|
107
|
+
if (config.response !== undefined) {
|
|
108
|
+
return [2 /*return*/, {
|
|
109
|
+
success: true,
|
|
110
|
+
data: config.response,
|
|
111
|
+
}];
|
|
112
|
+
}
|
|
113
|
+
// Default: return empty success
|
|
114
|
+
return [2 /*return*/, {
|
|
115
|
+
success: true,
|
|
116
|
+
data: {},
|
|
117
|
+
}];
|
|
118
|
+
});
|
|
119
|
+
}); };
|
|
120
|
+
var getLastInvocation = function () {
|
|
121
|
+
return invocations[invocations.length - 1];
|
|
122
|
+
};
|
|
123
|
+
var reset = function () {
|
|
124
|
+
invocations.length = 0;
|
|
125
|
+
};
|
|
126
|
+
return {
|
|
127
|
+
props: props,
|
|
128
|
+
fn: fn,
|
|
129
|
+
invocations: invocations,
|
|
130
|
+
getLastInvocation: getLastInvocation,
|
|
131
|
+
reset: reset,
|
|
132
|
+
};
|
|
133
|
+
}
|
package/dist/http.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FlinkApp, FlinkResponse } from "@flink-app/flink";
|
|
1
|
+
import { FlinkApp, FlinkContext, FlinkResponse } from "@flink-app/flink";
|
|
2
2
|
export type HttpOpts = {
|
|
3
3
|
/***
|
|
4
4
|
* Optional query string
|
|
@@ -26,7 +26,7 @@ export type HttpOpts = {
|
|
|
26
26
|
* Initializes test flink app.
|
|
27
27
|
* Must be invoked prior to using test HTTP methods.
|
|
28
28
|
*/
|
|
29
|
-
export declare function init(_app: FlinkApp<
|
|
29
|
+
export declare function init<C extends FlinkContext<any>>(_app: FlinkApp<C>, host?: string): void;
|
|
30
30
|
export declare function get<Res = any>(path: string, opts?: HttpOpts): Promise<FlinkResponse<Res>>;
|
|
31
31
|
export declare function post<Req = any, Res = any>(path: string, body: Req, opts?: HttpOpts): Promise<FlinkResponse<Res>>;
|
|
32
32
|
export declare function put<Req = any, Res = any>(path: string, body: Req, opts?: HttpOpts): Promise<FlinkResponse<Res>>;
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -16,3 +16,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./http"), exports);
|
|
18
18
|
__exportStar(require("./mocks"), exports);
|
|
19
|
+
__exportStar(require("./ai"), exports);
|
|
20
|
+
__exportStar(require("./requestContext"), exports);
|
package/dist/mocks.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FlinkAuthPlugin, FlinkRequest } from "@flink-app/flink";
|
|
1
|
+
import { FlinkAuthPlugin, FlinkContext, FlinkRequest } from "@flink-app/flink";
|
|
2
2
|
interface TestFlinkRequest<T, P, Q> extends Omit<Partial<FlinkRequest<T, P, Q>>, "body" | "params" | "query"> {
|
|
3
3
|
body?: T;
|
|
4
4
|
params?: P;
|
|
@@ -17,4 +17,17 @@ export declare function mockReq<T, P, Q>(req?: TestFlinkRequest<T, P, Q>): Flink
|
|
|
17
17
|
* @returns
|
|
18
18
|
*/
|
|
19
19
|
export declare function noOpAuthPlugin(): FlinkAuthPlugin;
|
|
20
|
+
/**
|
|
21
|
+
* Creates a mock FlinkContext with only the parts you need.
|
|
22
|
+
* Useful for testing services with mocked dependencies.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* const carService = new CarService();
|
|
27
|
+
* carService.ctx = mockCtx<AppCtx>({
|
|
28
|
+
* repos: { carRepo: mockCarRepo },
|
|
29
|
+
* });
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export declare function mockCtx<C extends FlinkContext>(partial?: Partial<C>): C;
|
|
20
33
|
export {};
|
package/dist/mocks.js
CHANGED
|
@@ -49,6 +49,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
49
49
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
50
50
|
exports.mockReq = mockReq;
|
|
51
51
|
exports.noOpAuthPlugin = noOpAuthPlugin;
|
|
52
|
+
exports.mockCtx = mockCtx;
|
|
52
53
|
/**
|
|
53
54
|
* Creates a mocked FlinkRequest object where only essential properties are required.
|
|
54
55
|
* Will convert req body to JSON to ensure the body is a plain object.
|
|
@@ -81,3 +82,19 @@ function noOpAuthPlugin() {
|
|
|
81
82
|
}); }); },
|
|
82
83
|
};
|
|
83
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* Creates a mock FlinkContext with only the parts you need.
|
|
87
|
+
* Useful for testing services with mocked dependencies.
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* ```typescript
|
|
91
|
+
* const carService = new CarService();
|
|
92
|
+
* carService.ctx = mockCtx<AppCtx>({
|
|
93
|
+
* repos: { carRepo: mockCarRepo },
|
|
94
|
+
* });
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
function mockCtx(partial) {
|
|
98
|
+
if (partial === void 0) { partial = {}; }
|
|
99
|
+
return __assign({ repos: {}, plugins: {} }, partial);
|
|
100
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { RequestContext } from '@flink-app/flink';
|
|
2
|
+
/**
|
|
3
|
+
* Create a mock request context for testing
|
|
4
|
+
*/
|
|
5
|
+
export declare function createMockRequestContext(overrides?: Partial<RequestContext>): RequestContext;
|
|
6
|
+
/**
|
|
7
|
+
* Execute a function within a mocked request context
|
|
8
|
+
* Useful for testing tools and agents that use AsyncLocalStorage
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* const result = await withRequestContext(
|
|
12
|
+
* { user: { id: '123', username: 'test' }, reqId: 'req-123' },
|
|
13
|
+
* async () => {
|
|
14
|
+
* return await someTool.execute({ carId: 'car-1' });
|
|
15
|
+
* }
|
|
16
|
+
* );
|
|
17
|
+
*/
|
|
18
|
+
export declare function withRequestContext<T>(context: Partial<RequestContext>, fn: () => T | Promise<T>): Promise<T>;
|
|
19
|
+
/**
|
|
20
|
+
* Create a test user with common properties
|
|
21
|
+
*/
|
|
22
|
+
export declare function createMockUser(overrides?: any): any;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __assign = (this && this.__assign) || function () {
|
|
3
|
+
__assign = Object.assign || function(t) {
|
|
4
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
+
s = arguments[i];
|
|
6
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
+
t[p] = s[p];
|
|
8
|
+
}
|
|
9
|
+
return t;
|
|
10
|
+
};
|
|
11
|
+
return __assign.apply(this, arguments);
|
|
12
|
+
};
|
|
13
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
14
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
15
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
16
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
17
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
18
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
19
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
23
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
24
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
25
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
26
|
+
function step(op) {
|
|
27
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
28
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
29
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
30
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
31
|
+
switch (op[0]) {
|
|
32
|
+
case 0: case 1: t = op; break;
|
|
33
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
34
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
35
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
36
|
+
default:
|
|
37
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
38
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
39
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
40
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
41
|
+
if (t[2]) _.ops.pop();
|
|
42
|
+
_.trys.pop(); continue;
|
|
43
|
+
}
|
|
44
|
+
op = body.call(thisArg, _);
|
|
45
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
46
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
50
|
+
exports.createMockRequestContext = createMockRequestContext;
|
|
51
|
+
exports.withRequestContext = withRequestContext;
|
|
52
|
+
exports.createMockUser = createMockUser;
|
|
53
|
+
var flink_1 = require("@flink-app/flink");
|
|
54
|
+
/**
|
|
55
|
+
* Create a mock request context for testing
|
|
56
|
+
*/
|
|
57
|
+
function createMockRequestContext(overrides) {
|
|
58
|
+
return __assign({ reqId: "test-req-" + Math.random().toString(36).substring(7), timestamp: Date.now() }, overrides);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Execute a function within a mocked request context
|
|
62
|
+
* Useful for testing tools and agents that use AsyncLocalStorage
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* const result = await withRequestContext(
|
|
66
|
+
* { user: { id: '123', username: 'test' }, reqId: 'req-123' },
|
|
67
|
+
* async () => {
|
|
68
|
+
* return await someTool.execute({ carId: 'car-1' });
|
|
69
|
+
* }
|
|
70
|
+
* );
|
|
71
|
+
*/
|
|
72
|
+
function withRequestContext(context, fn) {
|
|
73
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
74
|
+
var fullContext;
|
|
75
|
+
return __generator(this, function (_a) {
|
|
76
|
+
fullContext = createMockRequestContext(context);
|
|
77
|
+
return [2 /*return*/, flink_1.requestContext.run(fullContext, fn)];
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Create a test user with common properties
|
|
83
|
+
*/
|
|
84
|
+
function createMockUser(overrides) {
|
|
85
|
+
return __assign({ id: "user-" + Math.random().toString(36).substring(7), username: "testuser", email: "test@example.com" }, overrides);
|
|
86
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flink-app/test-utils",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0-alpha.101",
|
|
4
4
|
"description": "Test utils for Flink",
|
|
5
5
|
"author": "joel@frost.se",
|
|
6
6
|
"license": "MIT",
|
|
@@ -11,20 +11,24 @@
|
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
13
|
"got": "^9.6.0",
|
|
14
|
-
"qs": "^6.7.0"
|
|
14
|
+
"qs": "^6.7.0",
|
|
15
|
+
"zod": "^4.3.6"
|
|
15
16
|
},
|
|
16
17
|
"devDependencies": {
|
|
17
18
|
"@types/got": "^9.6.12",
|
|
19
|
+
"@types/jasmine": "^3.7.1",
|
|
18
20
|
"@types/node": "22.13.10",
|
|
19
21
|
"@types/qs": "^6.9.7",
|
|
22
|
+
"jasmine": "^3.10.0",
|
|
23
|
+
"jasmine-ts": "^0.3.3",
|
|
20
24
|
"ts-node": "^10.9.2",
|
|
21
25
|
"tsc-watch": "^4.2.9",
|
|
22
|
-
"@flink-app/flink": "
|
|
26
|
+
"@flink-app/flink": "2.0.0-alpha.101"
|
|
23
27
|
},
|
|
24
28
|
"gitHead": "4243e3b3cd6d4e1ca001a61baa8436bf2bbe4113",
|
|
25
29
|
"scripts": {
|
|
26
|
-
"test": "
|
|
27
|
-
"build": "tsc",
|
|
30
|
+
"test": "jasmine-ts --config=./spec/support/jasmine.json",
|
|
31
|
+
"build": "tsc --project tsconfig.dist.json",
|
|
28
32
|
"watch": "tsc-watch",
|
|
29
33
|
"clean": "rimraf dist .flink"
|
|
30
34
|
}
|