1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/js/xpconnect/tests/chrome/test_xrayToJS.xul Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,170 @@ 1.4 +<?xml version="1.0"?> 1.5 +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> 1.6 +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> 1.7 +<!-- 1.8 +https://bugzilla.mozilla.org/show_bug.cgi?id=933681 1.9 +--> 1.10 +<window title="Mozilla Bug 933681" 1.11 + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> 1.12 + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> 1.13 + 1.14 + <!-- test results are displayed in the html:body --> 1.15 + <body xmlns="http://www.w3.org/1999/xhtml"> 1.16 + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=933681" 1.17 + target="_blank">Mozilla Bug 933681</a> 1.18 + </body> 1.19 + 1.20 + <!-- test code goes here --> 1.21 + <script type="application/javascript"> 1.22 + <![CDATA[ 1.23 + 1.24 + /** Test for ES constructors on Xrayed globals. **/ 1.25 + SimpleTest.waitForExplicitFinish(); 1.26 + const Cu = Components.utils; 1.27 + let global = Cu.getGlobalForObject.bind(Cu); 1.28 + 1.29 + simpleConstructors = ['Object', 'Function', 'Array', 'Boolean', 'Date', 'Number', 1.30 + 'String', 'RegExp', 'Error', 'InternalError', 'EvalError', 1.31 + 'RangeError', 'ReferenceError', 'SyntaxError', 'TypeError', 1.32 + 'URIError', 'ArrayBuffer', 'Int8Array', 'Uint8Array', 1.33 + 'Int16Array', 'Uint16Array', 'Int32Array', 'Uint32Array', 1.34 + 'Float32Array', 'Float64Array', 'Uint8ClampedArray', 1.35 + 'WeakMap', 'Map', 'Set']; 1.36 + 1.37 + function go() { 1.38 + window.iwin = document.getElementById('ifr').contentWindow; 1.39 + 1.40 + // Test constructors that can be instantiated with zero arguments. 1.41 + for (var c of simpleConstructors) { 1.42 + ok(iwin[c], "Constructors appear: " + c); 1.43 + is(iwin[c], Cu.unwaiveXrays(iwin.wrappedJSObject[c]), 1.44 + "we end up with the appropriate constructor: " + c); 1.45 + is(Cu.unwaiveXrays(Cu.waiveXrays(new iwin[c]).constructor), iwin[c], 1.46 + "constructor property is set up right: " + c); 1.47 + is(Object.getPrototypeOf(new iwin[c]), 1.48 + Cu.unwaiveXrays(Cu.waiveXrays(iwin[c]).prototype), 1.49 + "prototype is correct: " + c); 1.50 + is(global(new iwin[c]), iwin, "Got the right global: " + c); 1.51 + } 1.52 + 1.53 + // Test Object in more detail. 1.54 + var num = new iwin.Object(4); 1.55 + is(num.valueOf(), 4, "primitive object construction works"); 1.56 + is(global(num), iwin, "correct global for num"); 1.57 + var obj = new iwin.Object(); 1.58 + obj.foo = 2; 1.59 + var withProto = iwin.Object.create(obj); 1.60 + is(global(withProto), iwin, "correct global for withProto"); 1.61 + is(withProto.foo, 2, "Inherits properly"); 1.62 + 1.63 + // Test Function. 1.64 + var primitiveFun = new iwin.Function('return 2'); 1.65 + is(global(primitiveFun), iwin, "function construction works"); 1.66 + is(primitiveFun(), 2, "basic function works"); 1.67 + var doSetFoo = new iwin.Function('arg', 'arg.foo = 2;'); 1.68 + is(global(doSetFoo), iwin, "function with args works"); 1.69 + try { 1.70 + doSetFoo(new Object()); 1.71 + ok(false, "should have thrown while setting property on object"); 1.72 + } catch (e) { 1.73 + ok(!!/denied/.test(e), "Threw correctly: " + e); 1.74 + } 1.75 + var factoryFun = new iwin.Function('return {foo: 32}'); 1.76 + is(global(factoryFun), iwin, "proper global for factoryFun"); 1.77 + is(factoryFun().foo, 32, "factoryFun invokable"); 1.78 + is(global(factoryFun()), iwin, "minted objects live in the content scope"); 1.79 + 1.80 + // Test interface objects that don't actually construct things. 1.81 + is(iwin.Math.tan(4.5), Math.tan(4.5), "Math.tan works"); 1.82 + is(iwin.Math.E, Math.E, "Math.E works"); 1.83 + var json = JSON.stringify({a: 2, b: 'hi', c: {d: 'there'}}); 1.84 + is(global(iwin.JSON.parse(json)), iwin, "JSON rehydrated into the right context"); 1.85 + is(iwin.JSON.stringify(iwin.JSON.parse(json)), json, "JSON composition identity holds"); 1.86 + 1.87 + // Test proxies. 1.88 + var targetObject = new iwin.Object(); 1.89 + targetObject.foo = 9; 1.90 + var forwardingProxy = new iwin.Proxy(targetObject, new iwin.Object()); 1.91 + is(global(forwardingProxy), iwin, "proxy global correct"); 1.92 + is(forwardingProxy.foo, 9, "forwards correctly"); 1.93 + // NB: COW-implemented proxy handlers are super dangerous, and we should not 1.94 + // encourage them. 1.95 + var handler = {get: function(target, name) { return name * 2; }, __exposedProps__: {get: 'r'}}; 1.96 + var doublingProxy = new iwin.Proxy(targetObject, handler); 1.97 + is(global(doublingProxy), iwin, "doubling proxy global correct"); 1.98 + is(doublingProxy[3], 6, "Doubles correctly"); 1.99 + is(doublingProxy[20], 40, "Doubles correctly"); 1.100 + 1.101 + // Test eval. 1.102 + var toEval = "({a: 2, b: {foo: 'bar'}, f: function() { return window; }})"; 1.103 + is(global(iwin.eval(toEval)), iwin, "eval creates objects in the correct global"); 1.104 + is(iwin.eval(toEval).b.foo, 'bar', "eval-ed object looks right"); 1.105 + is(iwin.eval(toEval).f(), iwin, "evaled function works right"); 1.106 + 1.107 + testDate(); 1.108 + 1.109 + // We could also test DataView and Iterator here for completeness, but it's 1.110 + // more trouble than it's worth. 1.111 + 1.112 + 1.113 + SimpleTest.finish(); 1.114 + } 1.115 + 1.116 + function filterOut(array, props) { 1.117 + return array.filter(p => props.indexOf(p) == -1); 1.118 + } 1.119 + 1.120 + function testXray(classname, xray, xray2, propsToSkip) { 1.121 + propsToSkip = propsToSkip || []; 1.122 + let xrayProto = Object.getPrototypeOf(xray); 1.123 + let localProto = window[classname].prototype; 1.124 + let protoProps = filterOut(Object.getOwnPropertyNames(localProto), propsToSkip).sort(); 1.125 + let protoMethods = protoProps.filter(name => typeof localProto[name] == 'function' && 1.126 + name != 'constructor'); 1.127 + ok(protoMethods.length > 0, "Need something to test"); 1.128 + is(xrayProto, iwin[classname].prototype, "Xray proto is correct"); 1.129 + is(xrayProto, xray.__proto__, "Proto accessors agree"); 1.130 + is(Object.getPrototypeOf(xrayProto), iwin.Object.prototype, "proto proto is correct"); 1.131 + for (let name of protoMethods) { 1.132 + info("Running tests for property: " + name); 1.133 + ok(xrayProto.hasOwnProperty(name), "proto should have the property as own"); 1.134 + ok(!xray.hasOwnProperty(name), "instance should not have the property as own"); 1.135 + let method = xrayProto[name]; 1.136 + is(typeof method, 'function', "Methods from Xrays are functions"); 1.137 + is(global(method), window, "Methods from Xrays are local"); 1.138 + ok(method instanceof Function, "instanceof works on methods from Xrays"); 1.139 + is(xrayProto[name], method, "Holder caching works properly"); 1.140 + is(xray[name], method, "Proto props resolve on the instance"); 1.141 + let local = localProto[name]; 1.142 + is(method.length, local.length, "Function.length identical"); 1.143 + if (method.length == 0) { 1.144 + is(xray[name]() + "", local.call(xray) + "", 1.145 + "Xray and local method results stringify identically"); 1.146 + is(xray[name]() + "", xray.wrappedJSObject[name]() + "", 1.147 + "Xray and waived method results stringify identically"); 1.148 + } 1.149 + } 1.150 + is(Object.getOwnPropertyNames(xrayProto).sort().toSource(), 1.151 + protoProps.toSource(), "getOwnPropertyNames works"); 1.152 + 1.153 + is(xrayProto.constructor, iwin[classname], "constructor property works"); 1.154 + 1.155 + xrayProto.expando = 42; 1.156 + is(xray.expando, 42, "Xrayed instances see proto expandos"); 1.157 + is(xray2.expando, 42, "Xrayed instances see proto expandos"); 1.158 + } 1.159 + 1.160 + function testDate() { 1.161 + // toGMTString is handled oddly in the engine. We don't bother to support 1.162 + // it over Xrays. 1.163 + // 1.164 + // We don't yet support self-hosted functions on Xrays. See bug 972987. 1.165 + let propsToSkip = ['toGMTString', 'toLocaleString', 1.166 + 'toLocaleDateString', 'toLocaleTimeString']; 1.167 + testXray('Date', new iwin.Date(), new iwin.Date(), propsToSkip); 1.168 + } 1.169 + 1.170 + ]]> 1.171 + </script> 1.172 + <iframe id="ifr" onload="go();" src="http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html" /> 1.173 +</window>