structured-serialization.html (5964B)
1 <!DOCTYPE html> 2 <title>Geometry Interfaces: Serialize and deserialize</title> 3 <link rel="help" href="https://drafts.fxtf.org/geometry/#structured-serialization"> 4 <script src="/resources/testharness.js"></script> 5 <script src="/resources/testharnessreport.js"></script> 6 <div id=log></div> 7 <script> 8 function clone(obj) { 9 return new Promise((resolve, reject) => { 10 const channel = new MessageChannel(); 11 channel.port2.onmessage = e => resolve(e.data); 12 channel.port1.postMessage(obj); 13 }); 14 } 15 function defineThrowingGetters(object, attrs) { 16 for (let attr of attrs) { 17 Object.defineProperty(object, attr, { 18 get: () => assert_unreached(`getter for ${attr}`) 19 }); 20 } 21 } 22 23 [ 24 ["DOMPointReadOnly", "x", "y", "z", "w"], 25 ["DOMPoint", "x", "y", "z", "w"], 26 ["DOMRectReadOnly", "x", "y", "width", "height"], 27 ["DOMRect", "x", "y", "width", "height"], 28 ["DOMQuad", "p1", "p2", "p3", "p4"], 29 ["DOMMatrixReadOnly", "a", "b", "c", "d", "e", "f", "m11", "m12", "m13", "m14", "m21", "m22", "m23", "m24", "m31", "m32", "m33", "m34", "m41", "m42", "m43", "m44", "is2D"], 30 ["DOMMatrix", "a", "b", "c", "d", "e", "f", "m11", "m12", "m13", "m14", "m21", "m22", "m23", "m24", "m31", "m32", "m33", "m34", "m41", "m42", "m43", "m44", "is2D"], 31 ].forEach(([constr, ...attrs]) => { 32 const prefix = `${constr} clone:`; 33 34 promise_test(t => { 35 const object = new self[constr](); 36 return clone(object).then(other => { 37 assert_not_equals(object, other); 38 assert_class_string(other, constr); 39 for (let attr of attrs) { 40 if (constr === "DOMQuad") { 41 assert_not_equals(other[attr], object[attr], attr); 42 assert_class_string(other[attr], "DOMPoint", attr); 43 assert_equals(other[attr].x, object.p1.x, `${attr}.x`); 44 assert_equals(other[attr].y, object.p1.y, `${attr}.y`); 45 assert_equals(other[attr].z, object.p1.z, `${attr}.z`); 46 assert_equals(other[attr].w, object.p1.w, `${attr}.w`); 47 } else { 48 assert_equals(other[attr], object[attr], attr); 49 } 50 } 51 t.done(); 52 }); 53 }, `${prefix} basic`); 54 55 promise_test(t => { 56 const object = new self[constr](); 57 object.foo = "bar"; 58 return clone(object).then(other => { 59 assert_false("foo" in other, 'foo should not exist in other'); 60 t.done(); 61 }); 62 }, `${prefix} custom property`); 63 64 promise_test(t => { 65 const object = new self[constr](); 66 // The custom throwing getter on object should not be copied to other. 67 defineThrowingGetters(object, attrs); 68 return clone(object).then(other => { 69 for (let attr of attrs) { 70 // This should call the standard getter, and therefore not throw. 71 // If this were to call the throwing getter defined on object, the test would fail. 72 other[attr]; 73 } 74 t.done(); 75 }); 76 }, `${prefix} throwing getters`); 77 78 // More specific tests for each type 79 switch(constr) { 80 case "DOMPointReadOnly": 81 case "DOMPoint": 82 case "DOMRectReadOnly": 83 case "DOMRect": 84 promise_test(t => { 85 const object = new self[constr](1, -0, Infinity, NaN); 86 return clone(object).then(other => { 87 for (let attr of attrs) { 88 assert_equals(other[attr], object[attr], attr); 89 } 90 t.done(); 91 }); 92 }, `${prefix} non-initial values`); 93 break; 94 case "DOMQuad": 95 promise_test(t => { 96 const object = new self[constr]({x:1, y:2, z:3, w:4}, 97 {x:-0, y:-0, z:-0, w:-0}, 98 {x:Infinity, y:Infinity, z:Infinity, w:Infinity}, 99 {x:NaN, y:NaN, z:NaN, w:NaN}); 100 return clone(object).then(other => { 101 for (let attr of attrs) { 102 assert_equals(other[attr].x, object[attr].x, `${attr}.x`); 103 assert_equals(other[attr].y, object[attr].y, `${attr}.y`); 104 assert_equals(other[attr].z, object[attr].z, `${attr}.z`); 105 assert_equals(other[attr].w, object[attr].w, `${attr}.w`); 106 } 107 t.done(); 108 }); 109 }, `${prefix} non-initial values`); 110 break; 111 case "DOMMatrixReadOnly": 112 case "DOMMatrix": 113 promise_test(t => { 114 const object = new self[constr]([1, -0, Infinity, NaN, 5, 6]); 115 object.m13 = -0; 116 object.m14 = -0; 117 object.m23 = -0; 118 object.m24 = -0; 119 object.m31 = -0; 120 object.m32 = -0; 121 object.m34 = -0; 122 object.m43 = -0; 123 assert_true(object.is2D, 'is2D after setting m13 etc to -0'); 124 return clone(object).then(other => { 125 for (let attr of attrs) { 126 if (attr === 'm13' || 127 attr === 'm14' || 128 attr === 'm23' || 129 attr === 'm24' || 130 attr === 'm31' || 131 attr === 'm32' || 132 attr === 'm34' || 133 attr === 'm43') { 134 assert_equals(other[attr], 0, attr); 135 } else { 136 assert_equals(other[attr], object[attr], attr); 137 } 138 } 139 t.done(); 140 }); 141 }, `${prefix} non-initial values (2d)`); 142 143 promise_test(t => { 144 const object = new self[constr]([11, -0, Infinity, NaN, 145 21, 22, 23, 24, 146 31, 32, 33, 34, 147 41, 42, 43, 44]); 148 return clone(object).then(other => { 149 for (let attr of attrs) { 150 assert_equals(other[attr], object[attr], attr); 151 } 152 t.done(); 153 }); 154 }, `${prefix} non-initial values (3d)`); 155 break; 156 default: 157 throw new Error(`Test bug: ${constr} has no test for non-initial values`); 158 } 159 }); 160 161 promise_test((t) => { 162 const object = document.getElementById('log').getClientRects(); 163 return promise_rejects_dom(t, "DataCloneError", clone(object)); 164 }, 'DOMRectList clone');0 165 </script>