OLD | NEW |
---|---|
1 <!doctype html> | 1 <!doctype html> |
2 <html> | 2 <html> |
3 <head> | 3 <head> |
4 <title>Test AudioContext.close()</title> | 4 <title>Test AudioContext.close()</title> |
5 <script src="resources/compatibility.js"></script> | 5 <script src="../resources/js-test.js"></script> |
6 <script src="resources/audio-testing.js"></script> | 6 <script src="resources/compatibility.js"></script> |
7 <script src="../resources/js-test.js"></script> | 7 <script src="resources/audio-testing.js"></script> |
8 </head> | 8 </head> |
9 | 9 |
10 <body> | 10 <body> |
11 <script> | 11 <script> |
12 description("Basic functionality test of closing an AudioContext"); | 12 description("Basic functionality test of closing an AudioContext"); |
13 window.jsTestIsAsync = true; | |
13 | 14 |
14 var context; | 15 var context; |
15 var offline; | 16 var offline; |
16 var osc; | 17 var osc; |
17 var gain; | 18 var gain; |
18 var promise1; | 19 var promise1; |
19 var promise2; | 20 var promise2; |
20 var offlinePromise; | 21 var offlinePromise; |
21 var wave = new Float32Array(1); | 22 var wave = new Float32Array(1); |
23 | |
24 var audit = Audit.createTaskRunner(); | |
25 | |
26 // Task: test online context (1). | |
27 audit.defineTask('test-online-context-1', function (done) { | |
28 | |
29 // Create a context and verify that the various states are correct and | |
30 // that close() exists. | |
31 shouldNotThrow("context = new AudioContext()"); | |
32 shouldBeEqualToString("context.state", "running"); | |
33 | |
34 // Create gain and oscillator for testing later. | |
35 shouldNotThrow("osc = context.createOscillator()"); | |
36 shouldNotThrow("gain = context.createGain()"); | |
37 shouldNotThrow("gain.connect(context.destination)"); | |
38 | |
39 // Close the context. When the promise is resolved, continue the next | |
40 // test task. | |
41 context.close().then( | |
42 function () { | |
43 testPassed("context.close() was correctly resolved"); | |
44 }, | |
45 function () { | |
46 testFailed("context.close() was erroneously rejected"); | |
47 } | |
48 ).then(done); | |
49 | |
50 }); | |
51 | |
52 // Task: test online context (2). | |
53 audit.defineTask('test-online-context-2', function (done) { | |
54 | |
55 // Context is closed, so verify that we cannot create any more nodes, | |
56 // nor connect any. | |
57 shouldThrow("context.createAnalyser()"); | |
58 shouldThrow("context.createBiquadFilter()"); | |
59 | |
60 // createBuffer is an exception because it's not really tied in any way | |
61 // to an audio context. And it's useful to be able to create a buffer | |
62 // inside the oncomplete event of an offline context to use for testing | |
63 // purposes. | |
64 shouldNotThrow("context.createBuffer(1, 1, 48000)"); | |
65 | |
66 shouldThrow("context.createBufferSource()"); | |
67 shouldThrow("context.createChannelMerger()"); | |
68 shouldThrow("context.createChannelSplitter()"); | |
69 shouldThrow("context.createConvolver()"); | |
70 shouldThrow("context.createDelay()"); | |
71 shouldThrow("context.createDynamicsCompressor()"); | |
72 shouldThrow("context.createGain()"); | |
73 shouldThrow("context.createOscillator()"); | |
74 shouldThrow("context.createPanner()"); | |
75 shouldThrow("context.createPeriodicWave(wave, wave)"); | |
76 shouldThrow("context.createScriptProcessor()"); | |
77 shouldThrow("context.createStereoPanner()"); | |
78 shouldThrow("context.createWaveShaper()"); | |
79 | |
80 shouldThrow("osc.connect(gain)"); | |
81 shouldNotThrow("gain.disconnect()"); | |
82 | |
83 // Can't resume a context that is closed (released). | |
84 context.resume().then( | |
85 function () { | |
86 testFailed("Attempt to resume a closed context erroneously succeeded") ; | |
87 }, | |
88 function () { | |
89 testPassed("Attempt to resume a closed context was correctly rejected" ); | |
90 } | |
91 ).then(done); | |
92 }); | |
93 | |
94 // Task: test online context (3). | |
95 audit.defineTask('test-online-context-3', function (done) { | |
22 | 96 |
97 // Try closing the context again. The promise should be rejected. | |
98 context.close().then( | |
99 function () { | |
100 testFailed("Closing context again erroneously resolved successfully.") ; | |
101 }, | |
102 function () { | |
103 testPassed("Closing context again correctly rejected promise."); | |
23 | 104 |
24 function runTest() { | 105 // Finally, run GC. The context should be gone, but this seems |
25 window.jsTestIsAsync = true; | 106 // difficult to verify. |
26 runOnlineTest(); | 107 if (window.hasOwnProperty('GCController')) { |
27 } | 108 asyncGC(function () { |
109 shouldBeNull("context.destination"); | |
110 }); | |
111 } else { | |
112 shouldBeNull("context.destination"); | |
113 testFailed("asyncGC test not run"); | |
114 } | |
115 } | |
116 ).then(done); | |
117 }); | |
118 | |
119 // Task: test offline context (1). | |
120 audit.defineTask('test-offline-context-1', function (done) { | |
28 | 121 |
29 function runOnlineTest() { | 122 // For an offline context, just check that if we try to close the context, |
30 // Create a context and verify that the various states are correct and t hat close() exists. | 123 // nothing happens except that the promise returned by close() is rejected . |
31 shouldNotThrow("context = new AudioContext()"); | 124 shouldNotThrow("offline = new OfflineAudioContext(1, 1000, 48000)"); |
32 shouldBeEqualToString("context.state", "running"); | 125 shouldBeEqualToString("offline.state", "suspended"); |
126 offline.close().then( | |
127 function () { | |
128 testFailed("Closing offline context erroneously resolved"); | |
129 }, | |
130 function () { | |
131 testPassed("Closing offline context correctly rejected"); | |
132 } | |
133 ).then(done); | |
134 }); | |
33 | 135 |
34 // Create gain and oscillator for testing later. | 136 // Task: test offline context (2). |
35 shouldNotThrow("osc = context.createOscillator()"); | 137 audit.defineTask('test-offline-context-2', function (done) { |
36 shouldNotThrow("gain = context.createGain()"); | 138 |
37 shouldNotThrow("gain.connect(context.destination)"); | 139 // Try closing again |
140 offline.close().then( | |
141 function () { | |
142 testFailed("Closing offline context again erroneously resolved"); | |
143 }, | |
144 function () { | |
145 testPassed("Closing offline context again correctly rejected"); | |
146 } | |
147 ).then( | |
148 function () { | |
38 | 149 |
39 // Close the context. When the promise is resolved, continue online tes ting, and then run | 150 // Render the context, and check for a valid state |
40 // the offline tests. | 151 offline.oncomplete = function (event) { |
41 context.close() | 152 shouldBeEqualToString("offline.state", "closed"); |
hongchan
2015/02/20 22:23:04
I will do this in the next patch set. Sorry for mi
| |
42 .then(function () { | 153 done(); |
43 testPassed("context.close() was correctly resolved"); | 154 }; |
44 continueOnlineTest(); | 155 shouldNotThrow("offline.startRendering()"); |
45 }, | 156 } |
46 function () { | 157 ); |
47 testFailed("context.close() was erroneously rejected"); | |
48 }) | |
49 .then(runOfflineTest); | |
50 } | |
51 | 158 |
52 function continueOnlineTest() { | 159 }); |
53 // Context is released, so verify that we cannot create any more nodes, nor connect any. | |
54 shouldThrow("context.createAnalyser()"); | |
55 shouldThrow("context.createBiquadFilter()"); | |
56 // createBuffer is an exception because it's not really tied in any way to an audio | |
57 // context. And it's useful to be able to create a buffer inside the onc omplete event of an | |
58 // offline context to use for testing purposes. | |
59 shouldNotThrow("context.createBuffer(1, 1, 48000)"); | |
60 shouldThrow("context.createBufferSource()"); | |
61 shouldThrow("context.createChannelMerger()"); | |
62 shouldThrow("context.createChannelSplitter()"); | |
63 shouldThrow("context.createConvolver()"); | |
64 shouldThrow("context.createDelay()"); | |
65 shouldThrow("context.createDynamicsCompressor()"); | |
66 shouldThrow("context.createGain()"); | |
67 shouldThrow("context.createOscillator()"); | |
68 shouldThrow("context.createPanner()"); | |
69 shouldThrow("context.createPeriodicWave(wave, wave)"); | |
70 shouldThrow("context.createScriptProcessor()"); | |
71 shouldThrow("context.createStereoPanner()"); | |
72 shouldThrow("context.createWaveShaper()"); | |
73 | 160 |
74 shouldThrow("osc.connect(gain)"); | 161 audit.defineTask('finish-test', function (done) { |
75 shouldNotThrow("gain.disconnect()"); | 162 done(); |
163 finishJSTest(); | |
164 }); | |
76 | 165 |
77 // Can't resume a context that is closed (released). | 166 audit.runTasks( |
78 context.resume() | 167 'test-online-context-1', |
79 .then(function () { | 168 'test-online-context-2', |
80 testFailed("Attempt to resume a closed context erroneousl y succeeded"); | 169 'test-online-context-3', |
81 }, | 170 'test-offline-context-1', |
82 function () { | 171 'test-offline-context-2', |
83 testPassed("Attempt to resume a closed context was correc tly rejected"); | 172 'finish-test' |
84 }) | 173 ); |
85 .then(continueOnlineTest2); | 174 |
86 | 175 successfullyParsed = true; |
87 } | 176 </script> |
88 | 177 </body> |
89 function continueOnlineTest2() { | |
90 // Try closing the context again. The promise should be rejected. | |
91 context.close() | |
92 .then(function () { | |
93 testFailed("Closing context again erroneously resolved su ccessfully."); | |
94 }, | |
95 function () { | |
96 testPassed("Closing context again correctly rejected prom ise."); | |
97 // Finally, run GC. The context should be gone, but this seems difficult to verify. | |
98 if (window.hasOwnProperty('GCController')) { | |
99 asyncGC(function () { | |
100 shouldBeNull("context.destination"); | |
101 }); | |
102 } else { | |
103 shouldBeNull("context.destination"); | |
104 testFailed("asyncGC test not run"); | |
105 } | |
106 }); | |
107 } | |
108 | |
109 function runOfflineTest () { | |
110 // For an offline context, just check that if we try to close the contex t, nothing happens | |
111 // except that the promise returned by close() is rejected. | |
112 shouldNotThrow("offline = new OfflineAudioContext(1, 1000, 48000)"); | |
113 shouldBeEqualToString("offline.state", "suspended"); | |
114 offline.close() | |
115 .then(function () { | |
116 testFailed("Closing offline context erroneously resolved" ); | |
117 }, | |
118 function () { | |
119 testPassed("Closing offline context correctly rejected"); | |
120 }) | |
121 .then(continueOfflineTest); | |
122 } | |
123 | |
124 function continueOfflineTest () { | |
125 // Try closing again | |
126 offline.close() | |
127 .then(function () { | |
128 testFailed("Closing offline context again erroneously res olved"); | |
129 }, function () { | |
130 testPassed("Closing offline context again correctly rejec ted"); | |
131 }) | |
132 .then(function () { | |
133 // Render the context, and check for a valid state | |
134 offline.oncomplete = function (event) { | |
135 shouldBeEqualToString("offline.sta te", "closed"); | |
136 finishJSTest(); | |
137 }; | |
138 shouldNotThrow("offline.startRendering()"); | |
139 }); | |
140 } | |
141 | |
142 runTest(); | |
143 successfullyParsed = true; | |
144 </script> | |
145 </body> | |
146 </html> | 178 </html> |
OLD | NEW |