clone-object.js (4038B)
1 // |reftest| skip-if(!xulRuntime.shell) 2 // -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- 3 // Any copyright is dedicated to the Public Domain. 4 // http://creativecommons.org/licenses/publicdomain/ 5 6 function test() { 7 var check = clone_object_check; 8 9 check({}); 10 check([]); 11 check({x: 0}); 12 check({x: 0.7, p: "forty-two", y: null, z: undefined}); 13 check(Array.prototype); 14 check(Object.prototype); 15 16 // before and after 17 var b, a; 18 19 // Slow array. 20 b = [, 1, 2, 3]; 21 b.expando = true; 22 b[5] = 5; 23 b[0] = 0; 24 b[4] = 4; 25 delete b[2]; 26 check(b); 27 28 // Check cloning properties other than basic data properties. (check() 29 // asserts that the properties of the clone are configurable, writable, 30 // enumerable data properties.) 31 b = {}; 32 Object.defineProperties(b, { 33 x: {enumerable: true, get: function () { return 12479; }}, 34 y: {enumerable: true, configurable: true, writable: false, value: 0}, 35 z: {enumerable: true, configurable: false, writable: true, value: 0}, 36 hidden: {enumerable:false, value: 1334}}); 37 check(b); 38 39 // Check corner cases involving property names. 40 b = {"-1": -1, 41 0xffffffff: null, 42 0x100000000: null, 43 "": 0, 44 "\xff\x7f\u7fff\uffff\ufeff\ufffe": 1, // random unicode id 45 "\ud800 \udbff \udc00 \udfff": 2}; // busted surrogate pairs 46 check(b); 47 48 b = []; 49 b[-1] = -1; 50 b[0xffffffff] = null; 51 b[0x100000000] = null; 52 b[""] = 0; 53 b["\xff\x7f\u7fff\uffff\ufeff\ufffe"] = 1; 54 b["\ud800 \udbff \udc00 \udfff"] = 2; 55 check(b); 56 57 // Check that array's .length property is cloned. 58 b = Array(5); 59 assertEq(b.length, 5); 60 a = check(b); 61 assertEq(a.length, 5); 62 63 b = Array(0); 64 b[1] = "ok"; 65 a = check(b); 66 assertEq(a.length, 2); 67 68 // Check that prototypes are not cloned, per spec. 69 b = Object.create({x:1}); 70 b.y = 2; 71 b.z = 3; 72 check(b); 73 74 // Check that cloning does not separate merge points in the tree. 75 var same = {}; 76 b = {one: same, two: same}; 77 a = check(b); 78 assertEq(a.one === a.two, true); 79 80 b = [same, same]; 81 a = check(b); 82 assertEq(a[0] === a[1], true); 83 84 /* 85 XXX TODO spin this out into its own test 86 // This fails quickly with an OOM error. An exception would be nicer. 87 function Infinitree() { 88 return { get left() { return new Infinitree; }, 89 get right() { return new Infinitree; }}; 90 } 91 var threw = false; 92 try { 93 serialize(new Infinitree); 94 } catch (exc) { 95 threw = true; 96 } 97 assertEq(threw, true); 98 */ 99 100 // Clone an array with holes. 101 check([0, 1, 2, , 4, 5, 6]); 102 103 // Array holes should not take up space. 104 b = []; 105 b[255] = 1; 106 check(b); 107 assertEq(serialize(b).clonebuffer.length < 255, true); 108 109 // Check that trailing holes in an array are preserved. 110 b = [1,2,3,,]; 111 assertEq(b.length, 4); 112 a = check(b); 113 assertEq(a.length, 4); 114 assertEq(a.toString(), "1,2,3,"); 115 116 b = [1,2,3,,,]; 117 assertEq(b.length, 5); 118 a = check(b); 119 assertEq(a.length, 5); 120 assertEq(a.toString(), "1,2,3,,"); 121 122 // Self-modifying object. 123 // This should never read through to b's prototype. 124 b = Object.create({y: 2}, 125 {x: {enumerable: true, 126 configurable: true, 127 get: function() { if (this.hasOwnProperty("y")) delete this.y; return 1; }}, 128 y: {enumerable: true, 129 configurable: true, 130 writable: true, 131 value: 3}}); 132 check(b, "selfModifyingObject"); 133 134 // Ignore properties with object-ids. 135 var uri = "http://example.net"; 136 b = {x: 1, y: 2}; 137 Object.defineProperty(b, Array(uri, "x"), {enumerable: true, value: 3}); 138 Object.defineProperty(b, Array(uri, "y"), {enumerable: true, value: 5}); 139 check(b); 140 } 141 142 test(); 143 reportCompare(0, 0, 'ok');