Bkmartinjr/state mgr tests (#298)

Jest tests for part of util/stateManager

* reorganize test directories

* lint

* add Jest config to eslint

* add Jest config to eslint

* lint

* fix babel configuration for tests

* start at kvCache tests

* reorganize test directories

* lint

* add Jest config to eslint

* add Jest config to eslint

* lint

* fix babel configuration for tests

* start at kvCache tests

* fix cache flush bug manifest by new test cases

* new kvCache tests

* skeletal universe test

* fix race in test case

* more universe test cases
This commit is contained in:
Bruce Martin
2018-10-04 17:41:26 -07:00
committed by GitHub
parent 8674ad1f7f
commit 19f2728a18
10 changed files with 3194 additions and 2652 deletions
+51 -17
View File
@@ -2,7 +2,8 @@
import _ from "lodash";
/*
Very simple key/value cache for use by World & Universe.
Very simple key/value cache for use by World & Universe. Cache keys must
be a string, and values are any JS non-primitive value.
* constructor(lowWatermark, minTTL):
- lowWatermark defines the number of cache elements below which
@@ -18,8 +19,21 @@ Very simple key/value cache for use by World & Universe.
*/
const cachePrivateKey = "__kvcachekey__";
const defaultLowWatermark = 32;
const defaultMinTTL = 1000;
function create(lowWatermark = defaultLowWatermark, minTTL = defaultMinTTL) {
if (typeof minTTL !== "number" || typeof lowWatermark !== "number") {
throw new TypeError(
"minTTL and lowWatermark parameters must be a primitive number"
);
}
if (lowWatermark < 0 || minTTL < 0) {
throw new RangeError(
"minTTL and lowWatermark parameters must be number greater than zero"
);
}
function create(lowWatermark = 32, minTTL = 1000) {
return {
[cachePrivateKey]: {
lowWatermark,
@@ -29,6 +43,10 @@ function create(lowWatermark = 32, minTTL = 1000) {
}
function get(kvcache, key) {
if (key === cachePrivateKey) {
throw new RangeError(`key parameter may not have value ${cachePrivateKey}`);
}
const val = kvcache[key];
if (val) {
val[cachePrivateKey] = Date.now();
@@ -37,10 +55,20 @@ function get(kvcache, key) {
}
function set(kvcache, key, val) {
if (key === cachePrivateKey) {
throw new RangeError(`key parameter may not have value ${cachePrivateKey}`);
}
const newKvCache = { ...kvcache };
newKvCache[key] = val;
val[cachePrivateKey] = Date.now();
flush(newKvCache, newKvCache[cachePrivateKey].minTTL);
flushInPlace(newKvCache);
return newKvCache;
}
function flush(kvcache) {
const newKvCache = { ...kvcache };
flushInPlace(newKvCache);
return newKvCache;
}
@@ -48,24 +76,24 @@ function set(kvcache, key, val) {
Flush elements from cache IF cache size is greater than lowWatermark, and
those elements are older than minAgeMS
*/
function flush(kvcache, minAgeMs = 0) {
if (minAgeMs < 0) return kvcache;
const eol = Date.now() - minAgeMs;
const { lowWatermark } = kvcache[cachePrivateKey];
const keys = _(kvcache)
function flushInPlace(kvCache) {
const { lowWatermark, minTTL } = kvCache[cachePrivateKey];
const eol = Date.now() - minTTL;
const allKeys = _(kvCache)
.keys()
.filter(k => k !== cachePrivateKey)
.filter(k => kvcache[k][cachePrivateKey] < eol)
.sortBy([k => kvcache[k][cachePrivateKey]])
.sortBy([k => kvCache[k][cachePrivateKey]])
.value();
if (keys.length > lowWatermark) {
const numKeysToDelete = keys.length - lowWatermark;
const keysToDelete = _.slice(keys, 0, numKeysToDelete);
_.forEach(keysToDelete, k => delete kvcache[k]);
if (allKeys.length > lowWatermark) {
const keysToDelete = _(allKeys)
.slice(0, allKeys.length - lowWatermark)
.filter(k => kvCache[k][cachePrivateKey] <= eol)
.value();
_.forEach(keysToDelete, k => delete kvCache[k]);
}
return kvcache;
return kvCache;
}
/*
@@ -76,9 +104,15 @@ function map(srcKvCache, cb, createOptions) {
.keys()
.filter(k => k !== cachePrivateKey)
.value();
const newKvCache = create(createOptions.lowWatermark, createOptions.minTTL);
const lowWatermark = _.get(
createOptions,
"lowWatermark",
defaultLowWatermark
);
const minTTL = _.get(createOptions, "minTTL", defaultMinTTL);
const newKvCache = create(lowWatermark, minTTL);
_.forEach(keysInSrcKvCache, key => {
const val = cb(get(srcKvCache, key));
const val = cb(get(srcKvCache, key), key);
newKvCache[key] = val;
val[cachePrivateKey] = Date.now();
});