diff --git a/src/lib/color.test.ts b/src/lib/color.test.ts new file mode 100644 index 0000000..fbfd735 --- /dev/null +++ b/src/lib/color.test.ts @@ -0,0 +1,29 @@ +import {Color} from './color' + +describe('Color', () => { + test('fromLumaChromaHue', () => { + expect(Color.fromLumaChromaHue(0, 0, 0).toCSS()).toEqual('rgba(0, 0, 0, 1.00)') + expect(Color.fromLumaChromaHue(1, 0, 0).toCSS()).toEqual('rgba(255, 255, 255, 1.00)') + + expect(Color.fromLumaChromaHue(0.5, 0, 30).toCSS()).toEqual('rgba(128, 128, 128, 1.00)') + expect(Color.fromLumaChromaHue(0.5, 0, 60).toCSS()).toEqual('rgba(128, 128, 128, 1.00)') + + expect(Color.fromLumaChromaHue(0.5, 0.5, 0).toCSS()).toEqual('rgba(217, 89, 89, 1.00)') + + expect(Color.fromLumaChromaHue(0.5, 1.0, 0).toCSS()).toEqual('rgba(255, 51, 51, 1.00)') + expect(Color.fromLumaChromaHue(0.5, 1.0, 60).toCSS()).toEqual('rgba(156, 156, 0, 1.00)') + expect(Color.fromLumaChromaHue(0.5, 1.0, 120).toCSS()).toEqual('rgba(0, 232, 0, 1.00)') + expect(Color.fromLumaChromaHue(0.5, 1.0, 180).toCSS()).toEqual('rgba(0, 204, 204, 1.00)') + expect(Color.fromLumaChromaHue(0.5, 1.0, 240).toCSS()).toEqual('rgba(99, 99, 255, 1.00)') + expect(Color.fromLumaChromaHue(0.5, 1.0, 300).toCSS()).toEqual('rgba(255, 23, 255, 1.00)') + expect(Color.fromLumaChromaHue(0.5, 1.0, 360).toCSS()).toEqual('rgba(255, 51, 51, 1.00)') + }) + + test('toCSS', () => { + expect(new Color().toCSS()).toEqual('rgba(0, 0, 0, 1.00)') + expect(new Color(1, 0, 0, 1).toCSS()).toEqual('rgba(255, 0, 0, 1.00)') + expect(new Color(0, 1, 0, 1).toCSS()).toEqual('rgba(0, 255, 0, 1.00)') + expect(new Color(0, 0, 1, 1).toCSS()).toEqual('rgba(0, 0, 255, 1.00)') + expect(new Color(0, 0, 1, 0.599).toCSS()).toEqual('rgba(0, 0, 255, 0.60)') + }) +}) diff --git a/src/lib/color.ts b/src/lib/color.ts index f859d31..92dcce1 100644 --- a/src/lib/color.ts +++ b/src/lib/color.ts @@ -1,3 +1,5 @@ +import {clamp} from './math' + export class Color { constructor( readonly r: number = 0, @@ -7,6 +9,9 @@ export class Color { ) {} static fromLumaChromaHue(L: number, C: number, H: number) { + // 0 <= L <= 1 + // 0 <= C <= 1 + // 0 <= H <= 360 // https://en.wikipedia.org/wiki/HSL_and_HSV#From_luma/chroma/hue const hPrime = H / 60 @@ -26,7 +31,7 @@ export class Color { const m = L - (0.3 * R1 + 0.59 * G1 + 0.11 * B1) - return new Color(R1 + m, G1 + m, B1 + m, 1.0) + return new Color(clamp(R1 + m, 0, 1), clamp(G1 + m, 0, 1), clamp(B1 + m, 0, 1), 1.0) } toCSS(): string { diff --git a/src/lib/demangle-cpp.test.ts b/src/lib/demangle-cpp.test.ts index ce6f5be..cd024f3 100644 --- a/src/lib/demangle-cpp.test.ts +++ b/src/lib/demangle-cpp.test.ts @@ -6,4 +6,8 @@ test('demangleCpp', () => { expect(demangleCpp('__ZNK7Support6ColorFeqERKS0_')).toBe( 'Support::ColorF::operator==(Support::ColorF const&) const', ) + // Running a second time to test the cache + expect(demangleCpp('__ZNK7Support6ColorFeqERKS0_')).toBe( + 'Support::ColorF::operator==(Support::ColorF const&) const', + ) }) diff --git a/src/lib/hash-params.test.ts b/src/lib/hash-params.test.ts new file mode 100644 index 0000000..804221b --- /dev/null +++ b/src/lib/hash-params.test.ts @@ -0,0 +1,27 @@ +import {getHashParams} from './hash-params' + +test('getHashParams', () => { + expect(getHashParams('')).toEqual({}) + expect(getHashParams('#')).toEqual({}) + expect(getHashParams('#title=hello')).toEqual({title: 'hello'}) + expect(getHashParams('#localProfilePath=file:///tmp/file.js')).toEqual({ + localProfilePath: 'file:///tmp/file.js', + }) + expect( + getHashParams( + '#profileURL=https://raw.githubusercontent.com/jlfwong/speedscope/master/sample/profiles/speedscope/0.1.2/simple-sampled.speedscope.json', + ), + ).toEqual({ + profileURL: + 'https://raw.githubusercontent.com/jlfwong/speedscope/master/sample/profiles/speedscope/0.1.2/simple-sampled.speedscope.json', + }) + expect(getHashParams('#title=hello&localProfilePath=file:///tmp/file.js')).toEqual({ + title: 'hello', + localProfilePath: 'file:///tmp/file.js', + }) + expect(getHashParams('#title=hello%20world')).toEqual({ + title: 'hello world', + }) + expect(getHashParams('#abc=bcd')).toEqual({}) + expect(getHashParams('garbage')).toEqual({}) +}) diff --git a/src/lib/hash-params.ts b/src/lib/hash-params.ts index 6a6e227..469e820 100644 --- a/src/lib/hash-params.ts +++ b/src/lib/hash-params.ts @@ -4,22 +4,22 @@ export interface HashParams { localProfilePath?: string } -export function getHashParams(): HashParams { +export function getHashParams(hashContents = window.location.hash): HashParams { try { - const hashContents = window.location.hash if (!hashContents.startsWith('#')) { return {} } const components = hashContents.substr(1).split('&') const result: HashParams = {} for (const component of components) { - const [key, value] = component.split('=') + let [key, value] = component.split('=') + value = decodeURIComponent(value) if (key === 'profileURL') { - result.profileURL = decodeURIComponent(value) + result.profileURL = value } else if (key === 'title') { - result.title = decodeURIComponent(value) + result.title = value } else if (key === 'localProfilePath') { - result.localProfilePath = decodeURIComponent(value) + result.localProfilePath = value } } return result