diff --git a/src/conversion.ts b/src/conversion.ts index a1db0a0..f05c2f8 100644 --- a/src/conversion.ts +++ b/src/conversion.ts @@ -10,7 +10,7 @@ import { RGB, HSL, HSV, Numberify } from './interfaces'; * *Assumes:* r, g, b in [0, 255] or [0, 1] * *Returns:* { r, g, b } in [0, 255] */ -export function rgbToRgb(r: number, g: number, b: number): Numberify { +export function rgbToRgb(r: number | string, g: number | string, b: number | string): Numberify { return { r: bound01(r, 255) * 255, g: bound01(g, 255) * 255, @@ -90,10 +90,10 @@ function hue2rgb(p: number, q: number, t: number): number { * *Assumes:* h is contained in [0, 1] or [0, 360] and s and l are contained [0, 1] or [0, 100] * *Returns:* { r, g, b } in the set [0, 255] */ -export function hslToRgb(h: number, s: number, l: number): Numberify { - let r; - let g; - let b; +export function hslToRgb(h: number | string, s: number | string, l: number | string): Numberify { + let r: number; + let g: number; + let b: number; h = bound01(h, 360); s = bound01(s, 100); @@ -162,7 +162,7 @@ export function rgbToHsv(r: number, g: number, b: number): Numberify { * *Assumes:* h is contained in [0, 1] or [0, 360] and s and v are contained in [0, 1] or [0, 100] * *Returns:* { r, g, b } in the set [0, 255] */ -export function hsvToRgb(h: number, s: number, v: number): Numberify { +export function hsvToRgb(h: number | string, s: number | string, v: number | string): Numberify { h = bound01(h, 360) * 6; s = bound01(s, 100); v = bound01(v, 100); diff --git a/src/util.ts b/src/util.ts index 797ed84..78aa2a7 100644 --- a/src/util.ts +++ b/src/util.ts @@ -7,11 +7,11 @@ export function bound01(n: any, max: number): number { n = '100%'; } - const processPercent = isPercentage(n); + const isPercent = isPercentage(n); n = max === 360 ? n : Math.min(max, Math.max(0, parseFloat(n))); // Automatically convert percentage into number - if (processPercent) { + if (isPercent) { n = parseInt(String(n * max), 10) / 100; } @@ -32,7 +32,7 @@ export function bound01(n: any, max: number): number { n = (n % max) / parseFloat(String(max)); } - return n as number; + return n; } /** diff --git a/test/conversions.spec.ts b/test/conversions.spec.ts new file mode 100644 index 0000000..ad5c424 --- /dev/null +++ b/test/conversions.spec.ts @@ -0,0 +1,113 @@ +import { describe, it, expect } from '@jest/globals'; + +import { TinyColor } from '../src/public_api'; +import conversions from './conversions'; + +describe('TinyColor Conversions', () => { + it('should have color equality', () => { + expect(conversions.length).toBe(16); + for (const c of conversions) { + const tiny = new TinyColor(c.hex); + expect(tiny.isValid).toBe(true); + expect(new TinyColor(c.rgb).equals(c.hex)).toBe(true); + expect(new TinyColor(c.rgb).equals(c.hex8)).toBe(true); + expect(new TinyColor(c.rgb).equals(c.hsl)).toBe(true); + expect(new TinyColor(c.rgb).equals(c.hsv)).toBe(true); + expect(new TinyColor(c.rgb).equals(c.rgb)).toBe(true); + expect(new TinyColor(c.hex).equals(c.hex)).toBe(true); + expect(new TinyColor(c.hex).equals(c.hex8)).toBe(true); + expect(new TinyColor(c.hex).equals(c.hsl)).toBe(true); + expect(new TinyColor(c.hex).equals(c.hsv)).toBe(true); + expect(new TinyColor(c.hsl).equals(c.hsv)).toBe(true); + } + }); + it('HSL Object', () => { + for (const c of conversions) { + const tiny = new TinyColor(c.hex); + expect(tiny.toHexString()).toBe(new TinyColor(tiny.toHsl()).toHexString()); + } + }); + it('HSL String', () => { + for (const c of conversions) { + const tiny = new TinyColor(c.hex); + const input = tiny.toRgb(); + const output = new TinyColor(tiny.toHslString()).toRgb(); + const maxDiff = 2; + + // toHslString red value difference <= ' + maxDiff + expect(Math.abs(input.r - output.r) <= maxDiff).toBe(true); + // toHslString green value difference <= ' + maxDiff + expect(Math.abs(input.g - output.g) <= maxDiff).toBe(true); + // toHslString blue value difference <= ' + maxDiff + expect(Math.abs(input.b - output.b) <= maxDiff).toBe(true); + } + }); + it('HSV String', () => { + for (const c of conversions) { + const tiny = new TinyColor(c.hex); + const input = tiny.toRgb(); + const output = new TinyColor(tiny.toHsvString()).toRgb(); + const maxDiff = 2; + + // toHsvString red value difference <= ' + maxDiff + expect(Math.abs(input.r - output.r) <= maxDiff).toBe(true); + // toHsvString green value difference <= ' + maxDiff + expect(Math.abs(input.g - output.g) <= maxDiff).toBe(true); + // toHsvString blue value difference <= ' + maxDiff + expect(Math.abs(input.b - output.b) <= maxDiff).toBe(true); + } + }); + + it('HSV Object', () => { + for (const c of conversions) { + const tiny = new TinyColor(c.hsv); + expect(tiny.toHexString()).toBe(new TinyColor(tiny.toHsv()).toHexString()); + } + }); + + it('RGB Object', () => { + for (const c of conversions) { + const tiny = new TinyColor(c.hex); + expect(tiny.toHexString()).toBe(new TinyColor(tiny.toRgb()).toHexString()); + } + }); + + it('RGB String', () => { + for (const c of conversions) { + const tiny = new TinyColor(c.hex); + expect(tiny.toHexString()).toBe(new TinyColor(tiny.toRgbString()).toHexString()); + } + }); + + it('PRGB Object', () => { + for (const c of conversions) { + const tiny = new TinyColor(c.hex); + const input = tiny.toRgb(); + const output = new TinyColor(tiny.toPercentageRgb()).toRgb(); + const maxDiff = 2; + + expect(Math.abs(input.r - output.r)).toBeLessThanOrEqual(maxDiff); + expect(Math.abs(input.g - output.g)).toBeLessThanOrEqual(maxDiff); + expect(Math.abs(input.b - output.b)).toBeLessThanOrEqual(maxDiff); + } + }); + + it('PRGB String', () => { + for (const c of conversions) { + const tiny = new TinyColor(c.hex); + const input = tiny.toRgb(); + const output = new TinyColor(tiny.toPercentageRgbString()).toRgb(); + const maxDiff = 2; + + expect(Math.abs(input.r - output.r)).toBeLessThanOrEqual(maxDiff); + expect(Math.abs(input.g - output.g)).toBeLessThanOrEqual(maxDiff); + expect(Math.abs(input.b - output.b)).toBeLessThanOrEqual(maxDiff); + } + }); + it('Object', () => { + for (const c of conversions) { + const tiny = new TinyColor(c.hex); + expect(tiny.toHexString()).toBe(new TinyColor(tiny).toHexString()); + } + }); +});