UNPKG

csx

Version:

Utility functions for TypeStyle

781 lines (682 loc) 26.3 kB
import * as assert from 'assert'; import { color, hsl, hsla, rgb, rgba } from '../src/color'; const cyan = rgb(0, 255, 255); const blue = rgb(0, 0, 255); const green = rgb(0, 128, 0); const maroon = rgb(128, 0, 0); const black = rgb(0, 0, 0); const white = rgb(255, 255, 255); const red = rgb(255, 0, 0); const transparent = rgba(0, 0, 0, 0); const purple = rgb(128, 0, 128); describe('color', () => { describe('toString()', () => { it('handles named colors', () => { const c1 = red.toString(); assert.equal(c1, 'rgb(255, 0, 0)'); }); it('handles transparency', () => { const c1 = transparent.toString(); assert.equal(c1, 'rgba(0, 0, 0, 0)'); }); it('truncates alpha channel values to the 5th decimal', () => { const c1 = rgba(255, 242, 216, 0.49); assert.equal(c1.toString(), 'rgba(255, 242, 216, 0.49)'); }); it('truncates alpha channel repeating values to the 5th decimal', () => { const c1 = rgba(255, 242, 216, 1 / 3); assert.equal(c1.toString(), 'rgba(255, 242, 216, 0.33333)'); }); }); describe('rgb()', () => { it('handles rgb with numbers', () => { const color = rgb(255, 0, 0).toString(); assert.equal(color, 'rgb(255, 0, 0)'); }); it('rounds channels to the nearest integer', () => { const color = rgb(100.5, 100.3, -1).toString(); assert.equal(color, 'rgb(101, 100, 0)'); }); it('uses the alpha channel if specified.', () => { const color = rgb(255, 0, 0, 0.5).toString(); assert.equal(color, 'rgba(255, 0, 0, 0.5)'); }); }); describe('rgba()', () => { it('handles rgba with numbers', () => { const color = rgba(255, 0, 0, 1).toString(); assert.equal(color, 'rgba(255, 0, 0, 1)'); }); it('handles rgba with percent string', () => { const color = rgba(255, 0, 0, '80%').toString(); assert.equal(color, 'rgba(255, 0, 0, 0.8)'); }); it('rounds channels to the nearest integer', () => { const color = rgba(100.5, 100.3, -1, 0.5).toString(); assert.equal(color, 'rgba(101, 100, 0, 0.5)'); }); }); describe('hsl()', () => { it('handles negative hues', () => { const color1 = hsl(-180, 1, 0.5).toString(); const color2 = hsl(180, 1, 0.5).toString(); assert.equal(color1, color2); }); it('handles out of range hues', () => { const color1 = hsl(90, 1, 0.5).toString(); const color2 = hsl(360 + 90, 1, 0.5).toString(); const color3 = hsl(-360 - 270, 1, 0.5).toString(); assert.equal(color1, color2); assert.equal(color1, color3); }); it('handles hsl with percent strings', () => { const color = hsl(0, '100%', '50%').toString(); assert.equal(color, 'hsl(0, 100%, 50%)'); }); it('handles hsl with percent numbers', () => { const color = hsl(0, 1, 0.5).toString(); assert.equal(color, 'hsl(0, 100%, 50%)'); }); it('rounds hue to the nearest integer', () => { const color = hsl(100.5, 0.5, 0.5).toString(); assert.equal(color, 'hsl(101, 50%, 50%)'); }); it('uses the alpha channel if specified.', () => { const color = hsl(100.5, 0.5, 0.5, 0.5).toString(); assert.equal(color, 'hsla(101, 50%, 50%, 0.5)'); }); }); describe('hsla()', () => { it('handles hsla with percent numbers', () => { const color = hsla(0, 1, 0.5, 0.1).toString(); assert.equal(color, 'hsla(0, 100%, 50%, 0.1)'); }); it('handles hsla with percent strings', () => { const color = hsla(0, '100%', '50%', 0.1).toString(); assert.equal(color, 'hsla(0, 100%, 50%, 0.1)'); }); it('rounds hue to the nearest integer', () => { const color = hsla(100.5, 0.5, 0.5, 0).toString(); assert.equal(color, 'hsla(101, 50%, 50%, 0)'); }); }); it('converts from a named color to rgb', () => { const color1 = red.toString(); const color2 = rgb(255, 0, 0).toString(); assert.equal(color1, color2); }); describe('color()', () => { it('converts from a hex color (3 digit) to rgb', () => { const color1 = color('#FF0000').toString(); const color2 = rgb(255, 0, 0).toString(); assert.equal(color1, color2); }); it('converts from a hex color (6 digit) to rgb', () => { const color1 = color('#F00').toString(); const color2 = rgb(255, 0, 0).toString(); assert.equal(color1, color2); }); it('converts from a rgb color', () => { const color1 = color('rgb(255,0,0)').toString(); const color2 = rgb(255, 0, 0).toString(); assert.equal(color1, color2); }); it('converts from a rgba color', () => { const color1 = color('rgba(0,0,255,.1)').toString(); const color2 = rgba(0, 0, 255, 0.1).toString(); assert.equal(color1, color2); }); it('converts from a hsl color', () => { const color1 = color('hsl(345,100%,5%)').toString(); const color2 = hsl(345, 1, 0.05).toString(); assert.equal(color1, color2); }); it('converts from a hsla color', () => { const color1 = color('hsla(10, 10%, 60%, .85)').toString(); const color2 = hsla(10, 0.1, 0.6, 0.85).toString(); assert.equal(color1, color2); }); }); describe('toHexString()', () => { it('converts white to #FFFFFF', () => { const color = white.toHexString(); assert.equal(color, '#FFFFFF'); }); it('converts black to #000000', () => { const color = black.toHexString(); assert.equal(color, '#000000'); }); it('converts red to #FF0000', () => { const color = red.toHexString(); assert.equal(color, '#FF0000'); }); it('converts green to #008000', () => { const color = green.toHexString(); assert.equal(color, '#008000'); }); it('converts blue to #0000FF', () => { const color = blue.toHexString(); assert.equal(color, '#0000FF'); }); it('converts rgb(0, 127.5, 0) to #009900', () => { const color = rgb(0, 127.5, 0).toHexString(); assert.equal(color, '#008000'); }); it('converts to a # and a six digit hex code', () => { const c = color('#16A085') .darken('10%') .toHexString(); assert.equal(c.length, 7); }); }); describe('toHSL()', () => { it('converts from a named color to hsl', () => { const color1 = red.toHSL().toString(); const color2 = hsl(0, 1, 0.5).toString(); assert.equal(color1, color2); }); it('converts from rgb to hsl', () => { const color1 = rgb(255, 0, 0) .toHSL() .toString(); const color2 = hsl(0, 1, 0.5).toString(); assert.equal(color1, color2); }); }); describe('toHSLA()', () => { it('converts from a named color to hsla', () => { const color1 = red.toHSLA().toString(); const color2 = hsla(0, 1, 0.5, 1).toString(); assert.equal(color1, color2); }); it('converts from rgb to hsla', () => { const color1 = rgb(255, 0, 0) .toHSLA() .toString(); const color2 = hsla(0, 1, 0.5, 1).toString(); assert.equal(color1, color2); }); it('converts from rgba to hsla', () => { const color1 = rgba(255, 0, 0, 0.5) .toHSLA() .toString(); const color2 = hsla(0, 1, 0.5, 0.5).toString(); assert.equal(color1, color2); }); }); describe('toRGB()', () => { it('converts from a named color to rgba', () => { const color1 = red.toRGBA().toString(); const color2 = rgba(255, 0, 0, 1).toString(); assert.equal(color1, color2); }); it('converts from hsl to rgb', () => { const color1 = hsl(0, 1, 0.5) .toRGB() .toString(); const color2 = rgb(255, 0, 0).toString(); assert.equal(color1, color2); }); it('converts from hsla to rgb', () => { const color1 = hsla(0, 1, 0.5, 0.5) .toRGB() .toString(); const color2 = rgb(255, 0, 0).toString(); assert.equal(color1, color2); }); }); describe('toRGBA()', () => { it('converts from hsla to rgba', () => { const color1 = hsla(0, 1, 0.5, 0.5) .toRGBA() .toString(); const color2 = rgba(255, 0, 0, 0.5).toString(); assert.equal(color1, color2); }); }); describe('red()', () => { it('returns the red channel from rgb', () => { const color1 = rgb(255, 0, 0); assert.equal(255, color1.red()); }); it('returns the red channel from rgba', () => { const color1 = rgba(255, 0, 0, 0.5); assert.equal(255, color1.red()); }); }); describe('green()', () => { it('returns the green channel from rgb', () => { const color1 = rgb(0, 255, 0); assert.equal(255, color1.green()); }); it('returns the green channel from rgba', () => { const color1 = rgba(0, 255, 0, 0.5); assert.equal(255, color1.green()); }); }); describe('blue()', () => { it('returns the blue channel from rgb', () => { const color1 = rgb(0, 0, 255); assert.equal(255, color1.blue()); }); it('returns the blue channel from rgba', () => { const color1 = rgba(0, 0, 255, 0.5); assert.equal(255, color1.blue()); }); }); describe('opacity()', () => { it('returns the alpha channel from rgb', () => { const color1 = rgb(0, 0, 0); assert.equal(1, color1.alpha()); assert.equal(1, color1.opacity()); }); it('returns the alpha channel from rgba', () => { const color1 = rgba(0, 0, 0, 0.5); assert.equal(0.5, color1.alpha()); assert.equal(0.5, color1.opacity()); }); }); describe('invert()', () => { it('inverts rgb', () => { const color1 = rgb(255, 0, 0) .invert() .toString(); const color2 = cyan.toString(); assert.equal(color1, color2); }); it('inverts rgba', () => { const color1 = rgba(255, 0, 0, 0.5) .invert() .toString(); const color2 = cyan.fade(0.5).toString(); assert.equal(color1, color2); }); it('inverts hsl', () => { const color1 = hsl(0, 1, 0.5) .invert() .toString(); const color2 = cyan.toHSL().toString(); assert.equal(color1, color2); }); it('inverts hsla', () => { const color1 = hsla(0, 1, 0.5, 1) .invert() .toString(); const color2 = cyan.toHSLA().toString(); assert.equal(color1, color2); }); }); describe('lighten()', () => { it('lightens black to white', () => { const color1 = black.lighten(1).toString(); const color2 = white.toString(); assert.equal(color1, color2); }); it('lightens black to gray', () => { const color1 = black.lighten(0.5).toString(); const color2 = rgb(128, 128, 128).toString(); assert.equal(color1, color2); }); it('lightens from the absolute max', () => { const color1 = hsl(25, 1, 0.2) .lighten(0.3) .toString(); const color2 = hsl(25, 1, 0.5).toString(); assert.equal(color1, color2); }); it('lightens from the current color', () => { const color1 = hsl(25, 1, 0.2).lighten(0.3, true); const color2 = hsl(25, 1, 0.44); assert.equal(color1.lightness(), color2.lightness()); }); }); describe('darken()', () => { it('changes white to black', () => { const color1 = white.darken(1).toString(); const color2 = black.toString(); assert.equal(color1, color2); }); it('changes black to gray', () => { const color1 = white .darken(0.5) .toHSL() .toString(); const color2 = hsl(0, 0, 0.5).toString(); assert.equal(color1, color2); }); it('keeps the color format it started with', () => { const color1 = rgb(255, 0, 0) .darken(0.5) .toString(); const color2 = rgb(0, 0, 0).toString(); assert.equal(color1, color2); }); it('keeps its alpha channel', () => { const color1 = rgba(69, 86, 100, '70%').darken(0.3); assert.equal(color1.opacity() - 0.7 < 0.0001, true); }); it('darkens from the absolute max', () => { const color1 = hsl(25, 1, 0.8) .darken(0.3) .toString(); const color2 = hsl(25, 1, 0.5).toString(); assert.equal(color1, color2); }); it('darkens from the current color', () => { const color1 = hsl(25, 1, 0.8) .darken(0.3, true) .toString(); const color2 = hsl(25, 1, 0.56).toString(); assert.equal(color1, color2); }); }); describe('saturate()', () => { it('changes white to midred', () => { const color1 = hsl(0, 0, 1) .saturate(0.5) .toString(); const color2 = hsl(0, 0.5, 1).toString(); assert.equal(color1, color2); }); it('changes white to red', () => { const color1 = hsl(0, 0, 1) .saturate(1) .toString(); const color2 = hsl(0, 1, 1).toString(); assert.equal(color1, color2); }); it('saturates from the absolute max', () => { const color1 = hsl(25, 0.2, 0.5) .saturate(0.3) .toString(); const color2 = hsl(25, 0.5, 0.5).toString(); assert.equal(color1, color2); }); it('saturates from the current color', () => { const color1 = hsl(25, 0.2, 0.5) .saturate(0.3, true) .toString(); const color2 = hsl(25, 0.44, 0.5).toString(); assert.equal(color1, color2); }); }); describe('desaturate()', () => { it('changes red to midred', () => { const color1 = hsl(0, 1, 1) .desaturate(0.5) .toString(); const color2 = hsl(0, 0.5, 1).toString(); assert.equal(color1, color2); }); it('changes red to white', () => { const color1 = red.desaturate(1).toString(); const color2 = rgb(128, 128, 128).toString(); assert.equal(color1, color2); }); it('desaturates from the absolute max', () => { const color1 = hsl(25, 0.8, 0.5) .desaturate(0.3) .toString(); const color2 = hsl(25, 0.5, 0.5).toString(); assert.equal(color1, color2); }); it('desaturates from the current color', () => { const color1 = hsl(25, 0.8, 0.5) .desaturate(0.3, true) .toString(); const color2 = hsl(25, 0.56, 0.5).toString(); assert.equal(color1, color2); }); }); describe('grayscale()', () => { it('handles red', () => { const color1 = red.grayscale().toHSL(); assert.equal(color1.hue(), 0); assert.equal(color1.saturation(), 0); assert.equal(Math.round(color1.lightness() * 100), 50); }); it('handles green', () => { const color1 = green.grayscale().toHSL(); assert.equal(color1.hue(), 0); assert.equal(color1.saturation(), 0); assert.equal(Math.round(color1.lightness() * 100), 25); }); it('handles blue', () => { const color1 = blue.grayscale().toHSL(); assert.equal(color1.hue(), 0); assert.equal(color1.saturation(), 0); assert.equal(Math.round(color1.lightness() * 100), 50); }); it('handles white', () => { const color1 = white.grayscale().toString(); const color2 = white.toString(); assert.equal(color1, color2); }); it('handles black', () => { const color1 = black.grayscale().toString(); const color2 = rgb(0, 0, 0).toString(); assert.equal(color1, color2); }); }); describe('fade()', () => { it('changes rgb to rgba', () => { const color1 = rgb(255, 255, 255) .fade(1) .toString(); const color2 = rgba(255, 255, 255, 1).toString(); assert.equal(color1, color2); }); it('changes hsl to hsla', () => { const color1 = hsl(0, 0, 1) .fade(1) .toString(); const color2 = hsla(0, 0, 1, 1).toString(); assert.equal(color1, color2); }); it('clamps < 0 at 0% opacity', () => { const color1 = rgba(255, 0, 0, 0) .fade(-0.5) .toString(); const color2 = rgba(255, 0, 0, 0).toString(); assert.equal(color1, color2); }); it('sets 0 to 0% opacity', () => { const color1 = rgba(255, 0, 0, 0) .fade(0) .toString(); const color2 = rgba(255, 0, 0, 0).toString(); assert.equal(color1, color2); }); it('sets .5 to 50% opacity', () => { const color1 = rgba(255, 0, 0, 0) .fade(0.5) .toString(); const color2 = rgba(255, 0, 0, 0.5).toString(); assert.equal(color1, color2); }); it('sets 1 to 100% opacity', () => { const color1 = rgba(255, 0, 0, 0) .fade(1) .toString(); const color2 = rgba(255, 0, 0, 1).toString(); assert.equal(color1, color2); }); it('clamps > 1 to 100% opacity', () => { const color1 = rgba(255, 0, 0, 0) .fade(1.5) .toString(); const color2 = rgba(255, 0, 0, 1).toString(); assert.equal(color1, color2); }); }); describe('fadeOut', () => { it('clamps at 0%', () => { const color1 = rgba(255, 0, 0, 0) .fadeOut(0.25) .toString(); const color2 = rgba(255, 0, 0, 0).toString(); assert.equal(color1, color2); }); it('.75 = 1 - .25', () => { const color1 = rgba(255, 0, 0, 1) .fadeOut(0.25) .toString(); const color2 = rgba(255, 0, 0, 0.75).toString(); assert.equal(color1, color2); }); it('.5 = .75 - .25', () => { const color1 = rgba(255, 0, 0, 0.75) .fadeOut(0.25) .toString(); const color2 = rgba(255, 0, 0, 0.5).toString(); assert.equal(color1, color2); }); it('.25 = .5 - .25', () => { const color1 = rgba(255, 0, 0, 0.5) .fadeOut(0.25) .toString(); const color2 = rgba(255, 0, 0, 0.25).toString(); assert.equal(color1, color2); }); it('0 = .25 - .25', () => { const color1 = rgba(255, 0, 0, 0.25) .fadeOut(0.25) .toString(); const color2 = rgba(255, 0, 0, 0).toString(); assert.equal(color1, color2); }); it('fades out from the absolute max', () => { const color1 = rgba(255, 0, 0, 0.8) .fadeOut(0.3) .toString(); const color2 = rgba(255, 0, 0, 0.5).toString(); assert.equal(color1, color2); }); it('fades out from the current opacity', () => { const color1 = rgba(255, 0, 0, 0.8) .fadeOut(0.3, true) .toString(); const color2 = rgba(255, 0, 0, 0.56).toString(); assert.equal(color1, color2); }); }); describe('fadeIn', () => { it('.25 = 0 - .25', () => { const color1 = rgba(255, 0, 0, 0) .fadeIn(0.25) .toString(); const color2 = rgba(255, 0, 0, 0.25).toString(); assert.equal(color1, color2); }); it('.5 = .25 - .25', () => { const color1 = rgba(255, 0, 0, 0.25) .fadeIn(0.25) .toString(); const color2 = rgba(255, 0, 0, 0.5).toString(); assert.equal(color1, color2); }); it('.75 = .5 - .25', () => { const color1 = rgba(255, 0, 0, 0.5) .fadeIn(0.25) .toString(); const color2 = rgba(255, 0, 0, 0.75).toString(); assert.equal(color1, color2); }); it('1 = .75 - .25', () => { const color1 = rgba(255, 0, 0, 0.75) .fadeIn(0.25) .toString(); const color2 = rgba(255, 0, 0, 1).toString(); assert.equal(color1, color2); }); it('clamps at 100%', () => { const color1 = rgba(255, 0, 0, 1) .fadeIn(0.25) .toString(); const color2 = rgba(255, 0, 0, 1).toString(); assert.equal(color1, color2); }); it('fades in from the absolute max', () => { const color1 = rgba(255, 0, 0, 0.2) .fadeIn(0.3) .toString(); const color2 = rgba(255, 0, 0, 0.5).toString(); assert.equal(color1, color2); }); it('fades in from the current opacity', () => { const color1 = rgba(255, 0, 0, 0.2).fadeIn(0.3, true); const color2 = rgba(255, 0, 0, 0.44); assert.equal(color1.lightness(), color2.lightness()); }); }); describe('mix()', () => { // $c0: mix(red, green); // $c1: mix(red, blue); // $c2: mix(red, white); // $c3: mix(red, transparent); // $c4: mix(red, black); it('red + green', () => { // sass converts rgb to hex, so the actual result should be // rgb(127.5, 64, 0) if the numbers were preserved const color1 = red.mix(green).toString(); const color2 = rgb(128, 64, 0).toString(); assert.equal(color1, color2); }); it('red + blue', () => { const color1 = red.mix(blue).toString(); const color2 = purple.toString(); assert.equal(color1, color2); }); it('red + white', () => { const color1 = red.mix(white).toString(); const color2 = rgb(255, 128, 128).toString(); assert.equal(color1, color2); }); it('red + transparent', () => { const color1 = red.mix(transparent).toString(); const color2 = rgba(255, 0, 0, 0.5).toString(); assert.equal(color1, color2); }); it('red + black', () => { const color1 = red.mix(black).toString(); const color2 = maroon.toString(); assert.equal(color1, color2); }); }); describe('tint()', () => { it('changed red to a lighter red', () => { const color1 = red.tint(0.3).toString(); // color2 was tested on the SASS compiler with mix(white, red, 30%) const color2 = rgb(255, 77, 77).toString(); assert.equal(color1, color2); }); }); describe('shade()', () => { it('changed red to a darker red', () => { const color1 = red.shade(0.3).toString(); // color2 was tested on the SASS compiler with mix(black, red, 30%) const color2 = rgb(179, 0, 0).toString(); assert.equal(color1, color2); }); }); describe('spin()', () => { it('spinning 360 degrees returns same color', () => { const color1 = red.toString(); const color2 = red.spin(360).toString(); assert.equal(color1, color2); }); it('spinning -360 degrees returns same color', () => { const color1 = red.toString(); const color2 = red.spin(-360).toString(); assert.equal(color1, color2); }); it('spinning -120 degrees from red returns blue', () => { const color1 = red.spin(-120).toHexString(); assert.equal('#0000FF', color1); }); it('spinning 120 degrees from red returns yellow', () => { const color1 = red.spin(120).toHexString(); assert.equal('#00FF00', color1); }); }); });