Storage Mocks for SSR/Node
by JakobJingleheimer
JavaScript
const _cookieSym = Symbol('Cookie');
class StorageMock {}
function storageMockFactory(type) {
/**
* A symbol is used to avoid accidentally accessing the underlying implementation.
* @var {Symbol} sym - A unique key.
*/
const sym = Symbol(`${type}Storage`);
return Object.create(StorageMock.prototype, {
clear: {
value() {
return this[sym].clear();
},
},
getItem: {
value(k) {
const val = this[sym].get(k);
return typeof val === 'undefined'
? null
: val;
},
},
key: {
value(n) {
return [...this[sym].keys()][n]; // eslint-disable-line
},
},
length: {
enumerable: true,
get() {
return this[sym].size;
},
},
removeItem: {
value(k) {
return this[sym].delete(k);
},
},
setItem: {
value(k, v) {
return this[sym].set(k, v);
},
},
[sym]: { value: new Map() },
});
}
const document = Object.create(Object.prototype, {
[_cookieSym]: {
value: new Map(),
},
cookie: {
enumerable: true,
get() {
const items = [
...this[_cookieSym],
];
return _map(items, (item) => item.join('='))
.join('; ');
},
set(input) { // eslint-disable-line consistent-return
if (!input) {
console.warn(`[CookieMock] Provided value "${input}"" is invalid. Aborting.`);
return void 0;
}
if (input === '__VOID_CLEAR__') { // for specs
return this[_cookieSym].clear();
}
const pieces = input.split(/[=;]/);
const key = pieces.shift().trim();
...