165 lines
5.8 KiB
HTML
165 lines
5.8 KiB
HTML
<!DOCTYPE html>
|
|
<title>Geometry Interfaces: Serialize and deserialize</title>
|
|
<link rel="help" href="https://drafts.fxtf.org/geometry/#structured-serialization">
|
|
<script src="/resources/testharness.js"></script>
|
|
<script src="/resources/testharnessreport.js"></script>
|
|
<div id=log></div>
|
|
<script>
|
|
function clone(obj) {
|
|
return new Promise((resolve, reject) => {
|
|
const channel = new MessageChannel();
|
|
channel.port2.onmessage = e => resolve(e.data);
|
|
channel.port1.postMessage(obj);
|
|
});
|
|
}
|
|
function defineThrowingGetters(object, attrs) {
|
|
for (let attr of attrs) {
|
|
Object.defineProperty(object, attr, {
|
|
get: () => assert_unreached(`getter for ${attr}`)
|
|
});
|
|
}
|
|
}
|
|
|
|
[
|
|
["DOMPointReadOnly", "x", "y", "z", "w"],
|
|
["DOMPoint", "x", "y", "z", "w"],
|
|
["DOMRectReadOnly", "x", "y", "width", "height"],
|
|
["DOMRect", "x", "y", "width", "height"],
|
|
["DOMQuad", "p1", "p2", "p3", "p4"],
|
|
["DOMMatrixReadOnly", "a", "b", "c", "d", "e", "f", "m11", "m12", "m13", "m14", "m21", "m22", "m23", "m24", "m31", "m32", "m33", "m34", "m41", "m42", "m43", "m44", "is2D"],
|
|
["DOMMatrix", "a", "b", "c", "d", "e", "f", "m11", "m12", "m13", "m14", "m21", "m22", "m23", "m24", "m31", "m32", "m33", "m34", "m41", "m42", "m43", "m44", "is2D"],
|
|
].forEach(([constr, ...attrs]) => {
|
|
const prefix = `${constr} clone:`;
|
|
|
|
promise_test(t => {
|
|
const object = new self[constr]();
|
|
return clone(object).then(other => {
|
|
assert_not_equals(object, other);
|
|
assert_class_string(other, constr);
|
|
for (let attr of attrs) {
|
|
if (constr === "DOMQuad") {
|
|
assert_not_equals(other[attr], object[attr], attr);
|
|
assert_class_string(other[attr], "DOMPoint", attr);
|
|
assert_equals(other[attr].x, object.p1.x, `${attr}.x`);
|
|
assert_equals(other[attr].y, object.p1.y, `${attr}.y`);
|
|
assert_equals(other[attr].z, object.p1.z, `${attr}.z`);
|
|
assert_equals(other[attr].w, object.p1.w, `${attr}.w`);
|
|
} else {
|
|
assert_equals(other[attr], object[attr], attr);
|
|
}
|
|
}
|
|
t.done();
|
|
});
|
|
}, `${prefix} basic`);
|
|
|
|
promise_test(t => {
|
|
const object = new self[constr]();
|
|
object.foo = "bar";
|
|
return clone(object).then(other => {
|
|
assert_false("foo" in other, 'foo should not exist in other');
|
|
t.done();
|
|
});
|
|
}, `${prefix} custom property`);
|
|
|
|
promise_test(t => {
|
|
const object = new self[constr]();
|
|
// The custom throwing getter on object should not be copied to other.
|
|
defineThrowingGetters(object, attrs);
|
|
return clone(object).then(other => {
|
|
for (let attr of attrs) {
|
|
// This should call the standard getter, and therefore not throw.
|
|
// If this were to call the throwing getter defined on object, the test would fail.
|
|
other[attr];
|
|
}
|
|
t.done();
|
|
});
|
|
}, `${prefix} throwing getters`);
|
|
|
|
// More specific tests for each type
|
|
switch(constr) {
|
|
case "DOMPointReadOnly":
|
|
case "DOMPoint":
|
|
case "DOMRectReadOnly":
|
|
case "DOMRect":
|
|
promise_test(t => {
|
|
const object = new self[constr](1, -0, Infinity, NaN);
|
|
return clone(object).then(other => {
|
|
for (let attr of attrs) {
|
|
assert_equals(other[attr], object[attr], attr);
|
|
}
|
|
t.done();
|
|
});
|
|
}, `${prefix} non-initial values`);
|
|
break;
|
|
case "DOMQuad":
|
|
promise_test(t => {
|
|
const object = new self[constr]({x:1, y:2, z:3, w:4},
|
|
{x:-0, y:-0, z:-0, w:-0},
|
|
{x:Infinity, y:Infinity, z:Infinity, w:Infinity},
|
|
{x:NaN, y:NaN, z:NaN, w:NaN});
|
|
return clone(object).then(other => {
|
|
for (let attr of attrs) {
|
|
assert_equals(other[attr].x, object[attr].x, `${attr}.x`);
|
|
assert_equals(other[attr].y, object[attr].y, `${attr}.y`);
|
|
assert_equals(other[attr].z, object[attr].z, `${attr}.z`);
|
|
assert_equals(other[attr].w, object[attr].w, `${attr}.w`);
|
|
}
|
|
t.done();
|
|
});
|
|
}, `${prefix} non-initial values`);
|
|
break;
|
|
case "DOMMatrixReadOnly":
|
|
case "DOMMatrix":
|
|
promise_test(t => {
|
|
const object = new self[constr]([1, -0, Infinity, NaN, 5, 6]);
|
|
object.m13 = -0;
|
|
object.m14 = -0;
|
|
object.m23 = -0;
|
|
object.m24 = -0;
|
|
object.m31 = -0;
|
|
object.m32 = -0;
|
|
object.m34 = -0;
|
|
object.m43 = -0;
|
|
assert_true(object.is2D, 'is2D after setting m13 etc to -0');
|
|
return clone(object).then(other => {
|
|
for (let attr of attrs) {
|
|
if (attr === 'm13' ||
|
|
attr === 'm14' ||
|
|
attr === 'm23' ||
|
|
attr === 'm24' ||
|
|
attr === 'm31' ||
|
|
attr === 'm32' ||
|
|
attr === 'm34' ||
|
|
attr === 'm43') {
|
|
assert_equals(other[attr], 0, attr);
|
|
} else {
|
|
assert_equals(other[attr], object[attr], attr);
|
|
}
|
|
}
|
|
t.done();
|
|
});
|
|
}, `${prefix} non-initial values (2d)`);
|
|
|
|
promise_test(t => {
|
|
const object = new self[constr]([11, -0, Infinity, NaN,
|
|
21, 22, 23, 24,
|
|
31, 32, 33, 34,
|
|
41, 42, 43, 44]);
|
|
return clone(object).then(other => {
|
|
for (let attr of attrs) {
|
|
assert_equals(other[attr], object[attr], attr);
|
|
}
|
|
t.done();
|
|
});
|
|
}, `${prefix} non-initial values (3d)`);
|
|
break;
|
|
default:
|
|
throw new Error(`Test bug: ${constr} has no test for non-initial values`);
|
|
}
|
|
});
|
|
|
|
promise_test((t) => {
|
|
const object = document.getElementById('log').getClientRects();
|
|
return promise_rejects_dom(t, "DataCloneError", clone(object));
|
|
}, 'DOMRectList clone');0
|
|
</script>
|