186 lines
7.2 KiB
JavaScript
186 lines
7.2 KiB
JavaScript
'use strict';
|
|
|
|
/**
|
|
* Create test that a CSS property computes to the expected value.
|
|
* The document element #target is used to perform the test.
|
|
*
|
|
* @param {string} property The name of the CSS property being tested.
|
|
* @param {string} value A specified value for the property.
|
|
* @param {string|array} serializedValue The expected serialized value,
|
|
* or an array of permitted serializations.
|
|
* If omitted, defaults to the specified value.
|
|
* @param {object} options Additional test information, such as a custom
|
|
* comparison function required for color tests.
|
|
* comparisonFunction is a function that takes two
|
|
* arguments, actual and expected and contains asserts.
|
|
*/
|
|
function test_valid_value(property, value, serializedValue, options = {}) {
|
|
if (arguments.length < 3)
|
|
serializedValue = value;
|
|
|
|
var stringifiedValue = JSON.stringify(value);
|
|
|
|
test(function(){
|
|
var div = document.getElementById('target') || document.createElement('div');
|
|
div.style[property] = "";
|
|
div.style[property] = value;
|
|
var readValue = div.style.getPropertyValue(property);
|
|
assert_not_equals(readValue, "", "property should be set");
|
|
if (options.comparisonFunction)
|
|
options.comparisonFunction(readValue, serializedValue);
|
|
else if (Array.isArray(serializedValue))
|
|
assert_in_array(readValue, serializedValue, "serialization should be sound");
|
|
else
|
|
assert_equals(readValue, serializedValue, "serialization should be canonical");
|
|
|
|
div.style[property] = readValue;
|
|
assert_equals(div.style.getPropertyValue(property), readValue, "serialization should round-trip");
|
|
|
|
}, "e.style['" + property + "'] = " + stringifiedValue + " should set the property value");
|
|
}
|
|
|
|
function test_invalid_value(property, value) {
|
|
var stringifiedValue = JSON.stringify(value);
|
|
|
|
test(function(){
|
|
var div = document.getElementById('target') || document.createElement('div');
|
|
div.style[property] = "";
|
|
div.style[property] = value;
|
|
assert_equals(div.style.getPropertyValue(property), "");
|
|
}, "e.style['" + property + "'] = " + stringifiedValue + " should not set the property value");
|
|
}
|
|
|
|
function test_valid_forgiving_selector(selector) {
|
|
test_valid_selector(selector, selector, { onlyWhenForgiving: true });
|
|
}
|
|
|
|
// serializedSelector can be the expected serialization of selector,
|
|
// or an array of permitted serializations,
|
|
// or omitted if value should serialize as selector.
|
|
function test_valid_selector(selector, serializedSelector, options) {
|
|
if (arguments.length < 2)
|
|
serializedSelector = selector;
|
|
|
|
const stringifiedSelector = JSON.stringify(selector);
|
|
|
|
test(function(){
|
|
document.querySelector(selector);
|
|
assert_true(true, stringifiedSelector + " should not throw in querySelector");
|
|
|
|
const style = document.createElement("style");
|
|
document.head.append(style);
|
|
const {sheet} = style;
|
|
document.head.removeChild(style);
|
|
const {cssRules} = sheet;
|
|
|
|
assert_equals(cssRules.length, 0, "Sheet should have no rule");
|
|
sheet.insertRule(selector + "{}");
|
|
assert_equals(cssRules.length, 1, "Sheet should have 1 rule");
|
|
|
|
const readSelector = cssRules[0].selectorText;
|
|
if (Array.isArray(serializedSelector))
|
|
assert_in_array(readSelector, serializedSelector, "serialization should be sound");
|
|
else
|
|
assert_equals(readSelector, serializedSelector, "serialization should be canonical");
|
|
|
|
sheet.deleteRule(0);
|
|
assert_equals(cssRules.length, 0, "Sheet should have no rule");
|
|
sheet.insertRule(readSelector + "{}");
|
|
assert_equals(cssRules.length, 1, "Sheet should have 1 rule");
|
|
|
|
assert_equals(cssRules[0].selectorText, readSelector, "serialization should round-trip");
|
|
|
|
let supports = !options?.onlyWhenForgiving;
|
|
assert_equals(CSS.supports(`selector(${selector})`), supports, "CSS.supports() reports the expected value");
|
|
}, stringifiedSelector + " should be a valid selector");
|
|
}
|
|
|
|
function test_invalid_selector(selector) {
|
|
const stringifiedSelector = JSON.stringify(selector);
|
|
|
|
test(function(){
|
|
assert_throws_dom(
|
|
DOMException.SYNTAX_ERR,
|
|
() => document.querySelector(selector),
|
|
stringifiedSelector + " should throw in querySelector");
|
|
|
|
const style = document.createElement("style");
|
|
document.head.append(style);
|
|
const {sheet} = style;
|
|
document.head.removeChild(style);
|
|
|
|
assert_throws_dom(
|
|
DOMException.SYNTAX_ERR,
|
|
() => sheet.insertRule(selector + "{}"),
|
|
stringifiedSelector + " should throw in insertRule");
|
|
}, stringifiedSelector + " should be an invalid selector");
|
|
}
|
|
|
|
// serialized can be the expected serialization of rule, or an array of
|
|
// permitted serializations, or omitted if value should serialize as rule.
|
|
function test_valid_rule(rule, serialized) {
|
|
if (serialized === undefined)
|
|
serialized = rule;
|
|
|
|
test(function(){
|
|
const style = document.createElement("style");
|
|
document.head.append(style);
|
|
const {sheet} = style;
|
|
document.head.removeChild(style);
|
|
const {cssRules} = sheet;
|
|
|
|
assert_equals(cssRules.length, 0, "Sheet should have no rules");
|
|
sheet.insertRule(rule);
|
|
assert_equals(cssRules.length, 1, "Sheet should have 1 rule");
|
|
|
|
const serialization = cssRules[0].cssText;
|
|
if (Array.isArray(serialized))
|
|
assert_in_array(serialization, serialized, "serialization should be sound");
|
|
else
|
|
assert_equals(serialization, serialized, "serialization should be canonical");
|
|
|
|
sheet.deleteRule(0);
|
|
assert_equals(cssRules.length, 0, "Sheet should have no rule");
|
|
sheet.insertRule(serialization);
|
|
assert_equals(cssRules.length, 1, "Sheet should have 1 rule");
|
|
|
|
assert_equals(cssRules[0].cssText, serialization, "serialization should round-trip");
|
|
}, rule + " should be a valid rule");
|
|
}
|
|
|
|
function test_invalid_rule(rule) {
|
|
test(function(){
|
|
const style = document.createElement("style");
|
|
document.head.append(style);
|
|
const {sheet} = style;
|
|
document.head.removeChild(style);
|
|
|
|
assert_throws_dom(
|
|
DOMException.SYNTAX_ERR,
|
|
() => sheet.insertRule(rule),
|
|
rule + " should throw in insertRule");
|
|
}, rule + " should be an invalid rule");
|
|
}
|
|
|
|
function _set_style(rule) {
|
|
const style = document.createElement('style');
|
|
style.innerText = rule;
|
|
document.head.append(style);
|
|
const { sheet } = style;
|
|
document.head.removeChild(style);
|
|
return sheet;
|
|
}
|
|
|
|
function test_keyframes_name_valid(keyframes_name) {
|
|
test(t => {
|
|
const sheet = _set_style(`@keyframes ${keyframes_name} {}`);
|
|
assert_equals(sheet.cssRules.length, 1);
|
|
}, `valid: @keyframes ${keyframes_name} { }`);
|
|
}
|
|
|
|
function test_keyframes_name_invalid(keyframes_name) {
|
|
test(t => {
|
|
const sheet = _set_style(`@keyframes ${keyframes_name} {}`);
|
|
assert_equals(sheet.cssRules.length, 0);
|
|
}, `invalid: @keyframes ${keyframes_name} { }`);
|
|
}
|