@js-draw/math
Version:
A math library for js-draw.
95 lines (77 loc) • 3.75 kB
text/typescript
import Color4 from './Color4';
import Vec3 from './Vec3';
describe('Color4', () => {
it('should convert to #RRGGBB-format hex strings (when no alpha)', () => {
expect(Color4.black.toHexString()).toBe('#000000');
expect(Color4.fromHex('#f0f').toHexString()).toBe('#f000f0');
});
it('should create #RRGGBBAA-format hex strings when there is an alpha component', () => {
expect(Color4.ofRGBA(1, 1, 1, 0.5).toHexString()).toBe('#ffffff80');
});
it('should parse rgb and rgba-format strings', () => {
expect(Color4.fromString('rgb(0, 0, 0)')).objEq(Color4.black);
expect(Color4.fromString('rgb ( 255, 0,\t 0)')).objEq(Color4.ofRGBA(1, 0, 0, 1));
expect(Color4.fromString('rgba ( 255, 0,\t 0, 0.5)')).objEq(Color4.ofRGBA(1, 0, 0, 0.5));
expect(Color4.fromString('rgba( 0, 0, 128, 0)')).objEq(Color4.ofRGBA(0, 0, 128 / 255, 0));
});
it('should parse transparent/none as completely transparent', () => {
expect(Color4.fromString('none')).toBe(Color4.transparent);
expect(Color4.fromString('transparent')).toBe(Color4.transparent);
});
it('should mix blue and red to get dark purple', () => {
expect(Color4.ofRGB(1, 0, 0).mix(Color4.ofRGB(0, 0, 1), 0.5)).objEq(Color4.ofRGB(0.5, 0, 0.5));
expect(Color4.ofRGB(1, 0, 0).mix(Color4.ofRGB(0, 0, 1), 0.1)).objEq(Color4.ofRGB(0.9, 0, 0.1));
});
it('should mix red and green to get yellow', () => {
expect(Color4.ofRGB(1, 0, 0).mix(Color4.ofRGB(0, 1, 0), 0.3)).objEq(Color4.ofRGB(0.7, 0.3, 0));
});
it('should mix red with nothing and get red', () => {
expect(Color4.average([Color4.red])).objEq(Color4.red);
});
it('different colors should be different', () => {
expect(Color4.red.eq(Color4.red)).toBe(true);
expect(Color4.red.eq(Color4.green)).toBe(false);
expect(Color4.fromString('#ff000000').eq(Color4.transparent)).toBe(true);
});
it('should correctly convert to hsv', () => {
expect(Color4.red.asHSV()).objEq(Vec3.of(0, 1, 1));
expect(Color4.ofRGB(0.5, 0.5, 0.5).asHSV()).objEq(Vec3.of(0, 0, 0.5));
expect(Color4.ofRGB(0.5, 0.25, 0.5).asHSV()).objEq(Vec3.of((Math.PI * 5) / 3, 0.5, 0.5), 0.1);
});
it('fromHSV(color.asHSV) should return the original color', () => {
const testColors = [Color4.red, Color4.green, Color4.blue, Color4.white, Color4.black];
const testWithColor = (color: Color4) => {
expect(Color4.fromHSV(...color.asHSV().asArray())).objEq(color);
};
for (const color of testColors) {
testWithColor(color);
}
for (let i = 0; i <= 6; i++) {
testWithColor(Color4.fromHSV((i * Math.PI) / 7, 0.5, 0.5));
testWithColor(Color4.fromHSV((i * Math.PI) / 6, 0.5, 0.5));
}
});
it('.rgb should return a 3-component vector', () => {
expect(Color4.red.rgb).objEq(Vec3.of(1, 0, 0));
expect(Color4.green.rgb).objEq(Vec3.of(0, 1, 0));
expect(Color4.blue.rgb).objEq(Vec3.of(0, 0, 1));
});
it('should return correct contrast ratios', () => {
// Expected values from https://webaim.org/resources/contrastchecker/
const testCases: [Color4, Color4, number][] = [
[Color4.white, Color4.black, 21],
[Color4.fromHex('#FF0000'), Color4.black, 5.25],
[Color4.fromHex('#FF0000'), Color4.fromHex('#0000FF'), 2.14],
[Color4.fromHex('#300000'), Color4.fromHex('#003000'), 1.26],
[Color4.fromHex('#300000'), Color4.fromHex('#003000'), 1.26],
[Color4.fromHex('#D60000'), Color4.fromHex('#003000'), 2.71],
];
for (const [colorA, colorB, expectedContrast] of testCases) {
expect(Color4.contrastRatio(colorA, colorB)).toBeCloseTo(expectedContrast, 1);
}
});
it('should support creating colors from an RGBA array', () => {
expect(Color4.fromRGBArray([255, 0, 0])).objEq(Color4.ofRGB(1, 0, 0));
expect(Color4.fromRGBArray([255, 0, 0, 128])).objEq(Color4.ofRGBA(1, 0, 0, 0.5));
});
});