cachette 4.0.12 → 4.0.14

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.
@@ -2,9 +2,7 @@ import { expect } from 'chai';
2
2
 
3
3
  import { LocalCache } from '../src/lib/LocalCache';
4
4
 
5
-
6
5
  describe('LocalCache', () => {
7
-
8
6
  it('can set values', async () => {
9
7
  const cache = new LocalCache();
10
8
  const wasSet = await cache.setValue('key', 'value');
@@ -50,13 +48,12 @@ describe('LocalCache', () => {
50
48
 
51
49
  it('can set values with expiry', async () => {
52
50
  const cache = new LocalCache();
53
- await cache.setValue('key', 'value', .2);
51
+ await cache.setValue('key', 'value', 0.2);
54
52
  let value = await cache.getValue('key');
55
53
  expect(value).to.equal('value');
56
54
  await sleep(250);
57
55
  value = await cache.getValue('key');
58
56
  expect(value).to.equal(undefined);
59
-
60
57
  });
61
58
 
62
59
  it('can delete a value', async () => {
@@ -67,7 +64,6 @@ describe('LocalCache', () => {
67
64
  await cache.delValue('key');
68
65
 
69
66
  expect(await cache.getValue('key')).not.to.exist;
70
-
71
67
  });
72
68
 
73
69
  it('will not grow in size past the maximum size', async () => {
@@ -92,8 +88,7 @@ describe('LocalCache', () => {
92
88
 
93
89
  // restore
94
90
  LocalCache['DEFAULT_MAX_ITEMS'] = origMax;
95
-
96
- })
91
+ });
97
92
 
98
93
  it('can get the remaining TTL of an item', async () => {
99
94
  const cache = new LocalCache();
@@ -120,7 +115,6 @@ describe('LocalCache', () => {
120
115
  expect(wasSet).to.be.true;
121
116
  expect(cacheTtl).to.equal(0);
122
117
  });
123
-
124
118
  });
125
119
 
126
120
  function sleep(ms: number): Promise<void> {
@@ -3,9 +3,7 @@ import * as sinon from 'sinon';
3
3
 
4
4
  import { RedisCache, SIZE_THRESHOLD_WARNING_BYTES } from '../src/lib/RedisCache';
5
5
 
6
-
7
6
  describe('RedisCache', () => {
8
-
9
7
  describe('constructor', () => {
10
8
  it('will not crash the application given an invalid Redis URL', async () => {
11
9
  let cache = new RedisCache('redis://localhost:9999');
@@ -17,20 +15,15 @@ describe('RedisCache', () => {
17
15
  });
18
16
 
19
17
  it('will raise an error if given a Redis URL without protocol', async () => {
20
- expect(
21
- () => new RedisCache('rer17kq3qdwc5wmy.4gzf3f.ng.0001.use1.cache.amazonaws.com'),
22
- ).to.throw();
18
+ expect(() => new RedisCache('rer17kq3qdwc5wmy.4gzf3f.ng.0001.use1.cache.amazonaws.com')).to.throw();
23
19
  });
24
20
 
25
21
  it('will raise an error if given a Redis URL with an invalid protocol', async () => {
26
- expect(
27
- () => new RedisCache('potato://rer17kq3qdwc5wmy.4gzf3f.ng.0001.use1.cache.amazonaws.com'),
28
- ).to.throw();
22
+ expect(() => new RedisCache('potato://rer17kq3qdwc5wmy.4gzf3f.ng.0001.use1.cache.amazonaws.com')).to.throw();
29
23
  });
30
24
  });
31
25
 
32
26
  describe('value serialization', () => {
33
-
34
27
  it('can serialize the null value', () => {
35
28
  let value = RedisCache.serializeValue(null);
36
29
  expect(value).to.equal(RedisCache.NULL_VALUE);
@@ -58,12 +51,15 @@ describe('RedisCache', () => {
58
51
  value = RedisCache.deserializeValue(value);
59
52
  expect(value).to.deep.equal(obj);
60
53
  });
61
-
54
+
62
55
  it('can serialize an object with a nested map', () => {
63
- const mapStructure: Map<string, {
64
- checksum: number;
65
- originCommentId?: string;
66
- }> = new Map();
56
+ const mapStructure: Map<
57
+ string,
58
+ {
59
+ checksum: number;
60
+ originCommentId?: string;
61
+ }
62
+ > = new Map();
67
63
  mapStructure.set('key1', { checksum: 1, originCommentId: 'c1' });
68
64
  mapStructure.set('key2', { checksum: 2, originCommentId: 'c2' });
69
65
  const obj = {
@@ -83,7 +79,7 @@ describe('RedisCache', () => {
83
79
  value = RedisCache.deserializeValue(value);
84
80
  expect(value).to.deep.equal(obj);
85
81
  });
86
-
82
+
87
83
  it('can serialize an object with a nested set', () => {
88
84
  const setStructure: Set<string> = new Set();
89
85
  setStructure.add('key1');
@@ -124,7 +120,6 @@ describe('RedisCache', () => {
124
120
  const value = RedisCache.deserializeValue(null);
125
121
  expect(value).to.equal(undefined);
126
122
  });
127
-
128
123
  });
129
124
 
130
125
  describe('setValue', async () => {
@@ -237,7 +232,10 @@ describe('RedisCache', () => {
237
232
  const key = `emits-warning-on-large-value-${Math.random()}`;
238
233
  await cache.setValue(key, 'a'.repeat(SIZE_THRESHOLD_WARNING_BYTES));
239
234
 
240
- const warningsAfterSetLargeKey = warnSpy.getCalls().map(c => c.firstArg).filter(msg => msg.includes('Writing large value to Redis!'));
235
+ const warningsAfterSetLargeKey = warnSpy
236
+ .getCalls()
237
+ .map((c) => c.firstArg)
238
+ .filter((msg) => msg.includes('Writing large value to Redis!'));
241
239
  expect(warningsAfterSetLargeKey.length).to.equal(1);
242
240
  });
243
241
 
@@ -254,13 +252,15 @@ describe('RedisCache', () => {
254
252
  const key = `doesnt-emit-warning-on-small-value-${Math.random()}`;
255
253
  await cache.setValue(key, 'a'.repeat(SIZE_THRESHOLD_WARNING_BYTES - 1));
256
254
 
257
- const warningsAfterSetLargeKey = warnSpy.getCalls().map(c => c.firstArg).filter(msg => msg.includes('Writing large value to Redis!'));
255
+ const warningsAfterSetLargeKey = warnSpy
256
+ .getCalls()
257
+ .map((c) => c.firstArg)
258
+ .filter((msg) => msg.includes('Writing large value to Redis!'));
258
259
  expect(warningsAfterSetLargeKey.length).to.equal(0);
259
260
  });
260
261
  });
261
262
 
262
263
  describe('itemCount', async () => {
263
-
264
264
  it('can count the items in the redis cache.', async function (): Promise<void> {
265
265
  if (!process.env.TEST_REDIS_URL) {
266
266
  this.skip();
@@ -293,7 +293,7 @@ describe('RedisCache', () => {
293
293
  await cache.clear();
294
294
 
295
295
  await cache.setValue('test1', 'value1');
296
-
296
+
297
297
  const replicationAcknowledged = await cache.waitForReplication(0, 50);
298
298
 
299
299
  // No replicas so we expect 0. This test basically confirms that waitForReplication doesn't crash. 🤷‍♂️
@@ -11,24 +11,18 @@ function makeFakeWriteThroughCache(): WriteThroughCache {
11
11
  return cache;
12
12
  }
13
13
 
14
-
15
14
  describe('WriteThroughCache', () => {
16
-
17
15
  it('will fallback to using a local cache is no connection to redis is made', async () => {
18
-
19
16
  const cache = new WriteThroughCache('redis://localhost:9999');
20
17
 
21
18
  // We know the connection was not made, but we should still be able to use the local cache.
22
19
  await cache.setValue('key', 'value');
23
20
  const value = await cache.getValue('key');
24
21
  expect(value).to.equal('value');
25
-
26
22
  });
27
23
 
28
24
  describe('setValue', () => {
29
-
30
25
  it('will write the value in both caches', async () => {
31
-
32
26
  const cache = makeFakeWriteThroughCache();
33
27
 
34
28
  const response = await cache.setValue('key', 'value');
@@ -42,15 +36,11 @@ describe('WriteThroughCache', () => {
42
36
 
43
37
  value = await cache['redisCacheForReading'].getValue('key');
44
38
  expect(value).to.equal('value');
45
-
46
39
  });
47
-
48
40
  });
49
41
 
50
42
  describe('getValue', () => {
51
-
52
43
  it('will populate the local cache with right ttl when fetching from redis', async function (): Promise<void> {
53
-
54
44
  if (!process.env.TEST_REDIS_URL) {
55
45
  this.skip();
56
46
  }
@@ -64,15 +54,18 @@ describe('WriteThroughCache', () => {
64
54
 
65
55
  let value = await cache.getValue('key');
66
56
  expect(value).to.equal('value');
67
- sinon.assert.calledWith(spy, 'key', 'value', sinon.match(ttl => ttl > 99.9 && ttl <= 100));
57
+ sinon.assert.calledWith(
58
+ spy,
59
+ 'key',
60
+ 'value',
61
+ sinon.match((ttl) => ttl > 99.9 && ttl <= 100),
62
+ );
68
63
 
69
64
  value = await cache['localCache'].getValue('key');
70
65
  expect(value).to.equal('value');
71
-
72
66
  });
73
67
 
74
68
  it('will get directly from the local cache if available', async () => {
75
-
76
69
  const cache = makeFakeWriteThroughCache();
77
70
 
78
71
  await cache['localCache'].setValue('key', 'value');
@@ -82,11 +75,9 @@ describe('WriteThroughCache', () => {
82
75
 
83
76
  value = await cache['redisCacheForReading'].getValue('key');
84
77
  expect(value).not.to.exist;
85
-
86
78
  });
87
79
 
88
80
  it('will populate the local cache for a null value', async () => {
89
-
90
81
  const cache = makeFakeWriteThroughCache();
91
82
 
92
83
  await cache['redisCacheForWriting'].setValue('key', null);
@@ -96,11 +87,9 @@ describe('WriteThroughCache', () => {
96
87
 
97
88
  value = await cache['localCache'].getValue('key');
98
89
  expect(value).to.equal(null);
99
-
100
90
  });
101
91
 
102
92
  it('will populate the local cache for an empty string', async () => {
103
-
104
93
  const cache = makeFakeWriteThroughCache();
105
94
 
106
95
  await cache['redisCacheForWriting'].setValue('key', '');
@@ -110,7 +99,6 @@ describe('WriteThroughCache', () => {
110
99
 
111
100
  value = await cache['localCache'].getValue('key');
112
101
  expect(value).to.equal('');
113
-
114
102
  });
115
103
 
116
104
  it('returns nothing if value in cache has expired', async function (): Promise<void> {
@@ -120,17 +108,14 @@ describe('WriteThroughCache', () => {
120
108
  const cache = new WriteThroughCache(process.env.TEST_REDIS_URL as string);
121
109
  await cache.setValue('fakeKey', 'fakeValue', 0.1);
122
110
  // sleep 100 ms
123
- await new Promise(resolve => setTimeout(resolve, 150));
111
+ await new Promise((resolve) => setTimeout(resolve, 150));
124
112
  const fakeValue = await cache.getValue('fakeKey');
125
113
  expect(fakeValue).to.be.undefined;
126
114
  });
127
-
128
115
  });
129
116
 
130
117
  describe('delValue', () => {
131
-
132
118
  it('will delete values from both caches', async () => {
133
-
134
119
  const cache = makeFakeWriteThroughCache();
135
120
 
136
121
  await cache.setValue('key', 'value');
@@ -148,30 +133,26 @@ describe('WriteThroughCache', () => {
148
133
 
149
134
  value = await cache['localCache'].getValue('key');
150
135
  expect(value).not.to.exist;
151
-
152
136
  });
153
-
154
137
  });
155
138
 
156
139
  describe('clear', () => {
157
-
158
140
  it('clears from both caches', async () => {
159
141
  const cache = makeFakeWriteThroughCache();
160
142
 
161
143
  const base = [...Array(10).keys()];
162
- await Promise.all(base.map(i => cache.setValue(`key${i}`, i)));
144
+ await Promise.all(base.map((i) => cache.setValue(`key${i}`, i)));
163
145
  expect(await cache.itemCount()).to.equal(20);
164
146
 
165
- let values = await Promise.all(base.map(i => cache.getValue(`key${i}`)));
147
+ let values = await Promise.all(base.map((i) => cache.getValue(`key${i}`)));
166
148
  expect(values.sort()).to.eql(base);
167
149
 
168
150
  await cache.clear();
169
151
  expect(await cache.itemCount()).to.equal(0);
170
152
 
171
- values = await Promise.all(base.map(i => cache.getValue(`key${i}`)));
172
- values.forEach(value => expect(value).to.be.undefined);
153
+ values = await Promise.all(base.map((i) => cache.getValue(`key${i}`)));
154
+ values.forEach((value) => expect(value).to.be.undefined);
173
155
  });
174
-
175
156
  });
176
157
 
177
158
  describe('metrics', () => {
@@ -187,7 +168,7 @@ describe('WriteThroughCache', () => {
187
168
  afterEach(() => {
188
169
  delete process.env.CACHETTE_METRICS_PERIOD_MINUTES;
189
170
  sinonClock.restore();
190
- })
171
+ });
191
172
 
192
173
  it('stores metrics if env. var is set', async function () {
193
174
  if (!process.env.TEST_REDIS_URL) {
@@ -282,25 +263,39 @@ describe('WriteThroughCache', () => {
282
263
  await cache.getValue(key);
283
264
 
284
265
  // Testing we emitted at requested period
285
- const metricsReports0 = infoSpy.getCalls().map(c => c.firstArg).filter(msg => msg.includes('metrics'));
266
+ const metricsReports0 = infoSpy
267
+ .getCalls()
268
+ .map((c) => c.firstArg)
269
+ .filter((msg) => msg.includes('metrics'));
286
270
  expect(metricsReports0.length).to.equal(0);
287
271
 
288
272
  sinonClock.tick(59999); // t = 1min minus a millisecond
289
- const metricsReports59s = infoSpy.getCalls().map(c => c.firstArg).filter(msg => msg.includes('metrics'));
273
+ const metricsReports59s = infoSpy
274
+ .getCalls()
275
+ .map((c) => c.firstArg)
276
+ .filter((msg) => msg.includes('metrics'));
290
277
  expect(metricsReports59s.length).to.equal(0);
291
278
 
292
279
  sinonClock.tick(2); // t = 1min plus a millisecond
293
- const metricsReports61s = infoSpy.getCalls().map(c => c.firstArg).filter(msg => msg.includes('metrics'));
280
+ const metricsReports61s = infoSpy
281
+ .getCalls()
282
+ .map((c) => c.firstArg)
283
+ .filter((msg) => msg.includes('metrics'));
294
284
  expect(metricsReports61s.length).to.equal(1);
295
- expect(metricsReports61s[0]).to.equal('WriteThroughCache metrics during last 1 min - Total: 3, Local hits: 1 (33%), Redis hits: 1 (33%), Double misses: 1 (33%).')
285
+ expect(metricsReports61s[0]).to.equal(
286
+ 'WriteThroughCache metrics during last 1 min - Total: 3, Local hits: 1 (33%), Redis hits: 1 (33%), Double misses: 1 (33%).',
287
+ );
296
288
 
297
289
  // Causing no activity for a minute and testing we emit again
298
290
  sinonClock.tick(60000); // t = 2min plus a millisecond
299
- const metricsReports121s = infoSpy.getCalls().map(c => c.firstArg).filter(msg => msg.includes('metrics'));
291
+ const metricsReports121s = infoSpy
292
+ .getCalls()
293
+ .map((c) => c.firstArg)
294
+ .filter((msg) => msg.includes('metrics'));
300
295
  expect(metricsReports121s.length).to.equal(2);
301
- expect(metricsReports121s[1]).to.equal('WriteThroughCache metrics during last 1 min - Total: 0, Local hits: 0 (0%), Redis hits: 0 (0%), Double misses: 0 (0%).')
296
+ expect(metricsReports121s[1]).to.equal(
297
+ 'WriteThroughCache metrics during last 1 min - Total: 0, Local hits: 0 (0%), Redis hits: 0 (0%), Double misses: 0 (0%).',
298
+ );
302
299
  });
303
-
304
300
  });
305
-
306
301
  });