Skip to content

Commit cb22017

Browse files
Add unit test
1 parent 60aa25d commit cb22017

File tree

3 files changed

+76
-12
lines changed

3 files changed

+76
-12
lines changed

src/storages/inLocalStorage/MySegmentsCacheInLocal.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export class MySegmentsCacheInLocal extends AbstractMySegmentsCacheSync {
5151

5252
getRegisteredSegments(): string[] {
5353
const registeredSegments: string[] = [];
54-
for (let i = 0; i < this.storage.length; i++) {
54+
for (let i = 0, len = this.storage.length; i < len; i++) {
5555
const segmentName = this.keys.extractSegmentName(this.storage.key(i)!);
5656
if (segmentName) registeredSegments.push(segmentName);
5757
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import { storageAdapter } from '../storageAdapter';
2+
import { loggerMock } from '../../../logger/__tests__/sdkLogger.mock';
3+
4+
5+
const syncWrapper = {
6+
getItem: jest.fn(() => JSON.stringify({ key1: 'value1' })),
7+
setItem: jest.fn(),
8+
removeItem: jest.fn(),
9+
};
10+
11+
const asyncWrapper = {
12+
getItem: jest.fn(() => Promise.resolve(JSON.stringify({ key1: 'value1' }))),
13+
setItem: jest.fn(() => Promise.resolve()),
14+
removeItem: jest.fn(() => Promise.resolve()),
15+
};
16+
17+
test.each([
18+
[syncWrapper],
19+
[asyncWrapper],
20+
])('storageAdapter', async (wrapper) => {
21+
22+
const storage = storageAdapter(loggerMock, 'prefix', wrapper);
23+
24+
await storage.load!();
25+
26+
expect(wrapper.getItem).toHaveBeenCalledWith('prefix');
27+
28+
expect(storage.length).toBe(1);
29+
expect(storage.key(0)).toBe('key1');
30+
expect(storage.getItem('key1')).toBe('value1');
31+
32+
storage.setItem('key2', 'value2');
33+
expect(storage.getItem('key2')).toBe('value2');
34+
expect(storage.length).toBe(2);
35+
36+
storage.removeItem('key1');
37+
expect(storage.getItem('key1')).toBe(null);
38+
expect(storage.length).toBe(1);
39+
40+
await storage.save!();
41+
expect(wrapper.setItem).not.toHaveBeenCalled();
42+
43+
storage.setItem('.till', '1');
44+
expect(storage.length).toBe(2);
45+
expect(storage.key(0)).toBe('key2');
46+
expect(storage.key(1)).toBe('.till');
47+
48+
await storage.save!();
49+
expect(wrapper.setItem).toHaveBeenCalledWith('prefix', JSON.stringify({ key2: 'value2', '.till': '1' }));
50+
51+
storage.removeItem('.till');
52+
53+
await storage.save!();
54+
expect(wrapper.setItem).toHaveBeenCalledWith('prefix', JSON.stringify({ key2: 'value2' }));
55+
56+
await storage.save!();
57+
expect(wrapper.setItem).toHaveBeenCalledTimes(2);
58+
});

src/storages/inLocalStorage/storageAdapter.ts

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,29 @@ function isTillKey(key: string) {
1010
export function storageAdapter(log: ILogger, prefix: string, wrapper: SplitIO.StorageWrapper): StorageAdapter {
1111
let cache: Record<string, string> = {};
1212

13-
let connectPromise: Promise<void> | undefined;
14-
let disconnectPromise = Promise.resolve();
13+
let loadPromise: Promise<void> | undefined;
14+
let savePromise = Promise.resolve();
15+
16+
function _save() {
17+
return savePromise = savePromise.then(() => {
18+
return Promise.resolve(wrapper.setItem(prefix, JSON.stringify(cache)));
19+
}).catch((e) => {
20+
log.error(LOG_PREFIX + 'Rejected promise calling wrapper `setItem` method, with error: ' + e);
21+
});
22+
}
1523

1624
return {
1725
load() {
18-
return connectPromise || (connectPromise = Promise.resolve(wrapper.getItem(prefix)).then((storedCache) => {
26+
return loadPromise || (loadPromise = Promise.resolve().then(() => {
27+
return wrapper.getItem(prefix);
28+
}).then((storedCache) => {
1929
cache = JSON.parse(storedCache || '{}');
2030
}).catch((e) => {
21-
log.error(LOG_PREFIX + 'Rejected promise calling storage getItem, with error: ' + e);
31+
log.error(LOG_PREFIX + 'Rejected promise calling wrapper `getItem` method, with error: ' + e);
2232
}));
2333
},
2434
save() {
25-
return disconnectPromise = disconnectPromise.then(() => {
26-
return Promise.resolve(wrapper.setItem(prefix, JSON.stringify(cache))).catch((e) => {
27-
log.error(LOG_PREFIX + 'Rejected promise calling storage setItem, with error: ' + e);
28-
});
29-
});
35+
return savePromise;
3036
},
3137

3238
get length() {
@@ -40,11 +46,11 @@ export function storageAdapter(log: ILogger, prefix: string, wrapper: SplitIO.St
4046
},
4147
removeItem(key: string) {
4248
delete cache[key];
43-
if (isTillKey(key)) this.save!();
49+
if (isTillKey(key)) _save();
4450
},
4551
setItem(key: string, value: string) {
4652
cache[key] = value;
47-
if (isTillKey(key)) this.save!();
53+
if (isTillKey(key)) _save();
4854
}
4955
};
5056
}

0 commit comments

Comments
 (0)