[Streams API] Replace ReadableStreamController by ReadableStreamDefaultController
[WebKit-https.git] / LayoutTests / streams / shadowing-Promise.html
1 <!DOCTYPE html>
2 <script src='../resources/testharness.js'></script>
3 <script src='../resources/testharnessreport.js'></script>
4 <script>
5 test(function() {
6     const PromiseBackup = Promise;
7
8     try {
9         Promise = function() { assert_unreached("streams should not use this Promise object"); };
10
11         new ReadableStream();
12         new WritableStream();
13     } finally {
14         Promise = PromiseBackup;
15     }
16 }, 'Streams and promises: replace Promise constructor');
17
18 test(function() {
19     const PromiseResolveBackup = Promise.resolve;
20
21     try {
22         Promise.resolve = function() { assert_unreached("streams should not use this Promise.resolve method"); };
23
24         new ReadableStream();
25         new WritableStream();
26     } finally {
27         Promise.resolve = PromiseResolveBackup;
28     }
29 }, 'Streams and promises: replace Promise.resolve');
30
31 test(function() {
32     const PromiseRejectBackup = Promise.reject;
33
34     try {
35         Promise.reject = function() { assert_unreached("streams should not use this Promise.reject method"); };
36
37         ReadableStream.prototype.cancel.call({}, "reason");
38         WritableStream.prototype.abort.call({}, "reason");
39     } finally {
40         Promise.reject = PromiseRejectBackup;
41     }
42 }, 'Streams and promises: replace Promise.reject');
43
44 test(function() {
45     function createMangledPromise() {
46         const promise = Promise.resolve();
47         Object.setPrototypeOf(promise, { constructor: Promise, then: function() { assert_unreached("streams should not use this promise then method"); } });
48         return promise;
49     }
50     new ReadableStream({ start: function() { return createMangledPromise(); } })
51     new WritableStream({ start: function() { return createMangledPromise(); } })
52 }, 'Streams and promises: replace prototype of a promise object');
53
54 test(function() {
55     const PromiseThenBackup = Promise.prototype.then;
56
57     try {
58         Promise.prototype.then = function() { assert_unreached("streams should not use this Promise.prototype.then method"); };
59
60         new ReadableStream();
61         new WritableStream();
62     } finally {
63         Promise.prototype.then = PromiseThenBackup;
64     }
65 }, 'Streams and promises: replace then method in Promise prototype');
66
67 test(function() {
68     const PromiseCatchBackup = Promise.prototype.catch;
69     const PromiseThenBackup = Promise.prototype.then;
70
71     try {
72         Promise.prototype.catch = function() { assert_unreached("streams should not use this Promise.prototype.catch method"); };
73         Promise.prototype.then = function() { assert_unreached("streams should not use this Promise.prototype.catch method"); };
74
75         const rs = new ReadableStream();
76         rs.tee();
77     } finally {
78         Promise.prototype.catch = PromiseCatchBackup;
79         Promise.prototype.then = PromiseThenBackup;
80     }
81 }, 'Streams and promises: replace catch method in Promise prototype');
82
83 test(function() {
84     function createMangledPromise() {
85         const promise = Promise.resolve();
86         promise.then = function() { assert_unreached("streams should not use this promise then method"); };
87         return promise;
88     }
89     new ReadableStream({ start: function() { return createMangledPromise(); } })
90     new WritableStream({ start: function() { return createMangledPromise(); } })
91 }, 'Streams and promises: replace then method in promise object');
92
93 test(function() {
94     const NumberBackup = Number;
95     const NumberIsNaNBackup = Number.isNaN;
96     const NumberIsFiniteBackup = Number.isFinite;
97
98     try {
99         Number.isNaN = function() { assert_unreached("streams should not use this Number.isNaN method"); };
100         Number.isFinite = function() { assert_unreached("streams should not use this Number.isFinite method"); };
101         Number = null;
102
103         new ReadableStream({
104             start: function(controller) {
105                 controller.enqueue("small potato");
106             }
107         }, {
108             size: function(chunk) { return 2; },
109             highWaterMark: 1
110         });
111
112     } finally {
113         Number = NumberBackup;
114         Number.isNaN = NumberIsNaNBackup;
115         Number.isFinite = NumberIsFiniteBackup;
116     }
117 }, 'Streams should not directly use Number and related methods');
118 test(function() {
119     const ReadableStreamGetReaderBackup = ReadableStream.prototype.getReader;
120
121     try {
122         ReadableStream.prototype.getReader = function() { assert_unreached("streams should not use this ReadableStream.getReader method"); };
123         new ReadableStream().tee();
124     } finally {
125         ReadableStream.prototype.getReader = ReadableStreamGetReaderBackup;
126     }
127 }, 'Streams should not directly use ReadableStream public APIs');
128
129 promise_test(function() {
130     const ReadableStreamDefaultReader = new ReadableStream().getReader().constructor;
131     const ReadableStreamDefaultReaderReadBackup = ReadableStreamDefaultReader.prototype.read;
132
133     function cleanTest() {
134         ReadableStreamDefaultReader.prototype.read = ReadableStreamDefaultReaderReadBackup;
135     }
136
137     try {
138         ReadableStreamDefaultReader.prototype.read = function() { assert_unreached("streams should not use this ReadableStreamDefaultReader.read method"); };
139
140         [s1, s2] = new ReadableStream({
141             start: function(controller) {
142                 controller.close();
143             }
144         }).tee();
145         return s1.getReader().closed.then(cleanTest, cleanTest);
146
147     } catch (error) {
148         cleanTest();
149         assert_unreached("test should not throw");
150     }
151 }, 'Streams should not directly use ReadableStreamDefaultReader read public API');
152
153 promise_test(function() {
154     const ArrayPushBackup = Array.prototype.push;
155     const ArrayShiftBackup = Array.prototype.shift;
156
157     // Use of testing variable to try not messing up testharness.js code.
158     // FIXME: this approach is far from perfect: push is used in case an assert fails.
159     // But cleanTest will not be called and we may end-up mask the real assertion failure by below assert_unreached messages.
160     // We might want to either improve testharness.js or  move these tests out of testharness.js.
161     let testing = true;
162     Array.prototype.push = function() {
163         if (testing) {
164             testing = false;
165             assert_unreached("Array.prototype.push called");
166         }
167         return ArrayPushBackup.apply(this, arguments);
168     }
169
170     Array.prototype.shift = function() {
171         if (testing) {
172             testing = false;
173             assert_unreached("Array.prototype.shift called");
174         }
175         return ArrayShiftBackup.call(this, arguments);
176     }
177
178     function cleanTest() {
179         Array.prototype.push = ArrayPushBackup;
180         Array.prototype.shift = ArrayShiftBackup;
181     }
182     try {
183         let _controller;
184         const reader = new ReadableStream({
185             start: function(controller) {
186                 _controller = controller;
187             }
188         }).getReader();
189         // checking whether pushing/shifting pending read promises is shielded.
190         const readPromise = reader.read().then(function(result) {
191             assert_equals(result.value, "half baked potato");
192             // checking whether pushing/shifting enqueued values is shielded.
193             _controller.enqueue("fully baked potato");
194             return reader.read().then(function(result) {
195                 assert_equals(result.value, "fully baked potato");
196                 cleanTest();
197             }, cleanTest);
198         }, cleanTest);
199         _controller.enqueue("half baked potato");
200         return readPromise;
201     } catch (error) {
202         cleanTest();
203         return Promise.reject(error);
204     }
205 }, 'Streams should not directly use array public APIs');
206 </script>