Index: LayoutTests/streams/streams-gc.html |
diff --git a/LayoutTests/streams/streams-gc.html b/LayoutTests/streams/streams-gc.html |
new file mode 100644 |
index 0000000000000000000000000000000000000000..c7e4adff8450ca9018ed179f262968c1f0cd7e9f |
--- /dev/null |
+++ b/LayoutTests/streams/streams-gc.html |
@@ -0,0 +1,174 @@ |
+<!DOCTYPE html> |
+<script src="../resources/testharness.js"></script> |
+<script src="../resources/testharnessreport.js"></script> |
+ |
+<div id="container"> |
+ <div id="element"></div> |
+</div> |
+ |
+<script> |
+"use strict"; |
+ |
+promise_test(function () { |
+ let request, source; |
+ { |
+ const holder = internals.createReadableStreamTestCase(); |
+ request = holder.request; |
+ source = holder.source; |
+ } |
+ |
+ const body = request.body; |
+ const reader = body.getReader(); |
+ request = undefined; |
+ |
+ gc(); |
+ |
+ source.enqueue(1); |
+ |
+ return reader.read().then(function (result) { |
+ assert_equals(result.value, 1); |
+ assert_equals(result.done, false); |
+ |
+ source.close(); |
+ |
+ return reader.read().then(function (result) { |
+ assert_equals(result.value, undefined); |
+ assert_equals(result.done, true); |
+ }); |
+ }); |
+}, "when the request is GCed (but not the stream), enqueue and close should still work"); |
+ |
+promise_test(function (t) { |
+ let request, source; |
+ { |
+ const holder = internals.createReadableStreamTestCase(); |
+ request = holder.request; |
+ source = holder.source; |
+ } |
+ |
+ let body = request.body; |
+ const reader = body.getReader(); |
+ request = undefined; |
+ body = undefined; |
+ |
+ gc(); |
+ |
+ source.enqueue(2); |
+ |
+ return reader.read().then(function (result) { |
+ assert_equals(result.value, 2); |
+ assert_equals(result.done, false); |
+ |
+ const e = new Error("boo!"); |
+ source.error(e); |
+ |
+ const unreached = t.unreached_func('promise should not be fulfilled'); |
+ return reader.read().then( |
+ unreached, |
+ function (err) { |
+ assert_equals(err, e); |
+ } |
+ ); |
+ }); |
+}, "when the request and stream are GCed (but not the reader), enqueue and error should still work"); |
+ |
+promise_test(function () { |
+ let request, source; |
+ { |
+ const holder = internals.createReadableStreamTestCase(); |
+ request = holder.request; |
+ source = holder.source; |
+ } |
+ |
+ let body = request.body; |
+ let reader = body.getReader(); |
+ const closed = reader.closed; |
+ request = undefined; |
+ body = undefined; |
+ reader = undefined; |
+ |
+ gc(); |
+ |
+ source.close(); |
+ |
+ return closed; |
+}, "when the request and stream and reader are GCed (but a closed promise is kept), close should still work"); |
+ |
+promise_test(function (t) { |
+ let request, source; |
+ { |
+ const holder = internals.createReadableStreamTestCase(); |
+ request = holder.request; |
+ source = holder.source; |
+ } |
+ |
+ let body = request.body; |
+ let reader = body.getReader(); |
+ const closed = reader.closed; |
+ request = undefined; |
+ body = undefined; |
+ reader = undefined; |
+ |
+ gc(); |
+ |
+ const e = new Error("boo!"); |
+ source.error(e); |
+ |
+ const unreached = t.unreached_func('promise should not be fulfilled'); |
+ return closed.then( |
+ unreached, |
+ function (err) { |
+ assert_equals(err, e); |
+ } |
+ ); |
+}, "when the request and stream and reader are GCed (but a closed promise is kept), error should still work"); |
+ |
+test(function () { |
+ let request, source; |
+ { |
+ const holder = internals.createReadableStreamTestCase(); |
+ request = holder.request; |
+ source = holder.source; |
+ } |
+ |
+ request = undefined; |
+ |
+ gc(); |
+ |
+ source.enqueue("a"); |
+ source.enqueue(2); |
+ source.close(); |
+}, "enqueuing and closing after the request/stream/etc. are collected should be a no-op, not a crash"); |
+ |
+test(function () { |
+ let request, source; |
+ { |
+ const holder = internals.createReadableStreamTestCase(); |
+ request = holder.request; |
+ source = holder.source; |
+ } |
+ |
+ request.body.cancel(); |
+ |
+ request = undefined; |
+ |
+ gc(); |
+ |
+ source.enqueue("a"); |
+ source.enqueue(2); |
+ source.close(); |
+}, "enqueuing and closing after the stream has been canceled should be a no-op, not a crash"); |
+ |
+test(function () { |
+ let request = internals.createReadableStreamTestCase().request; |
+ let body = request.body; |
+ |
+ body.request = request; |
+ |
+ request = undefined; |
+ body = undefined; |
+ |
+ gc(); |
+}, "attaching a request to a stream should not cause a leak or crash"); |
+ |
+</script> |