June 03, 2021
TestsSource
- WeakMap - intro
Source Code
The source code we wrote during the event.
WeakMap.spec.js
import {strict as assert} from 'assert';
import 'expose-gc';
describe('WeakMap - intro', () => {
it('is a function', () => {
assert.equal(typeof WeakMap, 'function');
});
xit('removing the last ref to the key, removes the entry from the WeakMap', () => {
// WE can NOT verify that a gc'ed key is NOT in the WeakMap anymore,
// we just have no reference to it
let a = {};
const map = new WeakMap([
[a, 'the value of `a`'],
]);
a = undefined;
global.gc(); // requires `import 'expose-gc';`
assert.equal(map.has(a), false); // <<<=== undefined (`a`) is not the actual key we used to add the element to the WeakMap
});
it('two refs to one object, remove one ref, with explicit gc THEN its still accessible', () => {
let a = {};
let b = a;
const map = new WeakMap([
[a, 'the value of `a`'],
]);
a = null;
global.gc(); // requires `import 'expose-gc';`
assert.equal(map.get(b), 'the value of `a`');
assert.equal(map.has(a), false);
});
it('null as a key throws a TypeError when creating the WeakMap (because its not an object)', () => {
assert.throws(() => {
const map = new WeakMap([
[null, 'null'],
]);
}, TypeError);
});
it('the key is still valid AFTER you added a property to the key', () => {
const key = {};
const map = new WeakMap([[key, 'keys value']]);
key.x = 'ax or X';
assert.equal(map.get(key), 'keys value');
});
it('`delete` a nested property with an external ref, keeps the value in the WeakMap', () => {
const a = {key: {}};
const b = a.key;
const map = new WeakMap([[a.key, 'a.key']]);
delete a.key;
assert.equal(map.get(b), 'a.key');
});
it('using a value of WeakMap A as key for WeakMap B works', () => {
const a = {};
const mapA = new WeakMap([[a, {}]]);
const mapB = new WeakMap([[mapA.get(a), 'the wormhole']]);
assert.equal(mapB.get(mapA.get(a)), 'the wormhole');
});
it('`Number()` returns a number', () => {
assert.equal(typeof Number(5), 'number');
});
it('`new Number()` returns an object', () => {
assert.equal(typeof new Number(5), 'object');
});
it('`new Number` does NOT strictly equal `new Number`', () => {
assert.notEqual(new Number(5), new Number(5));
});
it('`new Number` does NOT equal `new Number`', () => {
const compared = new Number(5) == new Number(5);
assert.equal(compared, false);
});
it('a reference is stable inside a timeout callback function', async () => {
let a = {};
const map = new WeakMap([[a, 'any value']]);
const p = new Promise((resolve) => {
setTimeout(() => {
const b = a;
a = {};
resolve(b);
}, 100);
});
const slowB = await p;
assert.equal(map.get(slowB), 'any value');
});
});