Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
michael@0 | 1 | <?xml version="1.0"?> |
michael@0 | 2 | <?xml-stylesheet type="text/css" href="chrome://global/skin"?> |
michael@0 | 3 | <?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> |
michael@0 | 4 | <!-- |
michael@0 | 5 | https://bugzilla.mozilla.org/show_bug.cgi?id=933681 |
michael@0 | 6 | --> |
michael@0 | 7 | <window title="Mozilla Bug 933681" |
michael@0 | 8 | xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> |
michael@0 | 9 | <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> |
michael@0 | 10 | |
michael@0 | 11 | <!-- test results are displayed in the html:body --> |
michael@0 | 12 | <body xmlns="http://www.w3.org/1999/xhtml"> |
michael@0 | 13 | <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=933681" |
michael@0 | 14 | target="_blank">Mozilla Bug 933681</a> |
michael@0 | 15 | </body> |
michael@0 | 16 | |
michael@0 | 17 | <!-- test code goes here --> |
michael@0 | 18 | <script type="application/javascript"> |
michael@0 | 19 | <![CDATA[ |
michael@0 | 20 | |
michael@0 | 21 | /** Test for ES constructors on Xrayed globals. **/ |
michael@0 | 22 | SimpleTest.waitForExplicitFinish(); |
michael@0 | 23 | const Cu = Components.utils; |
michael@0 | 24 | let global = Cu.getGlobalForObject.bind(Cu); |
michael@0 | 25 | |
michael@0 | 26 | simpleConstructors = ['Object', 'Function', 'Array', 'Boolean', 'Date', 'Number', |
michael@0 | 27 | 'String', 'RegExp', 'Error', 'InternalError', 'EvalError', |
michael@0 | 28 | 'RangeError', 'ReferenceError', 'SyntaxError', 'TypeError', |
michael@0 | 29 | 'URIError', 'ArrayBuffer', 'Int8Array', 'Uint8Array', |
michael@0 | 30 | 'Int16Array', 'Uint16Array', 'Int32Array', 'Uint32Array', |
michael@0 | 31 | 'Float32Array', 'Float64Array', 'Uint8ClampedArray', |
michael@0 | 32 | 'WeakMap', 'Map', 'Set']; |
michael@0 | 33 | |
michael@0 | 34 | function go() { |
michael@0 | 35 | window.iwin = document.getElementById('ifr').contentWindow; |
michael@0 | 36 | |
michael@0 | 37 | // Test constructors that can be instantiated with zero arguments. |
michael@0 | 38 | for (var c of simpleConstructors) { |
michael@0 | 39 | ok(iwin[c], "Constructors appear: " + c); |
michael@0 | 40 | is(iwin[c], Cu.unwaiveXrays(iwin.wrappedJSObject[c]), |
michael@0 | 41 | "we end up with the appropriate constructor: " + c); |
michael@0 | 42 | is(Cu.unwaiveXrays(Cu.waiveXrays(new iwin[c]).constructor), iwin[c], |
michael@0 | 43 | "constructor property is set up right: " + c); |
michael@0 | 44 | is(Object.getPrototypeOf(new iwin[c]), |
michael@0 | 45 | Cu.unwaiveXrays(Cu.waiveXrays(iwin[c]).prototype), |
michael@0 | 46 | "prototype is correct: " + c); |
michael@0 | 47 | is(global(new iwin[c]), iwin, "Got the right global: " + c); |
michael@0 | 48 | } |
michael@0 | 49 | |
michael@0 | 50 | // Test Object in more detail. |
michael@0 | 51 | var num = new iwin.Object(4); |
michael@0 | 52 | is(num.valueOf(), 4, "primitive object construction works"); |
michael@0 | 53 | is(global(num), iwin, "correct global for num"); |
michael@0 | 54 | var obj = new iwin.Object(); |
michael@0 | 55 | obj.foo = 2; |
michael@0 | 56 | var withProto = iwin.Object.create(obj); |
michael@0 | 57 | is(global(withProto), iwin, "correct global for withProto"); |
michael@0 | 58 | is(withProto.foo, 2, "Inherits properly"); |
michael@0 | 59 | |
michael@0 | 60 | // Test Function. |
michael@0 | 61 | var primitiveFun = new iwin.Function('return 2'); |
michael@0 | 62 | is(global(primitiveFun), iwin, "function construction works"); |
michael@0 | 63 | is(primitiveFun(), 2, "basic function works"); |
michael@0 | 64 | var doSetFoo = new iwin.Function('arg', 'arg.foo = 2;'); |
michael@0 | 65 | is(global(doSetFoo), iwin, "function with args works"); |
michael@0 | 66 | try { |
michael@0 | 67 | doSetFoo(new Object()); |
michael@0 | 68 | ok(false, "should have thrown while setting property on object"); |
michael@0 | 69 | } catch (e) { |
michael@0 | 70 | ok(!!/denied/.test(e), "Threw correctly: " + e); |
michael@0 | 71 | } |
michael@0 | 72 | var factoryFun = new iwin.Function('return {foo: 32}'); |
michael@0 | 73 | is(global(factoryFun), iwin, "proper global for factoryFun"); |
michael@0 | 74 | is(factoryFun().foo, 32, "factoryFun invokable"); |
michael@0 | 75 | is(global(factoryFun()), iwin, "minted objects live in the content scope"); |
michael@0 | 76 | |
michael@0 | 77 | // Test interface objects that don't actually construct things. |
michael@0 | 78 | is(iwin.Math.tan(4.5), Math.tan(4.5), "Math.tan works"); |
michael@0 | 79 | is(iwin.Math.E, Math.E, "Math.E works"); |
michael@0 | 80 | var json = JSON.stringify({a: 2, b: 'hi', c: {d: 'there'}}); |
michael@0 | 81 | is(global(iwin.JSON.parse(json)), iwin, "JSON rehydrated into the right context"); |
michael@0 | 82 | is(iwin.JSON.stringify(iwin.JSON.parse(json)), json, "JSON composition identity holds"); |
michael@0 | 83 | |
michael@0 | 84 | // Test proxies. |
michael@0 | 85 | var targetObject = new iwin.Object(); |
michael@0 | 86 | targetObject.foo = 9; |
michael@0 | 87 | var forwardingProxy = new iwin.Proxy(targetObject, new iwin.Object()); |
michael@0 | 88 | is(global(forwardingProxy), iwin, "proxy global correct"); |
michael@0 | 89 | is(forwardingProxy.foo, 9, "forwards correctly"); |
michael@0 | 90 | // NB: COW-implemented proxy handlers are super dangerous, and we should not |
michael@0 | 91 | // encourage them. |
michael@0 | 92 | var handler = {get: function(target, name) { return name * 2; }, __exposedProps__: {get: 'r'}}; |
michael@0 | 93 | var doublingProxy = new iwin.Proxy(targetObject, handler); |
michael@0 | 94 | is(global(doublingProxy), iwin, "doubling proxy global correct"); |
michael@0 | 95 | is(doublingProxy[3], 6, "Doubles correctly"); |
michael@0 | 96 | is(doublingProxy[20], 40, "Doubles correctly"); |
michael@0 | 97 | |
michael@0 | 98 | // Test eval. |
michael@0 | 99 | var toEval = "({a: 2, b: {foo: 'bar'}, f: function() { return window; }})"; |
michael@0 | 100 | is(global(iwin.eval(toEval)), iwin, "eval creates objects in the correct global"); |
michael@0 | 101 | is(iwin.eval(toEval).b.foo, 'bar', "eval-ed object looks right"); |
michael@0 | 102 | is(iwin.eval(toEval).f(), iwin, "evaled function works right"); |
michael@0 | 103 | |
michael@0 | 104 | testDate(); |
michael@0 | 105 | |
michael@0 | 106 | // We could also test DataView and Iterator here for completeness, but it's |
michael@0 | 107 | // more trouble than it's worth. |
michael@0 | 108 | |
michael@0 | 109 | |
michael@0 | 110 | SimpleTest.finish(); |
michael@0 | 111 | } |
michael@0 | 112 | |
michael@0 | 113 | function filterOut(array, props) { |
michael@0 | 114 | return array.filter(p => props.indexOf(p) == -1); |
michael@0 | 115 | } |
michael@0 | 116 | |
michael@0 | 117 | function testXray(classname, xray, xray2, propsToSkip) { |
michael@0 | 118 | propsToSkip = propsToSkip || []; |
michael@0 | 119 | let xrayProto = Object.getPrototypeOf(xray); |
michael@0 | 120 | let localProto = window[classname].prototype; |
michael@0 | 121 | let protoProps = filterOut(Object.getOwnPropertyNames(localProto), propsToSkip).sort(); |
michael@0 | 122 | let protoMethods = protoProps.filter(name => typeof localProto[name] == 'function' && |
michael@0 | 123 | name != 'constructor'); |
michael@0 | 124 | ok(protoMethods.length > 0, "Need something to test"); |
michael@0 | 125 | is(xrayProto, iwin[classname].prototype, "Xray proto is correct"); |
michael@0 | 126 | is(xrayProto, xray.__proto__, "Proto accessors agree"); |
michael@0 | 127 | is(Object.getPrototypeOf(xrayProto), iwin.Object.prototype, "proto proto is correct"); |
michael@0 | 128 | for (let name of protoMethods) { |
michael@0 | 129 | info("Running tests for property: " + name); |
michael@0 | 130 | ok(xrayProto.hasOwnProperty(name), "proto should have the property as own"); |
michael@0 | 131 | ok(!xray.hasOwnProperty(name), "instance should not have the property as own"); |
michael@0 | 132 | let method = xrayProto[name]; |
michael@0 | 133 | is(typeof method, 'function', "Methods from Xrays are functions"); |
michael@0 | 134 | is(global(method), window, "Methods from Xrays are local"); |
michael@0 | 135 | ok(method instanceof Function, "instanceof works on methods from Xrays"); |
michael@0 | 136 | is(xrayProto[name], method, "Holder caching works properly"); |
michael@0 | 137 | is(xray[name], method, "Proto props resolve on the instance"); |
michael@0 | 138 | let local = localProto[name]; |
michael@0 | 139 | is(method.length, local.length, "Function.length identical"); |
michael@0 | 140 | if (method.length == 0) { |
michael@0 | 141 | is(xray[name]() + "", local.call(xray) + "", |
michael@0 | 142 | "Xray and local method results stringify identically"); |
michael@0 | 143 | is(xray[name]() + "", xray.wrappedJSObject[name]() + "", |
michael@0 | 144 | "Xray and waived method results stringify identically"); |
michael@0 | 145 | } |
michael@0 | 146 | } |
michael@0 | 147 | is(Object.getOwnPropertyNames(xrayProto).sort().toSource(), |
michael@0 | 148 | protoProps.toSource(), "getOwnPropertyNames works"); |
michael@0 | 149 | |
michael@0 | 150 | is(xrayProto.constructor, iwin[classname], "constructor property works"); |
michael@0 | 151 | |
michael@0 | 152 | xrayProto.expando = 42; |
michael@0 | 153 | is(xray.expando, 42, "Xrayed instances see proto expandos"); |
michael@0 | 154 | is(xray2.expando, 42, "Xrayed instances see proto expandos"); |
michael@0 | 155 | } |
michael@0 | 156 | |
michael@0 | 157 | function testDate() { |
michael@0 | 158 | // toGMTString is handled oddly in the engine. We don't bother to support |
michael@0 | 159 | // it over Xrays. |
michael@0 | 160 | // |
michael@0 | 161 | // We don't yet support self-hosted functions on Xrays. See bug 972987. |
michael@0 | 162 | let propsToSkip = ['toGMTString', 'toLocaleString', |
michael@0 | 163 | 'toLocaleDateString', 'toLocaleTimeString']; |
michael@0 | 164 | testXray('Date', new iwin.Date(), new iwin.Date(), propsToSkip); |
michael@0 | 165 | } |
michael@0 | 166 | |
michael@0 | 167 | ]]> |
michael@0 | 168 | </script> |
michael@0 | 169 | <iframe id="ifr" onload="go();" src="http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html" /> |
michael@0 | 170 | </window> |