702 lines
34 KiB
HTML
702 lines
34 KiB
HTML
<!doctype html>
|
|
<html>
|
|
<head>
|
|
<script src="../../http/tests/inspector/resources/inspector-test.js"></script>
|
|
<script>
|
|
function test()
|
|
{
|
|
function formatToString(format) {
|
|
switch (format) {
|
|
case WI.Color.Format.Original:
|
|
return "Original";
|
|
case WI.Color.Format.Keyword:
|
|
return "Keyword";
|
|
case WI.Color.Format.HEX:
|
|
return "HEX";
|
|
case WI.Color.Format.ShortHEX:
|
|
return "Short HEX";
|
|
case WI.Color.Format.HEXAlpha:
|
|
return "HEX with Alpha";
|
|
case WI.Color.Format.ShortHEXAlpha:
|
|
return "Short HEX with Alpha";
|
|
case WI.Color.Format.RGB:
|
|
return "RGB";
|
|
case WI.Color.Format.RGBA:
|
|
return "RGBA";
|
|
case WI.Color.Format.HSL:
|
|
return "HSL";
|
|
case WI.Color.Format.HSLA:
|
|
return "HSLA";
|
|
case WI.Color.Format.ColorFunction:
|
|
return "Function";
|
|
default:
|
|
return "Unexpected format";
|
|
}
|
|
}
|
|
|
|
let suite = InspectorTest.createSyncSuite("WI.Color");
|
|
|
|
suite.addTestCase({
|
|
name: "WI.Color.fromString",
|
|
description: "Test we can detect colors from strings.",
|
|
test() {
|
|
function testGood(string, expectedFormat) {
|
|
let color = WI.Color.fromString(string);
|
|
InspectorTest.assert(color instanceof WI.Color, `'${string}' should be detected`);
|
|
InspectorTest.assert(color.format === expectedFormat, `'${string}' was the expected '${formatToString(expectedFormat)}' format`);
|
|
InspectorTest.log(`"${string}" resolves to "${color.toString()}"`);
|
|
}
|
|
|
|
function testBad(string) {
|
|
let color = WI.Color.fromString(string);
|
|
InspectorTest.expectNull(color, `'${string}' should not be detected`);
|
|
if (color)
|
|
InspectorTest.log(`'${string}' detected with format '${formatToString(color.format)}'`);
|
|
}
|
|
|
|
testGood("#000", WI.Color.Format.ShortHEX);
|
|
testGood("#a0A", WI.Color.Format.ShortHEX);
|
|
testGood("#000000", WI.Color.Format.HEX);
|
|
testGood("#a0Aa0A", WI.Color.Format.HEX);
|
|
|
|
testGood("#0000", WI.Color.Format.ShortHEXAlpha);
|
|
testGood("#a0Af", WI.Color.Format.ShortHEXAlpha);
|
|
testGood("#00000000", WI.Color.Format.HEXAlpha);
|
|
testGood("#a0Aa0Aff", WI.Color.Format.HEXAlpha);
|
|
|
|
testGood("rgb(10,20,30)", WI.Color.Format.RGB);
|
|
testGood("RGB(10,20,30)", WI.Color.Format.RGB);
|
|
testGood("rgb( 10 , 20 , 30 )", WI.Color.Format.RGB);
|
|
testGood("rgb(999, 999, 999)", WI.Color.Format.RGB);
|
|
|
|
testGood("rgb(10 20 30)", WI.Color.Format.RGB);
|
|
testGood("RGB(10 20 30)", WI.Color.Format.RGB);
|
|
testGood("rgb( 10 20 30 )", WI.Color.Format.RGB);
|
|
testGood("rgb(999 999 999)", WI.Color.Format.RGB);
|
|
|
|
testGood("rgb(10,20,30,40)", WI.Color.Format.RGBA);
|
|
testGood("RGB(10,20,30,40)", WI.Color.Format.RGBA);
|
|
testGood("rgb( 10 , 20 , 30 , 40 )", WI.Color.Format.RGBA);
|
|
testGood("rgb(999, 999, 999, 999)", WI.Color.Format.RGBA);
|
|
|
|
testGood("rgb(10,20,30,40%)", WI.Color.Format.RGBA);
|
|
testGood("RGB(10,20,30,40%)", WI.Color.Format.RGBA);
|
|
testGood("rgb( 10 , 20 , 30 , 40% )", WI.Color.Format.RGBA);
|
|
testGood("rgb(999, 999, 999, 999%)", WI.Color.Format.RGBA);
|
|
|
|
testGood("rgb(10 20 30 / 40)", WI.Color.Format.RGBA);
|
|
testGood("RGB(10 20 30 / 40)", WI.Color.Format.RGBA);
|
|
testGood("rgb( 10 20 30 / 40 )", WI.Color.Format.RGBA);
|
|
testGood("rgb(999 999 999 / 999)", WI.Color.Format.RGBA);
|
|
|
|
testGood("rgb(10 20 30 / 40%)", WI.Color.Format.RGBA);
|
|
testGood("RGB(10 20 30 / 40%)", WI.Color.Format.RGBA);
|
|
testGood("rgb( 10 20 30 / 40% )", WI.Color.Format.RGBA);
|
|
testGood("rgb(999 999 999 / 999%)", WI.Color.Format.RGBA);
|
|
|
|
testGood("rgba(10,20,30,40)", WI.Color.Format.RGBA);
|
|
testGood("RGBA(10,20,30,40)", WI.Color.Format.RGBA);
|
|
testGood("rgba( 10 , 20 , 30 , 40 )", WI.Color.Format.RGBA);
|
|
testGood("rgba(999, 999, 999, 999)", WI.Color.Format.RGBA);
|
|
|
|
testGood("rgba(10,20,30,40%)", WI.Color.Format.RGBA);
|
|
testGood("RGBA(10,20,30,40%)", WI.Color.Format.RGBA);
|
|
testGood("rgba( 10 , 20 , 30 , 40% )", WI.Color.Format.RGBA);
|
|
testGood("rgba(999, 999, 999, 999%)", WI.Color.Format.RGBA);
|
|
|
|
testGood("rgba(10 20 30 / 40)", WI.Color.Format.RGBA);
|
|
testGood("RGBA(10 20 30 / 40)", WI.Color.Format.RGBA);
|
|
testGood("rgba( 10 20 30 / 40 )", WI.Color.Format.RGBA);
|
|
testGood("rgba(999 999 999 / 999)", WI.Color.Format.RGBA);
|
|
|
|
testGood("rgba(10 20 30 / 40%)", WI.Color.Format.RGBA);
|
|
testGood("RGBA(10 20 30 / 40%)", WI.Color.Format.RGBA);
|
|
testGood("rgba( 10 20 30 / 40% )", WI.Color.Format.RGBA);
|
|
testGood("rgba(999 999 999 / 999%)", WI.Color.Format.RGBA);
|
|
|
|
testGood("rgb(10%,20%,30%)", WI.Color.Format.RGB);
|
|
testGood("RGB(10%,20%,30%)", WI.Color.Format.RGB);
|
|
testGood("rgb( 10% , 20% , 30% )", WI.Color.Format.RGB);
|
|
testGood("rgb(999%, 999%, 999%)", WI.Color.Format.RGB);
|
|
|
|
testGood("rgb(10% 20% 30%)", WI.Color.Format.RGB);
|
|
testGood("RGB(10% 20% 30%)", WI.Color.Format.RGB);
|
|
testGood("rgb( 10% 20% 30% )", WI.Color.Format.RGB);
|
|
testGood("rgb(999% 999% 999%)", WI.Color.Format.RGB);
|
|
|
|
testGood("rgb(10%,20%,30%,40)", WI.Color.Format.RGBA);
|
|
testGood("RGB(10%,20%,30%,40)", WI.Color.Format.RGBA);
|
|
testGood("rgb( 10% , 20% , 30% , 40 )", WI.Color.Format.RGBA);
|
|
testGood("rgb(999%, 999%, 999%, 999%)", WI.Color.Format.RGBA);
|
|
|
|
testGood("rgb(10%,20%,30%,40%)", WI.Color.Format.RGBA);
|
|
testGood("RGB(10%,20%,30%,40%)", WI.Color.Format.RGBA);
|
|
testGood("rgb( 10% , 20% , 30% , 40% )", WI.Color.Format.RGBA);
|
|
testGood("rgb(999%, 999%, 999%, 999%)", WI.Color.Format.RGBA);
|
|
|
|
testGood("rgb(10% 20% 30% / 40)", WI.Color.Format.RGBA);
|
|
testGood("RGB(10% 20% 30% / 40)", WI.Color.Format.RGBA);
|
|
testGood("rgb( 10% 20% 30% / 40 )", WI.Color.Format.RGBA);
|
|
testGood("rgb(999% 999% 999% / 999%)", WI.Color.Format.RGBA);
|
|
|
|
testGood("rgb(10% 20% 30% / 40%)", WI.Color.Format.RGBA);
|
|
testGood("RGB(10% 20% 30% / 40%)", WI.Color.Format.RGBA);
|
|
testGood("rgb( 10% 20% 30% / 40% )", WI.Color.Format.RGBA);
|
|
testGood("rgb(999% 999% 999% / 999%)", WI.Color.Format.RGBA);
|
|
|
|
testGood("rgba(10%,20%,30%,40)", WI.Color.Format.RGBA);
|
|
testGood("RGBA(10%,20%,30%,40)", WI.Color.Format.RGBA);
|
|
testGood("rgba( 10% , 20% , 30% , 40 )", WI.Color.Format.RGBA);
|
|
testGood("rgba(999%, 999%, 999%, 999%)", WI.Color.Format.RGBA);
|
|
|
|
testGood("rgba(10%,20%,30%,40%)", WI.Color.Format.RGBA);
|
|
testGood("RGBA(10%,20%,30%,40%)", WI.Color.Format.RGBA);
|
|
testGood("rgba( 10% , 20% , 30% , 40% )", WI.Color.Format.RGBA);
|
|
testGood("rgba(999%, 999%, 999%, 999%)", WI.Color.Format.RGBA);
|
|
|
|
testGood("rgba(10% 20% 30% / 40)", WI.Color.Format.RGBA);
|
|
testGood("RGBA(10% 20% 30% / 40)", WI.Color.Format.RGBA);
|
|
testGood("rgba( 10% 20% 30% / 40 )", WI.Color.Format.RGBA);
|
|
testGood("rgba(999% 999% 999% / 999%)", WI.Color.Format.RGBA);
|
|
|
|
testGood("rgba(10% 20% 30% / 40%)", WI.Color.Format.RGBA);
|
|
testGood("RGBA(10% 20% 30% / 40%)", WI.Color.Format.RGBA);
|
|
testGood("rgba( 10% 20% 30% / 40% )", WI.Color.Format.RGBA);
|
|
testGood("rgba(999% 999% 999% / 999%)", WI.Color.Format.RGBA);
|
|
|
|
for (let unit of ["", "deg", "rad", "grad", "turn"]) {
|
|
testGood(`hsl(10${unit},20%,30%)`, WI.Color.Format.HSL);
|
|
testGood(`HSL(10${unit},20%,30%)`, WI.Color.Format.HSL);
|
|
testGood(`hsl( 10${unit} , 20% , 30% )`, WI.Color.Format.HSL);
|
|
testGood(`hsl(999${unit}, 999%, 999%)`, WI.Color.Format.HSL);
|
|
|
|
testGood(`hsl(10${unit} 20% 30%)`, WI.Color.Format.HSL);
|
|
testGood(`HSL(10${unit} 20% 30%)`, WI.Color.Format.HSL);
|
|
testGood(`hsl( 10${unit} 20% 30% )`, WI.Color.Format.HSL);
|
|
testGood(`hsl(999${unit} 999% 999%)`, WI.Color.Format.HSL);
|
|
|
|
testGood(`hsl(10${unit},20%,30%,40)`, WI.Color.Format.HSLA);
|
|
testGood(`HSL(10${unit},20%,30%,40)`, WI.Color.Format.HSLA);
|
|
testGood(`hsl( 10${unit} , 20% , 30% , 40 )`, WI.Color.Format.HSLA);
|
|
testGood(`hsl(999${unit}, 999%, 999%, 999)`, WI.Color.Format.HSLA);
|
|
|
|
testGood(`hsl(10${unit},20%,30%,40%)`, WI.Color.Format.HSLA);
|
|
testGood(`HSL(10${unit},20%,30%,40%)`, WI.Color.Format.HSLA);
|
|
testGood(`hsl( 10${unit} , 20% , 30% , 40% )`, WI.Color.Format.HSLA);
|
|
testGood(`hsl(999${unit}, 999%, 999%, 999%)`, WI.Color.Format.HSLA);
|
|
|
|
testGood(`hsl(10${unit} 20% 30% / 40)`, WI.Color.Format.HSLA);
|
|
testGood(`HSL(10${unit} 20% 30% / 40)`, WI.Color.Format.HSLA);
|
|
testGood(`hsl( 10${unit} 20% 30% / 40 )`, WI.Color.Format.HSLA);
|
|
testGood(`hsl(999${unit} 999% 999% / 999)`, WI.Color.Format.HSLA);
|
|
|
|
testGood(`hsl(10${unit} 20% 30% / 40%)`, WI.Color.Format.HSLA);
|
|
testGood(`HSL(10${unit} 20% 30% / 40%)`, WI.Color.Format.HSLA);
|
|
testGood(`hsl( 10${unit} 20% 30% / 40% )`, WI.Color.Format.HSLA);
|
|
testGood(`hsl(999${unit} 999% 999% / 999%)`, WI.Color.Format.HSLA);
|
|
|
|
testGood(`hsl(10${unit},20%,30%,40)`, WI.Color.Format.HSLA);
|
|
testGood(`HSL(10${unit},20%,30%,40)`, WI.Color.Format.HSLA);
|
|
testGood(`hsl( 10${unit} , 20% , 30% , 40 )`, WI.Color.Format.HSLA);
|
|
testGood(`hsl(999${unit}, 999%, 999%, 999)`, WI.Color.Format.HSLA);
|
|
|
|
testGood(`hsl(10${unit},20%,30%,40%)`, WI.Color.Format.HSLA);
|
|
testGood(`HSL(10${unit},20%,30%,40%)`, WI.Color.Format.HSLA);
|
|
testGood(`hsl( 10${unit} , 20% , 30% , 40% )`, WI.Color.Format.HSLA);
|
|
testGood(`hsl(999${unit}, 999%, 999%, 999%)`, WI.Color.Format.HSLA);
|
|
|
|
testGood(`hsla(10${unit},20%,30%,40)`, WI.Color.Format.HSLA);
|
|
testGood(`HSLA(10${unit},20%,30%,40)`, WI.Color.Format.HSLA);
|
|
testGood(`hsla( 10${unit} , 0% , 50% , 40 )`, WI.Color.Format.HSLA);
|
|
testGood(`hsla(999${unit}, 999%, 999%, 999)`, WI.Color.Format.HSLA);
|
|
|
|
testGood(`hsla(10${unit},20%,30%,40%)`, WI.Color.Format.HSLA);
|
|
testGood(`HSLA(10${unit},20%,30%,40%)`, WI.Color.Format.HSLA);
|
|
testGood(`hsla( 10${unit} , 20% , 30% , 40% )`, WI.Color.Format.HSLA);
|
|
testGood(`hsla(999${unit}, 999%, 999%, 999%)`, WI.Color.Format.HSLA);
|
|
|
|
testGood(`hsla(10${unit} 20% 30% / 40)`, WI.Color.Format.HSLA);
|
|
testGood(`HSLA(10${unit} 20% 30% / 40)`, WI.Color.Format.HSLA);
|
|
testGood(`hsla( 10${unit} 20% 30% / 40 )`, WI.Color.Format.HSLA);
|
|
testGood(`hsla(999${unit} 999% 999% / 999)`, WI.Color.Format.HSLA);
|
|
|
|
testGood(`hsla(10${unit} 20% 30% / 40%)`, WI.Color.Format.HSLA);
|
|
testGood(`HSLA(10${unit} 20% 30% / 40%)`, WI.Color.Format.HSLA);
|
|
testGood(`hsla( 10${unit} 20% 30% / 40% )`, WI.Color.Format.HSLA);
|
|
testGood(`hsla(999${unit} 999% 999% / 999%)`, WI.Color.Format.HSLA);
|
|
}
|
|
|
|
testGood("color(display-p3 0 1 0.5)", WI.Color.Format.ColorFunction);
|
|
testGood("COLOR(DISPLAY-P3 0 1 0.5)", WI.Color.Format.ColorFunction);
|
|
|
|
testGood("color(srgb 0.123 0.999 1)", WI.Color.Format.ColorFunction);
|
|
testGood("COLOR(SRGB 0.123 0.999 1)", WI.Color.Format.ColorFunction);
|
|
testGood("color( display-p3 0 1 0.5 )", WI.Color.Format.ColorFunction);
|
|
testGood("color(display-p3 999 999 999)", WI.Color.Format.ColorFunction);
|
|
|
|
testGood("color(srgb 0.123 0.999 1/0.5)", WI.Color.Format.ColorFunction);
|
|
testGood("COLOR(SRGB 0.123 0.999 1/0.5)", WI.Color.Format.ColorFunction);
|
|
testGood("color( display-p3 0 1 0.5/0.5)", WI.Color.Format.ColorFunction);
|
|
testGood("color(display-p3 999 999 999/999)", WI.Color.Format.ColorFunction);
|
|
|
|
testGood("color(srgb 0.123 0.999 1 / 0.5)", WI.Color.Format.ColorFunction);
|
|
testGood("COLOR(SRGB 0.123 0.999 1 / 0.5)", WI.Color.Format.ColorFunction);
|
|
testGood("color( display-p3 0 1 0.5 / 0.5)", WI.Color.Format.ColorFunction);
|
|
testGood("color(display-p3 999 999 999 / 999)", WI.Color.Format.ColorFunction);
|
|
|
|
testGood("color(srgb 0.123 0.999 1/33%)", WI.Color.Format.ColorFunction);
|
|
testGood("COLOR(SRGB 0.123 0.999 1/33%)", WI.Color.Format.ColorFunction);
|
|
testGood("color( display-p3 0 1 0.5/33%)", WI.Color.Format.ColorFunction);
|
|
testGood("color(display-p3 999 999 999/999%)", WI.Color.Format.ColorFunction);
|
|
|
|
testGood("color(srgb 0.123 0.999 1 / 33%)", WI.Color.Format.ColorFunction);
|
|
testGood("COLOR(SRGB 0.123 0.999 1 / 33%)", WI.Color.Format.ColorFunction);
|
|
testGood("color( display-p3 0 1 0.5 / 33%)", WI.Color.Format.ColorFunction);
|
|
testGood("color(display-p3 999 999 999 / 999%)", WI.Color.Format.ColorFunction);
|
|
|
|
InspectorTest.log("");
|
|
|
|
testBad(" #000 "); // whitespace
|
|
testBad("#rgb"); // bad hex
|
|
testBad("#1"); // 1
|
|
testBad("#12"); // 2
|
|
testBad("#12345"); // 5
|
|
testBad("#1234567"); // 7
|
|
testBad("#123456789"); // 9
|
|
testBad("rgb(255, 255, 255, 0.5, 1)"); // extra values
|
|
testBad("rgba(255, 255, 255, 0.5, 1)"); // extra values
|
|
testBad("hsl(0, 0%, 50%, 1, 2)"); // extra value
|
|
testBad("hsla(0, 0%, 50%, 1, 2)"); // extra values
|
|
testBad("superblue"); // not a keyword
|
|
testBad("color(display-p3 0 1)"); // 2
|
|
testBad("color(display-p3 0 1 2 4 5)"); // 5
|
|
|
|
// FIXME: currentColor?
|
|
// FIXME: Should we consider missing %s as bad? Currently we just strip them.
|
|
// testBad("hsl(0, 0, 50)"); // missing %s
|
|
// testBad("hsla(0, 0, 50, 1)"); // missing %s
|
|
|
|
return true;
|
|
}
|
|
});
|
|
|
|
suite.addTestCase({
|
|
name: "WI.Color properties",
|
|
description: "Test different color properties.",
|
|
test() {
|
|
let color;
|
|
|
|
color = WI.Color.fromString("red");
|
|
InspectorTest.expectThat(color.alpha === 1, "'red' should have alpha of 1.");
|
|
InspectorTest.expectThat(color.simple === true, "'red' should be simple.");
|
|
InspectorTest.expectThat(color.isKeyword() === true, "'red' should be a keyword.");
|
|
InspectorTest.expectShallowEqual(color.rgb, [255, 0, 0], "'red' has rgb of [255, 0, 0].");
|
|
InspectorTest.expectShallowEqual(color.rgba, [255, 0, 0, 1], "'red' has rgba of [255, 0, 0, 1].");
|
|
InspectorTest.expectShallowEqual(color.hsl, [0, 100, 50], "'red' has hsl of [0, 100, 50].");
|
|
InspectorTest.expectShallowEqual(color.hsla, [0, 100, 50, 1], "'red' has hsla of [0, 100, 50, 1].");
|
|
InspectorTest.expectThat(color.canBeSerializedAsShortHEX() === true, "'red' should be serializable as a short Hex");
|
|
|
|
color = WI.Color.fromString("transparent");
|
|
InspectorTest.expectThat(color.alpha === 0, "'transparent' should have alpha of 0.");
|
|
InspectorTest.expectThat(color.simple === false, "'transparent' should not be simple.");
|
|
InspectorTest.expectThat(color.isKeyword() === true, "'transparent' should be a keyword.");
|
|
InspectorTest.expectShallowEqual(color.rgb, [0, 0, 0], "'transparent' has rgb of [0, 0, 0].");
|
|
InspectorTest.expectShallowEqual(color.rgba, [0, 0, 0, 0], "'transparent' has rgba of [0, 0, 0, 0].");
|
|
InspectorTest.expectShallowEqual(color.hsl, [0, 0, 0], "'transparent' has hsl of [0, 0, 0].");
|
|
InspectorTest.expectShallowEqual(color.hsla, [0, 0, 0, 0], "'transparent' has hsla of [0, 0, 0, 0].");
|
|
InspectorTest.expectThat(color.canBeSerializedAsShortHEX() === true, "'transparent' should be serializable as a short Hex");
|
|
|
|
color = WI.Color.fromString("#11122233");
|
|
InspectorTest.expectThat(color.alpha !== 0, "'#11122233' should not have alpha of 0.");
|
|
InspectorTest.expectThat(color.simple === false, "'#11122233' should be not be simple.");
|
|
InspectorTest.expectThat(color.isKeyword() === false, "'#11122233' should not be a keyword.");
|
|
InspectorTest.expectShallowEqual(color.rgba, [17, 18, 34, 0.2], "'#11122233' has rgba of [17, 18, 34, 0.2].");
|
|
InspectorTest.expectShallowEqual(color.hsla.map((value) => value.maxDecimals(2)), [236.47, 33.33, 10, 0.2], "'#11122233' has hsla of [236.47, 33.33, 10, 0.2].");
|
|
InspectorTest.expectThat(color.canBeSerializedAsShortHEX() === false, "'#11122233' should not be serializable as a short Hex");
|
|
|
|
color = WI.Color.fromString("#11223344");
|
|
InspectorTest.expectThat(color.canBeSerializedAsShortHEX() === true, "'#11223344' should be serializable as a short Hex");
|
|
|
|
color = WI.Color.fromString("#11223345");
|
|
InspectorTest.expectThat(color.canBeSerializedAsShortHEX() === false, "'#11223345' should not be serializable as a short Hex");
|
|
|
|
color = WI.Color.fromString("color(display-p3 0 1 0.5)");
|
|
InspectorTest.expectThat(color.alpha === 1, "'color(display-p3 0 1 0.5)' color should have a default alpha of 1");
|
|
InspectorTest.expectThat(color.isKeyword() === false, "color function is not a keyword");
|
|
InspectorTest.expectShallowEqual(color.normalizedRGB, [0, 1, 0.5], "'color(display-p3 0 1 0.5)' has normalized RGB of [0, 1, 0.5]");
|
|
InspectorTest.expectShallowEqual(color.normalizedRGBA, [0, 1, 0.5, 1], "'color(display-p3 0 1 0.5)' has normalized RGBA of [0, 1, 0.5, 1]");
|
|
|
|
color = WI.Color.fromString("color(display-p3 0 1 0.5 / 0.3)");
|
|
InspectorTest.expectThat(color.alpha === 0.3, "'color(display-p3 0 1 0.5 / 0.3)' should have an alpha of 0.3");
|
|
InspectorTest.expectThat(color.isKeyword() === false, "color function is not a keyword");
|
|
InspectorTest.expectShallowEqual(color.normalizedRGB, [0, 1, 0.5], "'color(display-p3 0 1 0.5 / 0.3)' has normalized RGB of [0, 1, 0.5]");
|
|
InspectorTest.expectShallowEqual(color.normalizedRGBA, [0, 1, 0.5, 0.3], "'color(display-p3 0 1 0.5 / 0.3)' has normalized RGBA of [0, 1, 0.5, 0.3]");
|
|
|
|
return true;
|
|
}
|
|
});
|
|
|
|
suite.addTestCase({
|
|
name: "WI.Color from components",
|
|
description: "Test different three- and four-component colors.",
|
|
test() {
|
|
function test(color, components) {
|
|
InspectorTest.log(`Check components for color '${color.toString()}'.`);
|
|
for (let key in components) {
|
|
let value = components[key];
|
|
InspectorTest.expectShallowEqual(color[key].map((value) => value.maxDecimals(2)), value, `Should have ${key} of ${JSON.stringify(value)}.`);
|
|
}
|
|
}
|
|
|
|
test(new WI.Color(WI.Color.Format.RGB, [255, 0, 0]), {
|
|
rgb: [255, 0, 0],
|
|
rgba: [255, 0, 0, 1],
|
|
hsl: [0, 100, 50],
|
|
hsla: [0, 100, 50, 1],
|
|
});
|
|
|
|
test(new WI.Color(WI.Color.Format.RGBA, [128, 128, 128, 0.5]), {
|
|
rgb: [128, 128, 128],
|
|
rgba: [128, 128, 128, 0.5],
|
|
hsl: [0, 0, 50.2],
|
|
hsla: [0, 0, 50.2, 0.5],
|
|
});
|
|
|
|
test(new WI.Color(WI.Color.Format.HSL, [0, 0, 50]), {
|
|
rgb: [127.5, 127.5, 127.5],
|
|
rgba: [127.5, 127.5, 127.5, 1],
|
|
hsl: [0, 0, 50],
|
|
hsla: [0, 0, 50, 1],
|
|
});
|
|
|
|
test(new WI.Color(WI.Color.Format.HSLA, [0, 0, 50, 0.5]), {
|
|
rgb: [127.5, 127.5, 127.5],
|
|
rgba: [127.5, 127.5, 127.5, 0.5],
|
|
hsl: [0, 0, 50],
|
|
hsla: [0, 0, 50, 0.5],
|
|
});
|
|
|
|
return true;
|
|
}
|
|
});
|
|
|
|
suite.addTestCase({
|
|
name: "WI.Color.prototype.nextFormat",
|
|
description: "Test we can cycle through color formats for different colors.",
|
|
test() {
|
|
function test(string, phases) {
|
|
let color = WI.Color.fromString(string);
|
|
color.format = WI.Color.Format.Original;
|
|
|
|
let pass = true;
|
|
for (let expectedNextFormat of phases) {
|
|
let nextFormat = color.nextFormat();
|
|
InspectorTest.assert(nextFormat === expectedNextFormat, `Next format '${formatToString(nextFormat)}' was not the expected '${formatToString(expectedNextFormat)}'`);
|
|
pass = pass && nextFormat === expectedNextFormat;
|
|
color.format = nextFormat;
|
|
}
|
|
|
|
InspectorTest.expectThat(pass, `All format phases of '${string}' should be as expected.`);
|
|
}
|
|
|
|
// All with alpha.
|
|
test("transparent", [
|
|
WI.Color.Format.RGBA,
|
|
WI.Color.Format.ColorFunction,
|
|
WI.Color.Format.HSLA,
|
|
WI.Color.Format.Keyword,
|
|
WI.Color.Format.ShortHEXAlpha,
|
|
WI.Color.Format.HEXAlpha,
|
|
]);
|
|
|
|
// All without alpha.
|
|
test("red", [
|
|
WI.Color.Format.RGB,
|
|
WI.Color.Format.ColorFunction,
|
|
WI.Color.Format.HSL,
|
|
WI.Color.Format.Keyword,
|
|
WI.Color.Format.ShortHEX,
|
|
WI.Color.Format.HEX,
|
|
]);
|
|
|
|
// No short hex or keyword.
|
|
test("rgb(100, 150, 200)", [
|
|
WI.Color.Format.RGB,
|
|
WI.Color.Format.ColorFunction,
|
|
WI.Color.Format.HSL,
|
|
WI.Color.Format.HEX,
|
|
]);
|
|
|
|
// No short hex alpha or keyword.
|
|
test("rgba(100, 150, 200, 0.5)", [
|
|
WI.Color.Format.RGBA,
|
|
WI.Color.Format.ColorFunction,
|
|
WI.Color.Format.HSLA,
|
|
WI.Color.Format.HEXAlpha,
|
|
]);
|
|
|
|
return true;
|
|
}
|
|
});
|
|
|
|
suite.addTestCase({
|
|
name: "WI.Color.prototype.toString",
|
|
description: "Test the different toString outputs.",
|
|
test() {
|
|
let color;
|
|
function test(expected, format) {
|
|
let pass = color.toString(format) === expected;
|
|
InspectorTest.expectThat(pass, `Color as '${formatToString(format)}' should be '${expected}'`);
|
|
if (!pass) InspectorTest.log("WAS: " + color.toString(format));
|
|
}
|
|
|
|
// A color with all formats.
|
|
color = WI.Color.fromString("RED");
|
|
test("RED", WI.Color.Format.Original);
|
|
test("red", WI.Color.Format.Keyword);
|
|
test("#f00", WI.Color.Format.ShortHEX);
|
|
test("#ff0000", WI.Color.Format.HEX);
|
|
test("#f00f", WI.Color.Format.ShortHEXAlpha);
|
|
test("#ff0000ff", WI.Color.Format.HEXAlpha);
|
|
test("rgb(255, 0, 0)", WI.Color.Format.RGB);
|
|
test("rgba(255, 0, 0, 1)", WI.Color.Format.RGBA);
|
|
test("hsl(0, 100%, 50%)", WI.Color.Format.HSL);
|
|
test("hsla(0, 100%, 50%, 1)", WI.Color.Format.HSLA);
|
|
|
|
// A color which cannot be some formats, those fallback to something else.
|
|
color = WI.Color.fromString("rGbA( 100, 200, 255, 0.5 )");
|
|
test("rgba(100, 200, 255, 0.5)", WI.Color.Format.Original); // Original text ignored for some formats.
|
|
test("rgba(100, 200, 255, 0.5)", WI.Color.Format.Keyword); // fallback (rgba)
|
|
test("rgba(100, 200, 255, 0.5)", WI.Color.Format.ShortHEX); // fallback (rgba)
|
|
test("rgba(100, 200, 255, 0.5)", WI.Color.Format.HEX); // fallback (rgba)
|
|
test("#64c8ff80", WI.Color.Format.ShortHEXAlpha); // fallback (hex alpha)
|
|
test("#64c8ff80", WI.Color.Format.HEXAlpha);
|
|
test("rgba(100, 200, 255, 0.5)", WI.Color.Format.RGB); // fallback (rgba)
|
|
test("rgba(100, 200, 255, 0.5)", WI.Color.Format.RGBA);
|
|
test("hsla(201.29, 100%, 69.61%, 0.5)", WI.Color.Format.HSL); // fallback (hsla)
|
|
test("hsla(201.29, 100%, 69.61%, 0.5)", WI.Color.Format.HSLA);
|
|
|
|
// FIXME: Should we clamp rgb(300, 300, 300) => rgb(255, 255, 255) in toStrings?
|
|
// FIXME: Should we always stash the original string, no matter how poor?
|
|
|
|
return true;
|
|
}
|
|
});
|
|
|
|
function testColorConversion(func, value, expected) {
|
|
let actual = func(...value);
|
|
InspectorTest.expectShallowEqual(actual, expected, `Should convert ${JSON.stringify(value)} to ${JSON.stringify(expected)}.`);
|
|
}
|
|
|
|
suite.addTestCase({
|
|
name: "WI.Color.rgb2hsl",
|
|
description: "Test conversion from RGB to HSL.",
|
|
test() {
|
|
testColorConversion(WI.Color.rgb2hsl, [0, 0, 0], [0, 0, 0]);
|
|
testColorConversion(WI.Color.rgb2hsl, [255, 255, 255], [0, 0, 100]);
|
|
testColorConversion(WI.Color.rgb2hsl, [255, 0, 0], [0, 100, 50]);
|
|
testColorConversion(WI.Color.rgb2hsl, [0, 255, 0], [120, 100, 50]);
|
|
testColorConversion(WI.Color.rgb2hsl, [0, 0, 255], [240, 100, 50]);
|
|
|
|
// Out-of-bounds and floating point inputs.
|
|
testColorConversion(WI.Color.rgb2hsl, [-1, -1, -1], [0, 0, 0]);
|
|
testColorConversion(WI.Color.rgb2hsl, [256, 256, 256], [0, 0, 100]);
|
|
testColorConversion(WI.Color.rgb2hsl, [254.9, 0, 0], [0, 100, 50]);
|
|
|
|
return true;
|
|
}
|
|
});
|
|
|
|
suite.addTestCase({
|
|
name: "WI.Color.hsl2rgb",
|
|
description: "Test conversion from HSL to RGB.",
|
|
test() {
|
|
testColorConversion(WI.Color.hsl2rgb, [0, 0, 0], [0, 0, 0]);
|
|
testColorConversion(WI.Color.hsl2rgb, [0, 0, 100], [255, 255, 255]);
|
|
testColorConversion(WI.Color.hsl2rgb, [0, 100, 50], [255, 0, 0]);
|
|
testColorConversion(WI.Color.hsl2rgb, [120, 100, 50], [0, 255, 0]);
|
|
testColorConversion(WI.Color.hsl2rgb, [240, 100, 50], [0, 0, 255]);
|
|
|
|
// Out-of-bounds.
|
|
testColorConversion(WI.Color.hsl2rgb, [-1, -1, -1], [0, 0, 0]);
|
|
testColorConversion(WI.Color.hsl2rgb, [361, 101, 50], [255, 0, 0]);
|
|
testColorConversion(WI.Color.hsl2rgb, [361, 101, 101], [255, 255, 255]);
|
|
|
|
return true;
|
|
}
|
|
});
|
|
|
|
suite.addTestCase({
|
|
name: "WI.Color.hsv2hsl",
|
|
description: "Test conversion from HSV to HSL.",
|
|
test() {
|
|
testColorConversion(WI.Color.hsv2hsl, [42, 100, 0], [42, 0, 0]);
|
|
testColorConversion(WI.Color.hsv2hsl, [42, 50, 100], [42, 100, 75]);
|
|
testColorConversion(WI.Color.hsv2hsl, [42, 100, 50], [42, 100, 25]);
|
|
testColorConversion(WI.Color.hsv2hsl, [42, 50, 50], [42, 33.33333333333333, 37.5]);
|
|
testColorConversion(WI.Color.hsv2hsl, [42, 100, 100], [42, 100, 50]);
|
|
|
|
// Out-of-bounds.
|
|
testColorConversion(WI.Color.hsv2hsl, [-1, -1, -1], [0, 0, 0]);
|
|
testColorConversion(WI.Color.hsv2hsl, [361, 101, 50], [360, 100, 25]);
|
|
testColorConversion(WI.Color.hsv2hsl, [361, 101, 101], [360, 100, 50]);
|
|
|
|
return true;
|
|
}
|
|
});
|
|
|
|
suite.addTestCase({
|
|
name: "WI.Color.rgb2hsv",
|
|
description: "Test conversion from RGB to HSV.",
|
|
test() {
|
|
testColorConversion(WI.Color.rgb2hsv, [0, 0, 0], [0, 0, 0]);
|
|
testColorConversion(WI.Color.rgb2hsv, [1, 1, 1], [0, 0, 100]);
|
|
testColorConversion(WI.Color.rgb2hsv, [1, 0, 0], [0, 100, 100]);
|
|
testColorConversion(WI.Color.rgb2hsv, [0, 1, 0], [120, 100, 100]);
|
|
testColorConversion(WI.Color.rgb2hsv, [0, 0, 1], [240, 100, 100]);
|
|
|
|
// Out-of-bounds.
|
|
testColorConversion(WI.Color.rgb2hsv, [-1, -1, -1], [0, 0, 0]);
|
|
testColorConversion(WI.Color.rgb2hsv, [1.1, 1.1, 1.1], [0, 0, 100]);
|
|
|
|
return true;
|
|
}
|
|
});
|
|
|
|
suite.addTestCase({
|
|
name: "WI.Color.hsv2rgb",
|
|
description: "Test conversion from HSV to RGB.",
|
|
test() {
|
|
testColorConversion(WI.Color.hsv2rgb, [42, 100, 0], [0, 0, 0]);
|
|
testColorConversion(WI.Color.hsv2rgb, [42, 50, 100], [1, 0.8500000000000001, 0.5]);
|
|
testColorConversion(WI.Color.hsv2rgb, [42, 100, 50], [0.5, 0.3500000000000001, 0]);
|
|
testColorConversion(WI.Color.hsv2rgb, [42, 50, 50], [0.5, 0.42500000000000004, 0.25]);
|
|
testColorConversion(WI.Color.hsv2rgb, [42, 100, 100], [1, 0.7000000000000002, 0]);
|
|
|
|
// Out-of-bounds.
|
|
testColorConversion(WI.Color.hsv2rgb, [-1, -1, -1], [0, 0, 0]);
|
|
testColorConversion(WI.Color.hsv2rgb, [361, 101, 50], [0.5, 0, 0]);
|
|
testColorConversion(WI.Color.hsv2rgb, [361, 101, 101], [1, 0, 0]);
|
|
|
|
return true;
|
|
}
|
|
});
|
|
|
|
suite.addTestCase({
|
|
name: "WI.Color.cmyk2rgb",
|
|
description: "Test conversion from CMYK to RGB.",
|
|
test() {
|
|
testColorConversion(WI.Color.cmyk2rgb, [0, 0, 0, 1], [0, 0, 0]);
|
|
testColorConversion(WI.Color.cmyk2rgb, [1, 0, 0, 0], [0, 255, 255]);
|
|
testColorConversion(WI.Color.cmyk2rgb, [0, 1, 0, 0], [255, 0, 255]);
|
|
testColorConversion(WI.Color.cmyk2rgb, [0, 0, 1, 0], [255, 255, 0]);
|
|
testColorConversion(WI.Color.cmyk2rgb, [0, 0, 0, 0], [255, 255, 255]);
|
|
|
|
// Out-of-bounds inputs.
|
|
testColorConversion(WI.Color.cmyk2rgb, [2, 0, 0, 0], [0, 255, 255]);
|
|
testColorConversion(WI.Color.cmyk2rgb, [-1, 0, 0, 0], [255, 255, 255]);
|
|
|
|
return true;
|
|
}
|
|
});
|
|
|
|
suite.addTestCase({
|
|
name: "WI.Color.normalized2rgb",
|
|
description: "Test conversion from normalized RGB to RGB.",
|
|
test() {
|
|
testColorConversion(WI.Color.normalized2rgb, [0, 0, 0], [0, 0, 0]);
|
|
testColorConversion(WI.Color.normalized2rgb, [1, 1, 1], [255, 255, 255]);
|
|
testColorConversion(WI.Color.normalized2rgb, [0.24, 0.25, 0.26], [61, 64, 66]); // Values chosen to test round up/down behavior.
|
|
|
|
// Out-of-bounds inputs.
|
|
testColorConversion(WI.Color.normalized2rgb, [2, 0, 0], [255, 0, 0]);
|
|
testColorConversion(WI.Color.normalized2rgb, [-1, 0, 0], [0, 0, 0]);
|
|
|
|
return true;
|
|
}
|
|
});
|
|
|
|
suite.addTestCase({
|
|
name: "WI.Color.displayP3toSRGB",
|
|
description: "Test conversion from display-P3 gamut to sRGB.",
|
|
test() {
|
|
testColorConversion(WI.Color.displayP3toSRGB, [0, 0, 0], [0, 0, 0]);
|
|
testColorConversion(WI.Color.displayP3toSRGB, [1, 1, 1], [0.9999, 1, 1.0001]);
|
|
testColorConversion(WI.Color.displayP3toSRGB, [1, 0, 0], [1.093, -0.5434, -0.2538]);
|
|
testColorConversion(WI.Color.displayP3toSRGB, [0, 1, 0], [-2.9058, 1.0183, -1.0162]);
|
|
testColorConversion(WI.Color.displayP3toSRGB, [0, 0, 1], [0, 0, 1.0421]);
|
|
|
|
// Out-of-bounds inputs.
|
|
testColorConversion(WI.Color.displayP3toSRGB, [2, 0, 0], [1.093, -0.5434, -0.2538]);
|
|
testColorConversion(WI.Color.displayP3toSRGB, [-1, 0, 0], [0, 0, 0]);
|
|
|
|
return true;
|
|
}
|
|
});
|
|
|
|
suite.addTestCase({
|
|
name: "WI.Color.srgbToDisplayP3",
|
|
description: "Test conversion from sRGB gamut to display-P3.",
|
|
test() {
|
|
testColorConversion(WI.Color.srgbToDisplayP3, [0, 0, 0], [0, 0, 0]);
|
|
testColorConversion(WI.Color.srgbToDisplayP3, [1, 1, 1], [1.0001, 1, 0.9999]);
|
|
testColorConversion(WI.Color.srgbToDisplayP3, [1, 0, 0], [0.9176, 0.2003, 0.1386]);
|
|
testColorConversion(WI.Color.srgbToDisplayP3, [0, 1, 0], [0.4584, 0.9853, 0.2983]);
|
|
testColorConversion(WI.Color.srgbToDisplayP3, [0, 0, 1], [0, 0, 0.9595]);
|
|
|
|
// Out-of-bounds inputs.
|
|
testColorConversion(WI.Color.srgbToDisplayP3, [2, 0, 0], [0.9176, 0.2003, 0.1386]);
|
|
testColorConversion(WI.Color.srgbToDisplayP3, [-1, 0, 0], [0, 0, 0]);
|
|
|
|
return true;
|
|
}
|
|
});
|
|
|
|
suite.addTestCase({
|
|
name: "WI.Color.isOutsideSRGB",
|
|
description: "Test conversion from sRGB gamut to display-P3.",
|
|
test() {
|
|
function test(string) {
|
|
let color = WI.Color.fromString(string);
|
|
let result = color.isOutsideSRGB();
|
|
InspectorTest.log(`"${string}" is ${result ? "outside" : "inside"} sRGB.`);
|
|
}
|
|
|
|
test("color(display-p3 0 0 0)");
|
|
test("color(display-p3 1 1 1)");
|
|
test("color(display-p3 0.04 0.14 0.016)"); // Barely inside sRGB. Values chosen to test rounding behavior.
|
|
test("color(display-p3 1 0 0)");
|
|
test("color(display-p3 0.93 0.353 0.353)"); // Barely outside sRGB.
|
|
|
|
return true;
|
|
}
|
|
});
|
|
|
|
suite.addTestCase({
|
|
name: "WI.Color.toProtocol",
|
|
description: "Test serialization of WI.Color into DOM.RGBAColor.",
|
|
test() {
|
|
function testInput(input, expected) {
|
|
let color = WI.Color.fromString(input);
|
|
let actual = color.toProtocol();
|
|
InspectorTest.expectShallowEqual(actual, expected, `Should convert ${input} to ${JSON.stringify(expected)}.`);
|
|
}
|
|
|
|
testInput("rgba(10,20,30,40)", {r: 10, g: 20, b: 30, a: 1});
|
|
testInput("rgb(10 20 30 / 40%)", {r: 10, g: 20, b: 30, a: 0.4});
|
|
testInput("#a0Aa0A", {r: 160, g: 170, b: 10, a: 1});
|
|
testInput("rgb(10% 20% 30% / 40%)", {r: 25.5, g: 51, b: 76.5, a: 0.4});
|
|
|
|
return true;
|
|
}
|
|
});
|
|
|
|
suite.runTestCasesAndFinish();
|
|
}
|
|
</script>
|
|
</head>
|
|
<body onload="runTest()">
|
|
<p>Tests for the WI.Color model object.</p>
|
|
</body>
|
|
</html>
|