pi-llama-cpp 0.10.0 → 0.12.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 +187 -10
- package/package.json +6 -6
- package/src/api/client.ts +76 -32
- package/src/constants.ts +15 -0
- package/src/index.ts +3 -5
- package/src/interfaces/events.ts +14 -3
- package/src/interfaces/server.ts +27 -0
- package/src/interfaces/settings.ts +76 -2
- package/src/managers/command.ts +369 -50
- package/src/managers/events.ts +28 -10
- package/src/managers/server.ts +90 -16
- package/src/managers/settings.ts +181 -44
- package/src/models/baseModel.ts +37 -15
- package/src/models/routerModel.ts +2 -1
- package/src/server.ts +103 -28
- package/src/sse/client.ts +28 -16
- package/src/sse/manager.ts +26 -13
- package/src/ui/dialog.ts +287 -0
- package/src/ui/overrideEntryEditor.ts +119 -0
- package/src/ui/overrideSettingsList.ts +682 -0
- package/src/ui/serverListEditor.ts +32 -0
- package/src/ui/serverSettingsList.ts +466 -0
- package/src/ui/strings.ts +127 -0
- package/src/utils/errors.ts +5 -0
- package/src/utils/settingsStore.ts +56 -0
- package/src/utils/urls.ts +16 -0
- package/tests/commandManager.test.ts +346 -11
- package/tests/dialog.test.ts +186 -0
- package/tests/events.test.ts +120 -88
- package/tests/legacyModel.test.ts +4 -19
- package/tests/mocks.ts +149 -32
- package/tests/overrides.test.ts +352 -0
- package/tests/server.test.ts +42 -40
- package/tests/serverManager.test.ts +264 -55
- package/tests/settings.test.ts +654 -51
- package/tests/settingsStore.test.ts +190 -0
- package/tests/singleModel.test.ts +32 -0
- package/tests/sseManager.test.ts +88 -11
- package/src/interfaces/auth.ts +0 -6
- package/src/utils/cache.ts +0 -39
- package/src/utils/mutex.ts +0 -24
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it } from "vitest";
|
|
2
|
+
import { FALLBACK_CTX } from "../src/constants";
|
|
3
|
+
import type { LlamaServer, ModelOverride } from "../src/interfaces/settings";
|
|
4
|
+
import { SingleModel } from "../src/models/singleModel";
|
|
5
|
+
import { Server } from "../src/server";
|
|
6
|
+
import {
|
|
7
|
+
addOverrideEntry,
|
|
8
|
+
applyCostFieldValue,
|
|
9
|
+
formatOverrideSummary,
|
|
10
|
+
parseCostValue,
|
|
11
|
+
removeOverrideEntry,
|
|
12
|
+
updateOverrideEntry,
|
|
13
|
+
} from "../src/ui/overrideEntryEditor";
|
|
14
|
+
import { createMockServer, mockRpc } from "./mocks";
|
|
15
|
+
|
|
16
|
+
beforeEach(() => {
|
|
17
|
+
mockRpc.mockReset();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const createModel = (overrides?: Record<string, ModelOverride>): SingleModel =>
|
|
21
|
+
new SingleModel(
|
|
22
|
+
{
|
|
23
|
+
id: "test",
|
|
24
|
+
tags: [],
|
|
25
|
+
object: "model",
|
|
26
|
+
owned_by: "test",
|
|
27
|
+
created: Date.now(),
|
|
28
|
+
},
|
|
29
|
+
createMockServer({ overrides }),
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
/** Standard server responses: /props for capabilities, /v1/models for n_ctx */
|
|
33
|
+
const mockDetection = (nCtx: number | undefined) =>
|
|
34
|
+
mockRpc.mockImplementation((endpoint: string) => {
|
|
35
|
+
if (endpoint.startsWith("/props")) {
|
|
36
|
+
return Promise.resolve({ modalities: { vision: false } });
|
|
37
|
+
}
|
|
38
|
+
return Promise.resolve({
|
|
39
|
+
data: [{ id: "test", meta: nCtx === undefined ? {} : { n_ctx: nCtx } }],
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// ─── Pattern matching (Server.findOverrideForModel) ───────────────────────
|
|
44
|
+
|
|
45
|
+
describe("Server.findOverrideForModel", () => {
|
|
46
|
+
const makeServer = (overrides: Record<string, ModelOverride>): Server =>
|
|
47
|
+
createMockServer({ overrides });
|
|
48
|
+
|
|
49
|
+
it("should match a model by id prefix", () => {
|
|
50
|
+
const server = makeServer({ lla: { reasoning: false } });
|
|
51
|
+
expect(server.findOverrideForModel("llama-3")).toEqual({
|
|
52
|
+
reasoning: false,
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it("should return undefined when no pattern matches", () => {
|
|
57
|
+
const server = makeServer({ qwen: { reasoning: false } });
|
|
58
|
+
expect(server.findOverrideForModel("llama-3")).toBeUndefined();
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it("should prefer the longest (most specific) matching pattern", () => {
|
|
62
|
+
const server = makeServer({
|
|
63
|
+
llama: { reasoning: false },
|
|
64
|
+
"llama-3-8b": { reasoning: true, contextSize: 128 },
|
|
65
|
+
});
|
|
66
|
+
expect(server.findOverrideForModel("llama-3-8b")).toEqual({
|
|
67
|
+
reasoning: true,
|
|
68
|
+
contextSize: 128,
|
|
69
|
+
});
|
|
70
|
+
expect(server.findOverrideForModel("llama-3-70b")).toEqual({
|
|
71
|
+
reasoning: false,
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it("should ignore empty patterns", () => {
|
|
76
|
+
const server = makeServer({ "": { reasoning: false } });
|
|
77
|
+
expect(server.findOverrideForModel("llama-3")).toBeUndefined();
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
// ─── reasoning override ────────────────────────────────────────────────────
|
|
82
|
+
|
|
83
|
+
describe("BaseModel reasoning override", () => {
|
|
84
|
+
it("should default to true when no override matches", () => {
|
|
85
|
+
expect(createModel().reasoning).toBe(true);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it("should let the override win over the default", () => {
|
|
89
|
+
const model = createModel({ test: { reasoning: false } });
|
|
90
|
+
expect(model.reasoning).toBe(false);
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
// ─── capabilities override ────────────────────────────────────────────────
|
|
95
|
+
|
|
96
|
+
describe("BaseModel capabilities override", () => {
|
|
97
|
+
it("should fully replace detection without contacting the server", async () => {
|
|
98
|
+
mockRpc.mockImplementation(() => {
|
|
99
|
+
throw new Error("override must not trigger a fetch");
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
const model = createModel({ test: { capabilities: ["text", "image"] } });
|
|
103
|
+
const capabilities = await model.getCapabilities();
|
|
104
|
+
|
|
105
|
+
expect(capabilities).toEqual(["text", "image"]);
|
|
106
|
+
expect(mockRpc).not.toHaveBeenCalled();
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it("should not intercept detection when no override matches", async () => {
|
|
110
|
+
mockDetection(8192);
|
|
111
|
+
|
|
112
|
+
const model = createModel({ other: { capabilities: ["text"] } });
|
|
113
|
+
const capabilities = await model.getCapabilities();
|
|
114
|
+
|
|
115
|
+
expect(capabilities).toEqual(["text"]);
|
|
116
|
+
expect(mockRpc).toHaveBeenCalled();
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
// ─── contextSize override ─────────────────────────────────────────────────
|
|
121
|
+
|
|
122
|
+
describe("BaseModel.getContextSize with contextSize override", () => {
|
|
123
|
+
it("should return the overridden context size instead of the detected one", async () => {
|
|
124
|
+
mockDetection(8192);
|
|
125
|
+
|
|
126
|
+
const model = createModel({ test: { contextSize: 32768 } });
|
|
127
|
+
const ctxSize = await model.getContextSize();
|
|
128
|
+
|
|
129
|
+
expect(ctxSize).toBe(32768);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it("should treat a stored 0 as absent and autodetect", async () => {
|
|
133
|
+
mockDetection(8192);
|
|
134
|
+
|
|
135
|
+
const model = createModel({ test: { contextSize: 0 } });
|
|
136
|
+
const ctxSize = await model.getContextSize();
|
|
137
|
+
|
|
138
|
+
expect(ctxSize).toBe(8192);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it("should autodetect when no override matches", async () => {
|
|
142
|
+
mockDetection(8192);
|
|
143
|
+
|
|
144
|
+
const model = createModel({ other: { contextSize: 32768 } });
|
|
145
|
+
const ctxSize = await model.getContextSize();
|
|
146
|
+
|
|
147
|
+
expect(ctxSize).toBe(8192);
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
// ─── toProviderConfig (cost, maxTokens, compat, precedence) ───────────────
|
|
152
|
+
|
|
153
|
+
describe("toProviderConfig overrides", () => {
|
|
154
|
+
it("should merge a partial cost override with zero defaults", async () => {
|
|
155
|
+
mockDetection(8192);
|
|
156
|
+
|
|
157
|
+
const model = createModel({ test: { cost: { input: 0.2 } } });
|
|
158
|
+
const config = await model.toProviderConfig();
|
|
159
|
+
|
|
160
|
+
expect(config.cost).toEqual({
|
|
161
|
+
input: 0.2,
|
|
162
|
+
output: 0,
|
|
163
|
+
cacheRead: 0,
|
|
164
|
+
cacheWrite: 0,
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
it("should default every cost field to zero without an override", async () => {
|
|
169
|
+
mockDetection(8192);
|
|
170
|
+
|
|
171
|
+
const model = createModel();
|
|
172
|
+
const config = await model.toProviderConfig();
|
|
173
|
+
|
|
174
|
+
expect(config.cost).toEqual({
|
|
175
|
+
input: 0,
|
|
176
|
+
output: 0,
|
|
177
|
+
cacheRead: 0,
|
|
178
|
+
cacheWrite: 0,
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
it("should pass a compat override through to the provider config", async () => {
|
|
183
|
+
mockDetection(8192);
|
|
184
|
+
|
|
185
|
+
const compat = {
|
|
186
|
+
supportsStore: false,
|
|
187
|
+
maxTokensField: "max_tokens",
|
|
188
|
+
} as const;
|
|
189
|
+
const model = createModel({ test: { compat } });
|
|
190
|
+
const config = await model.toProviderConfig();
|
|
191
|
+
|
|
192
|
+
expect(config.compat).toEqual(compat);
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
it("should leave compat undefined without an override", async () => {
|
|
196
|
+
mockDetection(8192);
|
|
197
|
+
|
|
198
|
+
const model = createModel();
|
|
199
|
+
const config = await model.toProviderConfig();
|
|
200
|
+
|
|
201
|
+
expect(config.compat).toBeUndefined();
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
it("should use the overridden context size for contextWindow and as the maxTokens fallback", async () => {
|
|
205
|
+
mockDetection(8192);
|
|
206
|
+
|
|
207
|
+
const model = createModel({ test: { contextSize: 32768 } });
|
|
208
|
+
const config = await model.toProviderConfig();
|
|
209
|
+
|
|
210
|
+
expect(config.contextWindow).toBe(32768);
|
|
211
|
+
expect(config.maxTokens).toBe(32768);
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
it("should prefer an explicit maxTokens override over the contextSize override", async () => {
|
|
215
|
+
mockDetection(8192);
|
|
216
|
+
|
|
217
|
+
const model = createModel({
|
|
218
|
+
test: { contextSize: 32768, maxTokens: 4096 },
|
|
219
|
+
});
|
|
220
|
+
const config = await model.toProviderConfig();
|
|
221
|
+
|
|
222
|
+
expect(config.contextWindow).toBe(32768);
|
|
223
|
+
expect(config.maxTokens).toBe(4096);
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
it("should use the detected context size when no override matches", async () => {
|
|
227
|
+
mockDetection(8192);
|
|
228
|
+
|
|
229
|
+
const model = createModel();
|
|
230
|
+
const config = await model.toProviderConfig();
|
|
231
|
+
|
|
232
|
+
expect(config.contextWindow).toBe(8192);
|
|
233
|
+
expect(config.maxTokens).toBe(8192);
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
it("should fall back to FALLBACK_CTX when the model is missing from detection", async () => {
|
|
237
|
+
mockRpc.mockImplementation((endpoint: string) => {
|
|
238
|
+
if (endpoint.startsWith("/props")) {
|
|
239
|
+
return Promise.resolve({ modalities: { vision: false } });
|
|
240
|
+
}
|
|
241
|
+
// /v1/models: no entry for this model → getContextSize throws → fallback
|
|
242
|
+
return Promise.resolve({ data: [] });
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
const model = createModel();
|
|
246
|
+
const config = await model.toProviderConfig();
|
|
247
|
+
|
|
248
|
+
expect(config.contextWindow).toBe(FALLBACK_CTX);
|
|
249
|
+
expect(config.maxTokens).toBe(FALLBACK_CTX);
|
|
250
|
+
});
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
// ─── formatOverrideSummary ────────────────────────────────────────────────
|
|
254
|
+
|
|
255
|
+
describe("formatOverrideSummary", () => {
|
|
256
|
+
it("should render every configured field", () => {
|
|
257
|
+
const summary = formatOverrideSummary({
|
|
258
|
+
cost: { input: 0.2, output: 0.6, cacheRead: 0.01 },
|
|
259
|
+
capabilities: ["text", "image"],
|
|
260
|
+
reasoning: false,
|
|
261
|
+
contextSize: 32768,
|
|
262
|
+
maxTokens: 4096,
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
expect(summary).toContain("input: $0.2");
|
|
266
|
+
expect(summary).toContain("output: $0.6");
|
|
267
|
+
expect(summary).toContain("cache read: $0.01");
|
|
268
|
+
expect(summary).toContain("capabilities: text,image");
|
|
269
|
+
expect(summary).toContain("reasoning: false");
|
|
270
|
+
expect(summary).toContain("contextSize: 32768");
|
|
271
|
+
expect(summary).toContain("maxTokens: 4096");
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
it("should omit zero, undefined and empty fields", () => {
|
|
275
|
+
const summary = formatOverrideSummary({
|
|
276
|
+
cost: { input: 0, output: 0.6 },
|
|
277
|
+
reasoning: undefined,
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
expect(summary).not.toContain("input:");
|
|
281
|
+
expect(summary).toContain("output: $0.6");
|
|
282
|
+
expect(summary).not.toContain("capabilities");
|
|
283
|
+
expect(summary).not.toContain("reasoning");
|
|
284
|
+
expect(summary).not.toContain("contextSize");
|
|
285
|
+
expect(summary).not.toContain("maxTokens");
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
it("should render an em dash for an empty override", () => {
|
|
289
|
+
expect(formatOverrideSummary({})).toBe("—");
|
|
290
|
+
});
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
// ─── override entry list helpers (overrideEntryEditor) ────────────────────
|
|
294
|
+
|
|
295
|
+
describe("override entry list helpers", () => {
|
|
296
|
+
const servers = [
|
|
297
|
+
{ url: "http://a", overrides: { "a-1": { reasoning: false } } },
|
|
298
|
+
{ url: "http://b" },
|
|
299
|
+
] as LlamaServer[];
|
|
300
|
+
|
|
301
|
+
it("addOverrideEntry should append a pattern → override entry", () => {
|
|
302
|
+
const next = addOverrideEntry(servers, 0, "a-2", { contextSize: 4096 });
|
|
303
|
+
expect(next[0].overrides).toEqual({
|
|
304
|
+
"a-1": { reasoning: false },
|
|
305
|
+
"a-2": { contextSize: 4096 },
|
|
306
|
+
});
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
it("updateOverrideEntry should replace in place without reordering", () => {
|
|
310
|
+
const next = updateOverrideEntry(servers, 0, 0, "a-renamed", {
|
|
311
|
+
reasoning: true,
|
|
312
|
+
});
|
|
313
|
+
expect(Object.keys(next[0].overrides!)).toEqual(["a-renamed"]);
|
|
314
|
+
expect(next[0].overrides!["a-renamed"]).toEqual({ reasoning: true });
|
|
315
|
+
expect(next[1]).toBe(servers[1]);
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
it("removeOverrideEntry should drop only the targeted entry", () => {
|
|
319
|
+
const withTwo = addOverrideEntry(servers, 0, "a-2", {});
|
|
320
|
+
const next = removeOverrideEntry(withTwo, 0, 0);
|
|
321
|
+
expect(Object.keys(next[0].overrides!)).toEqual(["a-2"]);
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
it("parseCostValue should accept blank, non-negative numbers; reject the rest", () => {
|
|
325
|
+
expect(parseCostValue("")).toBe(0);
|
|
326
|
+
expect(parseCostValue(" 0.5 ")).toBe(0.5);
|
|
327
|
+
expect(parseCostValue("-1")).toBeNull();
|
|
328
|
+
expect(parseCostValue("abc")).toBeNull();
|
|
329
|
+
expect(parseCostValue("Infinity")).toBeNull();
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
it("applyCostFieldValue should set a positive value, keeping other fields", () => {
|
|
333
|
+
const next = applyCostFieldValue({ input: 0.2 }, "output", 0.6);
|
|
334
|
+
expect(next).toEqual({ input: 0.2, output: 0.6 });
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
it("applyCostFieldValue should remove the field on zero", () => {
|
|
338
|
+
const next = applyCostFieldValue({ input: 0.2, output: 0.6 }, "input", 0);
|
|
339
|
+
expect(next).toEqual({ output: 0.6 });
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
it("applyCostFieldValue should return undefined when the last field is zeroed", () => {
|
|
343
|
+
expect(applyCostFieldValue({ input: 0.2 }, "input", 0)).toBeUndefined();
|
|
344
|
+
expect(applyCostFieldValue(undefined, "input", 0)).toBeUndefined();
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
it("applyCostFieldValue should treat an empty override as unset cost", () => {
|
|
348
|
+
expect(applyCostFieldValue(undefined, "input", 0.5)).toEqual({
|
|
349
|
+
input: 0.5,
|
|
350
|
+
});
|
|
351
|
+
});
|
|
352
|
+
});
|
package/tests/server.test.ts
CHANGED
|
@@ -1,29 +1,36 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, it } from "vitest";
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
2
|
import { POLLING_TIMEOUT, SERVER_TIMEOUT } from "../src/constants";
|
|
3
3
|
import { ServerStatus } from "../src/enums/serverStatus";
|
|
4
|
+
import type { LlamaSettingsManager } from "../src/managers/settings";
|
|
4
5
|
import { Server } from "../src/server";
|
|
5
|
-
import { createMockServer, mockRpc } from "./mocks";
|
|
6
|
+
import { createMockServer, makeSettingsStub, mockRpc } from "./mocks";
|
|
7
|
+
|
|
8
|
+
// Injected into every real Server below; fresh per test so per-case
|
|
9
|
+
// overrides never leak. The Server constructor resolves the API key eagerly
|
|
10
|
+
// (ApiClient built there) — the stub's placeholder key is never consumed.
|
|
11
|
+
let settings: LlamaSettingsManager;
|
|
6
12
|
|
|
7
13
|
beforeEach(() => {
|
|
8
14
|
mockRpc.mockClear();
|
|
15
|
+
settings = makeSettingsStub();
|
|
9
16
|
});
|
|
10
17
|
|
|
11
18
|
describe("Server providerId", () => {
|
|
12
19
|
it("should generate a unique provider ID from baseUrl", () => {
|
|
13
|
-
const server = new Server("http://127.0.0.1:8080");
|
|
20
|
+
const server = new Server(settings, { baseUrl: "http://127.0.0.1:8080" });
|
|
14
21
|
expect(server.providerId).toBe("llama-server=http://127.0.0.1:8080");
|
|
15
22
|
});
|
|
16
23
|
|
|
17
24
|
it("should generate different IDs for different baseUrls", () => {
|
|
18
|
-
const server1 = new Server("http://127.0.0.1:8080");
|
|
19
|
-
const server2 = new Server("http://127.0.0.1:8081");
|
|
25
|
+
const server1 = new Server(settings, { baseUrl: "http://127.0.0.1:8080" });
|
|
26
|
+
const server2 = new Server(settings, { baseUrl: "http://127.0.0.1:8081" });
|
|
20
27
|
expect(server1.providerId).not.toBe(server2.providerId);
|
|
21
28
|
});
|
|
22
29
|
});
|
|
23
30
|
|
|
24
31
|
describe("Server providerName", () => {
|
|
25
32
|
it("should generate a human-readable provider name", () => {
|
|
26
|
-
const server = new Server("http://127.0.0.1:8080");
|
|
33
|
+
const server = new Server(settings, { baseUrl: "http://127.0.0.1:8080" });
|
|
27
34
|
expect(server.providerName).toBe("Llama.cpp (http://127.0.0.1:8080)");
|
|
28
35
|
});
|
|
29
36
|
});
|
|
@@ -147,48 +154,43 @@ describe("Server postRequest", () => {
|
|
|
147
154
|
});
|
|
148
155
|
});
|
|
149
156
|
|
|
150
|
-
describe("Server timeouts", () => {
|
|
151
|
-
it("should
|
|
152
|
-
const server = new Server("http://127.0.0.1:8080");
|
|
157
|
+
describe("Server timeouts", async () => {
|
|
158
|
+
it("should resolve timeouts from the injected settings", async () => {
|
|
159
|
+
const server = new Server(settings, { baseUrl: "http://127.0.0.1:8080" });
|
|
153
160
|
|
|
154
|
-
expect(server.
|
|
155
|
-
expect(server.
|
|
161
|
+
expect(await server.getServerTimeout()).toBe(SERVER_TIMEOUT);
|
|
162
|
+
expect(await server.getPollingTimeout()).toBe(POLLING_TIMEOUT);
|
|
156
163
|
});
|
|
157
164
|
|
|
158
|
-
it("should
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
3000,
|
|
164
|
-
);
|
|
165
|
-
|
|
166
|
-
expect(server.serverTimeout).toBe(3000);
|
|
167
|
-
});
|
|
165
|
+
it("should return resolved custom values", async () => {
|
|
166
|
+
vi.mocked(settings.resolveTimeouts).mockResolvedValue({
|
|
167
|
+
pollingTimeout: 90000,
|
|
168
|
+
serverTimeout: 2000,
|
|
169
|
+
});
|
|
168
170
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
1000,
|
|
175
|
-
120000,
|
|
176
|
-
);
|
|
171
|
+
const server = new Server(settings, {
|
|
172
|
+
baseUrl: "http://127.0.0.1:8080",
|
|
173
|
+
customId: "my-id",
|
|
174
|
+
customName: "My Server",
|
|
175
|
+
});
|
|
177
176
|
|
|
178
|
-
expect(server.
|
|
177
|
+
expect(await server.getPollingTimeout()).toBe(90000);
|
|
179
178
|
});
|
|
180
179
|
|
|
181
|
-
it("should
|
|
182
|
-
const server = new Server(
|
|
183
|
-
"http://127.0.0.1:8080",
|
|
184
|
-
"my-id",
|
|
185
|
-
"My Server",
|
|
186
|
-
2000,
|
|
187
|
-
90000,
|
|
188
|
-
);
|
|
180
|
+
it("should read timeouts live from settings", async () => {
|
|
181
|
+
const server = new Server(settings, { baseUrl: "http://127.0.0.1:8080" });
|
|
189
182
|
|
|
190
|
-
|
|
191
|
-
|
|
183
|
+
vi.mocked(settings.resolveTimeouts).mockResolvedValue({
|
|
184
|
+
pollingTimeout: 120000,
|
|
185
|
+
serverTimeout: 3000,
|
|
186
|
+
});
|
|
187
|
+
expect(await server.getPollingTimeout()).toBe(120000);
|
|
188
|
+
|
|
189
|
+
vi.mocked(settings.resolveTimeouts).mockResolvedValue({
|
|
190
|
+
pollingTimeout: 90000,
|
|
191
|
+
serverTimeout: 2000,
|
|
192
|
+
});
|
|
193
|
+
expect(await server.getPollingTimeout()).toBe(90000);
|
|
192
194
|
});
|
|
193
195
|
});
|
|
194
196
|
|