|
1 <?xml version="1.0"?> |
|
2 <?xml-stylesheet type="text/css" href="chrome://global/skin"?> |
|
3 <?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> |
|
4 <window title="Mozilla Bug 503926" |
|
5 xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> |
|
6 <script type="application/javascript" |
|
7 src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> |
|
8 |
|
9 <!-- test results are displayed in the html:body --> |
|
10 <body xmlns="http://www.w3.org/1999/xhtml"> |
|
11 <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=964293" |
|
12 target="_blank">Cu.cloneInto()</a> |
|
13 </body> |
|
14 |
|
15 <!-- test code goes here --> |
|
16 <script type="application/javascript"> |
|
17 <![CDATA[ |
|
18 |
|
19 const Cu = Components.utils; |
|
20 const Ci = Components.interfaces; |
|
21 |
|
22 const TypedArrayThings = [ |
|
23 'Int8Array', |
|
24 'Uint8Array', |
|
25 'Uint8ClampedArray', |
|
26 'Int16Array', |
|
27 'Uint16Array', |
|
28 'Int32Array', |
|
29 'Uint32Array', |
|
30 'Float32Array', |
|
31 'Float64Array', |
|
32 ]; |
|
33 |
|
34 function getType(a) { |
|
35 if (a === null || a === undefined) |
|
36 return 'null'; |
|
37 |
|
38 if (Array.isArray(a)) |
|
39 return 'array'; |
|
40 |
|
41 if (a instanceof Ci.nsIDOMFile) |
|
42 return 'file'; |
|
43 |
|
44 if (a instanceof Ci.nsIDOMBlob) |
|
45 return 'blob'; |
|
46 |
|
47 if (TypedArrayThings.indexOf(a.constructor.name) !== -1) |
|
48 return a.constructor.name; |
|
49 |
|
50 if (typeof a == 'object') |
|
51 return 'object'; |
|
52 |
|
53 if (typeof a == 'function') |
|
54 return 'function'; |
|
55 |
|
56 return 'primitive'; |
|
57 } |
|
58 |
|
59 function compare(a, b) { |
|
60 is (getType(a), getType(b), 'Type matches'); |
|
61 |
|
62 var type = getType(a); |
|
63 if (type == 'array') { |
|
64 is (a.length, b.length, 'Array.length matches'); |
|
65 for (var i = 0; i < a.length; ++i) { |
|
66 compare(a[i], b[i]); |
|
67 } |
|
68 |
|
69 return; |
|
70 } |
|
71 |
|
72 if (type == 'file' || type == 'blob') { |
|
73 ok ( a === b, 'They should match'); |
|
74 return; |
|
75 } |
|
76 |
|
77 if (type == 'object') { |
|
78 ok ( a !== b, 'They should not match'); |
|
79 |
|
80 var aProps = []; |
|
81 for (var p in a) aProps.push(p); |
|
82 |
|
83 var bProps = []; |
|
84 for (var p in b) bProps.push(p); |
|
85 |
|
86 is (aProps.length, bProps.length, 'Props match'); |
|
87 is (aProps.sort().toSource(), bProps.sort().toSource(), 'Props match - using toSource()'); |
|
88 |
|
89 for (var p in a) { |
|
90 compare(a[p], b[p]); |
|
91 } |
|
92 |
|
93 return; |
|
94 } |
|
95 |
|
96 if (type == 'function') { |
|
97 ok ( a !== b, 'They should not match'); |
|
98 return; |
|
99 } |
|
100 |
|
101 if (type != 'null') { |
|
102 is (a.toSource(), b.toSource(), 'Matching using toSource()'); |
|
103 } |
|
104 } |
|
105 |
|
106 var sandboxOptions = { |
|
107 wantXrays: true, |
|
108 wantExportHelpers: true, |
|
109 }; |
|
110 var sandbox = new Cu.Sandbox(window, sandboxOptions); |
|
111 // The second sandbox is for testing the exportHelper version of the cloneInto |
|
112 var sandbox2 = new Cu.Sandbox("http://example.com", sandboxOptions); |
|
113 sandbox.sandbox2 = sandbox2; |
|
114 |
|
115 function cloneAndTest(test, cloneOptions) { |
|
116 var output = sandbox.test = Cu.cloneInto(test, sandbox, cloneOptions); |
|
117 compare(test, output); |
|
118 |
|
119 sandbox.cloneOptions = cloneOptions; |
|
120 output = Cu.evalInSandbox('cloneInto(test, sandbox2, cloneOptions)', sandbox); |
|
121 compare(test, output); |
|
122 } |
|
123 |
|
124 var tests = [ |
|
125 1, |
|
126 null, |
|
127 true, |
|
128 'hello world', |
|
129 [1, 2, 3], |
|
130 { a: 1, b: 2 }, |
|
131 { blob: new Blob([]), file: new File(new Blob([])) }, |
|
132 new Date(), |
|
133 { a: 1, b: {}, c: [1, 2, 3, { d: new Blob([]) } ], e: 'hello world' }, |
|
134 ]; |
|
135 |
|
136 for (var i = 0; i < tests.length; ++i) { |
|
137 cloneAndTest(tests[i]); |
|
138 } |
|
139 |
|
140 try { |
|
141 var output = Cu.cloneInto({ a: function() {} }, sandbox); |
|
142 ok(false, 'Function should not be cloned by default'); |
|
143 } catch(e) { |
|
144 ok(true, 'Function should not be cloned by default'); |
|
145 } |
|
146 |
|
147 try { |
|
148 sandbox2.sandbox = sandbox; |
|
149 Cu.evalInSandbox('cloneInto({}, sandbox)', sandbox2); |
|
150 ok(false, 'CloneInto should only work on less privileged target scopes.'); |
|
151 } catch(e) { |
|
152 ok(/denied|insecure/.test(e), |
|
153 'CloneInto should only work on less privileged target scopes.'); |
|
154 } |
|
155 |
|
156 var test = { a: function() { return 42; } } |
|
157 cloneAndTest(test, { cloneFunctions: true }); |
|
158 ]]> |
|
159 </script> |
|
160 </window> |