diff --git a/js/xpconnect/tests/chrome/test_xrayToJS.xul b/js/xpconnect/tests/chrome/test_xrayToJS.xul index 53f0100c6537..0b71e5c48bf7 100644 --- a/js/xpconnect/tests/chrome/test_xrayToJS.xul +++ b/js/xpconnect/tests/chrome/test_xrayToJS.xul @@ -146,6 +146,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=933681 testPromise(); + testArrayBuffer(); + // We could also test DataView and Iterator here for completeness, but it's // more trouble than it's worth. @@ -250,6 +252,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=933681 gConstructorProperties['Promise'] = constructorProps(["resolve", "reject", "all", "race", Symbol.species]); + gPrototypeProperties['ArrayBuffer'] = + ["constructor", "byteLength", "slice", Symbol.toStringTag]; + gConstructorProperties['ArrayBuffer'] = + constructorProps(["isView", "slice", Symbol.species]); + // Sort an array that may contain symbols as well as strings. function sortProperties(arr) { function sortKey(prop) { @@ -304,14 +311,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=933681 "Xray and local method results stringify identically"); // If invoking this method returns something non-Xrayable, the - // stringification is going to return [object Opaque]. This happens for - // xrayedTypedArray.buffer, for instance, since we don't have Xrays - // to ArrayBuffers. Just check for that case. - if (!/Opaque/.test(method.call(xray))) { - is(method.call(xray) + "", - lookupCallable(xray.wrappedJSObject).call(xray.wrappedJSObject) + "", - "Xray and waived method results stringify identically"); - } + // stringification is going to return [object Opaque]. + ok(!/Opaque/.test(method.call(xray)), "Method result is xrayable"); + is(method.call(xray) + "", + lookupCallable(xray.wrappedJSObject).call(xray.wrappedJSObject) + "", + "Xray and waived method results stringify identically"); } } } @@ -888,6 +892,36 @@ for (var prop of props) { is(Cu.getGlobalForObject(pr.wrappedJSObject.then), iwin, "Underlying global is correct"); } + function testArrayBuffer() { + testXray('ArrayBuffer', new iwin.ArrayBuffer(0), new iwin.ArrayBuffer(12)); + + var t = new iwin.ArrayBuffer(12); + is(t.byteLength, 12, "ArrayBuffer byteLength is correct"); + is(t.slice(4).byteLength, 8, "ArrayBuffer byteLength is correct after slicing"); + is(Cu.getGlobalForObject(t.slice(4)), iwin, "Slice results lives in the target compartment"); + is(Object.getPrototypeOf(t.slice(4)), iwin.ArrayBuffer.prototype, "Slice results proto lives in target compartment") + is(ArrayBuffer.slice(t, 4).byteLength, 8, "ArrayBuffer.slice (deprecated) works"); + + var i32Array = new Int32Array(t); + // i32Array is going to be created in the buffer's target compartment, + // but usually this is unobservable, because the proto is set to + // the current compartment's prototype. + // However Xrays ignore the object's proto and claim its proto is + // the default proto for that class in the relevant compartment, + // so see through this proto hack. + todo_is(Object.getPrototypeOf(i32Array), Int32Array.prototype, "Int32Array has correct proto"); + is(i32Array.length, 3, "Int32Array created from Xray ArrayBuffer has the correct length"); + is(i32Array.buffer, t, "Int32Array has the correct buffer that we passed in"); + + i32Array = new iwin.Int32Array(t); + is(Object.getPrototypeOf(i32Array), iwin.Int32Array.prototype, "Xray Int32Array has correct proto"); + is(i32Array.length, 3, "Xray Int32Array created from Xray ArrayBuffer has the correct length"); + is(i32Array.buffer, t, "Xray Int32Array has the correct buffer that we passed in"); + + t = (new iwin.Int32Array(2)).buffer; + is(t.byteLength, 8, "Can access ArrayBuffer returned by buffer property"); + } + ]]>