| OLD | NEW |
| 1 <!doctype html> | 1 <!doctype html> |
| 2 <html> | 2 <html> |
| 3 <head> | 3 <head> |
| 4 <title>Test AudioContext.suspend() and AudioContext.resume()</title> | 4 <title>Test AudioContext.suspend() and AudioContext.resume()</title> |
| 5 <script src="../../resources/js-test.js"></script> | 5 <script src="../../resources/testharness.js"></script> |
| 6 <script src="../../resources/testharnessreport.js"></script> |
| 6 <script src="../resources/audit-util.js"></script> | 7 <script src="../resources/audit-util.js"></script> |
| 7 <script src="../resources/audio-testing.js"></script> | 8 <script src="../resources/audit.js"></script> |
| 8 </head> | 9 </head> |
| 9 | 10 |
| 10 <body> | 11 <body> |
| 11 <script> | 12 <script> |
| 12 description("Test suspend/resume for an (offline) AudioContext"); | 13 let offlineContext; |
| 13 window.jsTestIsAsync = true; | 14 let osc; |
| 15 let p1; |
| 16 let p2; |
| 17 let p3; |
| 14 | 18 |
| 15 var offlineContext; | 19 let sampleRate = 44100; |
| 16 var osc; | 20 let durationInSeconds = 1; |
| 17 var p1; | |
| 18 var p2; | |
| 19 var p3; | |
| 20 | 21 |
| 21 var sampleRate = 44100; | 22 let audit = Audit.createTaskRunner(); |
| 22 var durationInSeconds = 1; | |
| 23 | |
| 24 var audit = Audit.createTaskRunner(); | |
| 25 | |
| 26 // Convenience function that returns a function that calls the |passFailFunc
| | |
| 27 // with the given |message|. The |passFailFunc| should be either |testPasse
d| | |
| 28 // or |testFailed|. | |
| 29 function handlePromise(passFailFunc, message) { | |
| 30 return function () { | |
| 31 passFailFunc(message); | |
| 32 }; | |
| 33 } | |
| 34 | 23 |
| 35 // Task: test suspend(). | 24 // Task: test suspend(). |
| 36 audit.defineTask('test-suspend', function (done) { | 25 audit.define('test-suspend', function (task, should) { |
| 37 | 26 task.describe("Test suspend() for offline context"); |
| 38 // Test suspend/resume. Ideally this test is best with a online | 27 // Test suspend/resume. Ideally this test is best with a online |
| 39 // AudioContext, but content shell doesn't really have a working online | 28 // AudioContext, but content shell doesn't really have a working online |
| 40 // AudioContext. Hence, use an OfflineAudioContext. Not all possible | 29 // AudioContext. Hence, use an OfflineAudioContext. Not all possible |
| 41 // scenarios can be easily checked with an offline context instead of an | 30 // scenarios can be easily checked with an offline context instead of an |
| 42 // online context. | 31 // online context. |
| 43 | 32 |
| 44 // Create an audio context with an oscillator. | 33 // Create an audio context with an oscillator. |
| 45 shouldNotThrow("offlineContext = new OfflineAudioContext(1, durationInSeco
nds * sampleRate, sampleRate)"); | 34 should(function () { |
| 35 offlineContext = new OfflineAudioContext(1, durationInSeconds * |
| 36 sampleRate, sampleRate); |
| 37 }, |
| 38 "offlineContext = new OfflineAudioContext(1, " + (durationInSeconds * |
| 39 sampleRate) + ", " + sampleRate + ")" |
| 40 ) |
| 41 .notThrow(); |
| 46 osc = offlineContext.createOscillator(); | 42 osc = offlineContext.createOscillator(); |
| 47 osc.connect(offlineContext.destination); | 43 osc.connect(offlineContext.destination); |
| 48 | 44 |
| 49 // Verify the state. | 45 // Verify the state. |
| 50 shouldBeEqualToString("offlineContext.state", "suspended"); | 46 should(offlineContext.state, "offlineContext.state") |
| 47 .beEqualTo("suspended"); |
| 51 | 48 |
| 52 // Multiple calls to suspend() should not be a problem. But we can't test | 49 // Multiple calls to suspend() should not be a problem. But we can't test |
| 53 // that on an offline context. Thus, check that suspend() on an | 50 // that on an offline context. Thus, check that suspend() on an |
| 54 // OfflineAudioContext rejects the promise. | 51 // OfflineAudioContext rejects the promise. |
| 55 shouldNotThrow("p1 = offlineContext.suspend()"); | 52 should(function () { |
| 56 shouldBeType("p1", "Promise"); | 53 p1 = offlineContext.suspend(); |
| 57 p1.then( | 54 }, "p1 = offlineContext.suspend()") |
| 58 handlePromise(testFailed, "offlineContext.suspend() should have been rej
ected for an offline context"), | 55 .notThrow(); |
| 59 function (e) { | 56 should(p1 instanceof Promise, "p1 instanceof Promise") |
| 60 if (e.name === "TypeError") { | 57 .beTrue(); |
| 61 testPassed( | 58 |
| 62 "offlineContext.suspend() was correctly rejected: " + e); | 59 should(p1, "p1") |
| 63 } else { | 60 .beRejected() |
| 64 testFailed( | 61 .then(task.done.bind(task)); |
| 65 "offlineContext.suspend() was correctly rejected but expected Type
Error, not: " + e); | |
| 66 } | |
| 67 } | |
| 68 ).then(done); | |
| 69 }); | 62 }); |
| 70 | 63 |
| 71 | 64 |
| 72 // Task: test resume(). | 65 // Task: test resume(). |
| 73 audit.defineTask('test-resume', function (done) { | 66 audit.define('test-resume', function (task, should) { |
| 74 | 67 task.describe("Test resume() for offline context"); |
| 75 // Multiple calls to resume should not be a problem. But we can't test | 68 // Multiple calls to resume should not be a problem. But we can't test |
| 76 // that on an offline context. Thus, check that resume() on an | 69 // that on an offline context. Thus, check that resume() on an |
| 77 // OfflineAudioContext rejects the promise. | 70 // OfflineAudioContext rejects the promise. |
| 78 shouldNotThrow("p2 = offlineContext.resume()"); | 71 should(function () { |
| 79 shouldBeType("p2", "Promise"); | 72 p2 = offlineContext.resume(); |
| 80 | 73 }, "p2 = offlineContext.resume()") |
| 74 .notThrow(); |
| 75 should(p2 instanceof Promise, "p2 instanceof Promise") |
| 76 .beTrue(); |
| 77 |
| 81 // Resume doesn't actually resume an offline context | 78 // Resume doesn't actually resume an offline context |
| 82 shouldBeEqualToString("offlineContext.state", "suspended"); | 79 should(offlineContext.state, "offlineContext.state") |
| 83 p2.then( | 80 .beEqualTo("suspended"); |
| 84 handlePromise(testFailed, "offlineContext.resume() should have been reje
cted for an offline context"), | 81 should(p2, "p2") |
| 85 function (e) { | 82 .beRejected() |
| 86 if (e.name === "InvalidStateError") { | 83 .then(task.done.bind(task)); |
| 87 testPassed( | |
| 88 "offlineContext.resume() was correctly rejected: " + e); | |
| 89 } else { | |
| 90 testFailed( | |
| 91 "offlineContext.resume() was correctly rejected but expected Inval
idAccessError, not: " + e); | |
| 92 } | |
| 93 } | |
| 94 ).then(done); | |
| 95 }); | 84 }); |
| 96 | 85 |
| 97 // Task: test the state after context closed. | 86 // Task: test the state after context closed. |
| 98 audit.defineTask('test-after-close', function (done) { | 87 audit.define('test-after-close', function (task, should) { |
| 99 | 88 task.describe("Test state after context closed"); |
| 100 // Render the offline context. | 89 // Render the offline context. |
| 101 osc.start(); | 90 osc.start(); |
| 102 | 91 |
| 103 // Test suspend/resume in tested promise pattern. We don't care about the | 92 // Test suspend/resume in tested promise pattern. We don't care about the |
| 104 // actual result of the offline rendering. | 93 // actual result of the offline rendering. |
| 105 shouldNotThrow("p3 = offlineContext.startRendering()"); | 94 should(function () { |
| 95 p3 = offlineContext.startRendering(); |
| 96 }, "p3 = offlineContext.startRendering()") |
| 97 .notThrow(); |
| 98 |
| 106 p3.then(function () { | 99 p3.then(function () { |
| 107 shouldBeEqualToString("offlineContext.state", "closed"); | 100 should(offlineContext.state, "offlineContext.state") |
| 101 .beEqualTo("closed"); |
| 108 | 102 |
| 109 // suspend() should be rejected on a closed context. | 103 // suspend() should be rejected on a closed context. |
| 110 offlineContext.suspend().then( | 104 should(offlineContext.suspend(), "offlineContext.suspend()") |
| 111 handlePromise(testFailed, "offlineContext.suspend() on a closed contex
t not rejected"), | 105 .beRejected() |
| 112 function (e) { | 106 .then(function () { |
| 113 if (e.name === "TypeError") { | 107 // resume() should be rejected on closed context. |
| 114 testPassed("offlineContext.suspend() on a closed context rejected:
" + e); | 108 should(offlineContext.resume(), "offlineContext.resume()") |
| 115 } else { | 109 .beRejected() |
| 116 testFailed("offlineContext.suspend() on a closed context rejected
but expected TypeError, not: " + e); | 110 .then(task.done.bind(task)); |
| 117 } | 111 }) |
| 118 } | |
| 119 ).then(function () { | |
| 120 // resume() should be rejected on closed context. | |
| 121 offlineContext.resume().then( | |
| 122 handlePromise(testFailed, "offlineContext.resume() on a closed conte
xt not rejected"), | |
| 123 function (e) { | |
| 124 if (e.name === "InvalidStateError") { | |
| 125 testPassed("offlineContext.resume() on a closed context rejected
: " + e); | |
| 126 } else { | |
| 127 testFailed("offlineContext.resume() on a closed context rejected
but expected InvalidStateError, not: " + e); | |
| 128 } | |
| 129 } | |
| 130 ).then(done); | |
| 131 }); | |
| 132 | |
| 133 }); | 112 }); |
| 134 }); | 113 }); |
| 135 | 114 |
| 136 audit.defineTask('finish-test', function (done) { | 115 audit.run(); |
| 137 done(); | |
| 138 finishJSTest(); | |
| 139 }); | |
| 140 | |
| 141 audit.runTasks( | |
| 142 'test-suspend', | |
| 143 'test-resume', | |
| 144 'test-after-close', | |
| 145 'finish-test' | |
| 146 ); | |
| 147 | |
| 148 successfullyParsed = true; | |
| 149 </script> | 116 </script> |
| 150 </body> | 117 </body> |
| 151 </html> | 118 </html> |
| OLD | NEW |