From fa29a29e342a09556c63eaa184f2ee7c647edb08 Mon Sep 17 00:00:00 2001 From: Corban Riley Date: Mon, 13 Nov 2023 14:50:45 -0500 Subject: [PATCH] Adding tests for color utils --- src/helpers/colors.test.ts | 52 ++++++++++++++++++++++++++++++++++++++ src/helpers/colors.ts | 33 +++++++++++++++++++----- 2 files changed, 79 insertions(+), 6 deletions(-) create mode 100644 src/helpers/colors.test.ts diff --git a/src/helpers/colors.test.ts b/src/helpers/colors.test.ts new file mode 100644 index 000000000..75b2c4997 --- /dev/null +++ b/src/helpers/colors.test.ts @@ -0,0 +1,52 @@ +import { Color } from './colors' + +describe('Color', () => { + it('parses rgb colors', () => { + expect(Color.from('rgb(255, 255, 255)').toRGB()).toEqual([255, 255, 255, 1]) + expect(Color.from('rgb(255, 0, 0)').toRGB()).toEqual([255, 0, 0, 1]) + expect(Color.from('rgb(256, 0, 0)').toRGB()).toEqual([255, 0, 0, 1]) + + // Modern format + expect(Color.from('rgb(255 255 255)').toRGB()).toEqual([255, 255, 255, 1]) + }) + + it('parses hls colors', () => { + expect(Color.from('hsl(0, 0%, 100%)').toRGB()).toEqual([255, 255, 255, 1]) + expect(Color.from('hsl(360, 0%, 100%)').toRGB()).toEqual([255, 255, 255, 1]) + expect(Color.from('hsl(0, 100%, 50%)').toRGB()).toEqual([255, 0, 0, 1]) + expect(Color.from('hsl(120, 100%, 50%)').toRGB()).toEqual([0, 255, 0, 1]) + expect(Color.from('hsl(240, 100%, 50%)').toRGB()).toEqual([0, 0, 255, 1]) + + // Modern format + expect(Color.from('hsl(0 0% 0%)').toRGB()).toEqual([0, 0, 0, 1]) + }) + + it('parses rgba colors', () => { + expect(Color.from('rgba(0, 0, 0, 0.5)').toRGB()).toEqual([0, 0, 0, 0.5]) + + // Modern format + expect(Color.from('rgba(0 0 255 / 0.5)').toRGB()).toEqual([0, 0, 255, 0.5]) + }) + + it('parses hsla colors', () => { + expect(Color.from('hsla(0, 0%, 0%, 0.5)').toRGB()).toEqual([0, 0, 0, 0.5]) + + // Modern format + expect(Color.from('hsla(0 0% 0% / 0.5)').toRGB()).toEqual([0, 0, 0, 0.5]) + }) + + it('parses hex colors', () => { + expect(Color.from('#000000').toRGB()).toEqual([0, 0, 0, 1]) + expect(Color.from('#ffff00').toRGB()).toEqual([255, 255, 0, 1]) + expect(Color.from('#000').toRGB()).toEqual([0, 0, 0, 1]) + expect(Color.from('#f00').toRGB()).toEqual([255, 0, 0, 1]) + }) + + it('parses color keywords', () => { + expect(Color.from('red').toRGB()).toEqual([255, 0, 0, 1]) + expect(Color.from('blue').toRGB()).toEqual([0, 0, 255, 1]) + expect(Color.from('transparent').toRGB()).toEqual([0, 0, 0, 0]) + expect(Color.from('pink').toRGB()).toEqual([255, 192, 203, 1]) + expect(Color.from('aquamarine').toRGB()).toEqual([127, 255, 212, 1]) + }) +}) diff --git a/src/helpers/colors.ts b/src/helpers/colors.ts index 6fe10689b..64ffc91ac 100644 --- a/src/helpers/colors.ts +++ b/src/helpers/colors.ts @@ -29,7 +29,12 @@ export class Color { } toRGB(): RawColor { - return [Math.round(this.r * 255), Math.round(this.g * 255), Math.round(this.b * 255), this.a] + return [ + Math.round(this.r * 255), + Math.round(this.g * 255), + Math.round(this.b * 255), + this.a, + ] } toHSL(): RawColor { @@ -75,7 +80,15 @@ export class Color { } const parseCSS = (color: string): RawColor => { - const value = parseHex(color) || parseHex(COLORS[color]) || parseRGB(color) || parseHSL(color) + if (color === 'transparent') { + return [0, 0, 0, 0] + } + + const value = + parseHex(color) || + parseHex(COLORS[color]) || + parseRGB(color) || + parseHSL(color) if (!value) { throw new Error(`Could not parse color ${color}`) @@ -99,7 +112,12 @@ const parseHex = (color: string | undefined): RawColor | undefined => { } const hex = Number('0x' + c) - return [((hex >> 16) & 255) / 255, ((hex >> 8) & 255) / 255, (hex & 255) / 255, 1] + return [ + ((hex >> 16) & 255) / 255, + ((hex >> 8) & 255) / 255, + (hex & 255) / 255, + 1, + ] } return @@ -113,7 +131,7 @@ const parseRGB = (color: string | undefined): RawColor | undefined => { const c = color.match(/rgba?\((.*)\)/) if (c) { - const [r, g, b, a] = c[1].split(',').map(parseFloat) + const [r, g, b, a] = c[1].split(/[,\s\/]+/).map(parseFloat) return [r / 255, g / 255, b / 255, a ?? 1] } @@ -129,7 +147,10 @@ const parseHSL = (color: string | undefined): RawColor | undefined => { const c = color.match(/hsla?\((.*)\)/) if (c) { - let [h, s, l, a] = c[1].split(',').map(parseFloat) + let [h, s, l, a] = c[1] + .replace(/deg|%/g, '') + .split(/[,\s\/]+/) + .map(parseFloat) h = h s /= 100 l /= 100 @@ -318,5 +339,5 @@ const COLORS: { [index: string]: string } = { white: '#ffffff', whitesmoke: '#f5f5f5', yellow: '#ffff00', - yellowgreen: '#9acd32' + yellowgreen: '#9acd32', }