UNPKG

reign

Version:

A persistent, typed-objects implementation.

480 lines (384 loc) 14.3 kB
"use strict"; var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); var _ = require("../.."); var _symbols = require("../../symbols"); describeRealm('HashMapType', function (options) { let realm; let HashMapType; let StructType; let SimpleMap; let instance; let T; before(() => { realm = options.realm; T = realm.T; HashMapType = realm.HashMapType; StructType = realm.StructType; }); it('HashMapType should be an instance of realm.TypeClass', function () { HashMapType.should.be.an.instanceOf(realm.TypeClass); }); it('should create a simple hash map type', function () { SimpleMap = new HashMapType(T.Uint32, T.Uint32); }); it('SimpleMap should be an instance of HashMapType', function () { SimpleMap.should.be.an.instanceOf(HashMapType); }); it('should create a new, empty instance', function () { instance = new SimpleMap(); }); it('should have a size of 0', function () { instance.size.should.equal(0); }); it('should not have the value', function () { instance.has(123).should.equal(false); }); it('should add an item to the map', function () { instance.set(123, 456); }); it('should have a size of 1', function () { instance.size.should.equal(1); }); it('should have the value', function () { instance.has(123).should.equal(true); }); it('should get the value', function () { instance.get(123).should.equal(456); }); it('should create a new instance from an array', function () { instance = new SimpleMap([[1, 2], [2, 3], [3, 4], [4, 5], [5, 6]]); }); it('should have the right size', function () { instance.size.should.equal(5); }); it('should have all the keys', function () { instance.has(1).should.equal(true); instance.has(2).should.equal(true); instance.has(3).should.equal(true); instance.has(4).should.equal(true); instance.has(5).should.equal(true); instance.has(6).should.equal(false); }); it('should get all the keys', function () { instance.get(1).should.equal(2); instance.get(2).should.equal(3); instance.get(3).should.equal(4); instance.get(4).should.equal(5); instance.get(5).should.equal(6); (instance.get(6) === undefined).should.equal(true); }); it('should create a new instance from a native Map', function () { instance = new SimpleMap(new Map([[1, 2], [2, 3], [3, 4], [4, 5], [5, 6]])); }); it('should have the right size', function () { instance.size.should.equal(5); }); it('should have all the keys', function () { instance.has(1).should.equal(true); instance.has(2).should.equal(true); instance.has(3).should.equal(true); instance.has(4).should.equal(true); instance.has(5).should.equal(true); instance.has(6).should.equal(false); }); it('should get all the keys', function () { instance.get(1).should.equal(2); instance.get(2).should.equal(3); instance.get(3).should.equal(4); instance.get(4).should.equal(5); instance.get(5).should.equal(6); (instance.get(6) === undefined).should.equal(true); }); it('should create a new instance from an object', function () { instance = new SimpleMap({ 1: 2, 2: 3, 3: 4, 4: 5, 5: 6 }); }); it('should have the right size', function () { instance.size.should.equal(5); }); it('should have all the keys', function () { instance.has(1).should.equal(true); instance.has(2).should.equal(true); instance.has(3).should.equal(true); instance.has(4).should.equal(true); instance.has(5).should.equal(true); instance.has(6).should.equal(false); }); it('should get all the keys', function () { instance.get(1).should.equal(2); instance.get(2).should.equal(3); instance.get(3).should.equal(4); instance.get(4).should.equal(5); instance.get(5).should.equal(6); (instance.get(6) === undefined).should.equal(true); }); describe('HashMap<String, String>', function () { let HashMap; it('should make a new hash map', function () { HashMap = new HashMapType(T.String, T.String); }); it('should have the right name', function () { HashMap.name.should.equal('HashMap<String, String>'); }); describe('Empty instance', function () { let instance; it('should create a new instance', function () { instance = new HashMap(); }); it('should have an initial size of 0', function () { instance.size.should.equal(0); }); it('should add an item', function () { instance.set("hello", "world"); }); it('should have the added item', function () { instance.has("hello").should.equal(true); }); it('should get the added item', function () { instance.get("hello").should.equal("world"); }); it('should not have any other items', function () { instance.has("nope").should.equal(false); }); it('should add another item', function () { instance.set("foo", "bar"); }); it('should have the added item', function () { instance.has("foo").should.equal(true); }); it('should get the added item', function () { instance.get("foo").should.equal("bar"); }); }); const inputs = { 'instance from array': [["hello", "world"], ["foo", "bar"]], 'instance from Map': new Map([["hello", "world"], ["foo", "bar"]]), 'instance from Object': { hello: "world", foo: "bar" } }; Object.keys(inputs).forEach(testName => { const input = inputs[testName]; describe(testName, function () { let instance; it('should create a new instance', function () { instance = new HashMap(input); }); it('should set the right size', function () { instance.size.should.equal(2); }); it('should have the first item', function () { instance.has("hello").should.equal(true); }); it('should get the first item', function () { instance.get("hello").should.equal("world"); }); it('should have the second item', function () { instance.has("foo").should.equal(true); }); it('should get the second item', function () { instance.get("foo").should.equal("bar"); }); it('should overwrite the first item', function () { instance.set("hello", "World!"); }); it('should not have incremented the size', function () { instance.size.should.equal(2); }); it('should add a new item', function () { instance.set("qux", "xuq"); }); it('should have incremented the size', function () { instance.size.should.equal(3); }); it('should have all the entries', function () { instance.has("hello").should.equal(true); instance.has("foo").should.equal(true); instance.has("qux").should.equal(true); }); it('should get all the entries', function () { instance.get("hello").should.equal("World!"); instance.get("foo").should.equal("bar"); instance.get("qux").should.equal("xuq"); }); it('should delete the first entry', function () { instance.delete("hello").should.equal(true); instance.delete("hello").should.equal(false); }); it('should delete the second entry', function () { instance.delete("foo").should.equal(true); instance.delete("foo").should.equal(false); }); it('should delete the third entry', function () { instance.delete("qux").should.equal(true); instance.delete("qux").should.equal(false); }); it('should have reset the size to zero', function () { instance.size.should.equal(0); }); }); }); }); PRIMITIVE_NAMES.forEach((keyTypeName, typeIndex) => { const valueTypeName = PRIMITIVE_NAMES[(typeIndex + 1) % PRIMITIVE_NAMES.length]; let HashMap; let KeyType; let ValueType; before(() => { KeyType = T[keyTypeName]; ValueType = T[valueTypeName]; }); describe(`HashMap<${ keyTypeName }, ${ valueTypeName }>`, function () { let instance; let key; let otherKey; let value; before(() => { HashMap = new HashMapType(KeyType, ValueType); key = KeyType.randomValue(); otherKey = KeyType.randomValue(); // avoid cases where we generate duplicate keys let count = 0; while (key === otherKey && count < 100) { count++; otherKey = KeyType.randomValue(); } if (key === otherKey) { throw new Error('Could not generate another key for ' + keyTypeName); } value = ValueType.randomValue(); }); it('should set the right name', function () { HashMap.name.should.equal(`HashMap<${ keyTypeName }, ${ valueTypeName }>`); }); it('should set the correct byte alignment', function () { HashMap.byteAlignment.should.equal(Math.max(8, KeyType.byteAlignment, ValueType.byteAlignment)); }); it('should create a random instance', function () { instance = HashMap.randomValue(); HashMap.accepts(instance).should.equal(true); instance.size.should.be.above(0); let count = 0; for (let _ref of instance) { var _ref2 = _slicedToArray(_ref, 2); let key = _ref2[0]; let value = _ref2[1]; KeyType.accepts(key).should.equal(true); ValueType.accepts(value).should.equal(true); count++; } count.should.equal(instance.size); }); it('should create a new hash map', function () { instance = new HashMap(); }); it('should have the right initial size', function () { instance.size.should.equal(0); }); it('should add a value to the map', function () { instance.set(key, value); }); it('should have the right size after adding 1 value', function () { instance.size.should.equal(1); }); it('should get a value from the map', function () { (instance.get(key) === value).should.equal(true); }); it('should not get a missing value from the map', function () { (instance.get(otherKey) === undefined).should.equal(true); }); it('should have the given key', function () { instance.has(key).should.equal(true); }); it('should not have the other key', function () { instance.has(otherKey).should.equal(false); }); it('should add the other key', function () { instance.set(otherKey, value); }); it('should have the right size after adding the other key', function () { instance.size.should.equal(2); }); it('should have the other key', function () { instance.has(otherKey).should.equal(true); }); it('should have the right value for the other key', function () { (instance.get(otherKey) === value).should.equal(true); }); it('should remove the first key', function () { instance.delete(key).should.equal(true); }); it('should have the right size', function () { instance.size.should.equal(1); }); it('should not remove the first key twice', function () { instance.delete(key).should.equal(false); }); it('should have the right size', function () { instance.size.should.equal(1); }); it('should remove the second key', function () { instance.delete(otherKey).should.equal(true); }); it('should have the right size after removing all keys', function () { instance.size.should.equal(0); }); }); }); describe('Hashmap within a struct', function () { let Container; let StringMap; let container; before(() => { StringMap = new HashMapType(T.InternedString, T.String); Container = new StructType({ name: T.String, dict: StringMap }); container = new Container(); }); it('should have an empty name', function () { container.name.should.equal(''); }); it('should set the name', function () { container.name = 'name goes here.'; }); it('should get the name', function () { container.name.should.equal('name goes here.'); }); it('should have an empty hash map', function () { container.dict.size.should.equal(0); }); it('should add some items to the dictionary', function () { container.dict.set('hello', 'world'); container.dict.set('foo', 'bar'); container.dict.set('greetings', 'aliens'); }); it('should have the right size', function () { container.dict.size.should.equal(3); }); it('should have the items', function () { container.dict.has('hello').should.equal(true); container.dict.has('foo').should.equal(true); container.dict.has('greetings').should.equal(true); }); it('should get the items', function () { container.dict.get('hello').should.equal('world'); container.dict.get('foo').should.equal('bar'); container.dict.get('greetings').should.equal('aliens'); }); it('should perform a number of garbage collection cycles', function () { realm.backing.gc.cycle(); realm.backing.gc.cycle(); realm.backing.gc.cycle(); realm.backing.gc.cycle(); realm.backing.gc.cycle(); }); }); });