@elysiumjs/mnemosyne 0.1.2 → 0.3.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/CHANGELOG.md +90 -0
- package/README.md +19 -16
- package/dist/cache.d.ts +134 -0
- package/dist/database.d.ts +127 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +2 -0
- package/dist/interfaces.d.ts +360 -0
- package/dist/keyv-redis.d.ts +88 -0
- package/dist/mnemosyne.module.d.ts +44 -0
- package/dist/model.d.ts +68 -0
- package/dist/repository.d.ts +96 -0
- package/dist/tenancy.d.ts +201 -0
- package/package.json +21 -12
- package/bunfig.toml +0 -19
- package/src/cache.ts +0 -218
- package/src/database.ts +0 -151
- package/src/index.ts +0 -47
- package/src/interfaces.ts +0 -449
- package/src/keyv-redis.ts +0 -313
- package/src/model.ts +0 -189
- package/src/repository.ts +0 -137
- package/src/tenancy.ts +0 -291
- package/tests/cache.test.ts +0 -464
- package/tests/database.test.ts +0 -249
- package/tests/model.test.ts +0 -234
- package/tests/repository.test.ts +0 -177
- package/tests/setup.ts +0 -26
- package/tsconfig.json +0 -12
package/tests/cache.test.ts
DELETED
|
@@ -1,464 +0,0 @@
|
|
|
1
|
-
// Copyright (c) 2025-present Workbud Technologies Inc. All rights reserved.
|
|
2
|
-
//
|
|
3
|
-
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
// you may not use this file except in compliance with the License.
|
|
5
|
-
// You may obtain a copy of the License at
|
|
6
|
-
//
|
|
7
|
-
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
//
|
|
9
|
-
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
// See the License for the specific language governing permissions and
|
|
13
|
-
// limitations under the License.
|
|
14
|
-
|
|
15
|
-
import type { Mock } from 'bun:test';
|
|
16
|
-
|
|
17
|
-
import { afterAll, beforeAll, beforeEach, describe, expect, it, mock, spyOn } from 'bun:test';
|
|
18
|
-
import { createCache } from 'cache-manager';
|
|
19
|
-
import * as KV from 'keyv';
|
|
20
|
-
|
|
21
|
-
import { Event, Redis } from '@elysiumjs/core';
|
|
22
|
-
|
|
23
|
-
import { Cache } from '../src/cache';
|
|
24
|
-
|
|
25
|
-
// Mock dependencies
|
|
26
|
-
mock.module('cache-manager', () => ({
|
|
27
|
-
createCache: mock(createCache)
|
|
28
|
-
}));
|
|
29
|
-
|
|
30
|
-
Redis.registerConnection('cache', {
|
|
31
|
-
url: process.env.REDIS_TEST_URL!
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
// Test the weak cache
|
|
35
|
-
describe('Cache.weak', () => {
|
|
36
|
-
it('should get data from the weak cache', () => {
|
|
37
|
-
// Create a test object to use as a context
|
|
38
|
-
const testContext = {};
|
|
39
|
-
|
|
40
|
-
// Get data from the cache (should initialize with empty object)
|
|
41
|
-
const data = Cache.weak.get(testContext);
|
|
42
|
-
|
|
43
|
-
// Check if the data is an empty object
|
|
44
|
-
expect(data).toEqual({});
|
|
45
|
-
|
|
46
|
-
// Verify that the context is now in the map
|
|
47
|
-
expect(Cache.weak.map.has(testContext)).toBe(true);
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
it('should return existing data from the weak cache', () => {
|
|
51
|
-
// Create a test object to use as a context
|
|
52
|
-
const testContext = {};
|
|
53
|
-
|
|
54
|
-
// Set some data in the cache
|
|
55
|
-
const testData = { test: 'data' };
|
|
56
|
-
Cache.weak.map.set(testContext, testData);
|
|
57
|
-
|
|
58
|
-
// Get data from the cache
|
|
59
|
-
const data = Cache.weak.get(testContext);
|
|
60
|
-
|
|
61
|
-
// Check if the data matches what we set
|
|
62
|
-
expect(data).toBe(testData);
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
it('should delete data from the weak cache', () => {
|
|
66
|
-
// Create a test object to use as a context
|
|
67
|
-
const testContext = {};
|
|
68
|
-
|
|
69
|
-
// Set some data in the cache
|
|
70
|
-
Cache.weak.map.set(testContext, { test: 'data' });
|
|
71
|
-
|
|
72
|
-
// Verify that the context is in the map
|
|
73
|
-
expect(Cache.weak.map.has(testContext)).toBe(true);
|
|
74
|
-
|
|
75
|
-
// Delete the data
|
|
76
|
-
Cache.weak.del(testContext);
|
|
77
|
-
|
|
78
|
-
// Verify that the context is no longer in the map
|
|
79
|
-
expect(Cache.weak.map.has(testContext)).toBe(false);
|
|
80
|
-
});
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
// Test the Redis cache
|
|
84
|
-
describe('Cache.redis', () => {
|
|
85
|
-
beforeAll(() => {
|
|
86
|
-
Cache.redis.clear();
|
|
87
|
-
Event.emit('elysium:app:launched', null, null);
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
// Reset mocks before each test
|
|
91
|
-
beforeEach(() => {
|
|
92
|
-
mock.restore();
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
it('should be created with the correct configuration', async () => {
|
|
96
|
-
// Check if createCache was called with the correct parameters
|
|
97
|
-
expect(createCache).toHaveBeenCalledWith({
|
|
98
|
-
stores: expect.arrayContaining([expect.any(Object)])
|
|
99
|
-
});
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
it('should call get method with the correct parameters', async () => {
|
|
103
|
-
const getSpy = spyOn(Cache.redis, 'get');
|
|
104
|
-
|
|
105
|
-
// Call the get method
|
|
106
|
-
const result = await Cache.redis.get('test-key');
|
|
107
|
-
|
|
108
|
-
// Check if the get method was called with the correct parameters
|
|
109
|
-
expect(getSpy).toHaveBeenCalledWith('test-key');
|
|
110
|
-
|
|
111
|
-
// Check if the result is correct
|
|
112
|
-
expect(result).toBeNull();
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
it('should call set method with the correct parameters', async () => {
|
|
116
|
-
const setSpy = spyOn(Cache.redis, 'set');
|
|
117
|
-
|
|
118
|
-
// Call the set method
|
|
119
|
-
const result = await Cache.redis.set('test-key', 'test-value', 3600);
|
|
120
|
-
|
|
121
|
-
// Check if the set method was called with the correct parameters
|
|
122
|
-
expect(setSpy).toHaveBeenCalledWith('test-key', 'test-value', 3600);
|
|
123
|
-
|
|
124
|
-
// Check if the result is correct
|
|
125
|
-
expect(result).toBe('test-value');
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
it('should call ttl method with the correct parameters', async () => {
|
|
129
|
-
const ttlSpy = spyOn(Cache.redis, 'ttl');
|
|
130
|
-
|
|
131
|
-
// Call the ttl method
|
|
132
|
-
const result = await Cache.redis.ttl('test-key');
|
|
133
|
-
|
|
134
|
-
// Check if the ttl method was called with the correct parameters
|
|
135
|
-
expect(ttlSpy).toHaveBeenCalledWith('test-key');
|
|
136
|
-
|
|
137
|
-
const date = new Date(result!);
|
|
138
|
-
|
|
139
|
-
// Check if the result is correct
|
|
140
|
-
expect(date.getTime()).toBeGreaterThanOrEqual(Date.now() - 3600 * 1000);
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
it('should call del method with the correct parameters', async () => {
|
|
144
|
-
const delSpy = spyOn(Cache.redis, 'del');
|
|
145
|
-
|
|
146
|
-
// Call the del method
|
|
147
|
-
const result = await Cache.redis.del('test-key');
|
|
148
|
-
|
|
149
|
-
// Check if the del method was called with the correct parameters
|
|
150
|
-
expect(delSpy).toHaveBeenCalledWith('test-key');
|
|
151
|
-
|
|
152
|
-
// Check if the result is correct
|
|
153
|
-
expect(result).toBe(true);
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
it('should call mset method with the correct parameters', async () => {
|
|
157
|
-
const msetSpy = spyOn(Cache.redis, 'mset');
|
|
158
|
-
|
|
159
|
-
// Set up the mock to return the test data
|
|
160
|
-
const testData = [
|
|
161
|
-
{ key: 'key1', value: 'value1', ttl: 3600 },
|
|
162
|
-
{ key: 'key2', value: 'value2' }
|
|
163
|
-
];
|
|
164
|
-
|
|
165
|
-
// Call the mset method
|
|
166
|
-
const result = await Cache.redis.mset(testData);
|
|
167
|
-
|
|
168
|
-
// Check if the mset method was called with the correct parameters
|
|
169
|
-
expect(msetSpy).toHaveBeenCalledWith(testData);
|
|
170
|
-
|
|
171
|
-
// Check if the result is correct
|
|
172
|
-
expect(result).toEqual(testData);
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
it('should call mget method with the correct parameters', async () => {
|
|
176
|
-
const mgetSpy = spyOn(Cache.redis, 'mget');
|
|
177
|
-
|
|
178
|
-
// Call the mget method
|
|
179
|
-
const result = await Cache.redis.mget(['key1', 'key2']);
|
|
180
|
-
|
|
181
|
-
// Check if the mget method was called with the correct parameters
|
|
182
|
-
expect(mgetSpy).toHaveBeenCalledWith(['key1', 'key2']);
|
|
183
|
-
|
|
184
|
-
// Check if the result is correct
|
|
185
|
-
expect(result).toEqual(['value1', 'value2']);
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
it('should call mdel method with the correct parameters', async () => {
|
|
189
|
-
const mdelSpy = spyOn(Cache.redis, 'mdel');
|
|
190
|
-
|
|
191
|
-
// Call the mdel method
|
|
192
|
-
const result = await Cache.redis.mdel(['key1', 'key2']);
|
|
193
|
-
|
|
194
|
-
// Check if the mdel method was called with the correct parameters
|
|
195
|
-
expect(mdelSpy).toHaveBeenCalledWith(['key1', 'key2']);
|
|
196
|
-
|
|
197
|
-
// Check if the result is correct
|
|
198
|
-
expect(result).toBe(true);
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
it('should call clear method', async () => {
|
|
202
|
-
const clearSpy = spyOn(Cache.redis, 'clear');
|
|
203
|
-
|
|
204
|
-
// Call the clear method
|
|
205
|
-
const result = await Cache.redis.clear();
|
|
206
|
-
|
|
207
|
-
// Check if the clear method was called
|
|
208
|
-
expect(clearSpy).toHaveBeenCalled();
|
|
209
|
-
|
|
210
|
-
// Check if the result is correct
|
|
211
|
-
expect(result).toBe(true);
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
it('should create a tagged cache with the correct namespace', () => {
|
|
215
|
-
const keyvSpy = spyOn(KV, 'Keyv').mockReturnThis();
|
|
216
|
-
|
|
217
|
-
// Call the tags method
|
|
218
|
-
Cache.redis.tags('tag1', 'tag2');
|
|
219
|
-
|
|
220
|
-
// Check if Keyv was instantiated with the correct namespace
|
|
221
|
-
expect(keyvSpy).toHaveBeenCalledWith({
|
|
222
|
-
store: expect.any(Object),
|
|
223
|
-
namespace: 'cache__tag1__tag2'
|
|
224
|
-
});
|
|
225
|
-
|
|
226
|
-
// Check if createCache was called
|
|
227
|
-
expect(createCache).toHaveBeenCalled();
|
|
228
|
-
});
|
|
229
|
-
});
|
|
230
|
-
|
|
231
|
-
// Test the memory cache
|
|
232
|
-
describe('Cache.memory', () => {
|
|
233
|
-
// Reset mocks before each test
|
|
234
|
-
beforeEach(() => {
|
|
235
|
-
mock.restore();
|
|
236
|
-
});
|
|
237
|
-
|
|
238
|
-
it('should be created with the correct configuration', () => {
|
|
239
|
-
// Check if createCache was called with the correct parameters
|
|
240
|
-
expect(createCache).toHaveBeenCalledWith({
|
|
241
|
-
stores: expect.arrayContaining([expect.any(Object)])
|
|
242
|
-
});
|
|
243
|
-
});
|
|
244
|
-
|
|
245
|
-
it('should call set method with the correct parameters', async () => {
|
|
246
|
-
const setSpy = spyOn(Cache.memory, 'set');
|
|
247
|
-
|
|
248
|
-
// Call the set method
|
|
249
|
-
const result = await Cache.memory.set('test-key', 'test-value', 3600);
|
|
250
|
-
|
|
251
|
-
// Check if the set method was called with the correct parameters
|
|
252
|
-
expect(setSpy).toHaveBeenCalledWith('test-key', 'test-value', 3600);
|
|
253
|
-
|
|
254
|
-
// Check if the result is correct
|
|
255
|
-
expect(result).toBe('test-value');
|
|
256
|
-
});
|
|
257
|
-
it('should call get method with the correct parameters', async () => {
|
|
258
|
-
const getSpy = spyOn(Cache.memory, 'get');
|
|
259
|
-
|
|
260
|
-
// Call the get method
|
|
261
|
-
const result = await Cache.memory.get('test-key');
|
|
262
|
-
|
|
263
|
-
// Check if the get method was called with the correct parameters
|
|
264
|
-
expect(getSpy).toHaveBeenCalledWith('test-key');
|
|
265
|
-
|
|
266
|
-
// Check if the result is correct
|
|
267
|
-
expect(result).toBe('test-value');
|
|
268
|
-
});
|
|
269
|
-
|
|
270
|
-
it('should call ttl method with the correct parameters', async () => {
|
|
271
|
-
const ttlSpy = spyOn(Cache.memory, 'ttl');
|
|
272
|
-
|
|
273
|
-
// Call the ttl method
|
|
274
|
-
const result = await Cache.memory.ttl('test-key');
|
|
275
|
-
|
|
276
|
-
// Check if the ttl method was called with the correct parameters
|
|
277
|
-
expect(ttlSpy).toHaveBeenCalledWith('test-key');
|
|
278
|
-
|
|
279
|
-
const date = new Date(result!);
|
|
280
|
-
|
|
281
|
-
// Check if the result is correct
|
|
282
|
-
expect(date.getTime()).toBeGreaterThanOrEqual(Date.now() - 3600 * 1000);
|
|
283
|
-
});
|
|
284
|
-
|
|
285
|
-
it('should call del method with the correct parameters', async () => {
|
|
286
|
-
const delSpy = spyOn(Cache.memory, 'del');
|
|
287
|
-
|
|
288
|
-
// Call the del method
|
|
289
|
-
const result = await Cache.memory.del('test-key');
|
|
290
|
-
|
|
291
|
-
// Check if the del method was called with the correct parameters
|
|
292
|
-
expect(delSpy).toHaveBeenCalledWith('test-key');
|
|
293
|
-
|
|
294
|
-
// Check if the result is correct
|
|
295
|
-
expect(result).toBe(true);
|
|
296
|
-
});
|
|
297
|
-
|
|
298
|
-
it('should call mset method with the correct parameters', async () => {
|
|
299
|
-
const msetSpy = spyOn(Cache.memory, 'mset');
|
|
300
|
-
|
|
301
|
-
// Set up the mock to return the test data
|
|
302
|
-
const testData = [
|
|
303
|
-
{ key: 'key1', value: 'value1', ttl: 3600 },
|
|
304
|
-
{ key: 'key2', value: 'value2' }
|
|
305
|
-
];
|
|
306
|
-
|
|
307
|
-
// Call the mset method
|
|
308
|
-
const result = await Cache.memory.mset(testData);
|
|
309
|
-
|
|
310
|
-
// Check if the mset method was called with the correct parameters
|
|
311
|
-
expect(msetSpy).toHaveBeenCalledWith(testData);
|
|
312
|
-
|
|
313
|
-
// Check if the result is correct
|
|
314
|
-
expect(result).toEqual(testData);
|
|
315
|
-
});
|
|
316
|
-
|
|
317
|
-
it('should call mget method with the correct parameters', async () => {
|
|
318
|
-
const mgetSpy = spyOn(Cache.memory, 'mget');
|
|
319
|
-
|
|
320
|
-
// Call the mget method
|
|
321
|
-
const result = await Cache.memory.mget(['key1', 'key2']);
|
|
322
|
-
|
|
323
|
-
// Check if the mget method was called with the correct parameters
|
|
324
|
-
expect(mgetSpy).toHaveBeenCalledWith(['key1', 'key2']);
|
|
325
|
-
|
|
326
|
-
// Check if the result is correct
|
|
327
|
-
expect(result).toEqual(['value1', 'value2']);
|
|
328
|
-
});
|
|
329
|
-
|
|
330
|
-
it('should call mdel method with the correct parameters', async () => {
|
|
331
|
-
const mdelSpy = spyOn(Cache.memory, 'mdel');
|
|
332
|
-
|
|
333
|
-
// Call the mdel method
|
|
334
|
-
const result = await Cache.memory.mdel(['key1', 'key2']);
|
|
335
|
-
|
|
336
|
-
// Check if the mdel method was called with the correct parameters
|
|
337
|
-
expect(mdelSpy).toHaveBeenCalledWith(['key1', 'key2']);
|
|
338
|
-
|
|
339
|
-
// Check if the result is correct
|
|
340
|
-
expect(result).toBe(true);
|
|
341
|
-
});
|
|
342
|
-
|
|
343
|
-
it('should call clear method', async () => {
|
|
344
|
-
const clearSpy = spyOn(Cache.memory, 'clear');
|
|
345
|
-
|
|
346
|
-
// Call the clear method
|
|
347
|
-
const result = await Cache.memory.clear();
|
|
348
|
-
|
|
349
|
-
// Check if the clear method was called
|
|
350
|
-
expect(clearSpy).toHaveBeenCalled();
|
|
351
|
-
|
|
352
|
-
// Check if the result is correct
|
|
353
|
-
expect(result).toBe(true);
|
|
354
|
-
});
|
|
355
|
-
|
|
356
|
-
it('should create a tagged cache with the correct namespace', () => {
|
|
357
|
-
const keyvSpy = spyOn(KV, 'Keyv').mockReturnThis();
|
|
358
|
-
|
|
359
|
-
// Call the tags method
|
|
360
|
-
Cache.memory.tags('tag1', 'tag2');
|
|
361
|
-
|
|
362
|
-
// Check if Keyv was instantiated with the correct namespace
|
|
363
|
-
expect(keyvSpy).toHaveBeenCalledWith({
|
|
364
|
-
store: expect.any(Object),
|
|
365
|
-
namespace: 'cache__tag1__tag2'
|
|
366
|
-
});
|
|
367
|
-
|
|
368
|
-
// Check if createCache was called
|
|
369
|
-
expect(createCache).toHaveBeenCalled();
|
|
370
|
-
});
|
|
371
|
-
});
|
|
372
|
-
|
|
373
|
-
// Test cache with different TTL values
|
|
374
|
-
describe('Cache with TTL', () => {
|
|
375
|
-
beforeEach(() => {
|
|
376
|
-
mock.restore();
|
|
377
|
-
});
|
|
378
|
-
|
|
379
|
-
it('should set cache with TTL', async () => {
|
|
380
|
-
const setSpy = spyOn(Cache.memory, 'set');
|
|
381
|
-
|
|
382
|
-
// Call the set method with TTL
|
|
383
|
-
await Cache.memory.set('test-key', 'test-value', 3600);
|
|
384
|
-
|
|
385
|
-
// Check if the set method was called with the correct TTL
|
|
386
|
-
expect(setSpy).toHaveBeenCalledWith('test-key', 'test-value', 3600);
|
|
387
|
-
});
|
|
388
|
-
|
|
389
|
-
it('should set cache without TTL', async () => {
|
|
390
|
-
const setSpy = spyOn(Cache.memory, 'set');
|
|
391
|
-
|
|
392
|
-
// Call the set method without TTL
|
|
393
|
-
await Cache.memory.set('test-key', 'test-value');
|
|
394
|
-
|
|
395
|
-
// Check if the set method was called without TTL
|
|
396
|
-
expect(setSpy).toHaveBeenCalledWith('test-key', 'test-value');
|
|
397
|
-
});
|
|
398
|
-
|
|
399
|
-
it('should set multiple cache entries with different TTLs', async () => {
|
|
400
|
-
const msetSpy = spyOn(Cache.memory, 'mset');
|
|
401
|
-
|
|
402
|
-
// Set up the mock to return the test data
|
|
403
|
-
const testData = [
|
|
404
|
-
{ key: 'key1', value: 'value1', ttl: 3600 },
|
|
405
|
-
{ key: 'key2', value: 'value2' }
|
|
406
|
-
];
|
|
407
|
-
|
|
408
|
-
// Call the mset method
|
|
409
|
-
await Cache.memory.mset(testData);
|
|
410
|
-
|
|
411
|
-
// Check if the mset method was called with the correct parameters
|
|
412
|
-
expect(msetSpy).toHaveBeenCalledWith(testData);
|
|
413
|
-
});
|
|
414
|
-
});
|
|
415
|
-
|
|
416
|
-
// Test cache namespacing and tagging
|
|
417
|
-
describe('Cache namespacing and tagging', () => {
|
|
418
|
-
beforeEach(() => {
|
|
419
|
-
mock.restore();
|
|
420
|
-
});
|
|
421
|
-
|
|
422
|
-
it('should create a tagged cache with a single tag', () => {
|
|
423
|
-
const keyvSpy = spyOn(KV, 'Keyv').mockReturnThis();
|
|
424
|
-
|
|
425
|
-
// Call the tags method with a single tag
|
|
426
|
-
Cache.memory.tags('tag1');
|
|
427
|
-
|
|
428
|
-
// Check if Keyv was instantiated with the correct namespace
|
|
429
|
-
expect(keyvSpy).toHaveBeenCalledWith(
|
|
430
|
-
expect.objectContaining({
|
|
431
|
-
namespace: 'cache__tag1'
|
|
432
|
-
})
|
|
433
|
-
);
|
|
434
|
-
|
|
435
|
-
// Check if createCache was called
|
|
436
|
-
expect(createCache).toHaveBeenCalled();
|
|
437
|
-
});
|
|
438
|
-
|
|
439
|
-
it('should create a tagged cache with multiple tags', () => {
|
|
440
|
-
const keyvSpy = spyOn(KV, 'Keyv').mockReturnThis();
|
|
441
|
-
|
|
442
|
-
// Call the tags method with multiple tags
|
|
443
|
-
Cache.memory.tags('tag1', 'tag2', 'tag3');
|
|
444
|
-
|
|
445
|
-
// Check if Keyv was instantiated with the correct namespace
|
|
446
|
-
expect(keyvSpy).toHaveBeenLastCalledWith(
|
|
447
|
-
expect.objectContaining({
|
|
448
|
-
namespace: 'cache__tag1__tag2__tag3'
|
|
449
|
-
})
|
|
450
|
-
);
|
|
451
|
-
|
|
452
|
-
// Check if createCache was called
|
|
453
|
-
expect(createCache).toHaveBeenCalled();
|
|
454
|
-
|
|
455
|
-
keyvSpy.mockClear();
|
|
456
|
-
(createCache as Mock<typeof createCache>).mockClear();
|
|
457
|
-
|
|
458
|
-
// Call the tags method with multiple tags
|
|
459
|
-
Cache.memory.tags('tag3', 'tag2', 'tag1');
|
|
460
|
-
|
|
461
|
-
expect(keyvSpy).not.toHaveBeenCalled();
|
|
462
|
-
expect(createCache).not.toHaveBeenCalled();
|
|
463
|
-
});
|
|
464
|
-
});
|
package/tests/database.test.ts
DELETED
|
@@ -1,249 +0,0 @@
|
|
|
1
|
-
// Copyright (c) 2025-present Workbud Technologies Inc. All rights reserved.
|
|
2
|
-
//
|
|
3
|
-
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
// you may not use this file except in compliance with the License.
|
|
5
|
-
// You may obtain a copy of the License at
|
|
6
|
-
//
|
|
7
|
-
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
//
|
|
9
|
-
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
// See the License for the specific language governing permissions and
|
|
13
|
-
// limitations under the License.
|
|
14
|
-
|
|
15
|
-
import { afterEach, beforeEach, describe, expect, it, jest, mock, spyOn } from 'bun:test';
|
|
16
|
-
|
|
17
|
-
import { Application, Service } from '@elysiumjs/core';
|
|
18
|
-
|
|
19
|
-
import { AbstractDatabase } from '../src/database';
|
|
20
|
-
|
|
21
|
-
const mockDriver = {
|
|
22
|
-
createConnection: mock((config: any) => ({ mockConnection: true, config })),
|
|
23
|
-
withTransaction: mock((conn: any, cb: any) => cb(conn)),
|
|
24
|
-
getRawClient: mock((conn: any) => ({ rawClient: true })),
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
class TestDatabase extends AbstractDatabase<any, any> {
|
|
28
|
-
protected driver = mockDriver;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
describe('AbstractDatabase', () => {
|
|
32
|
-
// Mock console.error and process.exit to prevent actual console output and process exit
|
|
33
|
-
const originalConsoleError = console.error;
|
|
34
|
-
const originalProcessExit = process.exit;
|
|
35
|
-
|
|
36
|
-
beforeEach(() => {
|
|
37
|
-
console.error = mock();
|
|
38
|
-
process.exit = mock() as any;
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
afterEach(() => {
|
|
42
|
-
console.error = originalConsoleError;
|
|
43
|
-
process.exit = originalProcessExit;
|
|
44
|
-
jest.clearAllMocks();
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
describe('registerConnection', () => {
|
|
48
|
-
it('should register a new connection', () => {
|
|
49
|
-
const db = new TestDatabase();
|
|
50
|
-
|
|
51
|
-
// Mock Service.exists to return false (connection doesn't exist)
|
|
52
|
-
const existsSpy = spyOn(Service, 'exists').mockReturnValueOnce(false);
|
|
53
|
-
const instanceSpy = spyOn(Service, 'instance');
|
|
54
|
-
|
|
55
|
-
// Call the function
|
|
56
|
-
const result = db.registerConnection('test', { connection: 'sqlite:test.db' });
|
|
57
|
-
|
|
58
|
-
// Check if Service.exists was called with the correct connection name
|
|
59
|
-
expect(existsSpy).toHaveBeenCalledWith('db.connection.test');
|
|
60
|
-
|
|
61
|
-
// Check if the driver's createConnection was called with the config
|
|
62
|
-
expect(mockDriver.createConnection).toHaveBeenCalledWith({ connection: 'sqlite:test.db' });
|
|
63
|
-
|
|
64
|
-
// Check if Service.instance was called with the correct parameters
|
|
65
|
-
expect(instanceSpy).toHaveBeenCalledWith('db.connection.test', {
|
|
66
|
-
mockConnection: true,
|
|
67
|
-
config: { connection: 'sqlite:test.db' }
|
|
68
|
-
});
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
it('should throw an error if the connection already exists', () => {
|
|
72
|
-
const db = new TestDatabase();
|
|
73
|
-
|
|
74
|
-
// Mock Service.exists to return true (connection exists)
|
|
75
|
-
const existsSpy = spyOn(Service, 'exists').mockReturnValueOnce(true);
|
|
76
|
-
|
|
77
|
-
// Call the function
|
|
78
|
-
db.registerConnection('test', { connection: 'sqlite:test.db' });
|
|
79
|
-
|
|
80
|
-
// Check if console.error and process.exit were called
|
|
81
|
-
expect(console.error).toHaveBeenCalledWith(
|
|
82
|
-
expect.stringContaining('A connection with the name test has already been registered')
|
|
83
|
-
);
|
|
84
|
-
expect(process.exit).toHaveBeenCalledWith(1);
|
|
85
|
-
});
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
describe('getConnection', () => {
|
|
89
|
-
it('should retrieve an existing connection', () => {
|
|
90
|
-
const db = new TestDatabase();
|
|
91
|
-
|
|
92
|
-
// Mock Service.exists to return true (connection exists)
|
|
93
|
-
const existsSpy = spyOn(Service, 'exists').mockReturnValueOnce(true);
|
|
94
|
-
|
|
95
|
-
// Mock Service.get to return a mock connection
|
|
96
|
-
const mockConnection = { mockConnection: true };
|
|
97
|
-
const getSpy = spyOn(Service, 'get').mockReturnValue(mockConnection);
|
|
98
|
-
|
|
99
|
-
// Call the function
|
|
100
|
-
const result = db.getConnection('test');
|
|
101
|
-
|
|
102
|
-
// Check if Service.exists was called with the correct connection name
|
|
103
|
-
expect(existsSpy).toHaveBeenCalledWith('db.connection.test');
|
|
104
|
-
|
|
105
|
-
// Check if Service.get was called with the correct connection name
|
|
106
|
-
expect(getSpy).toHaveBeenCalledWith('db.connection.test');
|
|
107
|
-
|
|
108
|
-
// Check if the result is correct
|
|
109
|
-
expect(result as any).toEqual(mockConnection);
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
it('should throw an error if the connection does not exist', () => {
|
|
113
|
-
const db = new TestDatabase();
|
|
114
|
-
|
|
115
|
-
// Mock Service.exists to return false (connection doesn't exist)
|
|
116
|
-
const existsSpy = spyOn(Service, 'exists').mockReturnValueOnce(false);
|
|
117
|
-
|
|
118
|
-
// Call the function
|
|
119
|
-
db.getConnection('test');
|
|
120
|
-
|
|
121
|
-
// Check if console.error and process.exit were called
|
|
122
|
-
expect(console.error).toHaveBeenCalledWith(
|
|
123
|
-
expect.stringContaining('No connection with name test found')
|
|
124
|
-
);
|
|
125
|
-
expect(process.exit).toHaveBeenCalledWith(1);
|
|
126
|
-
});
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
describe('connectionExists', () => {
|
|
130
|
-
it('should return true if the connection exists', () => {
|
|
131
|
-
const db = new TestDatabase();
|
|
132
|
-
|
|
133
|
-
// Mock Service.exists to return true
|
|
134
|
-
const existsSpy = spyOn(Service, 'exists').mockReturnValueOnce(true);
|
|
135
|
-
|
|
136
|
-
// Call the function
|
|
137
|
-
const result = db.connectionExists('test');
|
|
138
|
-
|
|
139
|
-
// Check if Service.exists was called with the correct connection name
|
|
140
|
-
expect(existsSpy).toHaveBeenCalledWith('db.connection.test');
|
|
141
|
-
|
|
142
|
-
// Check if the result is correct
|
|
143
|
-
expect(result).toBe(true);
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
it('should return false if the connection does not exist', () => {
|
|
147
|
-
const db = new TestDatabase();
|
|
148
|
-
|
|
149
|
-
// Mock Service.exists to return false
|
|
150
|
-
const existsSpy = spyOn(Service, 'exists').mockReturnValueOnce(false);
|
|
151
|
-
|
|
152
|
-
// Call the function
|
|
153
|
-
const result = db.connectionExists('test');
|
|
154
|
-
|
|
155
|
-
// Check if Service.exists was called with the correct connection name
|
|
156
|
-
expect(existsSpy).toHaveBeenCalledWith('db.connection.test');
|
|
157
|
-
|
|
158
|
-
// Check if the result is correct
|
|
159
|
-
expect(result).toBe(false);
|
|
160
|
-
});
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
describe('getDefaultConnection', () => {
|
|
164
|
-
it('should retrieve the default connection', () => {
|
|
165
|
-
const db = new TestDatabase();
|
|
166
|
-
|
|
167
|
-
// Save original descriptor and mock Application.context
|
|
168
|
-
const originalDescriptor = Object.getOwnPropertyDescriptor(Application, 'context');
|
|
169
|
-
Object.defineProperty(Application, 'context', {
|
|
170
|
-
get: () => ({ getStore: () => null }),
|
|
171
|
-
configurable: true,
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
// Mock Service.exists to return true and Service.get to return a mock connection
|
|
175
|
-
const mockConnection = { mockConnection: true };
|
|
176
|
-
spyOn(Service, 'exists').mockReturnValueOnce(true);
|
|
177
|
-
spyOn(Service, 'get').mockReturnValue(mockConnection);
|
|
178
|
-
|
|
179
|
-
// Call the function
|
|
180
|
-
const result = db.getDefaultConnection();
|
|
181
|
-
|
|
182
|
-
// Check if the result is correct
|
|
183
|
-
expect(result as any).toEqual(mockConnection);
|
|
184
|
-
|
|
185
|
-
// Restore original descriptor
|
|
186
|
-
if (originalDescriptor) {
|
|
187
|
-
Object.defineProperty(Application, 'context', originalDescriptor);
|
|
188
|
-
}
|
|
189
|
-
});
|
|
190
|
-
});
|
|
191
|
-
|
|
192
|
-
describe('setDefaultConnection', () => {
|
|
193
|
-
it('should set the default connection', () => {
|
|
194
|
-
const db = new TestDatabase();
|
|
195
|
-
|
|
196
|
-
// Save original descriptor and mock Application.context
|
|
197
|
-
const originalDescriptor = Object.getOwnPropertyDescriptor(Application, 'context');
|
|
198
|
-
Object.defineProperty(Application, 'context', {
|
|
199
|
-
get: () => ({ getStore: () => null }),
|
|
200
|
-
configurable: true,
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
const instanceSpy = spyOn(Service, 'instance');
|
|
204
|
-
const removeSpy = spyOn(Service, 'remove');
|
|
205
|
-
|
|
206
|
-
// Mock getConnection to return a mock connection
|
|
207
|
-
const mockConnection = { mockConnection: true };
|
|
208
|
-
spyOn(Service, 'exists').mockReturnValue(true);
|
|
209
|
-
spyOn(Service, 'get').mockReturnValue(mockConnection);
|
|
210
|
-
|
|
211
|
-
// Call the function
|
|
212
|
-
const result = db.setDefaultConnection('test');
|
|
213
|
-
|
|
214
|
-
// Check if Service.remove was called with the correct connection name
|
|
215
|
-
expect(removeSpy).toHaveBeenCalledWith('db.connection.default');
|
|
216
|
-
|
|
217
|
-
// Check if Service.instance was called with the correct parameters
|
|
218
|
-
expect(instanceSpy).toHaveBeenCalledWith('db.connection.default', mockConnection);
|
|
219
|
-
|
|
220
|
-
// Check if the result is correct
|
|
221
|
-
expect(result as any).toEqual(mockConnection);
|
|
222
|
-
|
|
223
|
-
// Restore original descriptor
|
|
224
|
-
if (originalDescriptor) {
|
|
225
|
-
Object.defineProperty(Application, 'context', originalDescriptor);
|
|
226
|
-
}
|
|
227
|
-
});
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
describe('getRawClient', () => {
|
|
231
|
-
it('should return the raw client from the driver', () => {
|
|
232
|
-
const db = new TestDatabase();
|
|
233
|
-
|
|
234
|
-
// Mock getConnection to return a mock connection
|
|
235
|
-
const mockConnection = { mockConnection: true };
|
|
236
|
-
spyOn(Service, 'exists').mockReturnValue(true);
|
|
237
|
-
spyOn(Service, 'get').mockReturnValue(mockConnection);
|
|
238
|
-
|
|
239
|
-
// Call the function
|
|
240
|
-
const result = db.getRawClient('test');
|
|
241
|
-
|
|
242
|
-
// Check if the driver's getRawClient was called with the connection
|
|
243
|
-
expect(mockDriver.getRawClient).toHaveBeenCalledWith(mockConnection);
|
|
244
|
-
|
|
245
|
-
// Check if the result is correct
|
|
246
|
-
expect(result).toEqual({ rawClient: true });
|
|
247
|
-
});
|
|
248
|
-
});
|
|
249
|
-
});
|