2015-07-14 11:52:00 +00:00
|
|
|
/* vim: set ts=2 et sw=2 tw=80: */
|
|
|
|
/* Any copyright is dedicated to the Public Domain.
|
|
|
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This file tests the CSS syntax highlighter in the MdnDocsWidget object.
|
|
|
|
*
|
|
|
|
* The CSS syntax highlighter accepts:
|
|
|
|
* - a string containing CSS
|
|
|
|
* - a DOM node
|
|
|
|
*
|
|
|
|
* It parses the string and creates a collection of DOM nodes for different
|
|
|
|
* CSS token types. These DOM nodes have CSS classes applied to them,
|
|
|
|
* to apply the right style for that particular token type. The DOM nodes
|
|
|
|
* are returned as children of the node that was passed to the function.
|
|
|
|
*
|
|
|
|
* This test code defines a number of different strings containing valid and
|
|
|
|
* invalid CSS in various forms. For each string it defines the DOM nodes
|
|
|
|
* that it expects to get from the syntax highlighter.
|
|
|
|
*
|
|
|
|
* It then calls the syntax highlighter, and checks that the resulting
|
|
|
|
* collection of DOM nodes is what we expected.
|
|
|
|
*/
|
|
|
|
|
|
|
|
"use strict";
|
|
|
|
|
2015-09-21 17:04:18 +00:00
|
|
|
const {appendSyntaxHighlightedCSS} = require("devtools/client/shared/widgets/MdnDocsWidget");
|
2015-07-14 11:52:00 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* An array containing the actual test cases.
|
|
|
|
*
|
|
|
|
* The test code tests every case in the array. If you want to add more
|
|
|
|
* test cases, just add more items to the array.
|
|
|
|
*
|
|
|
|
* Each test case consists of:
|
|
|
|
* - description: string describing the salient features of this test case
|
|
|
|
* - example: the string to test
|
|
|
|
* - expected: an array of objects, one for each DOM node we expect, that
|
|
|
|
* captures the information about the node that we expect to test.
|
|
|
|
*/
|
|
|
|
const TEST_DATA = [{
|
|
|
|
description: "Valid syntax, string value.",
|
|
|
|
example: "name: stringValue;",
|
|
|
|
expected: [{type: "property-name", text: "name"},
|
|
|
|
{type: "text", text: ":"},
|
|
|
|
{type: "text", text: " "},
|
|
|
|
{type: "property-value", text: "stringValue"},
|
|
|
|
{type: "text", text: ";"}
|
|
|
|
]}, {
|
|
|
|
description: "Valid syntax, numeric value.",
|
|
|
|
example: "name: 1;",
|
|
|
|
expected: [{type: "property-name", text: "name"},
|
|
|
|
{type: "text", text: ":"},
|
|
|
|
{type: "text", text: " "},
|
|
|
|
{type: "property-value", text: "1"},
|
|
|
|
{type: "text", text: ";"}
|
|
|
|
]}, {
|
|
|
|
description: "Valid syntax, url value.",
|
|
|
|
example: "name: url(./name);",
|
|
|
|
expected: [{type: "property-name", text: "name"},
|
|
|
|
{type: "text", text: ":"},
|
|
|
|
{type: "text", text: " "},
|
|
|
|
{type: "property-value", text: "url(./name)"},
|
|
|
|
{type: "text", text: ";"}
|
|
|
|
]}, {
|
|
|
|
description: "Valid syntax, space before ':'.",
|
|
|
|
example: "name : stringValue;",
|
|
|
|
expected: [{type: "property-name", text: "name"},
|
|
|
|
{type: "text", text: " "},
|
|
|
|
{type: "text", text: ":"},
|
|
|
|
{type: "text", text: " "},
|
|
|
|
{type: "property-value", text: "stringValue"},
|
|
|
|
{type: "text", text: ";"}
|
|
|
|
]}, {
|
|
|
|
description: "Valid syntax, space before ';'.",
|
|
|
|
example: "name: stringValue ;",
|
|
|
|
expected: [{type: "property-name", text: "name"},
|
|
|
|
{type: "text", text: ":"},
|
|
|
|
{type: "text", text: " "},
|
|
|
|
{type: "property-value", text: "stringValue"},
|
|
|
|
{type: "text", text: " "},
|
|
|
|
{type: "text", text: ";"}
|
|
|
|
]}, {
|
|
|
|
description: "Valid syntax, trailing space.",
|
|
|
|
example: "name: stringValue; ",
|
|
|
|
expected: [{type: "property-name", text: "name"},
|
|
|
|
{type: "text", text: ":"},
|
|
|
|
{type: "text", text: " "},
|
|
|
|
{type: "property-value", text: "stringValue"},
|
|
|
|
{type: "text", text: ";"},
|
|
|
|
{type: "text", text: " "}
|
|
|
|
]}, {
|
|
|
|
description: "Valid syntax, leading space.",
|
|
|
|
example: " name: stringValue;",
|
|
|
|
expected: [{type: "text", text: " "},
|
|
|
|
{type: "property-name", text: "name"},
|
|
|
|
{type: "text", text: ":"},
|
|
|
|
{type: "text", text: " "},
|
|
|
|
{type: "property-value", text: "stringValue"},
|
|
|
|
{type: "text", text: ";"}
|
|
|
|
]}, {
|
|
|
|
description: "Valid syntax, two spaces.",
|
|
|
|
example: "name: stringValue;",
|
|
|
|
expected: [{type: "property-name", text: "name"},
|
|
|
|
{type: "text", text: ":"},
|
|
|
|
{type: "text", text: " "},
|
|
|
|
{type: "property-value", text: "stringValue"},
|
|
|
|
{type: "text", text: ";"}
|
|
|
|
]}, {
|
|
|
|
description: "Valid syntax, no spaces.",
|
|
|
|
example: "name:stringValue;",
|
|
|
|
expected: [{type: "property-name", text: "name"},
|
|
|
|
{type: "text", text: ":"},
|
|
|
|
{type: "property-value", text: "stringValue"},
|
|
|
|
{type: "text", text: ";"}
|
|
|
|
]}, {
|
|
|
|
description: "Valid syntax, two-part value.",
|
|
|
|
example: "name: stringValue 1;",
|
|
|
|
expected: [{type: "property-name", text: "name"},
|
|
|
|
{type: "text", text: ":"},
|
|
|
|
{type: "text", text: " "},
|
|
|
|
{type: "property-value", text: "stringValue"},
|
|
|
|
{type: "text", text: " "},
|
|
|
|
{type: "property-value", text: "1"},
|
|
|
|
{type: "text", text: ";"}
|
|
|
|
]}, {
|
|
|
|
description: "Valid syntax, two declarations.",
|
|
|
|
example: "name: stringValue;\n" +
|
|
|
|
"name: 1;",
|
|
|
|
expected: [{type: "property-name", text: "name"},
|
|
|
|
{type: "text", text: ":"},
|
|
|
|
{type: "text", text: " "},
|
|
|
|
{type: "property-value", text: "stringValue"},
|
|
|
|
{type: "text", text: ";"},
|
|
|
|
{type: "text", text: "\n"},
|
|
|
|
{type: "property-name", text: "name"},
|
|
|
|
{type: "text", text: ":"},
|
|
|
|
{type: "text", text: " "},
|
|
|
|
{type: "property-value", text: "1"},
|
|
|
|
{type: "text", text: ";"}
|
|
|
|
]}, {
|
|
|
|
description: "Valid syntax, commented, numeric value.",
|
|
|
|
example: "/* comment */\n" +
|
|
|
|
"name: 1;",
|
|
|
|
expected: [{type: "comment", text: "/* comment */"},
|
|
|
|
{type: "text", text: "\n"},
|
|
|
|
{type: "property-name", text: "name"},
|
|
|
|
{type: "text", text: ":"},
|
|
|
|
{type: "text", text: " "},
|
|
|
|
{type: "property-value", text: "1"},
|
|
|
|
{type: "text", text: ";"}
|
|
|
|
]}, {
|
|
|
|
description: "Valid syntax, multiline commented, string value.",
|
|
|
|
example: "/* multiline \n" +
|
|
|
|
"comment */\n" +
|
|
|
|
"name: stringValue;",
|
|
|
|
expected: [{type: "comment", text: "/* multiline \ncomment */"},
|
|
|
|
{type: "text", text: "\n"},
|
|
|
|
{type: "property-name", text: "name"},
|
|
|
|
{type: "text", text: ":"},
|
|
|
|
{type: "text", text: " "},
|
|
|
|
{type: "property-value", text: "stringValue"},
|
|
|
|
{type: "text", text: ";"}
|
|
|
|
]}, {
|
|
|
|
description: "Valid syntax, commented, two declarations.",
|
|
|
|
example: "/* comment 1 */\n" +
|
|
|
|
"name: 1;\n" +
|
|
|
|
"/* comment 2 */\n" +
|
|
|
|
"name: stringValue;",
|
|
|
|
expected: [{type: "comment", text: "/* comment 1 */"},
|
|
|
|
{type: "text", text: "\n"},
|
|
|
|
{type: "property-name", text: "name"},
|
|
|
|
{type: "text", text: ":"},
|
|
|
|
{type: "text", text: " "},
|
|
|
|
{type: "property-value", text: "1"},
|
|
|
|
{type: "text", text: ";"},
|
|
|
|
{type: "text", text: "\n"},
|
|
|
|
{type: "comment", text: "/* comment 2 */"},
|
|
|
|
{type: "text", text: "\n"},
|
|
|
|
{type: "property-name", text: "name"},
|
|
|
|
{type: "text", text: ":"},
|
|
|
|
{type: "text", text: " "},
|
|
|
|
{type: "property-value", text: "stringValue"},
|
|
|
|
{type: "text", text: ";"}
|
|
|
|
]}, {
|
|
|
|
description: "Valid syntax, multiline.",
|
|
|
|
example: "name: \n" +
|
|
|
|
"stringValue;",
|
|
|
|
expected: [{type: "property-name", text: "name"},
|
|
|
|
{type: "text", text: ":"},
|
|
|
|
{type: "text", text: " \n"},
|
|
|
|
{type: "property-value", text: "stringValue"},
|
|
|
|
{type: "text", text: ";"}
|
|
|
|
]}, {
|
|
|
|
description: "Valid syntax, multiline, two declarations.",
|
|
|
|
example: "name: \n" +
|
|
|
|
"stringValue \n" +
|
|
|
|
"stringValue2;",
|
|
|
|
expected: [{type: "property-name", text: "name"},
|
|
|
|
{type: "text", text: ":"},
|
|
|
|
{type: "text", text: " \n"},
|
|
|
|
{type: "property-value", text: "stringValue"},
|
|
|
|
{type: "text", text: " \n"},
|
|
|
|
{type: "property-value", text: "stringValue2"},
|
|
|
|
{type: "text", text: ";"}
|
|
|
|
]}, {
|
|
|
|
description: "Invalid: not CSS at all.",
|
|
|
|
example: "not CSS at all",
|
|
|
|
expected: [{type: "property-name", text: "not"},
|
|
|
|
{type: "text", text: " "},
|
|
|
|
{type: "property-name", text: "CSS"},
|
|
|
|
{type: "text", text: " "},
|
|
|
|
{type: "property-name", text: "at"},
|
|
|
|
{type: "text", text: " "},
|
|
|
|
{type: "property-name", text: "all"}
|
|
|
|
]}, {
|
|
|
|
description: "Invalid: switched ':' and ';'.",
|
|
|
|
example: "name; stringValue:",
|
|
|
|
expected: [{type: "property-name", text: "name"},
|
|
|
|
{type: "text", text: ";"},
|
|
|
|
{type: "text", text: " "},
|
|
|
|
{type: "property-name", text: "stringValue"},
|
|
|
|
{type: "text", text: ":"}
|
|
|
|
]}, {
|
|
|
|
description: "Invalid: unterminated comment.",
|
|
|
|
example: "/* unterminated comment\n" +
|
|
|
|
"name: stringValue;",
|
|
|
|
expected: [{type: "comment", text: "/* unterminated comment\nname: stringValue;"}
|
|
|
|
]}, {
|
|
|
|
description: "Invalid: bad comment syntax.",
|
|
|
|
example: "// invalid comment\n" +
|
|
|
|
"name: stringValue;",
|
|
|
|
expected: [{type: "text", text: "/"},
|
|
|
|
{type: "text", text: "/"},
|
|
|
|
{type: "text", text: " "},
|
|
|
|
{type: "property-name", text: "invalid"},
|
|
|
|
{type: "text", text: " "},
|
|
|
|
{type: "property-name", text: "comment"},
|
|
|
|
{type: "text", text: "\n"},
|
|
|
|
{type: "property-name", text: "name"},
|
|
|
|
{type: "text", text: ":"},
|
|
|
|
{type: "text", text: " "},
|
|
|
|
{type: "property-value", text: "stringValue"},
|
|
|
|
{type: "text", text: ";"}
|
|
|
|
]}, {
|
|
|
|
description: "Invalid: no trailing ';'.",
|
|
|
|
example: "name: stringValue\n" +
|
|
|
|
"name: stringValue2",
|
|
|
|
expected: [{type: "property-name", text: "name"},
|
|
|
|
{type: "text", text: ":"},
|
|
|
|
{type: "text", text: " "},
|
|
|
|
{type: "property-value", text: "stringValue"},
|
|
|
|
{type: "text", text: "\n"},
|
|
|
|
{type: "property-value", text: "name"},
|
|
|
|
{type: "text", text: ":"},
|
|
|
|
{type: "text", text: " "},
|
|
|
|
{type: "property-value", text: "stringValue2"},
|
|
|
|
]}
|
|
|
|
];
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Iterate through every test case, calling the syntax highlighter,
|
|
|
|
* then calling a helper function to check the output.
|
|
|
|
*/
|
|
|
|
add_task(function*() {
|
|
|
|
let doc = gBrowser.selectedTab.ownerDocument;
|
|
|
|
let parent = doc.createElement("div");
|
|
|
|
info("Testing all CSS syntax highlighter test cases");
|
|
|
|
for (let {description, example, expected} of TEST_DATA) {
|
|
|
|
info("Testing: " + description);
|
|
|
|
appendSyntaxHighlightedCSS(example, parent);
|
|
|
|
checkCssSyntaxHighlighterOutput(expected, parent);
|
|
|
|
while (parent.firstChild) {
|
|
|
|
parent.firstChild.remove();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|