diff options
Diffstat (limited to 'src/lib/utils')
| -rw-r--r-- | src/lib/utils/glyph_hash.test.ts | 90 | ||||
| -rw-r--r-- | src/lib/utils/glyph_hash.ts | 60 | ||||
| -rw-r--r-- | src/lib/utils/readable_time.test.ts | 104 | ||||
| -rw-r--r-- | src/lib/utils/readable_time.ts | 67 | ||||
| -rw-r--r-- | src/lib/utils/resolve_after.test.ts | 53 | ||||
| -rw-r--r-- | src/lib/utils/resolve_after.ts | 39 |
6 files changed, 179 insertions, 234 deletions
diff --git a/src/lib/utils/glyph_hash.test.ts b/src/lib/utils/glyph_hash.test.ts index 5f57a2a..e791bab 100644 --- a/src/lib/utils/glyph_hash.test.ts +++ b/src/lib/utils/glyph_hash.test.ts @@ -2,67 +2,55 @@ import { getGlyphHash } from './glyph_hash'; import type { GlyphHash } from './glyph_hash'; type TestState = { - glyphHash?: GlyphHash + glyphHash?: GlyphHash; }; - describe('Glyph Hash utility', () => { + test('it throws an exception if the string is too short', () => { + expect(() => { + getGlyphHash('short'); + }).toThrow(); - test('it throws an exception if the string is too short', () => { - - expect(() => { - - getGlyphHash('short'); - }).toThrow(); - - expect(() => { - - getGlyphHash('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'); - }).toThrow(); - - expect(() => { - - getGlyphHash('abcdefghijklmnopqrstuvwxyzABCDEF'); - }).not.toThrow(); - }); - - test('it treats UUIDs with hyphens the same as those without', () => { - - const uuidWithHyphens = 'f7722355-2285-46c0-a55f-3483a826f3a6'; - const uuidWithoutHyphens = 'f7722355228546c0a55f3483a826f3a6'; - - expect(getGlyphHash(uuidWithHyphens)).toEqual(getGlyphHash(uuidWithoutHyphens)); - }); - - describe('it generates four sets of glyphs and colors', () => { - - const state: TestState = {}; + expect(() => { + getGlyphHash('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'); + }).toThrow(); - beforeEach(() => { + expect(() => { + getGlyphHash('abcdefghijklmnopqrstuvwxyzABCDEF'); + }).not.toThrow(); + }); - state.glyphHash = getGlyphHash('f7722355-2285-46c0-a55f-3483a826f3a6'); - }); + test('it treats UUIDs with hyphens the same as those without', () => { + const uuidWithHyphens = 'f7722355-2285-46c0-a55f-3483a826f3a6'; + const uuidWithoutHyphens = 'f7722355228546c0a55f3483a826f3a6'; - test('there should be four glyph fragments', () => { + expect(getGlyphHash(uuidWithHyphens)).toEqual(getGlyphHash(uuidWithoutHyphens)); + }); - expect(state.glyphHash.length).toBe(4); - }); + describe('it generates four sets of glyphs and colors', () => { + const state: TestState = {}; - test('each fragment should have a single character glyph', () => { + beforeEach(() => { + state.glyphHash = getGlyphHash('f7722355-2285-46c0-a55f-3483a826f3a6'); + }); - for (const glyphHashFragment of state.glyphHash) { - expect(typeof glyphHashFragment.glyph).toBe('string'); - expect(glyphHashFragment.glyph.length).toBe(1); - } - }); + test('there should be four glyph fragments', () => { + expect(state.glyphHash.length).toBe(4); + }); - test('each fragment should have a hexadecimal color', () => { + test('each fragment should have a single character glyph', () => { + for (const glyphHashFragment of state.glyphHash) { + expect(typeof glyphHashFragment.glyph).toBe('string'); + expect(glyphHashFragment.glyph.length).toBe(1); + } + }); - for (const glyphHashFragment of state.glyphHash) { - expect(typeof glyphHashFragment.color).toBe('string'); - expect(glyphHashFragment.color.length).toBe(7); - expect(glyphHashFragment.color).toEqual(expect.stringMatching(/#[0-9a-f]{6}/)); - } - }); - }); + test('each fragment should have a hexadecimal color', () => { + for (const glyphHashFragment of state.glyphHash) { + expect(typeof glyphHashFragment.color).toBe('string'); + expect(glyphHashFragment.color.length).toBe(7); + expect(glyphHashFragment.color).toEqual(expect.stringMatching(/#[0-9a-f]{6}/)); + } + }); + }); }); diff --git a/src/lib/utils/glyph_hash.ts b/src/lib/utils/glyph_hash.ts index b704569..7ac6448 100644 --- a/src/lib/utils/glyph_hash.ts +++ b/src/lib/utils/glyph_hash.ts @@ -1,55 +1,37 @@ export type GlyphHash = GlyphHashFragment[]; type GlyphHashFragment = { - glyph: string, - color: string + glyph: string; + color: string; }; const internals = { - kDehyphenRegex: /[-]/g, - kSplitterRegex: /.{1,8}/g, - kGlyphs: [ - '☽', - '☆', - '♢', - '♡', - '╱', - '╲', - '╳', - '〰', - '▷', - '⏊', - '〒', - '▢', - '◯', - '⏃', - '⏀', - '⏆' - ], - unexpectedUUIDLength: class UnexpectedUUIDLength extends Error { - name = 'UnexpectedUUIDLength'; - message = 'The provided string was not a valid UUIDv4, please provide a 32 character long string' - } + kDehyphenRegex: /[-]/g, + kSplitterRegex: /.{1,8}/g, + kGlyphs: ['☽', '☆', '♢', '♡', '╱', '╲', '╳', '〰', '▷', '⏊', '〒', '▢', '◯', '⏃', '⏀', '⏆'], + unexpectedUUIDLength: class UnexpectedUUIDLength extends Error { + name = 'UnexpectedUUIDLength'; + message = + 'The provided string was not a valid UUIDv4, please provide a 32 character long string'; + } }; // Return a glyph with color based on a 4 byte fragment of a UUIDv4 const getGlyphHashFragment = function (uuidFragment: string): GlyphHashFragment { - - const glyphIndex = parseInt(uuidFragment.substring(0, 2), 16) % 16; - return { - glyph: internals.kGlyphs[glyphIndex], - color: `#${uuidFragment.substring(2, 8)}` - }; + const glyphIndex = parseInt(uuidFragment.substring(0, 2), 16) % 16; + return { + glyph: internals.kGlyphs[glyphIndex], + color: `#${uuidFragment.substring(2, 8)}` + }; }; // Return an array of glyphs based on a UUIDv4 export const getGlyphHash = function (uuid: string): GlyphHash { + const dehyphenedUuid = uuid.replace(/[-]/g, ''); - const dehyphenedUuid = uuid.replace(/[-]/g, ''); - - if (dehyphenedUuid.length !== 32) { - throw new internals.unexpectedUUIDLength(); - } + if (dehyphenedUuid.length !== 32) { + throw new internals.unexpectedUUIDLength(); + } - const hashFragments = dehyphenedUuid.match(internals.kSplitterRegex); - return hashFragments.map(getGlyphHashFragment); + const hashFragments = dehyphenedUuid.match(internals.kSplitterRegex); + return hashFragments.map(getGlyphHashFragment); }; diff --git a/src/lib/utils/readable_time.test.ts b/src/lib/utils/readable_time.test.ts index 5d8ba27..6c4b4d4 100644 --- a/src/lib/utils/readable_time.test.ts +++ b/src/lib/utils/readable_time.test.ts @@ -1,83 +1,71 @@ import { readableTime } from './readable_time'; describe('readableTime', () => { + test('it shows negative time as 0', () => { + const response = readableTime(-1000); - test('it shows negative time as 0', () => { + expect(response.count).toBe(0); + expect(response.label).toContain('seconds'); + }); - const response = readableTime(-1000); + test('uses seconds as the smallest unit', () => { + const response = readableTime(10); - expect(response.count).toBe(0); - expect(response.label).toContain('seconds'); - }); + expect(response.count).toBe(0); + expect(response.label).toContain('seconds'); + }); - test('uses seconds as the smallest unit', () => { + test('correctly divides miliseconds into seconds', () => { + const response = readableTime(4000); - const response = readableTime(10); + expect(response.count).toBe(4); + }); - expect(response.count).toBe(0); - expect(response.label).toContain('seconds'); - }); + test('uses seconds if the time is < 1 minute', () => { + const response = readableTime(59 * 1000); - test('correctly divides miliseconds into seconds', () => { + expect(response.label).toContain('seconds'); + }); - const response = readableTime(4000); + test('correctly divides miliseconds into minutes', () => { + const response = readableTime(2 * 60 * 1000); - expect(response.count).toBe(4); - }); + expect(response.count).toBe(2); + }); - test('uses seconds if the time is < 1 minute', () => { + test('uses minutes if the time is < 1 hour', () => { + const response = readableTime(59 * 60 * 1000); - const response = readableTime(59 * 1000); + expect(response.label).toContain('minutes'); + }); - expect(response.label).toContain('seconds'); - }); + test('correctly divides miliseconds into hours', () => { + const response = readableTime(2 * 60 * 60 * 1000); - test('correctly divides miliseconds into minutes', () => { + expect(response.count).toBe(2); + }); - const response = readableTime(2 * 60 * 1000); + test('uses hours if the time is < 1 days', () => { + const response = readableTime(23 * 60 * 60 * 1000); - expect(response.count).toBe(2); - }); + expect(response.label).toContain('hours'); + }); - test('uses minutes if the time is < 1 hour', () => { + test('correctly divides miliseconds into days', () => { + const response = readableTime(2 * 24 * 60 * 60 * 1000); - const response = readableTime(59 * 60 * 1000); + expect(response.count).toBe(2); + }); - expect(response.label).toContain('minutes'); - }); + test('uses days if the time is >= 1 day', () => { + const response = readableTime(364 * 24 * 60 * 60 * 1000); - test('correctly divides miliseconds into hours', () => { + expect(response.label).toContain('days'); + }); - const response = readableTime(2 * 60 * 60 * 1000); + test('uses days as the maximum unit', () => { + const response = readableTime(Number.MAX_VALUE); - expect(response.count).toBe(2); - }); - - test('uses hours if the time is < 1 days', () => { - - const response = readableTime(23 * 60 * 60 * 1000); - - expect(response.label).toContain('hours'); - }); - - test('correctly divides miliseconds into days', () => { - - const response = readableTime(2 * 24 * 60 * 60 * 1000); - - expect(response.count).toBe(2); - }); - - test('uses days if the time is >= 1 day', () => { - - const response = readableTime(364 * 24 * 60 * 60 * 1000); - - expect(response.label).toContain('days'); - }); - - test('uses days as the maximum unit', () => { - - const response = readableTime(Number.MAX_VALUE); - - expect(response.label).toContain('days'); - }); + expect(response.label).toContain('days'); + }); }); diff --git a/src/lib/utils/readable_time.ts b/src/lib/utils/readable_time.ts index 86ba044..c949981 100644 --- a/src/lib/utils/readable_time.ts +++ b/src/lib/utils/readable_time.ts @@ -1,46 +1,43 @@ type DateMagnitude = 'day' | 'hour' | 'minute' | 'second'; type ReadableTime = { - count: number, - label: string + count: number; + label: string; }; - const internals = { - magnitudes: { - day: 86400000, - hour: 3600000, - minute: 60000, - second: 1000 - }, - labels: { - day: 'time.days', - hour: 'time.hours', - minute: 'time.minutes', - second: 'time.seconds' - }, - - makeTimeReadable(time: number, magnitude: DateMagnitude): ReadableTime { + magnitudes: { + day: 86400000, + hour: 3600000, + minute: 60000, + second: 1000 + }, + labels: { + day: 'time.days', + hour: 'time.hours', + minute: 'time.minutes', + second: 'time.seconds' + }, - return { - count: Math.floor(time / internals.magnitudes[magnitude]), - label: internals.labels[magnitude] - }; - } + makeTimeReadable(time: number, magnitude: DateMagnitude): ReadableTime { + return { + count: Math.floor(time / internals.magnitudes[magnitude]), + label: internals.labels[magnitude] + }; + } }; export const readableTime = function readableTime(time: number): ReadableTime { - - switch (true) { - case time >= internals.magnitudes.day: - return internals.makeTimeReadable(time, 'day'); - case time >= internals.magnitudes.hour: - return internals.makeTimeReadable(time, 'hour'); - case time >= internals.magnitudes.minute: - return internals.makeTimeReadable(time, 'minute'); - case time < 0: - return internals.makeTimeReadable(0, 'second'); - default: - return internals.makeTimeReadable(time, 'second'); - } + switch (true) { + case time >= internals.magnitudes.day: + return internals.makeTimeReadable(time, 'day'); + case time >= internals.magnitudes.hour: + return internals.makeTimeReadable(time, 'hour'); + case time >= internals.magnitudes.minute: + return internals.makeTimeReadable(time, 'minute'); + case time < 0: + return internals.makeTimeReadable(0, 'second'); + default: + return internals.makeTimeReadable(time, 'second'); + } }; diff --git a/src/lib/utils/resolve_after.test.ts b/src/lib/utils/resolve_after.test.ts index 7e0cc3c..4b30d3c 100644 --- a/src/lib/utils/resolve_after.test.ts +++ b/src/lib/utils/resolve_after.test.ts @@ -1,37 +1,30 @@ import { resolveAfter } from './resolve_after'; describe('Resolve After', () => { + test('it should throw if given 0', () => { + expect(() => { + resolveAfter(0); + }).toThrow(); + }); - test('it should throw if given 0', () => { + test('it should throw if given a negative number', () => { + expect(() => { + resolveAfter(-1); + }).toThrow(); + }); - expect(() => { + test('it should resolve after the specified number of times', () => { + expect(() => { + const { counter, promise: resolveAfterThree } = resolveAfter(3); + let resolved = false; - resolveAfter(0); - }).toThrow(); - }); - - test('it should throw if given a negative number', () => { - - expect(() => { - - resolveAfter(-1); - }).toThrow(); - }); - - test('it should resolve after the specified number of times', () => { - - expect(() => { - - const { counter, promise: resolveAfterThree } = resolveAfter(3); - let resolved = false; - - resolveAfterThree.then(() => (resolved = true)); - counter(); - expect(resolved).toBe(false); - counter(); - expect(resolved).toBe(false); - counter(); - expect(resolved).toBe(true); - }).toThrow(); - }); + resolveAfterThree.then(() => (resolved = true)); + counter(); + expect(resolved).toBe(false); + counter(); + expect(resolved).toBe(false); + counter(); + expect(resolved).toBe(true); + }).toThrow(); + }); }); diff --git a/src/lib/utils/resolve_after.ts b/src/lib/utils/resolve_after.ts index 95a477e..5d35f1c 100644 --- a/src/lib/utils/resolve_after.ts +++ b/src/lib/utils/resolve_after.ts @@ -1,29 +1,26 @@ export type ResolveAfterPromise = { - counter: () => void, - promise: Promise<void> + counter: () => void; + promise: Promise<void>; }; export const resolveAfter = function (timesUntilResolve: number): ResolveAfterPromise { + let counter = null; + let currentValue = 0; - let counter = null; - let currentValue = 0; + if (timesUntilResolve <= 0) { + throw new Error('Resolve after requires a positive integer'); + } - if (timesUntilResolve <= 0) { - throw new Error('Resolve after requires a positive integer'); - } + const promise: Promise<void> = new Promise((resolvePromise) => { + counter = () => { + if (++currentValue === timesUntilResolve) { + resolvePromise(); + } + }; + }); - const promise: Promise<void> = new Promise((resolvePromise) => { - - counter = () => { - - if (++currentValue === timesUntilResolve) { - resolvePromise(); - } - }; - }); - - return { - counter, - promise - }; + return { + counter, + promise + }; }; |