Tests: Import some custom-property tests

To make it easier to track progress and regressions in subsequent
changes.
This commit is contained in:
Sam Atkins 2025-07-01 11:43:24 +01:00 committed by Tim Ledbetter
commit 59f2c8df7a
Notes: github-actions[bot] 2025-07-09 15:46:45 +00:00
6 changed files with 844 additions and 0 deletions

View file

@ -0,0 +1,14 @@
Harness status: OK
Found 8 tests
3 Pass
5 Fail
Pass e.style['width'] = "var(--x)" should set the property value
Pass e.style['width'] = "var(--x,)" should set the property value
Pass e.style['width'] = "var(--x, )" should set the property value
Fail e.style['width'] = "var(--x ())" should not set the property value
Fail e.style['width'] = "var(--x () )" should not set the property value
Fail e.style['width'] = "var(--x() )" should not set the property value
Fail e.style['width'] = "var(--x (),)" should not set the property value
Fail e.style['width'] = "var(--x(),)" should not set the property value

View file

@ -0,0 +1,36 @@
Harness status: OK
Found 30 tests
2 Pass
28 Fail
Pass `initial` as a value for an unregistered custom property
Fail `inherit` as a value for an unregistered custom property
Fail `unset` as a value for an unregistered custom property
Fail `revert` as a value for an unregistered custom property
Fail `revert-layer` as a value for an unregistered custom property
Fail `initial` as a value for a non-inheriting registered custom property
Fail `initial` as a value for an inheriting registered custom property
Fail `inherit` as a value for a non-inheriting registered custom property
Fail `inherit` as a value for an inheriting registered custom property
Fail `unset` as a value for a non-inheriting registered custom property
Fail `unset` as a value for an inheriting registered custom property
Fail `revert` as a value for a non-inheriting registered custom property
Fail `revert` as a value for an inheriting registered custom property
Fail `revert-layer` as a value for a non-inheriting registered custom property
Fail `revert-layer` as a value for an inheriting registered custom property
Pass `initial` as a `var()` fallback for an unregistered custom property
Fail `inherit` as a `var()` fallback for an unregistered custom property
Fail `unset` as a `var()` fallback for an unregistered custom property
Fail `revert` as a `var()` fallback for an unregistered custom property
Fail `revert-layer` as a `var()` fallback for an unregistered custom property
Fail `initial` as a `var()` fallback for a non-inheriting registered custom property
Fail `initial` as a `var()` fallback for an inheriting registered custom property
Fail `inherit` as a `var()` fallback for a non-inheriting registered custom property
Fail `inherit` as a `var()` fallback for an inheriting registered custom property
Fail `unset` as a `var()` fallback for a non-inheriting registered custom property
Fail `unset` as a `var()` fallback for an inheriting registered custom property
Fail `revert` as a `var()` fallback for a non-inheriting registered custom property
Fail `revert` as a `var()` fallback for an inheriting registered custom property
Fail `revert-layer` as a `var()` fallback for a non-inheriting registered custom property
Fail `revert-layer` as a `var()` fallback for an inheriting registered custom property

View file

@ -0,0 +1,17 @@
Harness status: OK
Found 11 tests
1 Pass
10 Fail
Fail Self-cycle
Fail Simple a/b cycle
Fail Three-var cycle
Fail Cycle that starts in the middle of a chain
Fail Cycle with extra edge
Fail Cycle with extra edge (2)
Fail Cycle with extra edge (3)
Fail Cycle with secondary cycle
Fail Cycle with overlapping secondary cycle
Fail Cycle with deeper secondary cycle
Pass Cycle in unused fallback

View file

@ -0,0 +1,21 @@
<!DOCTYPE html>
<title>CSS Custom Properties: var() parsing</title>
<link rel="help" href="https://drafts.csswg.org/css-variables">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="../../css/support/parsing-testcommon.js"></script>
<div id="target"></div>
<script>
test_valid_value('width', 'var(--x)');
test_valid_value('width', 'var(--x,)');
test_valid_value('width', 'var(--x, )');
test_invalid_value('width', 'var(--x ())');
test_invalid_value('width', 'var(--x () )');
test_invalid_value('width', 'var(--x() )');
test_invalid_value('width', 'var(--x (),)');
test_invalid_value('width', 'var(--x(),)');
</script>

View file

@ -0,0 +1,331 @@
<!DOCTYPE html>
<head>
<title>CSS Custom Properties: Using CSS-wide keywords</title>
<link rel="help" href="https://drafts.csswg.org/css-variables/#defining-variables">
<meta name="assert" content="The CSS-wide keywords can be used in custom properties, with the same meaning as in any another property." />
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<style>
body {
--is-initial: initial;
--should-not-inherit: tomato;
--should-inherit: lightgreen;
--registered-inherits-should-not-inherit: tomato;
--registered-should-not-inherit: tomato;
--registered-inherits-should-inherit: lightgreen;
--registered-should-inherit: lightgreen;
--registered-should-revert: tomato;
--registered-inherits-should-revert: tomato;
}
@property --registered-inherits-should-not-inherit {
syntax: '<color>';
initial-value: lightgreen;
inherits: true;
}
@property --registered-should-not-inherit {
syntax: '<color>';
initial-value: lightgreen;
inherits: false;
}
@property --registered-inherits-should-inherit {
syntax: '<color>';
initial-value: tomato;
inherits: true;
}
@property --registered-should-inherit {
syntax: '<color>';
initial-value: tomato;
inherits: false;
}
@property --registered-should-revert {
syntax: '<color>';
initial-value: orange;
inherits: false;
}
@property --registered-inherits-should-revert {
syntax: '<color>';
initial-value: orange;
inherits: true;
}
</style>
<!-- Tests for values of unregistered custom properties -->
<div class="test" style="
background: var(--should-not-inherit, lightgreen);
--should-not-inherit: initial;
">
`initial` as a value for an unregistered custom property
</div>
<div class="test" style="
background: var(--should-inherit, tomato);
--should-inherit: inherit;
">
`inherit` as a value for an unregistered custom property
</div>
<div class="test" style="
background: var(--should-inherit, tomato);
--should-inherit: unset;
">
`unset` as a value for an unregistered custom property
</div>
<div class="test" style="
background: var(--should-inherit, tomato);
--should-inherit: revert;
">
`revert` as a value for an unregistered custom property
</div>
<style>
#regular-revert-layer {
@layer {
--should-not-inherit: lightgreen;
}
@layer {
--should-not-inherit: revert-layer;
}
}
</style>
<div class="test" id="regular-revert-layer" style="
background: var(--should-not-inherit);
">
`revert-layer` as a value for an unregistered custom property
</div>
<!-- Tests for values of registered custom properties -->
<div class="test" style="
background: var(--registered-should-not-inherit);
--registered-should-not-inherit: initial;
">
`initial` as a value for a non-inheriting registered custom property
</div>
<div class="test" style="
background: var(--registered-inherits-should-not-inherit);
--registered-inherits-should-not-inherit: initial;
">
`initial` as a value for an inheriting registered custom property
</div>
<div class="test" style="
background: var(--registered-should-inherit);
--registered-should-inherit: inherit;
">
`inherit` as a value for a non-inheriting registered custom property
</div>
<div class="test" style="
background: var(--registered-inherits-should-inherit);
--registered-inherits-should-inherit: inherit;
">
`inherit` as a value for an inheriting registered custom property
</div>
<div class="test" style="
background: var(--registered-should-not-inherit);
--registered-should-not-inherit: unset;
">
`unset` as a value for a non-inheriting registered custom property
</div>
<div class="test" style="
background: var(--registered-inherits-should-inherit);
--registered-inherits-should-inherit: unset;
">
`unset` as a value for an inheriting registered custom property
</div>
<div class="test" style="
background: var(--registered-should-not-inherit);
--registered-should-not-inherit: revert;
">
`revert` as a value for a non-inheriting registered custom property
</div>
<div class="test" style="
background: var(--registered-inherits-should-inherit);
--registered-inherits-should-inherit: revert;
">
`revert` as a value for an inheriting registered custom property
</div>
<style>
#registered-revert-layer {
@layer {
--registered-should-revert: lightgreen;
}
@layer {
--registered-should-revert: revert-layer;
}
}
</style>
<div class="test" id="registered-revert-layer" style="
background: var(--registered-should-revert);
">
`revert-layer` as a value for a non-inheriting registered custom property
</div>
<style>
#registered-revert-layer-inherits {
@layer {
--registered-inherits-should-revert: lightgreen;
}
@layer {
--registered-inherits-should-revert: revert-layer;
}
}
</style>
<div class="test" id="registered-revert-layer-inherits" style="
background: var(--registered-inherits-should-revert);
">
`revert-layer` as a value for an inheriting registered custom property
</div>
<!-- Tests for `var()` fallbacks of unregistered custom properties -->
<div class="test" style="
background: var(--should-not-inherit, lightgreen);
--should-not-inherit: var(--is-initial, initial);
">
`initial` as a `var()` fallback for an unregistered custom property
</div>
<div class="test" style="
background: var(--should-inherit, tomato);
--should-inherit: var(--is-initial, inherit);
">
`inherit` as a `var()` fallback for an unregistered custom property
</div>
<div class="test" style="
background: var(--should-inherit, tomato);
--should-inherit: var(--is-initial, unset);
">
`unset` as a `var()` fallback for an unregistered custom property
</div>
<div class="test" style="
background: var(--should-inherit, tomato);
--should-inherit: var(--is-initial, unset);
">
`revert` as a `var()` fallback for an unregistered custom property
</div>
<style>
#regular-fallback-revert-layer {
@layer {
--should-not-inherit: lightgreen;
}
@layer {
--should-not-inherit: var(--is-initial, revert-layer);
}
}
</style>
<div class="test" id="regular-fallback-revert-layer" style="
background: var(--should-not-inherit);
">
`revert-layer` as a `var()` fallback for an unregistered custom property
</div>
<!-- Tests for `var()` fallbacks of registered custom properties -->
<div class="test" style="
background: var(--registered-should-not-inherit);
--registered-should-not-inherit: var(--is-initial, initial);
">
`initial` as a `var()` fallback for a non-inheriting registered custom property
</div>
<div class="test" style="
background: var(--registered-inherits-should-not-inherit);
--registered-inherits-should-not-inherit: var(--is-initial, initial);
">
`initial` as a `var()` fallback for an inheriting registered custom property
</div>
<div class="test" style="
background: var(--registered-should-inherit);
--registered-should-inherit: var(--is-initial, inherit);
">
`inherit` as a `var()` fallback for a non-inheriting registered custom property
</div>
<div class="test" style="
background: var(--registered-inherits-should-inherit);
--registered-inherits-should-inherit: var(--is-initial, inherit);
">
`inherit` as a `var()` fallback for an inheriting registered custom property
</div>
<div class="test" style="
background: var(--registered-should-not-inherit);
--registered-should-not-inherit: var(--is-initial, unset);
">
`unset` as a `var()` fallback for a non-inheriting registered custom property
</div>
<div class="test" style="
background: var(--registered-inherits-should-inherit);
--registered-inherits-should-inherit: var(--is-initial, unset);
">
`unset` as a `var()` fallback for an inheriting registered custom property
</div>
<div class="test" style="
background: var(--registered-should-not-inherit);
--registered-should-not-inherit: var(--is-initial, revert);
">
`revert` as a `var()` fallback for a non-inheriting registered custom property
</div>
<div class="test" style="
background: var(--registered-inherits-should-inherit);
--registered-inherits-should-inherit: var(--is-initial, revert);
">
`revert` as a `var()` fallback for an inheriting registered custom property
</div>
<style>
#registered-fallback-revert-layer {
@layer {
--registered-should-revert: lightgreen;
}
@layer {
--registered-should-revert: var(--is-initial, revert-layer);
}
}
</style>
<div class="test" id="registered-fallback-revert-layer" style="
background: var(--registered-should-revert);
">
`revert-layer` as a `var()` fallback for a non-inheriting registered custom property
</div>
<style>
#registered-fallback-revert-layer-inherits {
@layer {
--registered-inherits-should-revert: lightgreen;
}
@layer {
--registered-inherits-should-revert: var(--is-initial, revert-layer);
}
}
</style>
<div class="test" id="registered-fallback-revert-layer-inherits" style="
background: var(--registered-inherits-should-revert);
">
`revert-layer` as a `var()` fallback for an inheriting registered custom property
</div>
<pre id="out"></pre>
<script>
[...document.querySelectorAll('.test')].map(el => test(() => assert_equals(getComputedStyle(el).getPropertyValue('background-color'), 'rgb(144, 238, 144)'), el.textContent.trim()));
</script>

View file

@ -0,0 +1,425 @@
<!DOCTYPE html>
<meta charset="utf8">
<title>Test that custom property cycles behave correctly</title>
<link rel="help" href="https://drafts.csswg.org/css-variables/#cycles">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<main id=main></main>
<script>
// Test that, for the given list of |declarations|, the computed values
// of properties listed in |expected_invalid| are invalid (i.e. empty string),
// and the computed values listed in |expected_valid| are *not* invalid
// (i.e. not the empty string).
function test_cycles(declarations, expected_invalid, expected_valid, description) {
test(() => {
let element = document.createElement('div');
try {
declarations.push('--sanity:valid');
element.style = declarations.join(';');
main.append(element);
let cs = getComputedStyle(element);
for (let e of expected_invalid)
assert_equals(cs.getPropertyValue(e), '', `${e}`);
for (let e of expected_valid)
assert_not_equals(cs.getPropertyValue(e), '', `${e}`);
assert_equals(cs.getPropertyValue('--sanity'), 'valid', '--sanity');
} finally {
element.remove();
}
}, description);
}
// (Diagrams produced with graph-easy).
// ┌───┐
// │ │ ───┐
// │ a │ │
// │ │ ◀──┘
// └───┘
test_cycles(
['--a:var(--a)'],
['--a'],
[],
'Self-cycle');
// ┌───┐
// │ a │ ◀┐
// └───┘ │
// │ │
// │ │
// ▼ │
// ┌───┐ │
// │ b │ ─┘
// └───┘
test_cycles(
[
'--a:var(--b)',
'--b:var(--a)',
],
['--a', '--b'],
[],
'Simple a/b cycle');
// ┌───┐
// │ a │ ◀┐
// └───┘ │
// │ │
// │ │
// ▼ │
// ┌───┐ │
// │ b │ │
// └───┘ │
// │ │
// │ │
// ▼ │
// ┌───┐ │
// │ c │ ─┘
// └───┘
test_cycles(
[
'--a:var(--b, cycle)',
'--b:var(--c, cycle)',
'--c:var(--a, cycle)',
],
['--a', '--b', '--c'],
[],
'Three-var cycle');
// ┌───┐
// │ x │
// └───┘
// │
// │
// ▼
// ┌───┐
// │ y │
// └───┘
// │
// │
// ▼
// ┌───┐
// │ a │ ◀┐
// └───┘ │
// │ │
// │ │
// ▼ │
// ┌───┐ │
// │ b │ │
// └───┘ │
// │ │
// │ │
// ▼ │
// ┌───┐ │
// │ c │ ─┘
// └───┘
test_cycles(
[
'--x:var(--y, valid)',
'--y:var(--a, valid)',
'--a:var(--b, cycle)',
'--b:var(--c, cycle)',
'--c:var(--a, cycle)',
],
['--a', '--b', '--c'],
['--x', '--y'],
'Cycle that starts in the middle of a chain');
// ┌───┐
// │ x │
// └───┘
// │
// │
// ▼
// ┌───┐
// │ a │ ◀┐
// └───┘ │
// │ │
// │ │
// ▼ │
// ┌───┐ │
// │ b │ │
// └───┘ │
// │ │
// │ │
// ▼ │
// ┌───┐ │
// │ c │ ─┘
// └───┘
// │
// │
// ▼
// ┌───┐
// │ y │
// └───┘
test_cycles(
[
'--x:var(--a, valid)',
'--a:var(--b, cycle)',
'--b:var(--c, cycle)',
'--c:var(--a, cycle) var(--y)',
'--y:valid'
],
['--a', '--b', '--c'],
['--x', '--y'],
'Cycle with extra edge');
// ┌───┐
// │ x │
// └───┘
// │
// │
// ▼
// ┌───┐
// │ a │ ◀┐
// └───┘ │
// │ │
// │ │
// ▼ │
// ┌───┐ ┌───┐ │
// │ y │ ◀── │ b │ │
// └───┘ └───┘ │
// │ │
// │ │
// ▼ │
// ┌───┐ │
// │ c │ ─┘
// └───┘
test_cycles(
[
'--x:var(--a, valid)',
'--a:var(--b, cycle)',
'--b:var(--c, cycle) var(--y)',
'--c:var(--a, cycle)',
'--y:valid'
],
['--a', '--b', '--c'],
['--x', '--y'],
'Cycle with extra edge (2)');
// ┌───┐
// │ x │
// └───┘
// │
// │
// ▼
// ┌───┐
// │ a │ ◀┐
// └───┘ │
// │ │
// │ │
// ▼ │
// ┌───┐ │
// │ b │ │
// └───┘ │
// │ │
// │ │
// ▼ │
// ┌───┐ │
// │ c │ ─┘
// └───┘
// │
// │
// ▼
// ┌───┐
// │ y │
// └───┘
// │
// │
// ▼
// ┌───┐
// │ z │
// └───┘
test_cycles(
[
'--x:var(--a, valid)',
'--a:var(--b, cycle)',
'--b:var(--c, cycle)',
'--c:var(--a, cycle) var(--y)',
'--y:var(--z)',
'--z:valid'
],
['--a', '--b', '--c'],
['--x', '--y', '--z'],
'Cycle with extra edge (3)');
// ┌───┐
// │ x │
// └───┘
// │
// │
// ▼
// ┌───┐
// │ a │ ◀┐
// └───┘ │
// │ │
// │ │
// ▼ │
// ┌───┐ │
// ┌▶ │ b │ ─┘
// │ └───┘
// │ │
// │ │
// │ ▼
// │ ┌───┐
// │ │ c │
// │ └───┘
// │ │
// │ │
// │ ▼
// │ ┌───┐
// └─ │ d │
// └───┘
test_cycles(
[
'--x:var(--a, valid)',
'--a:var(--b, cycle)',
'--b:var(--c, cycle) var(--a, cycle)',
'--c:var(--d, cycle)',
'--d:var(--b, cycle)',
],
['--a', '--b', '--c', '--d'],
['--x'],
'Cycle with secondary cycle');
// ┌───┐
// │ x │
// └───┘
// │
// │
// ▼
// ┌───┐
// │ a │ ◀┐
// └───┘ │
// │ │
// │ │
// ▼ │
// ┌───┐ │
// ┌▶ │ b │ │
// │ └───┘ │
// │ │ │
// │ │ │
// │ ▼ │
// │ ┌───┐ │
// │ │ c │ ─┘
// │ └───┘
// │ │
// │ │
// │ ▼
// │ ┌───┐
// └─ │ d │
// └───┘
// │
// │
// ▼
// ┌───┐
// │ y │
// └───┘
test_cycles(
[
'--x:var(--a, valid)',
'--a:var(--b, cycle)',
'--b:var(--c, cycle)',
'--c:var(--d, cycle) var(--a, cycle)',
'--d:var(--b, cycle) var(--y)',
'--y:valid'
],
['--a', '--b', '--c', '--d'],
['--x', '--y'],
'Cycle with overlapping secondary cycle');
// ┌──────────────┐
// │ │
// │ ┌───┐ │
// │ │ x │ │
// │ └───┘ │
// │ │ │
// │ │ │
// │ ▼ ▼
// ┌───┐ ┌────────┐ ┌───┐
// │ b │ ◀── │ a │ ──▶ │ y │
// └───┘ └────────┘ └───┘
// │ ▲
// │ │
// ▼ │
// ┌───┐ │
// │ c │ │
// └───┘ │
// │ │
// │ │
// ▼ │
// ┌───┐ │
// │ d │ ─┘
// └───┘
test_cycles(
[
'--x:var(--a, valid)',
'--a:var(--b, cycle) var(--y, valid) var(--c, cycle)',
'--b:var(--a, cycle) ',
'--c:var(--d, cycle)',
'--d:var(--a, cycle)',
'--y:valid',
],
['--a', '--b', '--c', '--d'],
['--x', '--y'],
'Cycle with deeper secondary cycle');
// If we cared about cycles in unused fallbacks,
// then --a/--b/--c would be in a cycle in this case:
//
// ┌───┐
// │ x │
// └───┘
// │
// │
// ▼
// ┌───┐
// ┌─────▶ │ a │ ─┐
// │ └───┘ │
// │ │ │
// │ │ │
// │ ▼ │
// │ ┌───┐ │
// │ ┌─ │ b │ │
// │ │ └───┘ │
// │ │ │ │
// │ │ │ │
// │ │ ▼ │
// │ │ ┌───┐ │
// └────┼─ │ c │ │
// │ └───┘ │
// │ │ │
// │ │ │
// │ ▼ │
// │ ┌───┐ │
// └▶ │ y │ ◀┘
// └───┘
//
// However, as of https://github.com/w3c/csswg-drafts/issues/11500,
// we no longer care about such cycles.
test_cycles(
[
'--x:var(--a, valid)',
'--a:var(--y, var(--b, cycle))',
'--b:var(--y, var(--c, cycle))',
'--c:var(--y, var(--a, cycle))',
'--y:valid'
],
[], // Nothing is invalid.
['--a', '--b', '--c', '--x', '--y'],
'Cycle in unused fallback');
</script>