Web Inspector: add context menu items to switch CSS color property value syntax betwe...
[WebKit-https.git] / LayoutTests / inspector / model / color.html
1 <!doctype html>
2 <html>
3 <head>
4 <script src="../../http/tests/inspector/resources/inspector-test.js"></script>
5 <script>
6 function test()
7 {
8     function formatToString(format) {
9         switch (format) {
10         case WebInspector.Color.Format.Original:
11             return "Original";
12         case WebInspector.Color.Format.Keyword:
13             return "Keyword";
14         case WebInspector.Color.Format.HEX:
15             return "HEX";
16         case WebInspector.Color.Format.ShortHEX:
17             return "Short HEX";
18         case WebInspector.Color.Format.HEXAlpha:
19             return "HEX with Alpha";
20         case WebInspector.Color.Format.ShortHEXAlpha:
21             return "Short HEX with Alpha";
22         case WebInspector.Color.Format.RGB:
23             return "RGB";
24         case WebInspector.Color.Format.RGBA:
25             return "RGBA";
26         case WebInspector.Color.Format.HSL:
27             return "HSL";
28         case WebInspector.Color.Format.HSLA:
29             return "HSLA";
30         default:
31             return "Unexpected format";
32         }
33     }
34
35     let suite = InspectorTest.createAsyncSuite("WebInspector.Color");
36
37     suite.addTestCase({
38         name: "WebInspector.Color.fromString",
39         description: "Test we can detect colors from strings.",
40         test: (resolve, reject) => {
41             function testGood(string, expectedFormat) {
42                 let color = WebInspector.Color.fromString(string);
43                 InspectorTest.expectThat(color instanceof WebInspector.Color, `'${string}' should be detected`);
44                 InspectorTest.expectThat(color && color.format === expectedFormat, `'${string}' was the expected '${formatToString(expectedFormat)}' format`);
45             }
46
47             function testBad(string) {
48                 let color = WebInspector.Color.fromString(string);
49                 InspectorTest.expectThat(color === null, `'${string}' should not be detected`);
50                 if (color) InspectorTest.log(`'${string}' detected with format '${formatToString(color.format)}'`);
51             }
52
53             testGood("#000", WebInspector.Color.Format.ShortHEX);
54             testGood("#a0A", WebInspector.Color.Format.ShortHEX);
55             testGood("#000000", WebInspector.Color.Format.HEX);
56             testGood("#a0Aa0A", WebInspector.Color.Format.HEX);
57
58             testGood("#0000", WebInspector.Color.Format.ShortHEXAlpha);
59             testGood("#a0Af", WebInspector.Color.Format.ShortHEXAlpha);
60             testGood("#00000000", WebInspector.Color.Format.HEXAlpha);
61             testGood("#a0Aa0Aff", WebInspector.Color.Format.HEXAlpha);
62
63             testGood("rgb(1,2,3)", WebInspector.Color.Format.RGB);
64             testGood("RGB(1,2,3)", WebInspector.Color.Format.RGB);
65             testGood("rgb(999, 999, 999)", WebInspector.Color.Format.RGB);
66             testGood("rgb( 1 , 1 , 1 )", WebInspector.Color.Format.RGB);
67
68             testGood("rgba(1,2,3,0)", WebInspector.Color.Format.RGBA);
69             testGood("RGBA(1,2,3,0)", WebInspector.Color.Format.RGBA);
70             testGood("rgba(999, 999, 999, 999)", WebInspector.Color.Format.RGBA);
71             testGood("rgba( 1 , 1 , 1 , 0.5 )", WebInspector.Color.Format.RGBA);
72
73             testGood("hsl(0, 0%, 50%)", WebInspector.Color.Format.HSL);
74             testGood("HSL(0, 0%, 50%)", WebInspector.Color.Format.HSL);
75             testGood("hsl(999, 999%, 999%)", WebInspector.Color.Format.HSL);
76             testGood("hsl( 0 , 0% , 50% )", WebInspector.Color.Format.HSL);
77             
78             testGood("hsla(0, 0%, 50%, 0)", WebInspector.Color.Format.HSLA);
79             testGood("HSLA(0, 0%, 50%, 0)", WebInspector.Color.Format.HSLA);
80             testGood("hsla(999, 999%, 999%, 999)", WebInspector.Color.Format.HSLA);
81             testGood("hsla( 0 , 0% , 50% , 0.5 )", WebInspector.Color.Format.HSLA);
82
83             testGood("blue", WebInspector.Color.Format.Keyword);
84             testGood("BLuE", WebInspector.Color.Format.Keyword);
85             testGood("midnightblue", WebInspector.Color.Format.Keyword);
86             testGood("royalblue", WebInspector.Color.Format.Keyword);
87             testGood("steelblue", WebInspector.Color.Format.Keyword);
88             testGood("transparent", WebInspector.Color.Format.Keyword);
89
90             InspectorTest.log("");
91
92             testBad(" #000 "); // whitespace
93             testBad("#rgb"); // bad hex
94             testBad("#1"); // 1
95             testBad("#12"); // 2
96             testBad("#12345"); // 5
97             testBad("#1234567"); // 7
98             testBad("#123456789"); // 9
99             testBad("rgb(255, 255, 255, 0.5)"); // extra values
100             testBad("rgba(255, 255, 255, 0.5, 1)"); // extra values
101             testBad("hsl(0, 0%, 50%, 1)"); // extra value
102             testBad("hsla(0, 0%, 50%, 1, 2)"); // extra values
103             testBad("superblue"); // not a keyword
104
105             // FIXME: currentColor?
106             // FIXME: Should we consider missing %s as bad? Currently we just strip them.
107             // testBad("hsl(0, 0, 50)"); // missing %s
108             // testBad("hsla(0, 0, 50, 1)"); // missing %s
109
110             resolve();
111         }
112     });
113
114     suite.addTestCase({
115         name: "WebInspector.Color properties",
116         description: "Test different color properties.",
117         test: (resolve, reject) => {
118             function shallowEqual(arr1, arr2) {
119                 if (arr1.length !== arr2.length)
120                     return false;
121
122                 for (let i = 0; i < arr1.length; ++i) {
123                     if (arr1[i] !== arr2[i])
124                         return false;
125                 }
126
127                 return true;
128             }
129
130             let color;
131
132             color = WebInspector.Color.fromString("red");
133             InspectorTest.expectThat(color.alpha === 1, "'red' should have alpha of 1.");
134             InspectorTest.expectThat(color.simple === true, "'red' should be simple.");
135             InspectorTest.expectThat(color.isKeyword() === true, "'red' should be a keyword.");
136             InspectorTest.expectThat(shallowEqual(color.rgb, [255, 0, 0]), "'red' has rgb of [255, 0, 0].");
137             InspectorTest.expectThat(shallowEqual(color.rgba, [255, 0, 0, 1]), "'red' has rgba of [255, 0, 0, 1].");
138             InspectorTest.expectThat(shallowEqual(color.hsl, [0, 100, 50]), "'red' has hsl of [0, 100, 50].");
139             InspectorTest.expectThat(shallowEqual(color.hsla, [0, 100, 50, 1]), "'red' has hsla of [0, 100, 50, 1].");
140             InspectorTest.expectThat(color.canBeSerializedAsShortHEX() === true, "'red' should be serializable as a short Hex");
141
142             color = WebInspector.Color.fromString("transparent");
143             InspectorTest.expectThat(color.alpha === 0, "'transparent' should have alpha of 0.");
144             InspectorTest.expectThat(color.simple === false, "'transparent' should not be simple.");
145             InspectorTest.expectThat(color.isKeyword() === true, "'transparent' should be a keyword.");
146             InspectorTest.expectThat(shallowEqual(color.rgb, [0, 0, 0]), "'transparent' has rgb of [0, 0, 0].");
147             InspectorTest.expectThat(shallowEqual(color.rgba, [0, 0, 0, 0]), "'transparent' has rgba of [0, 0, 0, 0].");
148             InspectorTest.expectThat(shallowEqual(color.hsl, [0, 0, 0]), "'transparent' has hsl of [0, 0, 0].");
149             InspectorTest.expectThat(shallowEqual(color.hsla, [0, 0, 0, 0]), "'transparent' has hsla of [0, 0, 0, 0].");
150             InspectorTest.expectThat(color.canBeSerializedAsShortHEX() === true, "'transparent' should be serializable as a short Hex");
151
152             color = WebInspector.Color.fromString("#11122233");
153             InspectorTest.expectThat(color.alpha !== 0, "'#11122233' should not have alpha of 0.");
154             InspectorTest.expectThat(color.simple === false, "'#11122233' should be not be simple.");
155             InspectorTest.expectThat(color.isKeyword() === false, "'#11122233' should not be a keyword.");
156             InspectorTest.expectThat(shallowEqual(color.rgba, [17, 18, 34, 0.2]), "'#11122233' has rgba of [17, 18, 34, 0.2].");
157             InspectorTest.expectThat(shallowEqual(color.hsla, [236, 33, 10, 0.2]), "'#11122233' has hsla of [236, 33, 10, 0.2].");
158             InspectorTest.expectThat(color.canBeSerializedAsShortHEX() === false, "'#11122233' should not be serializable as a short Hex");
159
160             resolve();
161         }
162     });
163
164     suite.addTestCase({
165         name: "WebInspector.Color.prototype.nextFormat",
166         description: "Test we can cycle through color formats for different colors.",
167         test: (resolve, reject) => {
168             function test(string, phases) {
169                 let color = WebInspector.Color.fromString(string);
170                 color.format = WebInspector.Color.Format.Original;
171
172                 let pass = true;
173                 for (let expectedNextFormat of phases) {
174                     let nextFormat = color.nextFormat();
175                     InspectorTest.assert(nextFormat === expectedNextFormat, `Next format '${formatToString(nextFormat)}' was not the expected '${formatToString(expectedNextFormat)}'`);
176                     pass = pass && nextFormat === expectedNextFormat;
177                     color.format = nextFormat;
178                 }
179
180                 InspectorTest.expectThat(pass, `All format phases of '${string}' should be as expected.`);
181             }
182
183             // All with alpha.
184             test("transparent", [
185                 WebInspector.Color.Format.RGBA,
186                 WebInspector.Color.Format.HSLA,
187                 WebInspector.Color.Format.Keyword,
188                 WebInspector.Color.Format.ShortHEXAlpha,
189                 WebInspector.Color.Format.HEXAlpha,
190                 WebInspector.Color.Format.Original,
191             ]);
192
193             // All without alpha.
194             test("red", [
195                 WebInspector.Color.Format.RGB,
196                 WebInspector.Color.Format.HSL,
197                 WebInspector.Color.Format.Keyword,
198                 WebInspector.Color.Format.ShortHEX,
199                 WebInspector.Color.Format.HEX,
200                 WebInspector.Color.Format.Original,
201             ]);
202
203             // No short hex or keyword.
204             test("rgb(100, 150, 200)", [
205                 WebInspector.Color.Format.RGB,
206                 WebInspector.Color.Format.HSL,
207                 WebInspector.Color.Format.HEX,
208                 WebInspector.Color.Format.Original,
209             ]);
210
211             // No short hex alpha or keyword.
212             test("rgba(100, 150, 200, 0.5)", [
213                 WebInspector.Color.Format.RGBA,
214                 WebInspector.Color.Format.HSLA,
215                 WebInspector.Color.Format.HEXAlpha,
216                 WebInspector.Color.Format.Original,
217             ]);
218
219             resolve();
220         }
221     });
222
223     suite.addTestCase({
224         name: "WebInspector.Color.prototype.toString",
225         description: "Test the different toString outputs.",
226         test: (resolve, reject) => {
227             let color;
228             function test(expected, format) {
229                 let pass = color.toString(format) === expected;
230                 InspectorTest.expectThat(pass, `Color as '${formatToString(format)}' should be '${expected}'`);
231                 if (!pass) InspectorTest.log("WAS: " + color.toString(format));
232             }
233
234             // A color with all formats.
235             color = WebInspector.Color.fromString("RED");
236             test("RED", WebInspector.Color.Format.Original);
237             test("red", WebInspector.Color.Format.Keyword);
238             test("#f00", WebInspector.Color.Format.ShortHEX);
239             test("#ff0000", WebInspector.Color.Format.HEX);
240             test("#f00f", WebInspector.Color.Format.ShortHEXAlpha);
241             test("#ff0000ff", WebInspector.Color.Format.HEXAlpha);
242             test("rgb(255, 0, 0)", WebInspector.Color.Format.RGB);
243             test("rgba(255, 0, 0, 1)", WebInspector.Color.Format.RGBA);
244             test("hsl(0, 100%, 50%)", WebInspector.Color.Format.HSL);
245             test("hsla(0, 100%, 50%, 1)", WebInspector.Color.Format.HSLA);
246
247             // A color which cannot be some formats, those fallback to something else.
248             color = WebInspector.Color.fromString("rGbA(  100, 200, 255, 0.5  )");
249             test("rgba(100, 200, 255, 0.5)", WebInspector.Color.Format.Original); // Original text ignored for some formats.
250             test("rgba(100, 200, 255, 0.5)", WebInspector.Color.Format.Keyword); // fallback (rgba)
251             test("rgba(100, 200, 255, 0.5)", WebInspector.Color.Format.ShortHEX); // fallback (rgba)
252             test("rgba(100, 200, 255, 0.5)", WebInspector.Color.Format.HEX); // fallback (rgba)
253             test("#64c8ff80", WebInspector.Color.Format.ShortHEXAlpha); // fallback (hex alpha)
254             test("#64c8ff80", WebInspector.Color.Format.HEXAlpha);
255             test("rgba(100, 200, 255, 0.5)", WebInspector.Color.Format.RGB); // fallback (rgba)
256             test("rgba(100, 200, 255, 0.5)", WebInspector.Color.Format.RGBA);
257             test("hsla(201, 100%, 70%, 0.5)", WebInspector.Color.Format.HSL); // fallback (hsla)
258             test("hsla(201, 100%, 70%, 0.5)", WebInspector.Color.Format.HSLA);
259
260             // FIXME: Should we clamp rgb(300, 300, 300) => rgb(255, 255, 255) in toStrings?
261             // FIXME: Should we always stash the original string, no matter how poor?
262
263             resolve();
264         }
265     });
266
267     suite.runTestCasesAndFinish();
268 }
269 </script>
270 </head>
271 <body onload="runTest()">
272 <p>Tests for the WebInspector.Color model object.</p>
273 </body>
274 </html>