Bug 1452132 [wpt PR 9983] - Upstream registerProperty tests to WPT, a=testonly
authorChris Nardi <cnardi@chromium.org>
Mon, 09 Apr 2018 16:32:59 +0000
changeset 413477 eb4bb4149faf48c23a6770f241a706a24f802c52
parent 413476 efe7fae9f43f1c2ad25842b0cdf73ae75eccebba
child 413478 e64205aeff2efb2c164d4936d145324771a43d5a
push id33850
push userapavel@mozilla.com
push dateMon, 16 Apr 2018 09:53:48 +0000
treeherdermozilla-central@6276ec7ebbf3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstestonly
bugs1452132, 641877, 959422, 542649
milestone61.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1452132 [wpt PR 9983] - Upstream registerProperty tests to WPT, a=testonly Automatic update from web-platform-testsUpstream registerProperty tests to WPT Many tests of CSS.registerProperty were written, but none have been upstreamed to WPT. Upstream these tests to ensure interoperability. Bug: 641877 Change-Id: I8272b14c78cb75bb6f5f3cedb770091cbcba522a Reviewed-on: https://chromium-review.googlesource.com/959422 Reviewed-by: Robert Ma <robertma@chromium.org> Reviewed-by: Ian Kilpatrick <ikilpatrick@chromium.org> Commit-Queue: Chris Nardi <cnardi@chromium.org> Cr-Commit-Position: refs/heads/master@{#542649} wpt-commits: 28300a0874230d668f0b02cfddfd994f2a735a56 wpt-pr: 9983 wpt-commits: 28300a0874230d668f0b02cfddfd994f2a735a56 wpt-pr: 9983
testing/web-platform/meta/MANIFEST.json
testing/web-platform/tests/css/css-properties-values-api/register-property-syntax-parsing.html
testing/web-platform/tests/css/css-properties-values-api/register-property.html
testing/web-platform/tests/css/css-properties-values-api/registered-properties-inheritance.html
testing/web-platform/tests/css/css-properties-values-api/registered-property-computation.html
testing/web-platform/tests/css/css-properties-values-api/registered-property-cssom.html
testing/web-platform/tests/css/css-properties-values-api/registered-property-initial.html
testing/web-platform/tests/css/css-properties-values-api/var-reference-registered-properties-cycles.html
testing/web-platform/tests/css/css-properties-values-api/var-reference-registered-properties.html
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -314035,16 +314035,64 @@
     ]
    ],
    "css/css-position/position-sticky-transforms.html": [
     [
      "/css/css-position/position-sticky-transforms.html",
      {}
     ]
    ],
+   "css/css-properties-values-api/register-property-syntax-parsing.html": [
+    [
+     "/css/css-properties-values-api/register-property-syntax-parsing.html",
+     {}
+    ]
+   ],
+   "css/css-properties-values-api/register-property.html": [
+    [
+     "/css/css-properties-values-api/register-property.html",
+     {}
+    ]
+   ],
+   "css/css-properties-values-api/registered-properties-inheritance.html": [
+    [
+     "/css/css-properties-values-api/registered-properties-inheritance.html",
+     {}
+    ]
+   ],
+   "css/css-properties-values-api/registered-property-computation.html": [
+    [
+     "/css/css-properties-values-api/registered-property-computation.html",
+     {}
+    ]
+   ],
+   "css/css-properties-values-api/registered-property-cssom.html": [
+    [
+     "/css/css-properties-values-api/registered-property-cssom.html",
+     {}
+    ]
+   ],
+   "css/css-properties-values-api/registered-property-initial.html": [
+    [
+     "/css/css-properties-values-api/registered-property-initial.html",
+     {}
+    ]
+   ],
+   "css/css-properties-values-api/var-reference-registered-properties-cycles.html": [
+    [
+     "/css/css-properties-values-api/var-reference-registered-properties-cycles.html",
+     {}
+    ]
+   ],
+   "css/css-properties-values-api/var-reference-registered-properties.html": [
+    [
+     "/css/css-properties-values-api/var-reference-registered-properties.html",
+     {}
+    ]
+   ],
    "css/css-pseudo/first-letter-property-whitelist.html": [
     [
      "/css/css-pseudo/first-letter-property-whitelist.html",
      {}
     ]
    ],
    "css/css-regions/cssomview-apis-no-region-chain-001.html": [
     [
@@ -505076,16 +505124,48 @@
   "css/css-position/position-sticky-writing-modes.html": [
    "b6d16a38b73d4c107e587194818a542fee9d0716",
    "reftest"
   ],
   "css/css-position/resources/sticky-util.js": [
    "c7b441a3a07276cad9528dd3ef7d82844d06e2d8",
    "support"
   ],
+  "css/css-properties-values-api/register-property-syntax-parsing.html": [
+   "b065f4840b3c1deb4a2f8a59428e102f2ae11686",
+   "testharness"
+  ],
+  "css/css-properties-values-api/register-property.html": [
+   "df61ce5dd13847deaa9b7165dd1277c1ddefb646",
+   "testharness"
+  ],
+  "css/css-properties-values-api/registered-properties-inheritance.html": [
+   "131676bfa0733a64b679473b411ef651a9df1ab0",
+   "testharness"
+  ],
+  "css/css-properties-values-api/registered-property-computation.html": [
+   "875acfd6e6446e4cb14fcd19fe16e83630b5fe31",
+   "testharness"
+  ],
+  "css/css-properties-values-api/registered-property-cssom.html": [
+   "0fecf81c4089cb67107a9339ee52cd2c44cde60b",
+   "testharness"
+  ],
+  "css/css-properties-values-api/registered-property-initial.html": [
+   "fc0b90f23ea8c8dab20baa3fecdd7d60863527b6",
+   "testharness"
+  ],
+  "css/css-properties-values-api/var-reference-registered-properties-cycles.html": [
+   "bc061780caa0085fca5b003c1aed68c7b162eabd",
+   "testharness"
+  ],
+  "css/css-properties-values-api/var-reference-registered-properties.html": [
+   "988badd19fd1880446db9827e3d96cb4961732a0",
+   "testharness"
+  ],
   "css/css-pseudo/OWNERS": [
    "e196548942a4d77448f734235b3456e2a830a5a7",
    "support"
   ],
   "css/css-pseudo/first-letter-001-ref.html": [
    "f53ee70c3b61a9f812a9a44afb1364040563f473",
    "support"
   ],
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-properties-values-api/register-property-syntax-parsing.html
@@ -0,0 +1,163 @@
+<!DOCTYPE HTML>
+<link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api/#dom-css-registerproperty" />
+<link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api/#supported-syntax-strings" />
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+test_count = 0;
+
+function assert_valid(syntax, initialValue) {
+    // No actual assertions, this just shouldn't throw
+    test(function() {
+        var name = '--syntax-test-' + (test_count++);
+        CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue});
+    }, "syntax:'" + syntax + "', initialValue:'" + initialValue + "' is valid");
+}
+
+function assert_invalid(syntax, initialValue) {
+    test(function(){
+        var name = '--syntax-test-' + (test_count++);
+        assert_throws(new SyntaxError(),
+            () => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue}));
+    }, "syntax:'" + syntax + "', initialValue:'" + initialValue + "' is invalid");
+}
+
+assert_valid("*", "a");
+assert_valid(" * ", "b");
+assert_valid("<length>", "2px");
+assert_valid(" <number>", "5");
+assert_valid("<percentage> ", "10%");
+assert_valid("<color>+", "red");
+assert_valid(" <length>+ | <percentage>", "2px 8px");
+assert_valid("<length>|<percentage>|<length-percentage>", "2px"); // Valid but silly
+assert_valid("<color> | <image> | <url> | <integer> | <angle>", "red");
+assert_valid("<time> | <resolution> | <transform-list> | <custom-ident>", "red");
+
+assert_valid("*", ":> hello");
+assert_valid("*", "([ brackets ]) { yay (??)}");
+assert_valid("*", "yep 'this is valid too'");
+assert_valid("*", "unmatched opening bracket is valid :(");
+assert_valid("*", '"');
+
+assert_valid("<length>", "0");
+assert_valid("<length>", "10px /*:)*/");
+assert_valid("<length>", " calc(-2px)");
+assert_valid("<length>", "calc(2px*4 + 10px)");
+assert_valid("<length>", "7.1e-4cm");
+assert_valid("<length>", "calc(7in - 12px)");
+assert_valid("<length>+", "2px 7px calc(8px)");
+assert_valid("<percentage>", "-9.3e3%");
+assert_valid("<length-percentage>", "-54%");
+assert_valid("<length-percentage>", "0");
+assert_valid("<length-percentage>", "calc(-11px + 10.4%)");
+
+assert_valid("<number>", "-109");
+assert_valid("<number>", "2.3e4");
+assert_valid("<integer>", "-109");
+assert_valid("<integer>", "19");
+
+assert_valid("<angle>", "10deg");
+assert_valid("<angle>", "20.5rad");
+assert_valid("<angle>", "calc(50grad + 3.14159rad)");
+assert_valid("<time>", "2s");
+assert_valid("<time>", "calc(2s - 9ms)");
+assert_valid("<resolution>", "10dpi");
+assert_valid("<resolution>", "3dPpX");
+assert_valid("<resolution>", "-5.3dpcm");
+assert_valid("<transform-list>", "scale(2)");
+assert_valid("<transform-list>", "translateX(2px) rotate(20deg)");
+
+assert_valid("<color>", "rgb(12, 34, 56)");
+assert_valid("<color>", "lightgoldenrodyellow");
+assert_valid("<image>", "url(a)");
+assert_valid("<image>", "linear-gradient(yellow, blue)");
+assert_valid("<url>", "url(a)");
+
+assert_valid("banana", "banana");
+assert_valid("bAnAnA", "bAnAnA");
+assert_valid("ba-na-nya", "ba-na-nya");
+assert_valid("banana", "banan\\61");
+assert_valid("<custom-ident>", "banan\\61");
+assert_valid("big | bigger | BIGGER", "bigger");
+assert_valid("foo+|bar", "foo foo foo");
+assert_valid("default", "default");
+
+assert_valid("banana\t", "banana");
+assert_valid("\nbanana\r\n", "banana");
+assert_valid("ba\f\n|\tna\r|nya", "nya");
+
+assert_valid(null, "null");
+assert_valid(undefined, "undefined");
+assert_valid(["array"], "array");
+
+// Invalid syntax
+assert_invalid("banana,nya", "banana");
+assert_invalid("banan\\61", "banana");
+assert_invalid("<\\6c ength>", "10px");
+assert_invalid("<banana>", "banana");
+assert_invalid("<Number>", "10");
+assert_invalid("<length", "10px");
+assert_invalid("<LENGTH>", "10px");
+assert_invalid("< length>", "10px");
+assert_invalid("<length >", "10px");
+assert_invalid("<length> +", "10px");
+
+assert_invalid("<length>++", "10px");
+assert_invalid("<length> | *", "10px");
+assert_invalid("*|banana", "banana");
+assert_invalid("*+", "banana");
+
+assert_invalid("initial", "initial");
+assert_invalid("inherit", "inherit");
+assert_invalid("unset", "unset");
+assert_invalid("<length>|initial", "10px");
+assert_invalid("<length>|INHERIT", "10px");
+assert_invalid("<percentage>|unsEt", "2%");
+
+// Invalid initialValue
+assert_invalid("*", "initial");
+assert_invalid("*", "inherit");
+assert_invalid("*", "unset");
+assert_invalid("*", "revert");
+assert_invalid("<custom-ident>", "initial");
+assert_invalid("<custom-ident>+", "foo inherit bar");
+
+assert_invalid("*", ")");
+assert_invalid("*", "([)]");
+assert_invalid("*", "whee!");
+assert_invalid("*", '"\n');
+assert_invalid("*", "url(moo '')");
+assert_invalid("*", "semi;colon");
+assert_invalid("*", "var(invalid var ref)");
+assert_invalid("*", "var(--foo)");
+
+assert_invalid("banana", "bAnAnA");
+assert_invalid("<length>", "var(--moo)");
+assert_invalid("<length>", "10");
+assert_invalid("<length>", "10%");
+assert_invalid("<length>", "calc(5px + 10%)");
+assert_invalid("<length>", "calc(5px * 3px / 6px)");
+assert_invalid("<length>", "10em");
+assert_invalid("<length>", "10vmin");
+assert_invalid("<length>", "calc(4px + 3em)");
+assert_invalid("<length>", "calc(4px + calc(8 * 2em))");
+assert_invalid("<length>+", "calc(2ex + 16px)");
+assert_invalid("<length>+", "10px calc(20px + 4rem)");
+assert_invalid("<percentage> | <length>+", "calc(100vh - 10px) 30px");
+assert_invalid("<length>", "10px;");
+assert_invalid("<length-percentage>", "calc(2px + 10% + 7ex)");
+assert_invalid("<percentage>", "0");
+assert_invalid("<integer>", "1.0");
+assert_invalid("<integer>", "1e0");
+assert_invalid("<number>|foo", "foo var(--foo, bla)");
+
+assert_invalid("<angle>", "0");
+assert_invalid("<angle>", "10%");
+assert_invalid("<time>", "2px");
+assert_invalid("<resolution>", "10");
+assert_invalid("<transform-list>", "scale()");
+assert_invalid("<transform-list>+", "translateX(2px) rotate(20deg)");
+assert_invalid("<color>", "fancy-looking");
+assert_invalid("<image>", "banana.png");
+assert_invalid("<url>", "banana.png");
+</script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-properties-values-api/register-property.html
@@ -0,0 +1,42 @@
+<!DOCTYPE HTML>
+<link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api/#register-a-custom-property" />
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+// Tests for error checking during property registration
+
+test(function() {
+    assert_throws(new TypeError(), () => CSS.registerProperty());
+    assert_throws(new TypeError(), () => CSS.registerProperty(undefined));
+    assert_throws(new TypeError(), () => CSS.registerProperty(true));
+    assert_throws(new TypeError(), () => CSS.registerProperty(2));
+    assert_throws(new TypeError(), () => CSS.registerProperty("css"));
+    assert_throws(new TypeError(), () => CSS.registerProperty(null));
+}, "registerProperty requires a Dictionary type");
+
+test(function() {
+    // Valid property names, shouldn't throw
+    CSS.registerProperty({name: '--name1'});
+    CSS.registerProperty({name: '--name2, no need for escapes'});
+    CSS.registerProperty({name: ['--name', 3]});
+
+    // Invalid property names
+    assert_throws(new TypeError(), () => CSS.registerProperty({}));
+    assert_throws(new SyntaxError(), () => CSS.registerProperty({name: 'no-leading-dash'}));
+    assert_throws(new SyntaxError(), () => CSS.registerProperty({name: ''}));
+    assert_throws(new SyntaxError(), () => CSS.registerProperty({name: '\\--name'}));
+}, "registerProperty requires a name matching <custom-property-name>");
+
+test(function() {
+    CSS.registerProperty({name: '--syntax-test-1', syntax: '*'});
+    CSS.registerProperty({name: '--syntax-test-2', syntax: ' * '});
+    assert_throws(new SyntaxError(),
+        () => CSS.registerProperty({name: '--syntax-test-3', syntax: 'length'}));
+}, "registerProperty only allows omitting initialValue is syntax is '*'");
+
+test(function() {
+    CSS.registerProperty({name: '--re-register', syntax: '<length>', initialValue: '0px'});
+    assert_throws({name: 'InvalidModificationError'},
+        () => CSS.registerProperty({name: '--re-register', syntax: '<percentage>', initialValue: '0%'}));
+}, "registerProperty fails for an already registered property");
+</script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-properties-values-api/registered-properties-inheritance.html
@@ -0,0 +1,47 @@
+<!DOCTYPE HTML>
+<link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api/#dom-propertydescriptor-inherits" />
+<link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api/#register-a-custom-property" />
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+#outer {
+    --inherited-length-1: 10px;
+    --inherited-length-2: var(--non-inherited-length-1);
+    --inherited-length-3: 30px;
+    --non-inherited-length-1: 22px;
+    --non-inherited-length-3: calc(var(--non-inherited-length-2) * 10);
+}
+
+#inner {
+    --inherited-length-3: 15px;
+    --non-inherited-length-1: 40px;
+    --non-inherited-length-2: 90px;
+}
+</style>
+<div id=outer><div id=inner></div></div>
+<script>
+CSS.registerProperty({name: '--inherited-length-1', syntax: '<length>', initialValue: '1px', inherits: true});
+CSS.registerProperty({name: '--inherited-length-2', syntax: '<length>', initialValue: '2px', inherits: true});
+CSS.registerProperty({name: '--inherited-length-3', syntax: '<length>', initialValue: '3px', inherits: true});
+CSS.registerProperty({name: '--non-inherited-length-1', syntax: '<length>', initialValue: '4px'});
+CSS.registerProperty({name: '--non-inherited-length-2', syntax: '<length>', initialValue: '5px'});
+CSS.registerProperty({name: '--non-inherited-length-3', syntax: '<length>', initialValue: '6px'});
+
+test(function() {
+    outerComputedStyle = getComputedStyle(outer);
+    assert_equals(outerComputedStyle.getPropertyValue('--inherited-length-1'), '10px');
+    assert_equals(outerComputedStyle.getPropertyValue('--inherited-length-2'), '22px');
+    assert_equals(outerComputedStyle.getPropertyValue('--inherited-length-3'), '30px');
+    assert_equals(outerComputedStyle.getPropertyValue('--non-inherited-length-1'), '22px');
+    assert_equals(outerComputedStyle.getPropertyValue('--non-inherited-length-2'), '5px');
+    assert_equals(outerComputedStyle.getPropertyValue('--non-inherited-length-3'), '50px');
+
+    innerComputedStyle = getComputedStyle(inner);
+    assert_equals(innerComputedStyle.getPropertyValue('--inherited-length-1'), '10px');
+    assert_equals(innerComputedStyle.getPropertyValue('--inherited-length-2'), '22px');
+    assert_equals(innerComputedStyle.getPropertyValue('--inherited-length-3'), '15px');
+    assert_equals(innerComputedStyle.getPropertyValue('--non-inherited-length-1'), '40px');
+    assert_equals(innerComputedStyle.getPropertyValue('--non-inherited-length-2'), '90px');
+    assert_equals(innerComputedStyle.getPropertyValue('--non-inherited-length-3'), '6px');
+}, "Registered properties are correctly inherited (or not) depending on the inherits flag.");
+</script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-properties-values-api/registered-property-computation.html
@@ -0,0 +1,88 @@
+<!DOCTYPE HTML>
+<link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api/#calculation-of-computed-values" />
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<style>
+#divWithFontSizeSet, #parentDiv {
+    font-size: 10px;
+}
+#divWithFontSizeSet, #divWithFontSizeInherited {
+    --length-1: 12px;
+    --length-2: 13vw;
+    --length-3: 14em;
+    --length-4: 15vmin;
+    --length-5: calc(16px - 7em + 10vh);
+    --length-6: var(--length-3);
+    --length-percentage-1: 17em;
+    --length-percentage-2: 18%;
+    --length-percentage-3: calc(19em - 2%);
+    --list-1: 10px 3em;
+    --list-2: 4em 9px;
+    --list-3: 3% 10vmax 22px;
+    --list-4: calc(50% + 1em) 4px;
+}
+#fontSizeCycle {
+    --font-size: 2em;
+    font-size: var(--font-size);
+}
+</style>
+
+<div id=divWithFontSizeSet></div>
+<div id=parentDiv>
+    <div id=divWithFontSizeInherited></div>
+    <div id=fontSizeCycle></div>
+</div>
+
+<script>
+CSS.registerProperty({name: '--length-1', syntax: '<length>', initialValue: '0px'});
+CSS.registerProperty({name: '--length-2', syntax: '<length>', initialValue: '0px'});
+CSS.registerProperty({name: '--length-3', syntax: '<length>', initialValue: '0px'});
+CSS.registerProperty({name: '--length-4', syntax: '<length>', initialValue: '0px'});
+CSS.registerProperty({name: '--length-5', syntax: '<length>', initialValue: '0px'});
+CSS.registerProperty({name: '--length-6', syntax: '<length>', initialValue: '0px'});
+CSS.registerProperty({name: '--length-percentage-1', syntax: '<length-percentage>', initialValue: '0px'});
+CSS.registerProperty({name: '--length-percentage-2', syntax: '<length-percentage>', initialValue: '0px'});
+CSS.registerProperty({name: '--length-percentage-3', syntax: '<length-percentage>', initialValue: '0px'});
+CSS.registerProperty({name: '--list-1', syntax: '<length>+', initialValue: '0px'});
+CSS.registerProperty({name: '--list-2', syntax: '<length>+', initialValue: '0px'});
+CSS.registerProperty({name: '--list-3', syntax: '<length-percentage>+', initialValue: '0px'});
+CSS.registerProperty({name: '--list-4', syntax: '<length-percentage>+', initialValue: '0px'});
+CSS.registerProperty({name: '--font-size', syntax: '<length>', initialValue: '0px'});
+
+for (var element of [divWithFontSizeSet, divWithFontSizeInherited]) {
+    var id = element.id;
+    var computedStyle = getComputedStyle(element);
+
+    test(function() {
+        assert_equals(computedStyle.getPropertyValue('--length-1'), '12px');
+        assert_equals(computedStyle.getPropertyValue('--length-2'), '104px');
+        assert_equals(computedStyle.getPropertyValue('--length-3'), '140px');
+        assert_equals(computedStyle.getPropertyValue('--length-4'), '90px');
+        assert_equals(computedStyle.getPropertyValue('--length-5'), '6px');
+        assert_equals(computedStyle.getPropertyValue('--length-6'), '140px');
+    }, "<length> values are computed correctly for " + id);
+
+    test(function() {
+        assert_equals(computedStyle.getPropertyValue('--length-percentage-1'), '170px');
+        assert_equals(computedStyle.getPropertyValue('--length-percentage-2'), '18%');
+        assert_equals(computedStyle.getPropertyValue('--length-percentage-3'), 'calc(190px + -2%)');
+    }, "<length-percentage> values are computed correctly for " + id);
+
+    test(function() {
+        assert_equals(computedStyle.getPropertyValue('--list-1'), '10px 30px');
+        assert_equals(computedStyle.getPropertyValue('--list-2'), '40px 9px');
+    }, "<length>+ values are computed correctly for " + id);
+
+    test(function() {
+        assert_equals(computedStyle.getPropertyValue('--list-3'), '3% 80px 22px');
+        assert_equals(computedStyle.getPropertyValue('--list-4'), 'calc(10px + 50%) 4px');
+    }, "<length-percentage>+ values are computed correctly for " + id);
+}
+
+test(function() {
+    var computedStyle = getComputedStyle(fontSizeCycle);
+    assert_equals(computedStyle.fontSize, '20px');
+    assert_equals(computedStyle.getPropertyValue('--font-size'), '40px');
+}, "font-size with a var() reference to a registered property using ems works as expected");
+</script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-properties-values-api/registered-property-cssom.html
@@ -0,0 +1,86 @@
+<!DOCTYPE HTML>
+<link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api/#dom-css-registerproperty" />
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<style>
+#inner {
+  --length: 10px;
+  --color: red;
+}
+#outer {
+  --length: 77px;
+  --color: blue;
+}
+</style>
+
+<div id=outer>
+  <div id=inner></div>
+</div>
+
+<script>
+var computedStyle = getComputedStyle(inner);
+var inlineStyle = inner.style;
+var sheetStyle = document.styleSheets[0].cssRules[0].style;
+
+test(function() {
+  // Nothing registered yet, whatever you specify works
+  assert_equals(computedStyle.getPropertyValue('--length'), ' 10px');
+  assert_equals(computedStyle.getPropertyValue('--color'), ' red');
+
+  inlineStyle.setProperty('--length', '5');
+  inlineStyle.setProperty('--color', 'hello');
+
+  assert_equals(inlineStyle.getPropertyValue('--length'), '5');
+  assert_equals(inlineStyle.getPropertyValue('--color'), 'hello');
+  assert_equals(computedStyle.getPropertyValue('--length'), '5');
+  assert_equals(computedStyle.getPropertyValue('--color'), 'hello');
+}, "CSSOM setters function as expected for unregistered properties");
+
+CSS.registerProperty({name: '--length', syntax: '<length>', initialValue: '0px'});
+CSS.registerProperty({name: '--color', syntax: '<color>', initialValue: 'white', inherits: true});
+
+test(function() {
+  assert_equals(inlineStyle.getPropertyValue('--length'), '5');
+  assert_equals(inlineStyle.getPropertyValue('--color'), 'hello');
+  assert_equals(computedStyle.getPropertyValue('--length'), '0px');
+  assert_equals(computedStyle.getPropertyValue('--color'), 'blue');
+}, "Formerly valid values are still readable from inline styles but are computed as the unset value");
+
+test(function() {
+  inlineStyle.setProperty('--length', 'hi');
+  inlineStyle.setProperty('--color', '20');
+  assert_equals(inlineStyle.getPropertyValue('--length'), '5');
+  assert_equals(inlineStyle.getPropertyValue('--color'), 'hello');
+}, "Values not matching the registered type can't be set");
+
+test(function() {
+  inlineStyle.removeProperty('--length');
+  inlineStyle.setProperty('--color', '');
+  assert_equals(inlineStyle.getPropertyValue('--length'), '');
+  assert_equals(inlineStyle.getPropertyValue('--color'), '');
+  assert_equals(computedStyle.getPropertyValue('--length'), '10px');
+  assert_equals(computedStyle.getPropertyValue('--color'), 'red');
+}, "Values can be removed from inline styles");
+
+test(function() {
+  sheetStyle.setProperty('--length', 'banana'); // Invalid, no change
+  assert_equals(computedStyle.getPropertyValue('--length'), '10px');
+  sheetStyle.setProperty('--length', '20px');
+  assert_equals(computedStyle.getPropertyValue('--length'), '20px');
+  sheetStyle.setProperty('--length', 'initial');
+  assert_equals(computedStyle.getPropertyValue('--length'), '0px');
+}, "Stylesheets can be modified by CSSOM");
+
+test(function() {
+  inlineStyle.setProperty('--length', '30px');
+  inlineStyle.setProperty('--color', 'pink');
+  assert_equals(inlineStyle.getPropertyValue('--length'), '30px');
+  assert_equals(inlineStyle.getPropertyValue('--color'), 'pink');
+  assert_equals(computedStyle.getPropertyValue('--length'), '30px');
+  assert_equals(computedStyle.getPropertyValue('--color'), 'pink');
+  inlineStyle.setProperty('--color', 'inherit');
+  assert_equals(inlineStyle.getPropertyValue('--color'), 'inherit');
+  assert_equals(computedStyle.getPropertyValue('--color'), 'blue');
+}, "Valid values can be set on inline styles");
+</script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-properties-values-api/registered-property-initial.html
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML>
+<link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api/#dom-propertydescriptor-initialvalue" />
+<link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api/#register-a-custom-property" />
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+#target {
+  background: var(--inherited-color);
+  color: var(--non-inherited-color);
+}
+</style>
+<div id=target></div>
+<script>
+CSS.registerProperty({name: '--length', syntax: '<length>', initialValue: 'calc(10px + 15px)'});
+CSS.registerProperty({name: '--length-percentage', syntax: '<length-percentage>', initialValue: 'calc(1in + 10% + 4px)'});
+CSS.registerProperty({name: '--inherited-color', syntax: '<color>', initialValue: 'pink', inherits: true});
+CSS.registerProperty({name: '--non-inherited-color', syntax: '<color>', initialValue: 'purple'});
+CSS.registerProperty({name: '--single-transform-list', syntax: '<transform-list>', initialValue: 'scale(calc(2 + 2))'});
+CSS.registerProperty({name: '--multiple-transform-list', syntax: '<transform-list>', initialValue: 'scale(calc(2 + 1)) translateX(calc(3px + 1px))'});
+
+test(function() {
+    computedStyle = getComputedStyle(target);
+    assert_equals(computedStyle.getPropertyValue('--length'), '25px');
+    assert_equals(computedStyle.getPropertyValue('--length-percentage'), 'calc(100px + 10%)');
+    assert_equals(computedStyle.getPropertyValue('--inherited-color'), 'pink');
+    assert_equals(computedStyle.getPropertyValue('--non-inherited-color'), 'purple');
+    assert_equals(computedStyle.getPropertyValue('--single-transform-list'), 'scale(4)');
+    assert_equals(computedStyle.getPropertyValue('--multiple-transform-list'), 'scale(3) translateX(4px)');
+
+    assert_equals(computedStyle.backgroundColor, 'rgb(255, 192, 203)');
+    assert_equals(computedStyle.color, 'rgb(128, 0, 128)');
+}, "Initial values of registered properties can be referenced when no custom properties are explicitly set.");
+</script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-properties-values-api/var-reference-registered-properties-cycles.html
@@ -0,0 +1,145 @@
+<!DOCTYPE HTML>
+<link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api/#dom-css-registerproperty" />
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<style>
+#test1 {
+    --registered-1-a: var(--registered-1-b, 10px);
+    --registered-1-b: var(--registered-1-a, 20px);
+
+    --registered-1-c: var(--registered-1-b, 30px);
+    --registered-1-d: var(--registered-1-b);
+    --unregistered-1-a:var(--registered-1-a,40px);
+    --unregistered-1-a:var(--registered-1-a);
+    left: var(--registered-1-a, 50px);
+    top: var(--registered-1-b, 60px);
+}
+</style>
+<div id=test1></div>
+<script>
+test(function() {
+    CSS.registerProperty({name: '--registered-1-a', syntax: '<length>', initialValue: '1px'});
+    CSS.registerProperty({name: '--registered-1-b', syntax: '<length>', initialValue: '2px'});
+    CSS.registerProperty({name: '--registered-1-c', syntax: '<length>', initialValue: '3px'});
+    CSS.registerProperty({name: '--registered-1-d', syntax: '<length>', initialValue: '4px'});
+
+    computedStyle = getComputedStyle(test1);
+    assert_equals(computedStyle.getPropertyValue('--registered-1-a'), '1px');
+    assert_equals(computedStyle.getPropertyValue('--registered-1-b'), '2px');
+
+    assert_equals(computedStyle.getPropertyValue('--registered-1-c'), '2px');
+    assert_equals(computedStyle.getPropertyValue('--registered-1-d'), '2px');
+    assert_equals(computedStyle.getPropertyValue('--unregistered-1-a'), '1px');
+    assert_equals(computedStyle.left, '1px');
+    assert_equals(computedStyle.top, '2px');
+}, "A var() cycle between two registered properties is handled correctly.");
+</script>
+
+<style>
+#test2 {
+    --registered-2-a: var(--unregistered-2-a, 10px);
+    --unregistered-2-a:var(--registered-2-a,20px);
+
+    --registered-2-b: var(--registered-2-a, 30px);
+    --registered-2-c: var(--registered-2-a);
+    --registered-2-d: var(--unregistered-2-a, 40px);
+    --registered-2-e: var(--unregistered-2-a);
+    --unregistered-2-b:var(--registered-2-a,50px);
+    --unregistered-2-c:var(--registered-2-a);
+    --unregistered-2-d:var(--unregistered-2-a,60px);
+    --unregistered-2-e:var(--unregistered-2-a);
+    left: var(--registered-2-a, 70px);
+    top: var(--unregistered-2-a, 80px);
+}
+</style>
+<div id=test2></div>
+<script>
+test(function() {
+    CSS.registerProperty({name: '--registered-2-a', syntax: '<length>', initialValue: '1px'});
+    CSS.registerProperty({name: '--registered-2-b', syntax: '<length>', initialValue: '2px'});
+    CSS.registerProperty({name: '--registered-2-c', syntax: '<length>', initialValue: '3px'});
+    CSS.registerProperty({name: '--registered-2-d', syntax: '<length>', initialValue: '4px'});
+    CSS.registerProperty({name: '--registered-2-e', syntax: '<length>', initialValue: '5px'});
+
+    computedStyle = getComputedStyle(test2);
+    assert_equals(computedStyle.getPropertyValue('--registered-2-a'), '1px');
+    assert_equals(computedStyle.getPropertyValue('--unregistered-2-a'), '');
+
+    assert_equals(computedStyle.getPropertyValue('--registered-2-b'), '1px');
+    assert_equals(computedStyle.getPropertyValue('--registered-2-c'), '1px');
+    assert_equals(computedStyle.getPropertyValue('--registered-2-d'), '40px');
+    assert_equals(computedStyle.getPropertyValue('--registered-2-e'), '5px');
+    assert_equals(computedStyle.getPropertyValue('--unregistered-2-b'), '1px');
+    assert_equals(computedStyle.getPropertyValue('--unregistered-2-c'), '1px');
+    assert_equals(computedStyle.getPropertyValue('--unregistered-2-d'), '60px');
+    assert_equals(computedStyle.getPropertyValue('--unregistered-2-e'), '');
+    assert_equals(computedStyle.left, '1px');
+    assert_equals(computedStyle.top, '80px');
+}, "A var() cycle between a registered properties and an unregistered property is handled correctly.");
+</script>
+
+<style>
+#test3 {
+    --unregistered-3-a:var(--unregistered-3-b,10px);
+    --unregistered-3-b:var(--unregistered-3-a,20px);
+
+    --registered-3-a: var(--unregistered-3-a, 30px);
+    --registered-3-b: var(--unregistered-3-a);
+    --registered-3-c: var(--unregistered-3-b, 40px);
+    --registered-3-d: var(--registered-3-c, 50px);
+    left: var(--registered-3-d, 60px);
+    top: var(--registered-3-b, 70px);
+}
+</style>
+<div id=test3></div>
+<script>
+test(function() {
+    CSS.registerProperty({name: '--registered-3-a', syntax: '<length>', initialValue: '1px'});
+    CSS.registerProperty({name: '--registered-3-b', syntax: '<length>', initialValue: '2px'});
+    CSS.registerProperty({name: '--registered-3-c', syntax: '<length>', initialValue: '3px'});
+    CSS.registerProperty({name: '--registered-3-d', syntax: '<length>', initialValue: '4px'});
+
+    computedStyle = getComputedStyle(test3);
+    assert_equals(computedStyle.getPropertyValue('--unregistered-3-a'), '');
+    assert_equals(computedStyle.getPropertyValue('--unregistered-3-b'), '');
+
+    assert_equals(computedStyle.getPropertyValue('--registered-3-a'), '30px');
+    assert_equals(computedStyle.getPropertyValue('--registered-3-b'), '2px');
+    assert_equals(computedStyle.getPropertyValue('--registered-3-c'), '40px');
+    assert_equals(computedStyle.getPropertyValue('--registered-3-d'), '40px');
+    assert_equals(computedStyle.left, '40px');
+    assert_equals(computedStyle.top, '2px');
+}, "A var() cycle between a two unregistered properties is handled correctly.");
+</script>
+
+<style>
+#test4 {
+    --registered-4-a:var(--unregistered-4-a,hello);
+    --unregistered-4-a:var(--registered-4-a,world);
+
+    --registered-4-b:var(--unregistered-4-a,meow);
+    --registered-4-c:var(--unregistered-4-a);
+    --unregistered-4-b:var(--unregistered-4-a,woof);
+    --unregistered-4-c:var(--unregistered-4-a);
+    transition-property: var(--registered-4-a, water);
+}
+</style>
+<div id=test4></div>
+<script>
+test(function() {
+    CSS.registerProperty({name: '--registered-4-a', syntax: '*'});
+    CSS.registerProperty({name: '--registered-4-b', syntax: '*', initialValue: 'moo'});
+    CSS.registerProperty({name: '--registered-4-c', syntax: '*', initialValue: 'circle'});
+
+    computedStyle = getComputedStyle(test4);
+    assert_equals(computedStyle.getPropertyValue('--registered-4-a'), '');
+    assert_equals(computedStyle.getPropertyValue('--unregistered-4-a'), '');
+
+    assert_equals(computedStyle.getPropertyValue('--registered-4-b'), 'meow');
+    assert_equals(computedStyle.getPropertyValue('--registered-4-c'), 'circle');
+    assert_equals(computedStyle.getPropertyValue('--unregistered-4-b'), 'woof');
+    assert_equals(computedStyle.getPropertyValue('--unregistered-4-c'), '');
+    assert_equals(computedStyle.transitionProperty, 'water');
+}, "A var() cycle between a syntax:'*' property and an unregistered property is handled correctly.");
+</script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-properties-values-api/var-reference-registered-properties.html
@@ -0,0 +1,61 @@
+<!DOCTYPE HTML>
+<link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api/#dom-css-registerproperty" />
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+div {
+    --registered-length-1: 10px;
+    --registered-length-2: var(--registered-length-1);
+    --registered-length-3: var(--length-1);
+    --registered-length-4: calc(var(--length-1) + 40px);
+    --registered-length-5: var(--invalid, 70px);
+    --registered-length-6: calc(var(--registered-length-3)*4);
+    --registered-length-7: var(--123px, 6px);
+
+    --length-1: 20px;
+    --length-2: var(--registered-length-1);
+    --length-3: calc(var(--123px, 6px) + var(--123px));
+
+    --percentage: 10%;
+    --registered-length-invalid: var(--percentage);
+
+    --registered-token-stream-1:var(--invalid);
+    --registered-token-stream-2:var(--invalid,fallback);
+    --token-stream-1:var(--registered-token-stream-1,moo);
+}
+</style>
+<div id=element></div>
+<script>
+CSS.registerProperty({name: '--123px', syntax: '<length>', initialValue: '123px'});
+
+CSS.registerProperty({name: '--registered-length-1', syntax: '<length>', initialValue: '0px'});
+CSS.registerProperty({name: '--registered-length-2', syntax: '<length>', initialValue: '0px'});
+CSS.registerProperty({name: '--registered-length-3', syntax: '<length>', initialValue: '0px'});
+CSS.registerProperty({name: '--registered-length-4', syntax: '<length>', initialValue: '0px'});
+CSS.registerProperty({name: '--registered-length-5', syntax: '<length>', initialValue: '0px'});
+CSS.registerProperty({name: '--registered-length-6', syntax: '<length>', initialValue: '0px'});
+CSS.registerProperty({name: '--registered-length-7', syntax: '<length>', initialValue: '0px'});
+CSS.registerProperty({name: '--registered-length-invalid', syntax: '<length>', initialValue: '15px'});
+
+CSS.registerProperty({name: '--registered-token-stream-1', syntax: '*'});
+CSS.registerProperty({name: '--registered-token-stream-2', syntax: '*'});
+
+test(function() {
+    computedStyle = getComputedStyle(element);
+    assert_equals(computedStyle.getPropertyValue('--registered-length-1'), '10px');
+    assert_equals(computedStyle.getPropertyValue('--registered-length-2'), '10px');
+    assert_equals(computedStyle.getPropertyValue('--registered-length-3'), '20px');
+    assert_equals(computedStyle.getPropertyValue('--registered-length-4'), '60px');
+    assert_equals(computedStyle.getPropertyValue('--registered-length-5'), '70px');
+    assert_equals(computedStyle.getPropertyValue('--registered-length-6'), '80px');
+    assert_equals(computedStyle.getPropertyValue('--registered-length-7'), '123px');
+    assert_equals(computedStyle.getPropertyValue('--length-1'), ' 20px');
+    assert_equals(computedStyle.getPropertyValue('--length-2'), '  10px');
+    assert_equals(computedStyle.getPropertyValue('--length-3'), ' calc(123px + 123px)');
+    assert_equals(computedStyle.getPropertyValue('--registered-length-invalid'), '15px');
+
+    assert_equals(computedStyle.getPropertyValue('--registered-token-stream-1'), '');
+    assert_equals(computedStyle.getPropertyValue('--registered-token-stream-2'), 'fallback');
+    assert_equals(computedStyle.getPropertyValue('--token-stream-1'), 'moo');
+}, "var() references work with registered properties");
+</script>