blob: bb558d2f6ad7078c70f77f89b560c59a0de322b6 [file]
<!DOCTYPE html>
<!--
Copyright 2021 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>lru-cache tests</title>
<script src="../node_modules/@webcomponents/webcomponentsjs/webcomponents-loader.js"></script>
<script src="../node_modules/web-component-tester/browser.js"></script>
<script type="module">
import {
CacheObject,
} from '../src/main/resources/static/cache-object.js';
import {
LRUMemoryCacheObject,
} from '../src/main/resources/static/lru-memory-cache-object.js';
import {
LRUStorageCacheObject,
} from '../src/main/resources/static/lru-storage-cache-object.js';
suite('LRUMemoryCacheObject', () => {
let cache;
setup(() => {
cache = new LRUMemoryCacheObject(2);
});
teardown(() => {
cache.clear();
});
test('read with no entry for key returns undefined', () => {
assert.strictEqual(cache.read('a'), undefined);
});
test('write followed by read succeeds', () => {
cache.write('a', 1);
assert.strictEqual(cache.read('a'), 1);
});
test('write then clear then read yields empty cache', () => {
cache.write('a', 1);
cache.clear();
assert.strictEqual(cache.read('a'), undefined);
});
test('delete deletes keys', () => {
cache.write('a', 'c');
cache.write('b', 'd');
cache.delete('a');
assert.strictEqual(cache.read('a'), undefined);
assert.strictEqual(cache.read('b'), 'd');
});
test('cache evicts LRU element', () => {
cache.write('a', 1);
cache.write('b', 2);
cache.write('c', 3);
assert.strictEqual(cache.read('a'), undefined);
cache.clear();
cache.write('a', 1);
cache.write('b', 2);
assert.strictEqual(cache.read('a'), 1);
cache.write('c', 3);
assert.strictEqual(cache.read('b'), undefined);
cache.clear();
cache.write('a', 1);
cache.write('b', 2);
cache.write('a', 3);
cache.write('c', 3);
assert.strictEqual(cache.read('b'), undefined);
});
});
suite('LRUStorageCacheObject', () => {
let sandbox;
let cache;
const cacheKey = 'key';
setup(() => {
sandbox = sinon.sandbox.create();
cache = new LRUStorageCacheObject(2, cacheKey);
});
teardown(() => {
cache.clear();
});
test('read with no entry for key returns undefined', () => {
assert.strictEqual(cache.read('a'), undefined);
});
test('write followed by read succeeds', () => {
cache.write('a', 1);
assert.strictEqual(cache.read('a'), 1);
});
test('write then clear then read yields empty cache', () => {
cache.write('a', 1);
const key = cache.formatKey('a');
assert.deepEqual(JSON.parse(localStorage.getItem(key)), {value: 1});
cache.clear();
assert.strictEqual(cache.read('a'), undefined);
assert.deepEqual(cache.accessKeys, []);
assert.strictEqual(JSON.parse(localStorage.getItem(key)), null);
});
test('delete deletes keys', () => {
cache.write('a', 'c');
cache.write('b', 'd');
cache.delete('a');
assert.strictEqual(cache.read('a'), undefined);
assert.strictEqual(cache.read('b'), 'd');
});
test('cache evicts LRU element', () => {
cache.write('a', 1);
cache.write('b', 2);
cache.write('c', 3);
assert.strictEqual(cache.read('a'), undefined);
cache.clear();
cache.write('a', 1);
cache.write('b', 2);
assert.strictEqual(cache.read('a'), 1);
cache.write('c', 3);
assert.strictEqual(cache.read('b'), undefined);
cache.clear();
cache.write('a', 1);
cache.write('b', 2);
cache.write('a', 3);
cache.write('c', 3);
assert.strictEqual(cache.read('b'), undefined);
});
test('cache persists', () => {
cache.write('a', 1);
cache.write('b', 2);
const otherCache = new LRUStorageCacheObject(2, cacheKey);
assert.strictEqual(otherCache.read('a'), 1);
assert.strictEqual(otherCache.read('b'), 2);
});
test('cache resizes', () => {
cache.write('a', 1);
cache.write('b', 2);
const smallerCache = new LRUStorageCacheObject(1, cacheKey);
assert.strictEqual(smallerCache.read('a'), undefined);
assert.strictEqual(JSON.parse(localStorage.getItem('a')), null);
assert.strictEqual(smallerCache.read('b'), 2);
smallerCache.clear();
cache = new LRUStorageCacheObject(2, cacheKey);
cache.write('a', 1);
cache.write('b', 2);
const biggerCache = new LRUStorageCacheObject(3, cacheKey);
biggerCache.write('c', 3);
assert.strictEqual(biggerCache.read('a'), 1);
assert.strictEqual(biggerCache.read('b'), 2);
assert.strictEqual(biggerCache.read('c'), 3);
});
test('cache halves when storage capacity is reached', () => {
const cache = new LRUStorageCacheObject(4, 'foo');
cache.write('a', 1);
cache.write('b', 2);
cache.write('c', 3);
cache.write('d', 4);
const stub = sandbox.stub(CacheObject.prototype, 'write');
stub.onCall(0).throws('QuotaExceededError');
stub.onCall(1).returns((
() => localStorage.setItem(
cache.formatKey('e'), JSON.stringify({value: 5}))
)());
cache.write('e', 5);
assert.strictEqual(cache.read('a'), undefined);
assert.strictEqual(cache.read('b'), undefined);
assert.strictEqual(cache.read('c'), 3);
assert.strictEqual(cache.read('d'), 4);
assert.strictEqual(cache.read('e'), 5);
});
});
</script>