UNPKG

cluster-id

Version:

Database cluster friendly object id with great query isolation.

137 lines (117 loc) 4.48 kB
/* global test, expect */ var gen = require('./generator') var YEAR_MS = parseInt(365.26 * 24 * 60 * 60 * 1000) var validId = /([\w-]{13}|[\w-]{26})/ // TODO: expect.extend test('return function to generate ids', function () { var id = gen() expect(typeof id).toBe('function') expect(id.name).toBe('id') }) test('return valid base64 id for default params', function () { var id = gen() expect(id()).toMatch(validId) }) test('accept valid epoch', function () { expect(gen({epoch: 0})()).toMatch(validId) expect(gen({epoch: new Date(2000).getTime()})()).toMatch(validId) expect(gen({epoch: Date.now() - 1})()).toMatch(validId) }) test('throw an error for invalid epoch', function () { expect(function () { return gen({epoch: -1})(); }).toThrow('Invalid epoch -1') expect(function () { return gen({epoch: Date.now() + 1000})(); }).toThrow('Invalid epoch') expect(function () { return gen({epoch: '123'})(); }).toThrow('Invalid epoch') }) test('reserve for instance 2..4 symbols', function () { expect(gen({instanceLen: 2})()).toMatch(validId) expect(gen({instanceLen: 4})()).toMatch(validId) expect(function () { return gen({instanceLen: 1})(); }).toThrow('Invalid instance') expect(function () { return gen({instanceLen: 5})(); }).toThrow('Invalid instance') }) test('accept segment in range 0..63', function () { expect(gen()({segment: 0})).toMatch(/^-/) expect(gen()({segment: 1})).toMatch(/^0/) expect(gen()({segment: 20})).toMatch(/^J/) expect(gen()({segment: 40})).toMatch(/^c/) expect(gen()({segment: 63})).toMatch(/^z/) }) test('reject invalid segments out of range 0..63', function () { expect(function () { return gen()({segment: -1}); }).toThrow('Invalid segment: -1') expect(function () { return gen()({segment: 64}); }).toThrow('Invalid segment: 64') expect(function () { return gen()({segment: 'str'}); }).toThrow('Invalid segment: str') }) test('accept time > epoch', function () { expect(gen()({time: Date.now()})).toMatch(validId) expect(gen({epoch: Date.now() - 1})({time: Date.now()})).toMatch(validId) expect(gen({epoch: 0})({time: 10})).toBe('-9-----------') expect(gen({epoch: 0})({time: 1 * YEAR_MS})).toBe('-O_z0---0sNh-') expect(gen({epoch: 0})({time: 100 * YEAR_MS})).toBe('-6QL6--1w5aJ-') }) test('fail if time is 2500 years ahead', function () { expect(function () { return gen()({time: 2500 * YEAR_MS}); }).toThrow('Too far away') }) test('fail with time <= epoch', function () { expect(function () { return gen()({time: 0}); }).toThrow() }) test('accept root id as scope', function () { var id = gen({epoch: 0})({ scope: '-YfCY--0T2I9-', time: 51 * YEAR_MS }) expect(id).toMatch(validId) expect(id).toMatch('-YfCY--0T2I9--0Uvfr-wme_--') }) test('accept scoped id as scope', function () { var id = gen({epoch: 0})({ scope: '-YfCY--0T2I9--0Uvfr-_emw--', time: 70 * YEAR_MS }) expect(id).toMatch(validId) expect(id).toMatch('-_emw--0Uvfr--12f0D-NtXA--') }) test('use scope segment from provided scope by default', function () { var id = gen({epoch: 0})({ scope: '-YfCY--0T2I9-S0Uvfr-_emw--', // S is segment time: 70 * YEAR_MS }) expect(id).toMatch(validId) expect(id).toMatch('S_emw--0Uvfr-S12f0D-NtXA--') }) test('use custom segment', function () { var id = gen({epoch: 0})({ segment: 10, time: 15 * YEAR_MS }) expect(id).toMatch(validId) expect(id).toMatch('9rktS---RCmY-') }) test('use custom segment in child part with root id', function () { var id = gen({epoch: 0})({ segment: 3, scope: '9Stkr---RCmY-', // 9 is segment time: 15 * YEAR_MS }) expect(id).toMatch('9Stkr---RCmY-2-RCmY-rktS--') }) test('use custom segment in child part with scoped id', function () { var id = gen({epoch: 0})({ segment: 63, // z scope: '9Stkr---RCmY-2-RCmY-Stkr--', // 2 is segment time: 15 * YEAR_MS }) expect(id).toMatch('2Stkr---RCmY-z-RCmY-rktS--') }) test('swap use custom segment in child part with scoped id', function () { var id = gen({epoch: 0})({ segment: 63, // z scope: '9Stkr---RCmY-2-RCmY-Stkr--', // 2 is segment time: 15 * YEAR_MS }) expect(id).toMatch('2Stkr---RCmY-z-RCmY-rktS--') }) test('change first symbol of counter on each step for better cardinality', function () { var id = gen() expect(id({time: YEAR_MS})).toBe('-O_z0---0sNh-') expect(id({time: YEAR_MS + 1})).toBe('-P_z0---0sNh-') expect(id({time: YEAR_MS + 2})).toBe('-Q_z0---0sNh-') })