import { assert } from 'chai'; import { fuzzyEqual } from '../../../lib/math/float'; import { Color, Spec, Format, Alpha, parseColor, rgb, rgba, colors, isGray, gray } from '../../../lib/graphics/Color'; const formats = [Format.HexRgb, Format.Functional, Format.Named]; // const alphas = [Alpha.SkipFullyOpaque, Alpha.Include, Alpha.Exclude]; describe('graphics.Color', () => { describe('parseColor', () => { [ ['', undefined], ['red', { spec: Spec.Rgb, r: 255, g: 0, b: 0, a: 1 }], ['black', { spec: Spec.Rgb, r: 0, g: 0, b: 0, a: 1 }], ['transparent', { spec: Spec.Rgb, r: 0, g: 0, b: 0, a: 0 }], ['foo', undefined], ['#f09', { spec: Spec.Rgb, r: 255, g: 0, b: 153 }], ['#ff0099', { spec: Spec.Rgb, r: 255, g: 0, b: 153 }], ['#FF0099', { spec: Spec.Rgb, r: 255, g: 0, b: 153 }], ['#', undefined], ['#f0', undefined], ['#xx0099', undefined], ['#3a30', { spec: Spec.Rgb, r: 51, g: 170, b: 51, a: 0 }], ['#3a3f', { spec: Spec.Rgb, r: 51, g: 170, b: 51, a: 1 }], ['#3a38', { spec: Spec.Rgb, r: 51, g: 170, b: 51, a: 0.5333333333333333 }], ['#33aa3300', { spec: Spec.Rgb, r: 51, g: 170, b: 51, a: 0 }], ['#33aa33ff', { spec: Spec.Rgb, r: 51, g: 170, b: 51, a: 1 }], ['#33aa3388', { spec: Spec.Rgb, r: 51, g: 170, b: 51, a: 0.5333333333333333 }], ['rgb(255, 0, 153)', { spec: Spec.Rgb, r: 255, g: 0, b: 153 }], ['rgb(100%,0%,60%)', { spec: Spec.Rgb, r: 255, g: 0, b: 153 }], ['rgb(255, 0, 153, 1)', { spec: Spec.Rgb, r: 255, g: 0, b: 153, a: 1 }], ['rgb(255, 0, 153, 100%)', { spec: Spec.Rgb, r: 255, g: 0, b: 153, a: 1 }], ['rgb(255 0 153)', { spec: Spec.Rgb, r: 255, g: 0, b: 153 }], ['rgb(255 0 153 / 100%)', { spec: Spec.Rgb, r: 255, g: 0, b: 153, a: 1 }], ['rgb(255 0 153 / 1)', { spec: Spec.Rgb, r: 255, g: 0, b: 153, a: 1 }], ['rgba(51, 170, 51, .1)', { spec: Spec.Rgb, r: 51, g: 170, b: 51, a: 0.1 }], ['rgba(51 170 51 / 0.4)', { spec: Spec.Rgb, r: 51, g: 170, b: 51, a: 0.4 }], ['rgba(51 170 51 / 40%)', { spec: Spec.Rgb, r: 51, g: 170, b: 51, a: 0.4 }], ['rgb(255, 0 153)', undefined], ['rgb(255, O, 153)', undefined], ['rbg(255, 0, 153)', undefined], ['rgba(51 / 170 / 51 / 0.4)', undefined], ['hsl(270,60%,70%)', { spec: Spec.Hsl, h: 270, s: 60, l: 70 }], ['hsl(270, 60%, 70%)', { spec: Spec.Hsl, h: 270, s: 60, l: 70 }], ['hsl(270 60% 70%)', { spec: Spec.Hsl, h: 270, s: 60, l: 70 }], ['hsl(270deg, 60%, 70%)', { spec: Spec.Hsl, h: 270, s: 60, l: 70 }], ['hsl(4.71239rad, 60%, 70%)', { spec: Spec.Hsl, h: 270.000058419654, s: 60, l: 70 }], ['hsl(.75turn, 60%, 70%)', { spec: Spec.Hsl, h: 270, s: 60, l: 70 }], ['hsl(270, 60%, 50%, .15)', { spec: Spec.Hsl, h: 270, s: 60, l: 50, a: 0.15 }], ['hsl(270, 60%, 50%, 15%)', { spec: Spec.Hsl, h: 270, s: 60, l: 50, a: 0.15 }], ['hsl(270 60% 50% / .15)', { spec: Spec.Hsl, h: 270, s: 60, l: 50, a: 0.15 }], ['hsl(270 60% 50% / 15%)', { spec: Spec.Hsl, h: 270, s: 60, l: 50, a: 0.15 }], ['hsla(240, 100%, 50%, .05)', { spec: Spec.Hsl, h: 240, s: 100, l: 50, a: 0.05 }], ['hsla(240 100% 50% / 5%) ', { spec: Spec.Hsl, h: 240, s: 100, l: 50, a: 0.05 }], ['hsv(270 60% 70%)', { spec: Spec.Hsv, h: 270, s: 60, v: 70 }], ['hsva(240 100% 50% / 5%) ', { spec: Spec.Hsv, h: 240, s: 100, v: 50, a: 0.05 }], ['cmyk(50% 60% 70% 80%)', { spec: Spec.Cmyk, c: 50, m: 60, y: 70, k: 80 }], ['cmyk(50% 60% 70% 80% / 0.5)', { spec: Spec.Cmyk, c: 50, m: 60, y: 70, k: 80, a: 0.5 }], ['cmyka(50, 60, 70, 80, 0.4)', { spec: Spec.Cmyk, c: 50, m: 60, y: 70, k: 80, a: 0.4 }], ].forEach((data, index) => { const input = data[0] as string; const result = data[1] as any; it(`parseColor@${input}`, () => { assert.deepEqual(parseColor(input), result); }); }); }); describe('constructor', () => { [ [undefined, { spec: Spec.Invalid }], ['red', { spec: Spec.Rgb, red: 255, green: 0, blue: 0, alpha: 1 }], ['black', { spec: Spec.Rgb, red: 0, green: 0, blue: 0, alpha: 1 }], ['transparent', { spec: Spec.Rgb, red: 0, green: 0, blue: 0, alpha: 0 }], ['foo', { spec: Spec.Invalid }], ['#ff0099', { spec: Spec.Rgb, red: 255, green: 0, blue: 153, alpha: 1 }], ['#33aa3388', { spec: Spec.Rgb, red: 51, green: 170, blue: 51, alpha: 0.5333333333333333 }], ['rgb(51, 170, 51)', { spec: Spec.Rgb, red: 51, green: 170, blue: 51, alpha: 1 }], ['rgba(51 170 51 / 0.4)', { spec: Spec.Rgb, red: 51, green: 170, blue: 51, alpha: 0.4 }], ['hsv(270 60% 70%)', { spec: Spec.Hsv, hsvHue: 270, hsvSaturation: 60, hsvValue: 70, alpha: 1 }], ['hsva(270 60% 70% / 40%)', { spec: Spec.Hsv, hsvHue: 270, hsvSaturation: 60, hsvValue: 70, alpha: 0.4 }], ['hsl(270, 60%, 70%)', { spec: Spec.Hsl, hue: 270, saturation: 60, lightness: 70, alpha: 1 }], ['hsla(.75turn, 60%, 70%, .4)', { spec: Spec.Hsl, hue: 270, saturation: 60, lightness: 70, alpha: 0.4 }], ['cmyk(50%, 60%, 70%, 80%)', { spec: Spec.Cmyk, cyan: 50, magenta: 60, yellow: 70, black: 80, alpha: 1 }], ['cmyka(50%, 60%, 70%, 80%, 40%)', { spec: Spec.Cmyk, cyan: 50, magenta: 60, yellow: 70, black: 80, alpha: 0.4 }], [0, { spec: Spec.Rgb, red: 0, green: 0, blue: 0, alpha: 0 }], [-1, { spec: Spec.Rgb, red: 255, green: 255, blue: 255, alpha: 1 }], [rgb(255, 0, 153), { spec: Spec.Rgb, red: 255, green: 0, blue: 153, alpha: 1 }], [rgba(255, 0, 153, 136), { spec: Spec.Rgb, red: 255, green: 0, blue: 153, alpha: 0.5333333333333333 }], [[255, 0, 0], { spec: Spec.Rgb, red: 255, green: 0, blue: 0, alpha: 1 }], [[51, 170, 51, 0.4], { spec: Spec.Rgb, red: 51, green: 170, blue: 51, alpha: 0.4 }], [[270, 60, 70], { spec: Spec.Hsl, hue: 270, saturation: 60, lightness: 70, alpha: 1 }, Spec.Hsl], [[270, 60, 70, 0.4], { spec: Spec.Hsl, hue: 270, saturation: 60, lightness: 70, alpha: 0.4 }, Spec.Hsl], [[270, 60, 70], { spec: Spec.Hsv, hsvHue: 270, hsvSaturation: 60, hsvValue: 70, alpha: 1 }, Spec.Hsv], [[270, 60, 70, 0.4], { spec: Spec.Hsv, hsvHue: 270, hsvSaturation: 60, hsvValue: 70, alpha: 0.4 }, Spec.Hsv], [[50, 60, 70, 80], { spec: Spec.Cmyk, cyan: 50, magenta: 60, yellow: 70, black: 80, alpha: 1 }, Spec.Cmyk], [[50, 60, 70, 80, 0.4], { spec: Spec.Cmyk, cyan: 50, magenta: 60, yellow: 70, black: 80, alpha: 0.4 }, Spec.Cmyk], [{ r: 51, g: 170, b: 51 }, { spec: Spec.Rgb, red: 51, green: 170, blue: 51, alpha: 1 }], [{ r: 51, g: 170, b: 51, a: 0.4 }, { spec: Spec.Rgb, red: 51, green: 170, blue: 51, alpha: 0.4 }], [{ h: 270, s: 60, v: 70 }, { spec: Spec.Hsv, hsvHue: 270, hsvSaturation: 60, hsvValue: 70, alpha: 1 }], [{ h: 270, s: 60, v: 70, a: 0.4 }, { spec: Spec.Hsv, hsvHue: 270, hsvSaturation: 60, hsvValue: 70, alpha: 0.4 }], [{ h: 270, s: 60 }, { spec: Spec.Invalid }], [{ h: 270, s: 60, l: 70 }, { spec: Spec.Hsl, hue: 270, saturation: 60, lightness: 70, alpha: 1 }], [{ h: 270, s: 60, l: 70, a: 0.4 }, { spec: Spec.Hsl, hue: 270, saturation: 60, lightness: 70, alpha: 0.4 }], [{ c: 50, m: 60, y: 70, k: 80 }, { spec: Spec.Cmyk, cyan: 50, magenta: 60, yellow: 70, black: 80, alpha: 1 }], [{ c: 50, m: 60, y: 70, k: 80, a: 0.4 }, { spec: Spec.Cmyk, cyan: 50, magenta: 60, yellow: 70, black: 80, alpha: 0.4 }], [new Color('#33aa3388'), { spec: Spec.Rgb, red: 51, green: 170, blue: 51, alpha: 0.5333333333333333 }], [new Color(), { spec: Spec.Invalid }], ].forEach((data, index) => { const input = data[0] as any; const result = data[1] as any; const spec = data[2] as any; it(`constructor@${input}`, () => { const color = new Color(input, spec); Object.keys(result).forEach((key) => { assert.strictEqual((color)[key], result[key], `color.${key} !== result.${key}: ${(color)[key]} !== ${result[key]}`); }); }); }); }); describe('getters/setters', () => { it('spec', () => { const col = new Color({ r: 64, g: 128, b: 192 }); assert.strictEqual(col.spec, Spec.Rgb); col.spec = Spec.Rgb; assert.strictEqual(col.spec, Spec.Rgb); col.spec = Spec.Hsl; assert.deepEqual(col.getHsl(), { h: 210, s: 50, l: 50 }); }); it('alpha', () => { const col = new Color({ r: 64, g: 128, b: 192, a: 0.5 }); assert.isTrue(fuzzyEqual(col.alpha, .5)); col.alpha = .75; assert.isTrue(fuzzyEqual(col.alpha, .75)); col.alpha = 2; assert.isTrue(fuzzyEqual(col.alpha, .75)); }); it('red', () => { const col = new Color({ r: 64, g: 128, b: 192 }); assert.strictEqual(col.red, 64); col.red = 128; assert.strictEqual(col.red, 128); col.red = 300; assert.strictEqual(col.red, 128); col.setHsl(210, 50, 50); assert.strictEqual(col.red, 64); col.red = 128; assert.strictEqual(col.red, 128); }); it('green', () => { const col = new Color({ r: 64, g: 128, b: 192 }); assert.strictEqual(col.green, 128); col.green = 64; assert.strictEqual(col.green, 64); col.green = 300; assert.strictEqual(col.green, 64); col.setHsl(210, 50, 50); assert.strictEqual(col.green, 128); col.green = 64; assert.strictEqual(col.green, 64); }); it('blue', () => { const col = new Color({ r: 64, g: 128, b: 192 }); assert.strictEqual(col.blue, 192); col.blue = 128; assert.strictEqual(col.blue, 128); col.blue = 300; assert.strictEqual(col.blue, 128); col.setHsl(210, 50, 50); assert.strictEqual(col.blue, 192); col.blue = 128; assert.strictEqual(col.blue, 128); }); it('cmyk', () => { const col = new Color({ r: 64, g: 128, b: 192 }); assert.strictEqual(col.cyan, 67); assert.strictEqual(col.magenta, 33); assert.strictEqual(col.yellow, 0); assert.strictEqual(col.black, 25); }); it('setRgb', () => { const col = new Color({ r: 64, g: 128, b: 192, a: 0.5 }); col.setRgb(64, 128, 192, 2); assert.isTrue(col.equals(new Color({ r: 64, g: 128, b: 192, a: 0.5 }))); }); it('getHsl', () => { const col = new Color('red'); assert.deepEqual(col.getHsl(), { h: 0, s: 100, l: 50 }); }); it('setHsl', () => { const col = new Color({ h: 0, s: 100, l: 50 }); col.setHsl(0, 200, 50); assert.isTrue(col.equals(new Color({ h: 0, s: 100, l: 50 }))); }); it('getHsv', () => { const col = new Color('red'); assert.deepEqual(col.getHsv(), { h: 0, s: 100, v: 100 }); }); it('setHsv', () => { const col = new Color({ h: 0, s: 100, v: 100 }); col.setHsv(0, 200, 50); assert.isTrue(col.equals(new Color({ h: 0, s: 100, v: 100 }))); }); it('getCmyk', () => { const col = new Color('red'); assert.deepEqual(col.getCmyk(), { c: 0, m: 100, y: 100, k: 0 }); }); it('setCmyk', () => { const col = new Color({ c: 0, m: 100, y: 100, k: 0 }); col.setCmyk(0, 200, 100, 0); assert.isTrue(col.equals(new Color({ c: 0, m: 100, y: 100, k: 0 }))); }); }); it('invalidate', () => { const col = new Color({ r: 50, g: 100, b: 200 }); assert.isTrue(col.isValid()); col.invalidate(); assert.isFalse(col.isValid()); }); it('clone', () => { const c1 = new Color({ r: 50, g: 100, b: 200 }); const c2 = c1.clone(); assert.isTrue(c2 instanceof Color); assert.isTrue(c2.equals(c1)); c1.setRgb(51, 101, 201); assert.isTrue(c2.equals(new Color({ r: 50, g: 100, b: 200 }))); }); describe('toString', () => { [ [undefined, '', '', '', '', '', '', '', '', ''], ['red', '#ff0000', '#ff0000ff', '#ff0000', 'rgb(255, 0, 0)', 'rgba(255, 0, 0, 1)', 'rgb(255, 0, 0)', 'red', 'red', 'red'], ['#33aa3388', '#33aa3388', '#33aa3388', '#33aa33', 'rgba(51, 170, 51, 0.53333)', 'rgba(51, 170, 51, 0.53333)', 'rgb(51, 170, 51)', '#33aa3388', '#33aa3388', '#33aa33'], ['#33aa3388', '#33aa3388', '#33aa3388', '#33aa33', 'rgba(51, 170, 51, 0.53)', 'rgba(51, 170, 51, 0.53)', 'rgb(51, 170, 51)', '#33aa3388', '#33aa3388', '#33aa33', 100], ['#00ff7f36', '#00ff7f36', '#00ff7f36', '#00ff7f', 'rgba(0, 255, 127, 0.21176)', 'rgba(0, 255, 127, 0.21176)', 'rgb(0, 255, 127)', '#00ff7f36', '#00ff7f36', 'springgreen'], ['rgba(51 170 51 / 0.4)', '#33aa3366', '#33aa3366', '#33aa33', 'rgba(51, 170, 51, 0.4)', 'rgba(51, 170, 51, 0.4)', 'rgb(51, 170, 51)', '#33aa3366', '#33aa3366', '#33aa33'], ['hsl(240 100% 50%)', '#0000ff', '#0000ffff', '#0000ff', 'hsl(240, 100%, 50%)', 'hsla(240, 100%, 50%, 1)', 'hsl(240, 100%, 50%)', 'blue', 'blue', 'blue'], ['hsv(240 100% 100%)', '#0000ff', '#0000ffff', '#0000ff', 'hsv(240, 100%, 100%)', 'hsva(240, 100%, 100%, 1)', 'hsv(240, 100%, 100%)', 'blue', 'blue', 'blue'], ['cmyk(100% 100% 0% 0%)', '#0000ff', '#0000ffff', '#0000ff', 'cmyk(100%, 100%, 0%, 0%)', 'cmyka(100%, 100%, 0%, 0%, 1)', 'cmyk(100%, 100%, 0%, 0%)', 'blue', 'blue', 'blue'], ['hsl(210 50% 50%)', '#4080c0', '#4080c0ff', '#4080c0', 'hsl(210, 50%, 50%)', 'hsla(210, 50%, 50%, 1)', 'hsl(210, 50%, 50%)', 'hsl(210, 50%, 50%)', 'hsla(210, 50%, 50%, 1)', 'hsl(210, 50%, 50%)'], ].forEach((data, index) => { const input = data[0] as any; const result = data.slice(1, 10) as string[]; const factor = data[10] as number; const color = new Color(input); [Format.HexRgb, Format.Functional, Format.Named].forEach((format, i) => { [Alpha.SkipFullyOpaque, Alpha.Include, Alpha.Exclude].forEach((alpha, j) => { const resultIndex = i * formats.length + j; it(`${input}.toString(${format},${alpha},${factor})`, () => { assert.strictEqual(color.toString(format, alpha, factor), result[resultIndex]); }); }); }); }); }); describe('toArray', () => { [ [undefined, [], [], []], ['#33aa33', [51, 170, 51], [51, 170, 51, 1], [51, 170, 51]], ['#33aa3388', [51, 170, 51, 0.5333333333333333], [51, 170, 51, 0.5333333333333333], [51, 170, 51]], ['hsl(270 60% 70%)', [270, 60, 70], [270, 60, 70, 1], [270, 60, 70]], ['hsla(270 60% 70% / 0.4)', [270, 60, 70, 0.4], [270, 60, 70, 0.4], [270, 60, 70]], ['hsv(270 60% 70%)', [270, 60, 70], [270, 60, 70, 1], [270, 60, 70]], ['hsva(270 60% 70% / 0.4)', [270, 60, 70, 0.4], [270, 60, 70, 0.4], [270, 60, 70]], ['cmyk(50%, 60%, 70%, 80%)', [50, 60, 70, 80], [50, 60, 70, 80, 1], [50, 60, 70, 80]], ['cmyka(50%, 60%, 70%, 80%, 40%)', [50, 60, 70, 80, 0.4], [50, 60, 70, 80, 0.4], [50, 60, 70, 80]], ].forEach((data, index) => { const input = data[0] as any; const result = data.slice(1, 4) as number[][]; const color = new Color(input); [Alpha.SkipFullyOpaque, Alpha.Include, Alpha.Exclude].forEach((alpha, i) => { it(`${input}.toArray(${alpha})`, () => { assert.deepEqual(color.toArray(alpha), result[i]); }); }); }); }); describe('toObject', () => { [ [undefined, {}, {}, {}], ['#33aa33', { r: 51, g: 170, b: 51 }, { r: 51, g: 170, b: 51, a: 1 }, { r: 51, g: 170, b: 51 }], ['#33aa3388', { r: 51, g: 170, b: 51, a: 0.5333333333333333 }, { r: 51, g: 170, b: 51, a: 0.5333333333333333 }, { r: 51, g: 170, b: 51 }], ['hsl(270 60% 70%)', { h: 270, s: 60, l: 70 }, { h: 270, s: 60, l: 70, a: 1 }, { h: 270, s: 60, l: 70 }], ['hsla(270 60% 70% / 0.4)', { h: 270, s: 60, l: 70, a: 0.4 }, { h: 270, s: 60, l: 70, a: 0.4 }, { h: 270, s: 60, l: 70 }], ['hsv(270 60% 70%)', { h: 270, s: 60, v: 70 }, { h: 270, s: 60, v: 70, a: 1 }, { h: 270, s: 60, v: 70 }], ['hsva(270 60% 70% / 0.4)', { h: 270, s: 60, v: 70, a: 0.4 }, { h: 270, s: 60, v: 70, a: 0.4 }, { h: 270, s: 60, v: 70 }], ['cmyk(50%, 60%, 70%, 80%)', { c: 50, m: 60, y: 70, k: 80 }, { c: 50, m: 60, y: 70, k: 80, a: 1 }, { c: 50, m: 60, y: 70, k: 80 }], ['cmyka(50%, 60%, 70%, 80%, 40%)', { c: 50, m: 60, y: 70, k: 80, a: 0.4 }, { c: 50, m: 60, y: 70, k: 80, a: 0.4 }, { c: 50, m: 60, y: 70, k: 80 }], ].forEach((data, index) => { const input = data[0] as any; const result = data.slice(1, 4) as any[]; const color = new Color(input); [Alpha.SkipFullyOpaque, Alpha.Include, Alpha.Exclude].forEach((alpha, i) => { it(`${input}.toObject(${alpha})`, () => { assert.deepEqual(color.toObject(alpha), result[i]); }); }); }); }); describe('toNumber', () => { [ [undefined, 0, 0, rgb(0, 0, 0)], ['red', rgb(255, 0, 0), rgb(255, 0, 0), rgb(255, 0, 0)], ['#33aa3388', rgba(51, 170, 51, 136), rgba(51, 170, 51, 136), rgb(51, 170, 51)], ].forEach((data, index) => { const input = data[0] as any; const result = data.slice(1, 4) as number[]; const color = new Color(input); [Alpha.SkipFullyOpaque, Alpha.Include, Alpha.Exclude].forEach((alpha, i) => { it(`${input}.toNumber(${alpha})`, () => { assert.strictEqual(color.toNumber(alpha), result[i]); }); }); }); }); describe('toRgb', () => { [ ['black', { r: 0, g: 0, b: 0 }, { h: -1, s: 0, v: 0 }, { c: 0, m: 0, y: 0, k: 100 }, { h: -1, s: 0, l: 0 }], ['white', { r: 255, g: 255, b: 255 }, { h: -1, s: 0, v: 100 }, { c: 0, m: 0, y: 0, k: 0 }, { h: -1, s: 0, l: 100 }], ['red', { r: 255, g: 0, b: 0 }, { h: 0, s: 100, v: 100 }, { c: 0, m: 100, y: 100, k: 0 }, { h: 0, s: 100, l: 50 }], ['green', { r: 0, g: 255, b: 0 }, { h: 120, s: 100, v: 100 }, { c: 100, m: 0, y: 100, k: 0 }, { h: 120, s: 100, l: 50 }], ['blue', { r: 0, g: 0, b: 255 }, { h: 240, s: 100, v: 100 }, { c: 100, m: 100, y: 0, k: 0 }, { h: 240, s: 100, l: 50 }], ['cyan', { r: 0, g: 255, b: 255 }, { h: 180, s: 100, v: 100 }, { c: 100, m: 0, y: 0, k: 0 }, { h: 180, s: 100, l: 50 }], ['magenta', { r: 255, g: 0, b: 255 }, { h: 300, s: 100, v: 100 }, { c: 0, m: 100, y: 0, k: 0 }, { h: 300, s: 100, l: 50 }], ['yellow', { r: 255, g: 255, b: 0 }, { h: 60, s: 100, v: 100 }, { c: 0, m: 0, y: 100, k: 0 }, { h: 60, s: 100, l: 50 }], ['gray', { r: 164, g: 164, b: 164 }, { h: -1, s: 100, v: 64.31375 }, { c: 0, m: 0, y: 0, k: 35.6863 }, { h: -1, s: 0, l: 64.31375 }], ].forEach((data) => { const name = data[0] as string; const expectedColor = new Color(data[1] as any); const hsvColor = new Color(data[2] as any); const cmykColor = new Color(data[3] as any); const hslColor = new Color(data[4] as any); it(`toRgb@${name}`, () => { assert.deepEqual(hsvColor.toRgb().getRgb(), expectedColor.getRgb()); assert.deepEqual(cmykColor.toRgb().getRgb(), expectedColor.getRgb()); assert.deepEqual(hslColor.toRgb().getRgb(), expectedColor.getRgb()); }); }); }); describe('toHsv', () => { [ ['data0', { h: 300, s: 100, v: 100 }, { r: 255, g: 0, b: 255 }, { c: 0, m: 100, y: 0, k: 0 }, { h: 300, s: 100, l: 50 }], ['data1', { h: 360, s: 100, v: 100 }, { r: 255, g: 0, b: 0 }, { c: 0, m: 100, y: 100, k: 0 }, { h: 360, s: 100, l: 50 }], ].forEach((data) => { const name = data[0] as string; const expectedColor = new Color(data[1] as any); const rgbColor = new Color(data[2] as any); const cmykColor = new Color(data[3] as any); const hslColor = new Color(data[4] as any); it(`toHsv@${name}`, () => { assert.deepEqual(rgbColor.toHsv().getHsv(), expectedColor.getHsv()); assert.deepEqual(cmykColor.toHsv().getHsv(), expectedColor.getHsv()); assert.deepEqual(hslColor.toHsv().getHsv(), expectedColor.getHsv()); }); }); }); describe('toCmyk', () => { [ ['data0', { c: 100, m: 0, y: 0, k: 0 }, { r: 0, g: 255, b: 255 }, { h: 180, s: 100, v: 100 }, { h: 180, s: 100, l: 50 }], ['data1', { c: 100, m: 100, y: 100, k: 100 }, { r: 0, g: 0, b: 0 }, { h: -1, s: 0, v: 0 }, { h: -1, s: 0, l: 0 }], ].forEach((data) => { const name = data[0] as string; const expectedColor = new Color(data[1] as any); const rgbColor = new Color(data[2] as any); const hsvColor = new Color(data[3] as any); const hslColor = new Color(data[4] as any); it(`toCmyk@${name}`, () => { assert.deepEqual(rgbColor.toCmyk().getCmyk(), expectedColor.getCmyk()); assert.deepEqual(hsvColor.toCmyk().getCmyk(), expectedColor.getCmyk()); assert.deepEqual(hslColor.toCmyk().getCmyk(), expectedColor.getCmyk()); }); }); }); describe('toHsl', () => { [ ['data0', { h: 300, s: 100, l: 50 }, { h: 300, s: 100, v: 100 }, { r: 255, g: 0, b: 255 }, { c: 0, m: 100, y: 0, k: 0 }], ['data1', { h: 360, s: 100, l: 50 }, { h: 360, s: 100, v: 100 }, { r: 255, g: 0, b: 0 }, { c: 0, m: 100, y: 100, k: 0 }], ].forEach((data) => { const name = data[0] as string; const expectedColor = new Color(data[1] as any); const rgbColor = new Color(data[2] as any); const cmykColor = new Color(data[3] as any); const hsvColor = new Color(data[4] as any); it(`toHsl@${name}`, () => { assert.deepEqual(rgbColor.toHsl().getHsl(), expectedColor.getHsl()); assert.deepEqual(cmykColor.toHsl().getHsl(), expectedColor.getHsl()); assert.deepEqual(hsvColor.toHsl().getHsl(), expectedColor.getHsl()); }); }); }); it('convertTo', () => { const color = new Color('black'); [ Spec.Rgb, Spec.Hsv, Spec.Cmyk, Spec.Hsl, Spec.Invalid, ].forEach((spec) => { assert.strictEqual(color.convertTo(spec).spec, spec); }); }); describe('lighter', () => { it('lighter@simple', () => { const gray = new Color(colors.gray); const lighter = gray.lighter(); assert.isTrue(lighter.value > gray.value); }); it('lighter@invalid', () => { const gray = new Color(colors.gray); const lighter = gray.lighter(-100); assert.isTrue(lighter.value === gray.value); }); it('lighter@darker', () => { const gray = new Color(colors.gray); const lighter = gray.lighter(50); assert.isTrue(lighter.value < gray.value); }); }); describe('darker', () => { it('darker@simple', () => { const gray = new Color(colors.gray); const darker = gray.darker(); assert.isTrue(darker.value < gray.value); }); it('darker@invalid', () => { const gray = new Color(colors.gray); const darker = gray.darker(-100); assert.isTrue(darker.value === gray.value); }); it('darker@simple', () => { const gray = new Color(colors.gray); const darker = gray.darker(50); assert.isTrue(darker.value > gray.value); }); }); describe('equals', () => { [ [undefined, undefined, true], ['red', undefined, false], ['red', 'red', true], ['red', 'blue', false], ['rgb(255,0,0)', 'rgba(255,0,0,0.5)', false], ['rgb(255,0,0,0.5)', 'rgba(255,0,0,0.5)', true], ['hsv(300,100,100)', 'rgb(255,0,255)', true], ].forEach((data, index) => { const lhs = new Color(data[0] as string); const rhs = new Color(data[1] as string); const result = data[2] as boolean; it(`equals@${lhs},${rhs}`, () => { assert.strictEqual(lhs.equals(rhs), result); assert.strictEqual(rhs.equals(lhs), result); assert.strictEqual(Color.equal(lhs, rhs), result); }); }); }); describe('compare', () => { [ [undefined, undefined, 0], ['red', undefined, 255], ['red', 'red', 0], ['red', 'blue', 255], ['blue', 'red', -255], ['rgb(255,0,0)', 'rgba(255,0,0,0.5)', 0.5], ['rgb(255,0,0,0.5)', 'rgba(255,0,0,0.5)', 0], ['hsv(300,100,100)', 'rgb(255,0,255)', 0], ].forEach((data, index) => { const lhs = new Color(data[0] as string); const rhs = new Color(data[1] as string); const result = data[2] as number; it(`compare@${lhs},${rhs}`, () => { assert.isTrue(fuzzyEqual(Color.compare(lhs, rhs), result)); }); }); }); describe('random', () => { for (let i = 0; i < 10; i++) { const color = Color.random(); it(`random@${color}`, () => { assert.isTrue(color.isValid()); assert.isTrue(color.red >= 0 && color.red <= 255); assert.isTrue(color.green >= 0 && color.green <= 255); assert.isTrue(color.blue >= 0 && color.blue <= 255); assert.isTrue(color.alpha >= 0 && color.alpha <= 1); }); } }); describe('blend', () => { [ ['red', 'blue', 'rgb(181,0,181)'], ['rgba(0,255,0,0.5)', 'rgba(255,0,255,0.5)', 'rgba(181,181,181,0.50001)'], ].forEach((data, index) => { it(`blend@${index}`, () => { const lhs = new Color(data[0] as any); const rhs = new Color(data[1] as any); const result = new Color(data[2] as any); assert.isTrue(Color.blend(lhs, rhs).equals(result)); }); }); }); describe('interpolate', () => { [ ['#cd5c5c88', '#cd5c5c', [0, 0.2, 0.4, 0.6, 0.8, 1], ['#cd5c5c88', '#cd5c5c9f', '#cd5c5cb7', '#cd5c5ccf', '#cd5c5ce7', '#cd5c5cff']], ].forEach((data, index) => { const from = new Color(data[0] as string); const to = new Color(data[1] as string); const steps = data[2] as number[]; const results = data[3] as string[]; steps.forEach((progress, index) => { it(`interpolate@${from},${to},${progress}`, () => { assert.strictEqual(Color.interpolate(from, to, progress).toString(Format.HexRgb, Alpha.Include), results[index]); }) }); }); }); describe('gray', () => { [ [colors.lightgray, 211], [colors.gray, 128], [colors.yellow, 215] ].forEach((data, index) => { const col = new Color(data[0] as number); const result = data[1] as number; it(`gray@${col.toString()}`, () => { assert.strictEqual(gray(col.red, col.green, col.blue), result); }); }); }); describe('isGray', () => { [ [colors.lightgray, true], [colors.gray, true], [colors.yellow, false] ].forEach((data, index) => { const col = data[0] as number; const result = data[1] as boolean; it(`isGray@${col}`, () => { assert.strictEqual(isGray(col), result); }); }); }); });