summaryrefslogtreecommitdiffstats
path: root/js/src/tests/non262/ReadableStream/subclassing.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/tests/non262/ReadableStream/subclassing.js')
-rw-r--r--js/src/tests/non262/ReadableStream/subclassing.js111
1 files changed, 111 insertions, 0 deletions
diff --git a/js/src/tests/non262/ReadableStream/subclassing.js b/js/src/tests/non262/ReadableStream/subclassing.js
new file mode 100644
index 0000000000..c1ab7d4413
--- /dev/null
+++ b/js/src/tests/non262/ReadableStream/subclassing.js
@@ -0,0 +1,111 @@
+// |reftest| skip-if(!xulRuntime.shell) -- needs drainJobQueue
+
+if ("ignoreUnhandledRejections" in this) {
+ ignoreUnhandledRejections();
+}
+
+// Spot-check subclassing of stream constructors.
+
+// ReadableStream can be subclassed.
+class PartyStreamer extends ReadableStream {}
+
+// The base class constructor is called.
+let started = false;
+let stream = new PartyStreamer({
+ // (The ReadableStream constructor calls this start method.)
+ start(c) { started = true; }
+});
+drainJobQueue();
+assertEq(started, true);
+
+// The instance's prototype chain is correct.
+assertEq(stream.__proto__, PartyStreamer.prototype);
+assertEq(stream.__proto__.__proto__, ReadableStream.prototype);
+assertEq(stream.__proto__.__proto__.__proto__, Object.prototype);
+assertEq(stream.__proto__.__proto__.__proto__.__proto__, null);
+assertEq(stream instanceof ReadableStream, true);
+
+// Non-generic methods can be called on the resulting stream.
+let reader = stream.getReader();
+assertEq(stream.locked, true);
+
+
+// CountQueuingStrategy can be subclassed.
+class PixelStrategy extends CountQueuingStrategy {}
+assertEq(new PixelStrategy({highWaterMark: 4}).__proto__, PixelStrategy.prototype);
+
+// The base class constructor is called.
+assertThrowsInstanceOf(() => new PixelStrategy, TypeError);
+assertEq(new PixelStrategy({highWaterMark: -1}).highWaterMark, -1);
+
+
+// VerySmartStrategy can be subclassed.
+class VerySmartStrategy extends ByteLengthQueuingStrategy {
+ size(chunk) {
+ return super.size(chunk) * 8;
+ }
+}
+let vss = new VerySmartStrategy({highWaterMark: 12});
+assertEq(vss.size(new ArrayBuffer(8)), 64);
+assertEq(vss.__proto__, VerySmartStrategy.prototype);
+
+
+// Even ReadableStreamDefaultReader can be subclassed.
+async function readerTest() {
+ const ReadableStreamDefaultReader = new ReadableStream().getReader().constructor;
+ class MindReader extends ReadableStreamDefaultReader {
+ async read() {
+ let foretold = {value: "death", done: false};
+ let actual = await super.read();
+ actual = foretold; // ZOMG I WAS RIGHT, EXACTLY AS FORETOLD they should call me a righter
+ return actual;
+ }
+ }
+
+ let stream = new ReadableStream({
+ start(c) { c.enqueue("one"); c.enqueue("two"); },
+ pull(c) { c.close(); }
+ });
+ let reader = new MindReader(stream);
+ let result = await reader.read();
+ assertEq(result.value, "death");
+ reader.releaseLock();
+
+ reader = stream.getReader();
+ result = await reader.read();
+ assertEq(result.done, false);
+ assertEq(result.value, "two");
+ result = await reader.read();
+ assertEq(result.done, true);
+ assertEq(result.value, undefined);
+}
+runAsyncTest(readerTest);
+
+
+// Even ReadableStreamDefaultController, which can't be constructed,
+// can be subclassed.
+let ReadableStreamDefaultController;
+new ReadableStream({
+ start(c) {
+ ReadableStreamDefaultController = c.constructor;
+ }
+});
+class MasterController extends ReadableStreamDefaultController {
+ constructor() {
+ // don't call super, it'll just throw
+ return Object.create(MasterController.prototype);
+ }
+}
+let c = new MasterController();
+
+// The prototype chain is per spec.
+assertEq(c instanceof ReadableStreamDefaultController, true);
+
+// But the instance does not have the internal slots of a
+// ReadableStreamDefaultController, so the non-generic methods can't be used.
+assertThrowsInstanceOf(() => c.enqueue("horse"), TypeError);
+
+
+if (typeof reportCompare === 'function') {
+ reportCompare(0, 0);
+}