@jamesaphoenix/tx-test-utils 0.5.9 → 0.5.10

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.
@@ -1,271 +0,0 @@
1
- /**
2
- * Effect test helpers unit tests.
3
- *
4
- * Tests the Effect runners and assertions for correct behavior.
5
- */
6
- import { describe, it, expect } from "vitest";
7
- import { Effect, Layer, Context, Data } from "effect";
8
- import { runEffect, runEffectFail, runEffectEither, expectEffectSuccess, expectEffectFailure, mergeLayers, createTestContext } from "./effect.js";
9
- import { Either } from "effect";
10
- // =============================================================================
11
- // Test Error Types
12
- // =============================================================================
13
- class TestError extends Data.TaggedError("TestError") {
14
- }
15
- class TestServiceTag extends Context.Tag("TestService")() {
16
- }
17
- const TestServiceLive = Layer.succeed(TestServiceTag, {
18
- getValue: () => Effect.succeed(42),
19
- getValueOrFail: (shouldFail) => shouldFail
20
- ? Effect.fail(new TestError({ message: "Test failure" }))
21
- : Effect.succeed(42)
22
- });
23
- // =============================================================================
24
- // runEffect Tests
25
- // =============================================================================
26
- describe("runEffect", () => {
27
- it("returns the value for a successful Effect", async () => {
28
- const result = await runEffect(Effect.succeed(42));
29
- expect(result).toBe(42);
30
- });
31
- it("works with complex values", async () => {
32
- const obj = { name: "test", value: 123 };
33
- const result = await runEffect(Effect.succeed(obj));
34
- expect(result).toEqual(obj);
35
- });
36
- it("throws an error for a failed Effect", async () => {
37
- const effect = Effect.fail(new TestError({ message: "oops" }));
38
- await expect(runEffect(effect)).rejects.toThrow("Effect failed:");
39
- });
40
- it("supports Layer injection", async () => {
41
- const effect = Effect.gen(function* () {
42
- const service = yield* TestServiceTag;
43
- return yield* service.getValue();
44
- });
45
- const result = await runEffect(effect, TestServiceLive);
46
- expect(result).toBe(42);
47
- });
48
- it("throws when Effect times out", async () => {
49
- const slowEffect = Effect.gen(function* () {
50
- yield* Effect.sleep(1000);
51
- return 42;
52
- });
53
- await expect(runEffect(slowEffect, undefined, { timeout: 50 })).rejects.toThrow("Effect failed:");
54
- });
55
- });
56
- // =============================================================================
57
- // runEffectFail Tests
58
- // =============================================================================
59
- describe("runEffectFail", () => {
60
- it("returns the cause for a failed Effect", async () => {
61
- const effect = Effect.fail(new TestError({ message: "expected failure" }));
62
- const cause = await runEffectFail(effect);
63
- expect(cause).toBeDefined();
64
- });
65
- it("throws when Effect succeeds unexpectedly", async () => {
66
- const effect = Effect.succeed(42);
67
- await expect(runEffectFail(effect)).rejects.toThrow("Expected Effect to fail, but it succeeded");
68
- });
69
- it("supports Layer injection for failure cases", async () => {
70
- const effect = Effect.gen(function* () {
71
- const service = yield* TestServiceTag;
72
- return yield* service.getValueOrFail(true);
73
- });
74
- const cause = await runEffectFail(effect, TestServiceLive);
75
- expect(cause).toBeDefined();
76
- });
77
- });
78
- // =============================================================================
79
- // runEffectEither Tests
80
- // =============================================================================
81
- describe("runEffectEither", () => {
82
- it("returns Right for successful Effect", async () => {
83
- const result = await runEffectEither(Effect.succeed(42));
84
- expect(Either.isRight(result)).toBe(true);
85
- if (Either.isRight(result)) {
86
- expect(result.right).toBe(42);
87
- }
88
- });
89
- it("returns Left for failed Effect", async () => {
90
- const effect = Effect.fail(new TestError({ message: "expected" }));
91
- const result = await runEffectEither(effect);
92
- expect(Either.isLeft(result)).toBe(true);
93
- if (Either.isLeft(result)) {
94
- expect(result.left._tag).toBe("TestError");
95
- }
96
- });
97
- it("never throws for typed failures", async () => {
98
- const effect = Effect.fail(new TestError({ message: "test" }));
99
- // Should not throw
100
- const result = await runEffectEither(effect);
101
- expect(Either.isLeft(result)).toBe(true);
102
- });
103
- it("supports Layer injection", async () => {
104
- const effect = Effect.gen(function* () {
105
- const service = yield* TestServiceTag;
106
- return yield* service.getValue();
107
- });
108
- const result = await runEffectEither(effect, TestServiceLive);
109
- expect(Either.isRight(result)).toBe(true);
110
- if (Either.isRight(result)) {
111
- expect(result.right).toBe(42);
112
- }
113
- });
114
- });
115
- // =============================================================================
116
- // expectEffectSuccess Tests
117
- // =============================================================================
118
- describe("expectEffectSuccess", () => {
119
- it("returns the value for successful Effect", async () => {
120
- const result = await expectEffectSuccess(Effect.succeed(42));
121
- expect(result).toBe(42);
122
- });
123
- it("supports validation callback", async () => {
124
- let validated = false;
125
- const result = await expectEffectSuccess(Effect.succeed({ id: 1, name: "test" }), undefined, (value) => {
126
- expect(value.id).toBe(1);
127
- expect(value.name).toBe("test");
128
- validated = true;
129
- });
130
- expect(result.id).toBe(1);
131
- expect(validated).toBe(true);
132
- });
133
- it("throws when Effect fails", async () => {
134
- const effect = Effect.fail(new TestError({ message: "fail" }));
135
- await expect(expectEffectSuccess(effect)).rejects.toThrow("Effect failed:");
136
- });
137
- it("supports async validation", async () => {
138
- let validated = false;
139
- await expectEffectSuccess(Effect.succeed(42), undefined, async (value) => {
140
- await Promise.resolve();
141
- expect(value).toBe(42);
142
- validated = true;
143
- });
144
- expect(validated).toBe(true);
145
- });
146
- });
147
- // =============================================================================
148
- // expectEffectFailure Tests
149
- // =============================================================================
150
- describe("expectEffectFailure", () => {
151
- it("returns the error for failed Effect", async () => {
152
- const effect = Effect.fail(new TestError({ message: "expected" }));
153
- const error = await expectEffectFailure(effect);
154
- expect(error._tag).toBe("TestError");
155
- expect(error.message).toBe("expected");
156
- });
157
- it("supports validation callback", async () => {
158
- const effect = Effect.fail(new TestError({ message: "check me" }));
159
- const error = await expectEffectFailure(effect, undefined, (err) => {
160
- expect(err._tag).toBe("TestError");
161
- expect(err.message).toBe("check me");
162
- });
163
- expect(error.message).toBe("check me");
164
- });
165
- it("throws when Effect succeeds", async () => {
166
- const effect = Effect.succeed(42);
167
- await expect(expectEffectFailure(effect)).rejects.toThrow("Expected Effect to fail, but it succeeded");
168
- });
169
- it("supports Layer injection", async () => {
170
- const effect = Effect.gen(function* () {
171
- const service = yield* TestServiceTag;
172
- return yield* service.getValueOrFail(true);
173
- });
174
- const error = await expectEffectFailure(effect, TestServiceLive, (err) => {
175
- expect(err._tag).toBe("TestError");
176
- });
177
- expect(error._tag).toBe("TestError");
178
- });
179
- });
180
- // =============================================================================
181
- // mergeLayers Tests
182
- // =============================================================================
183
- describe("mergeLayers", () => {
184
- class ServiceATag extends Context.Tag("ServiceA")() {
185
- }
186
- class ServiceBTag extends Context.Tag("ServiceB")() {
187
- }
188
- const ServiceALive = Layer.succeed(ServiceATag, { a: 1 });
189
- const ServiceBLive = Layer.succeed(ServiceBTag, { b: "hello" });
190
- it("returns empty layer when no layers provided", () => {
191
- const merged = mergeLayers();
192
- expect(merged).toBeDefined();
193
- });
194
- it("returns the layer when single layer provided", () => {
195
- const merged = mergeLayers(ServiceALive);
196
- expect(merged).toBeDefined();
197
- });
198
- it("merges multiple layers", async () => {
199
- const merged = mergeLayers(ServiceALive, ServiceBLive);
200
- const effect = Effect.gen(function* () {
201
- const a = yield* ServiceATag;
202
- const b = yield* ServiceBTag;
203
- return { a: a.a, b: b.b };
204
- });
205
- const result = await runEffect(effect, merged);
206
- expect(result).toEqual({ a: 1, b: "hello" });
207
- });
208
- });
209
- // =============================================================================
210
- // createTestContext Tests
211
- // =============================================================================
212
- describe("createTestContext", () => {
213
- it("creates a context with runEffect method", async () => {
214
- const ctx = createTestContext(() => TestServiceLive);
215
- const effect = Effect.gen(function* () {
216
- const service = yield* TestServiceTag;
217
- return yield* service.getValue();
218
- });
219
- const result = await ctx.runEffect(effect);
220
- expect(result).toBe(42);
221
- });
222
- it("reuses the layer across multiple calls", async () => {
223
- let layerCreationCount = 0;
224
- const ctx = createTestContext(() => {
225
- layerCreationCount++;
226
- return TestServiceLive;
227
- });
228
- const effect = Effect.gen(function* () {
229
- const service = yield* TestServiceTag;
230
- return yield* service.getValue();
231
- });
232
- await ctx.runEffect(effect);
233
- await ctx.runEffect(effect);
234
- await ctx.runEffect(effect);
235
- expect(layerCreationCount).toBe(1);
236
- });
237
- it("supports runEffectFail", async () => {
238
- const ctx = createTestContext(() => TestServiceLive);
239
- const effect = Effect.gen(function* () {
240
- const service = yield* TestServiceTag;
241
- return yield* service.getValueOrFail(true);
242
- });
243
- const cause = await ctx.runEffectFail(effect);
244
- expect(cause).toBeDefined();
245
- });
246
- it("supports runEffectEither", async () => {
247
- const ctx = createTestContext(() => TestServiceLive);
248
- const effect = Effect.gen(function* () {
249
- const service = yield* TestServiceTag;
250
- return yield* service.getValue();
251
- });
252
- const result = await ctx.runEffectEither(effect);
253
- expect(Either.isRight(result)).toBe(true);
254
- });
255
- it("reset forces layer recreation", async () => {
256
- let layerCreationCount = 0;
257
- const ctx = createTestContext(() => {
258
- layerCreationCount++;
259
- return TestServiceLive;
260
- });
261
- const effect = Effect.gen(function* () {
262
- const service = yield* TestServiceTag;
263
- return yield* service.getValue();
264
- });
265
- await ctx.runEffect(effect);
266
- ctx.reset();
267
- await ctx.runEffect(effect);
268
- expect(layerCreationCount).toBe(2);
269
- });
270
- });
271
- //# sourceMappingURL=effect.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"effect.test.js","sourceRoot":"","sources":["../../src/helpers/effect.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAC7C,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AACrD,OAAO,EACL,SAAS,EACT,aAAa,EACb,eAAe,EACf,mBAAmB,EACnB,mBAAmB,EACnB,WAAW,EACX,iBAAiB,EAClB,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAE/B,gFAAgF;AAChF,mBAAmB;AACnB,gFAAgF;AAEhF,MAAM,SAAU,SAAQ,IAAI,CAAC,WAAW,CAAC,WAAW,CAElD;CAAG;AAWL,MAAM,cAAe,SAAQ,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,EAGpD;CAAG;AAEN,MAAM,eAAe,GAAG,KAAK,CAAC,OAAO,CACnC,cAAc,EACd;IACE,QAAQ,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;IAClC,cAAc,EAAE,CAAC,UAAU,EAAE,EAAE,CAC7B,UAAU;QACR,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,CAAC;QACzD,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;CACzB,CACF,CAAA;AAED,gFAAgF;AAChF,kBAAkB;AAClB,gFAAgF;AAEhF,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;IACzB,EAAE,CAAC,2CAA2C,EAAE,KAAK,IAAI,EAAE;QACzD,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAA;QAClD,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IACzB,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,2BAA2B,EAAE,KAAK,IAAI,EAAE;QACzC,MAAM,GAAG,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,CAAA;QACxC,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAA;QACnD,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IAC7B,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;QACnD,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,CAAA;QAE9D,MAAM,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAA;IACnE,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,0BAA0B,EAAE,KAAK,IAAI,EAAE;QACxC,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YACjC,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,cAAc,CAAA;YACrC,OAAO,KAAK,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAA;QAClC,CAAC,CAAC,CAAA;QAEF,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,MAAM,EAAE,eAAe,CAAC,CAAA;QACvD,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IACzB,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,8BAA8B,EAAE,KAAK,IAAI,EAAE;QAC5C,MAAM,UAAU,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YACrC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;YACzB,OAAO,EAAE,CAAA;QACX,CAAC,CAAC,CAAA;QAEF,MAAM,MAAM,CACV,SAAS,CAAC,UAAU,EAAE,SAAS,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAClD,CAAC,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAA;IACrC,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,gFAAgF;AAChF,sBAAsB;AACtB,gFAAgF;AAEhF,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,EAAE,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;QACrD,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAAC,CAAC,CAAA;QAE1E,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,MAAM,CAAC,CAAA;QACzC,MAAM,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAA;IAC7B,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,0CAA0C,EAAE,KAAK,IAAI,EAAE;QACxD,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QAEjC,MAAM,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CACjD,2CAA2C,CAC5C,CAAA;IACH,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,4CAA4C,EAAE,KAAK,IAAI,EAAE;QAC1D,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YACjC,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,cAAc,CAAA;YACrC,OAAO,KAAK,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,CAAA;QAC5C,CAAC,CAAC,CAAA;QAEF,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,MAAM,EAAE,eAAe,CAAC,CAAA;QAC1D,MAAM,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAA;IAC7B,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,gFAAgF;AAChF,wBAAwB;AACxB,gFAAgF;AAEhF,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,EAAE,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;QACnD,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAA;QAExD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACzC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3B,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QAC/B,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,gCAAgC,EAAE,KAAK,IAAI,EAAE;QAC9C,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC,CAAA;QAClE,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,MAAM,CAAC,CAAA;QAE5C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACxC,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1B,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;QAC5C,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,iCAAiC,EAAE,KAAK,IAAI,EAAE;QAC/C,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,CAAA;QAE9D,mBAAmB;QACnB,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,MAAM,CAAC,CAAA;QAC5C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC1C,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,0BAA0B,EAAE,KAAK,IAAI,EAAE;QACxC,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YACjC,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,cAAc,CAAA;YACrC,OAAO,KAAK,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAA;QAClC,CAAC,CAAC,CAAA;QAEF,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,MAAM,EAAE,eAAe,CAAC,CAAA;QAC7D,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACzC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3B,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QAC/B,CAAC;IACH,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,gFAAgF;AAChF,4BAA4B;AAC5B,gFAAgF;AAEhF,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,EAAE,CAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;QACvD,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAA;QAC5D,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IACzB,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,8BAA8B,EAAE,KAAK,IAAI,EAAE;QAC5C,IAAI,SAAS,GAAG,KAAK,CAAA;QACrB,MAAM,MAAM,GAAG,MAAM,mBAAmB,CACtC,MAAM,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EACvC,SAAS,EACT,CAAC,KAAK,EAAE,EAAE;YACR,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YACxB,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;YAC/B,SAAS,GAAG,IAAI,CAAA;QAClB,CAAC,CACF,CAAA;QAED,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACzB,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC9B,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,0BAA0B,EAAE,KAAK,IAAI,EAAE;QACxC,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,CAAA;QAE9D,MAAM,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAA;IAC7E,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,2BAA2B,EAAE,KAAK,IAAI,EAAE;QACzC,IAAI,SAAS,GAAG,KAAK,CAAA;QACrB,MAAM,mBAAmB,CACvB,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,EAClB,SAAS,EACT,KAAK,EAAE,KAAK,EAAE,EAAE;YACd,MAAM,OAAO,CAAC,OAAO,EAAE,CAAA;YACvB,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;YACtB,SAAS,GAAG,IAAI,CAAA;QAClB,CAAC,CACF,CAAA;QAED,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC9B,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,gFAAgF;AAChF,4BAA4B;AAC5B,gFAAgF;AAEhF,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,EAAE,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;QACnD,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC,CAAA;QAElE,MAAM,KAAK,GAAG,MAAM,mBAAmB,CAAY,MAAM,CAAC,CAAA;QAC1D,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;QACpC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;IACxC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,8BAA8B,EAAE,KAAK,IAAI,EAAE;QAC5C,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC,CAAA;QAElE,MAAM,KAAK,GAAG,MAAM,mBAAmB,CACrC,MAAM,EACN,SAAS,EACT,CAAC,GAAG,EAAE,EAAE;YACN,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;YAClC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QACtC,CAAC,CACF,CAAA;QAED,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;IACxC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,6BAA6B,EAAE,KAAK,IAAI,EAAE;QAC3C,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QAEjC,MAAM,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CACvD,2CAA2C,CAC5C,CAAA;IACH,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,0BAA0B,EAAE,KAAK,IAAI,EAAE;QACxC,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YACjC,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,cAAc,CAAA;YACrC,OAAO,KAAK,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,CAAA;QAC5C,CAAC,CAAC,CAAA;QAEF,MAAM,KAAK,GAAG,MAAM,mBAAmB,CACrC,MAAa,EACb,eAAsB,EACtB,CAAC,GAAG,EAAE,EAAE;YACN,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;QACpC,CAAC,CACF,CAAA;QAED,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;IACtC,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,gFAAgF;AAChF,oBAAoB;AACpB,gFAAgF;AAEhF,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAQ3B,MAAM,WAAY,SAAQ,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,EAAyB;KAAG;IAC7E,MAAM,WAAY,SAAQ,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,EAAyB;KAAG;IAE7E,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;IACzD,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,CAAA;IAE/D,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,MAAM,MAAM,GAAG,WAAW,EAAE,CAAA;QAC5B,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAA;IAC9B,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,MAAM,MAAM,GAAG,WAAW,CAAC,YAAY,CAAC,CAAA;QACxC,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAA;IAC9B,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,wBAAwB,EAAE,KAAK,IAAI,EAAE;QACtC,MAAM,MAAM,GAAG,WAAW,CAAC,YAAY,EAAE,YAAY,CAAC,CAAA;QAEtD,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YACjC,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,WAAW,CAAA;YAC5B,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,WAAW,CAAA;YAC5B,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;QAC3B,CAAC,CAAC,CAAA;QAEF,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,MAAM,EAAE,MAAa,CAAC,CAAA;QACrD,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,CAAA;IAC9C,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,gFAAgF;AAChF,0BAA0B;AAC1B,gFAAgF;AAEhF,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,EAAE,CAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;QACvD,MAAM,GAAG,GAAG,iBAAiB,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,CAAA;QAEpD,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YACjC,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,cAAc,CAAA;YACrC,OAAO,KAAK,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAA;QAClC,CAAC,CAAC,CAAA;QAEF,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,CAAA;QAC1C,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IACzB,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,wCAAwC,EAAE,KAAK,IAAI,EAAE;QACtD,IAAI,kBAAkB,GAAG,CAAC,CAAA;QAE1B,MAAM,GAAG,GAAG,iBAAiB,CAAC,GAAG,EAAE;YACjC,kBAAkB,EAAE,CAAA;YACpB,OAAO,eAAe,CAAA;QACxB,CAAC,CAAC,CAAA;QAEF,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YACjC,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,cAAc,CAAA;YACrC,OAAO,KAAK,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAA;QAClC,CAAC,CAAC,CAAA;QAEF,MAAM,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,CAAA;QAC3B,MAAM,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,CAAA;QAC3B,MAAM,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,CAAA;QAE3B,MAAM,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACpC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,wBAAwB,EAAE,KAAK,IAAI,EAAE;QACtC,MAAM,GAAG,GAAG,iBAAiB,CAAC,GAAG,EAAE,CAAC,eAAsB,CAAC,CAAA;QAE3D,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YACjC,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,cAAc,CAAA;YACrC,OAAO,KAAK,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,CAAA;QAC5C,CAAC,CAAC,CAAA;QAEF,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,aAAa,CAAC,MAAa,CAAC,CAAA;QACpD,MAAM,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAA;IAC7B,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,0BAA0B,EAAE,KAAK,IAAI,EAAE;QACxC,MAAM,GAAG,GAAG,iBAAiB,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,CAAA;QAEpD,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YACjC,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,cAAc,CAAA;YACrC,OAAO,KAAK,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAA;QAClC,CAAC,CAAC,CAAA;QAEF,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,eAAe,CAAC,MAAM,CAAC,CAAA;QAChD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC3C,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,+BAA+B,EAAE,KAAK,IAAI,EAAE;QAC7C,IAAI,kBAAkB,GAAG,CAAC,CAAA;QAE1B,MAAM,GAAG,GAAG,iBAAiB,CAAC,GAAG,EAAE;YACjC,kBAAkB,EAAE,CAAA;YACpB,OAAO,eAAe,CAAA;QACxB,CAAC,CAAC,CAAA;QAEF,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YACjC,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,cAAc,CAAA;YACrC,OAAO,KAAK,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAA;QAClC,CAAC,CAAC,CAAA;QAEF,MAAM,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,CAAA;QAC3B,GAAG,CAAC,KAAK,EAAE,CAAA;QACX,MAAM,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,CAAA;QAE3B,MAAM,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACpC,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
@@ -1,7 +0,0 @@
1
- /**
2
- * Integration tests for LLM response caching.
3
- *
4
- * @module @tx/test-utils/llm-cache/cache.test
5
- */
6
- export {};
7
- //# sourceMappingURL=cache.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cache.test.d.ts","sourceRoot":"","sources":["../../src/llm-cache/cache.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -1,310 +0,0 @@
1
- /**
2
- * Integration tests for LLM response caching.
3
- *
4
- * @module @tx/test-utils/llm-cache/cache.test
5
- */
6
- import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
7
- import * as fs from "fs/promises";
8
- import * as path from "path";
9
- import * as os from "os";
10
- import { hashInput, cachedLLMCall, withLLMCache, configureLLMCache, resetCacheConfig, getCacheStats, clearCache, formatCacheStats, getCacheEntry, listCacheEntries } from "./index.js";
11
- // =============================================================================
12
- // Test Setup
13
- // =============================================================================
14
- describe("LLM Cache", () => {
15
- let tempDir;
16
- beforeEach(async () => {
17
- // Create isolated temp directory for each test
18
- tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "tx-llm-cache-test-"));
19
- configureLLMCache({ cacheDir: tempDir, logging: false });
20
- });
21
- afterEach(async () => {
22
- // Clean up temp directory
23
- resetCacheConfig();
24
- try {
25
- await fs.rm(tempDir, { recursive: true, force: true });
26
- }
27
- catch {
28
- // Ignore cleanup errors
29
- }
30
- });
31
- // ===========================================================================
32
- // hashInput Tests
33
- // ===========================================================================
34
- describe("hashInput", () => {
35
- it("should return deterministic SHA256 hash", () => {
36
- const input = "What is the capital of France?";
37
- const hash1 = hashInput(input);
38
- const hash2 = hashInput(input);
39
- expect(hash1).toBe(hash2);
40
- expect(hash1).toHaveLength(64); // SHA256 hex = 64 chars
41
- expect(hash1).toMatch(/^[a-f0-9]{64}$/);
42
- });
43
- it("should produce different hashes for different inputs", () => {
44
- const hash1 = hashInput("input one");
45
- const hash2 = hashInput("input two");
46
- expect(hash1).not.toBe(hash2);
47
- });
48
- it("should handle empty string", () => {
49
- const hash = hashInput("");
50
- expect(hash).toHaveLength(64);
51
- // SHA256 of empty string is a known value
52
- expect(hash).toBe("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855");
53
- });
54
- it("should handle unicode input", () => {
55
- const hash = hashInput("こんにちは世界 🌍");
56
- expect(hash).toHaveLength(64);
57
- expect(hashInput("こんにちは世界 🌍")).toBe(hash);
58
- });
59
- it("should handle very long input", () => {
60
- const longInput = "a".repeat(100000);
61
- const hash = hashInput(longInput);
62
- expect(hash).toHaveLength(64);
63
- });
64
- });
65
- // ===========================================================================
66
- // cachedLLMCall Tests
67
- // ===========================================================================
68
- describe("cachedLLMCall", () => {
69
- it("should call function on cache miss and store result", async () => {
70
- const mockCall = vi.fn().mockResolvedValue({ answer: "Paris" });
71
- const result = await cachedLLMCall("What is the capital of France?", "claude-sonnet-4", mockCall);
72
- expect(result).toEqual({ answer: "Paris" });
73
- expect(mockCall).toHaveBeenCalledTimes(1);
74
- // Verify cache file was created
75
- const files = await fs.readdir(tempDir);
76
- expect(files.length).toBe(1);
77
- expect(files[0]).toMatch(/^[a-f0-9]{64}\.json$/);
78
- });
79
- it("should return cached value on cache hit without calling function", async () => {
80
- const mockCall = vi.fn().mockResolvedValue({ answer: "Paris" });
81
- const input = "What is the capital of France?";
82
- // First call - cache miss
83
- await cachedLLMCall(input, "claude-sonnet-4", mockCall);
84
- expect(mockCall).toHaveBeenCalledTimes(1);
85
- // Second call - cache hit
86
- const result = await cachedLLMCall(input, "claude-sonnet-4", mockCall);
87
- expect(result).toEqual({ answer: "Paris" });
88
- expect(mockCall).toHaveBeenCalledTimes(1); // Not called again
89
- });
90
- it("should bypass cache when TX_NO_LLM_CACHE=1", async () => {
91
- const originalEnv = process.env.TX_NO_LLM_CACHE;
92
- process.env.TX_NO_LLM_CACHE = "1";
93
- try {
94
- const mockCall = vi.fn().mockResolvedValue({ answer: "Paris" });
95
- const input = "What is the capital of France?";
96
- // First call
97
- await cachedLLMCall(input, "claude-sonnet-4", mockCall);
98
- // Second call - should still call function
99
- await cachedLLMCall(input, "claude-sonnet-4", mockCall);
100
- expect(mockCall).toHaveBeenCalledTimes(2);
101
- // Cache should not have been written
102
- const files = await fs.readdir(tempDir);
103
- expect(files.length).toBe(0);
104
- }
105
- finally {
106
- if (originalEnv === undefined) {
107
- delete process.env.TX_NO_LLM_CACHE;
108
- }
109
- else {
110
- process.env.TX_NO_LLM_CACHE = originalEnv;
111
- }
112
- }
113
- });
114
- it("should bypass cache when forceRefresh=true", async () => {
115
- const mockCall = vi.fn()
116
- .mockResolvedValueOnce({ answer: "Paris" })
117
- .mockResolvedValueOnce({ answer: "Paris (updated)" });
118
- const input = "What is the capital of France?";
119
- // First call - cache miss
120
- await cachedLLMCall(input, "claude-sonnet-4", mockCall);
121
- // Second call with forceRefresh - should call function
122
- const result = await cachedLLMCall(input, "claude-sonnet-4", mockCall, { forceRefresh: true });
123
- expect(result).toEqual({ answer: "Paris (updated)" });
124
- expect(mockCall).toHaveBeenCalledTimes(2);
125
- });
126
- it("should trigger cache miss on version mismatch", async () => {
127
- const mockCall = vi.fn()
128
- .mockResolvedValueOnce({ answer: "Paris v1" })
129
- .mockResolvedValueOnce({ answer: "Paris v2" });
130
- const input = "What is the capital of France?";
131
- // First call with version 1
132
- await cachedLLMCall(input, "claude-sonnet-4", mockCall, { version: 1 });
133
- // Second call with version 2 - should be cache miss
134
- const result = await cachedLLMCall(input, "claude-sonnet-4", mockCall, { version: 2 });
135
- expect(result).toEqual({ answer: "Paris v2" });
136
- expect(mockCall).toHaveBeenCalledTimes(2);
137
- });
138
- it("should store correct cache entry format", async () => {
139
- const mockCall = vi.fn().mockResolvedValue({ answer: "Paris" });
140
- const input = "What is the capital of France?";
141
- await cachedLLMCall(input, "claude-sonnet-4", mockCall, { version: 3 });
142
- const hash = hashInput(input);
143
- const cacheFile = path.join(tempDir, `${hash}.json`);
144
- const content = JSON.parse(await fs.readFile(cacheFile, "utf-8"));
145
- expect(content.inputHash).toBe(hash);
146
- expect(content.input).toBe(input);
147
- expect(content.response).toEqual({ answer: "Paris" });
148
- expect(content.model).toBe("claude-sonnet-4");
149
- expect(content.version).toBe(3);
150
- expect(content.cachedAt).toMatch(/^\d{4}-\d{2}-\d{2}T/);
151
- });
152
- it("should truncate long input in cache entry", async () => {
153
- const mockCall = vi.fn().mockResolvedValue({ answer: "42" });
154
- const longInput = "a".repeat(2000);
155
- await cachedLLMCall(longInput, "claude-sonnet-4", mockCall);
156
- const hash = hashInput(longInput);
157
- const cacheFile = path.join(tempDir, `${hash}.json`);
158
- const content = JSON.parse(await fs.readFile(cacheFile, "utf-8"));
159
- expect(content.input.length).toBe(1000); // Truncated
160
- expect(content.inputHash).toBe(hash); // Full hash preserved
161
- });
162
- });
163
- // ===========================================================================
164
- // withLLMCache Tests
165
- // ===========================================================================
166
- describe("withLLMCache", () => {
167
- it("should wrap function with caching", async () => {
168
- const mockFn = vi.fn().mockResolvedValue("result");
169
- const cachedFn = withLLMCache(mockFn, { model: "claude-sonnet-4" });
170
- const result1 = await cachedFn("input");
171
- const result2 = await cachedFn("input");
172
- expect(result1).toBe("result");
173
- expect(result2).toBe("result");
174
- expect(mockFn).toHaveBeenCalledTimes(1);
175
- });
176
- it("should use custom serializer", async () => {
177
- const mockFn = vi.fn().mockResolvedValue("result");
178
- const cachedFn = withLLMCache(mockFn, {
179
- model: "claude-sonnet-4",
180
- // Only use query for cache key (ignore context)
181
- serialize: (input) => input.query
182
- });
183
- // Same query, different context - should hit cache
184
- await cachedFn({ query: "test", context: ["a"] });
185
- await cachedFn({ query: "test", context: ["b", "c"] });
186
- expect(mockFn).toHaveBeenCalledTimes(1);
187
- });
188
- it("should pass version to cachedLLMCall", async () => {
189
- const mockFn = vi.fn()
190
- .mockResolvedValueOnce("v1 result")
191
- .mockResolvedValueOnce("v2 result");
192
- const cachedFnV1 = withLLMCache(mockFn, { model: "claude-sonnet-4", version: 1 });
193
- const cachedFnV2 = withLLMCache(mockFn, { model: "claude-sonnet-4", version: 2 });
194
- await cachedFnV1("input");
195
- const result = await cachedFnV2("input");
196
- expect(result).toBe("v2 result");
197
- expect(mockFn).toHaveBeenCalledTimes(2);
198
- });
199
- });
200
- // ===========================================================================
201
- // CLI Utilities Tests
202
- // ===========================================================================
203
- describe("getCacheStats", () => {
204
- it("should return empty stats for empty cache", async () => {
205
- const stats = await getCacheStats();
206
- expect(stats.count).toBe(0);
207
- expect(stats.totalBytes).toBe(0);
208
- expect(stats.oldestDate).toBeNull();
209
- expect(stats.newestDate).toBeNull();
210
- expect(stats.byModel).toEqual({});
211
- expect(stats.byVersion).toEqual({});
212
- });
213
- it("should return correct stats for populated cache", async () => {
214
- // Create some cache entries
215
- await cachedLLMCall("input1", "claude-sonnet-4", () => Promise.resolve("r1"), { version: 1 });
216
- await cachedLLMCall("input2", "claude-sonnet-4", () => Promise.resolve("r2"), { version: 1 });
217
- await cachedLLMCall("input3", "claude-haiku", () => Promise.resolve("r3"), { version: 2 });
218
- const stats = await getCacheStats();
219
- expect(stats.count).toBe(3);
220
- expect(stats.totalBytes).toBeGreaterThan(0);
221
- expect(stats.oldestDate).toBeInstanceOf(Date);
222
- expect(stats.newestDate).toBeInstanceOf(Date);
223
- expect(stats.byModel).toEqual({
224
- "claude-sonnet-4": 2,
225
- "claude-haiku": 1
226
- });
227
- expect(stats.byVersion).toEqual({
228
- 1: 2,
229
- 2: 1
230
- });
231
- });
232
- });
233
- describe("clearCache", () => {
234
- it("should clear all entries with all=true", async () => {
235
- await cachedLLMCall("input1", "claude-sonnet-4", () => Promise.resolve("r1"));
236
- await cachedLLMCall("input2", "claude-sonnet-4", () => Promise.resolve("r2"));
237
- const deleted = await clearCache({ all: true });
238
- expect(deleted).toBe(-1); // Unknown count for all
239
- const files = await fs.readdir(tempDir);
240
- expect(files.length).toBe(0);
241
- });
242
- it("should clear entries by model", async () => {
243
- await cachedLLMCall("input1", "claude-sonnet-4", () => Promise.resolve("r1"));
244
- await cachedLLMCall("input2", "claude-haiku", () => Promise.resolve("r2"));
245
- const deleted = await clearCache({ model: "claude-sonnet-4" });
246
- expect(deleted).toBe(1);
247
- const stats = await getCacheStats();
248
- expect(stats.count).toBe(1);
249
- expect(stats.byModel).toEqual({ "claude-haiku": 1 });
250
- });
251
- it("should clear entries by version", async () => {
252
- await cachedLLMCall("input1", "claude-sonnet-4", () => Promise.resolve("r1"), { version: 1 });
253
- await cachedLLMCall("input2", "claude-sonnet-4", () => Promise.resolve("r2"), { version: 2 });
254
- const deleted = await clearCache({ version: 1 });
255
- expect(deleted).toBe(1);
256
- const stats = await getCacheStats();
257
- expect(stats.byVersion).toEqual({ 2: 1 });
258
- });
259
- it("should clear entries older than date", async () => {
260
- await cachedLLMCall("input1", "claude-sonnet-4", () => Promise.resolve("r1"));
261
- // Clear entries older than 1 second in the future (all entries)
262
- const futureDate = new Date(Date.now() + 1000);
263
- const deleted = await clearCache({ olderThan: futureDate });
264
- expect(deleted).toBe(1);
265
- });
266
- });
267
- describe("formatCacheStats", () => {
268
- it("should format stats as readable string", async () => {
269
- await cachedLLMCall("input1", "claude-sonnet-4", () => Promise.resolve("r1"), { version: 1 });
270
- await cachedLLMCall("input2", "claude-haiku", () => Promise.resolve("r2"), { version: 2 });
271
- const stats = await getCacheStats();
272
- const formatted = formatCacheStats(stats);
273
- expect(formatted).toContain("LLM Cache Statistics:");
274
- expect(formatted).toContain("Entries: 2");
275
- expect(formatted).toContain("By model:");
276
- expect(formatted).toContain("claude-sonnet-4: 1");
277
- expect(formatted).toContain("claude-haiku: 1");
278
- });
279
- });
280
- describe("getCacheEntry", () => {
281
- it("should return entry by hash", async () => {
282
- const input = "test input";
283
- await cachedLLMCall(input, "claude-sonnet-4", () => Promise.resolve("result"));
284
- const hash = hashInput(input);
285
- const entry = await getCacheEntry(hash);
286
- expect(entry).not.toBeNull();
287
- expect(entry?.response).toBe("result");
288
- expect(entry?.model).toBe("claude-sonnet-4");
289
- });
290
- it("should return null for non-existent hash", async () => {
291
- const entry = await getCacheEntry("nonexistent");
292
- expect(entry).toBeNull();
293
- });
294
- });
295
- describe("listCacheEntries", () => {
296
- it("should list all cache entry hashes", async () => {
297
- await cachedLLMCall("input1", "claude-sonnet-4", () => Promise.resolve("r1"));
298
- await cachedLLMCall("input2", "claude-sonnet-4", () => Promise.resolve("r2"));
299
- const entries = await listCacheEntries();
300
- expect(entries.length).toBe(2);
301
- expect(entries[0]).toHaveLength(64);
302
- expect(entries[1]).toHaveLength(64);
303
- });
304
- it("should return empty array for empty cache", async () => {
305
- const entries = await listCacheEntries();
306
- expect(entries).toEqual([]);
307
- });
308
- });
309
- });
310
- //# sourceMappingURL=cache.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cache.test.js","sourceRoot":"","sources":["../../src/llm-cache/cache.test.ts"],"names":[],"mappings":"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"}