| 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(() => { |
| 35 offlineContext = new OfflineAudioContext(1, durationInSeconds * |
| 36 sampleRate, sampleRate); |
| 37 }, |
| 38 "offlineContext = new OfflineAudioContext(1, " + ( |
| 39 durationInSeconds * |
| 40 sampleRate) + ", " + sampleRate + ")" |
| 41 ) |
| 42 .notThrow(); |
| 46 osc = offlineContext.createOscillator(); | 43 osc = offlineContext.createOscillator(); |
| 47 osc.connect(offlineContext.destination); | 44 osc.connect(offlineContext.destination); |
| 48 | 45 |
| 49 // Verify the state. | 46 // Verify the state. |
| 50 shouldBeEqualToString("offlineContext.state", "suspended"); | 47 should(offlineContext.state, "offlineContext.state") |
| 48 .beEqualTo("suspended"); |
| 51 | 49 |
| 52 // Multiple calls to suspend() should not be a problem. But we can't test | 50 // 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 | 51 // that on an offline context. Thus, check that suspend() on an |
| 54 // OfflineAudioContext rejects the promise. | 52 // OfflineAudioContext rejects the promise. |
| 55 shouldNotThrow("p1 = offlineContext.suspend()"); | 53 should(() => p1 = offlineContext.suspend(), |
| 56 shouldBeType("p1", "Promise"); | 54 "p1 = offlineContext.suspend()") |
| 57 p1.then( | 55 .notThrow(); |
| 58 handlePromise(testFailed, "offlineContext.suspend() should have been rej
ected for an offline context"), | 56 should(p1 instanceof Promise, "p1 instanceof Promise") |
| 59 function (e) { | 57 .beTrue(); |
| 60 if (e.name === "TypeError") { | 58 |
| 61 testPassed( | 59 should(p1, "p1") |
| 62 "offlineContext.suspend() was correctly rejected: " + e); | 60 .beRejected() |
| 63 } else { | 61 .then(task.done.bind(task)); |
| 64 testFailed( | |
| 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(() => p2 = offlineContext.resume(), |
| 79 shouldBeType("p2", "Promise"); | 72 "p2 = offlineContext.resume()") |
| 80 | 73 .notThrow(); |
| 74 should(p2 instanceof Promise, "p2 instanceof Promise") |
| 75 .beTrue(); |
| 76 |
| 81 // Resume doesn't actually resume an offline context | 77 // Resume doesn't actually resume an offline context |
| 82 shouldBeEqualToString("offlineContext.state", "suspended"); | 78 should(offlineContext.state, "offlineContext.state") |
| 83 p2.then( | 79 .beEqualTo("suspended"); |
| 84 handlePromise(testFailed, "offlineContext.resume() should have been reje
cted for an offline context"), | 80 should(p2, "p2") |
| 85 function (e) { | 81 .beRejected() |
| 86 if (e.name === "InvalidStateError") { | 82 .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 }); | 83 }); |
| 96 | 84 |
| 97 // Task: test the state after context closed. | 85 // Task: test the state after context closed. |
| 98 audit.defineTask('test-after-close', function (done) { | 86 audit.define('test-after-close', function (task, should) { |
| 99 | 87 task.describe("Test state after context closed"); |
| 100 // Render the offline context. | 88 // Render the offline context. |
| 101 osc.start(); | 89 osc.start(); |
| 102 | 90 |
| 103 // Test suspend/resume in tested promise pattern. We don't care about the | 91 // Test suspend/resume in tested promise pattern. We don't care about the |
| 104 // actual result of the offline rendering. | 92 // actual result of the offline rendering. |
| 105 shouldNotThrow("p3 = offlineContext.startRendering()"); | 93 should(() => p3 = offlineContext.startRendering(), |
| 106 p3.then(function () { | 94 "p3 = offlineContext.startRendering()") |
| 107 shouldBeEqualToString("offlineContext.state", "closed"); | 95 .notThrow(); |
| 96 |
| 97 p3.then(() => { |
| 98 should(offlineContext.state, "offlineContext.state") |
| 99 .beEqualTo("closed"); |
| 108 | 100 |
| 109 // suspend() should be rejected on a closed context. | 101 // suspend() should be rejected on a closed context. |
| 110 offlineContext.suspend().then( | 102 should(offlineContext.suspend(), "offlineContext.suspend()") |
| 111 handlePromise(testFailed, "offlineContext.suspend() on a closed contex
t not rejected"), | 103 .beRejected() |
| 112 function (e) { | 104 .then(() => { |
| 113 if (e.name === "TypeError") { | 105 // resume() should be rejected on closed context. |
| 114 testPassed("offlineContext.suspend() on a closed context rejected:
" + e); | 106 should(offlineContext.resume(), |
| 115 } else { | 107 "offlineContext.resume()") |
| 116 testFailed("offlineContext.suspend() on a closed context rejected
but expected TypeError, not: " + e); | 108 .beRejected() |
| 117 } | 109 .then(task.done.bind(task)); |
| 118 } | 110 }) |
| 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 }); | 111 }); |
| 134 }); | 112 }); |
| 135 | 113 |
| 136 audit.defineTask('finish-test', function (done) { | 114 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> | 115 </script> |
| 150 </body> | 116 </body> |
| 151 </html> | 117 </html> |
| OLD | NEW |