| OLD | NEW |
| 1 <!doctype html> | 1 <!doctype html> |
| 2 <html> | 2 <html> |
| 3 <head> | 3 <head> |
| 4 <title>Test Exceptions from setValueCurveAtTime</title> | 4 <title>Test Exceptions from setValueCurveAtTime</title> |
| 5 <script src="../../resources/testharness.js"></script> | 5 <script src="../../resources/testharness.js"></script> |
| 6 <script src="../../resources/testharnessreport.js"></script> | 6 <script src="../../resources/testharnessreport.js"></script> |
| 7 <script src="../resources/audit-util.js"></script> | 7 <script src="../resources/audit-util.js"></script> |
| 8 <script src="../resources/audio-testing.js"></script> | 8 <script src="../resources/audit.js"></script> |
| 9 </head> | 9 </head> |
| 10 | 10 |
| 11 <body> | 11 <body> |
| 12 <script> | 12 <script> |
| 13 | 13 |
| 14 var sampleRate = 48000; | 14 var sampleRate = 48000; |
| 15 // Some short duration because we don't need to run the test for very long
. | 15 // Some short duration because we don't need to run the test for very long
. |
| 16 var testDurationSec = 0.125; | 16 var testDurationSec = 0.125; |
| 17 var testDurationFrames = testDurationSec * sampleRate; | 17 var testDurationFrames = testDurationSec * sampleRate; |
| 18 | 18 |
| 19 var audit = Audit.createTaskRunner(); | 19 var audit = Audit.createTaskRunner(); |
| 20 | 20 |
| 21 audit.defineTask("setValueCurve", function(done) { | 21 audit.define("setValueCurve", (task, should) => { |
| 22 var success = true; | 22 var success = true; |
| 23 var context = new OfflineAudioContext(1, testDurationFrames, sampleRate)
; | 23 var context = new OfflineAudioContext(1, testDurationFrames, sampleRate)
; |
| 24 var g = context.createGain(); | 24 var g = context.createGain(); |
| 25 var curve = new Float32Array(2); | 25 var curve = new Float32Array(2); |
| 26 | 26 |
| 27 // Start time and duration for setValueCurveAtTime | 27 // Start time and duration for setValueCurveAtTime |
| 28 var curveStartTime = 0.1 * testDurationSec; | 28 var curveStartTime = 0.1 * testDurationSec; |
| 29 var duration = 0.1 * testDurationSec; | 29 var duration = 0.1 * testDurationSec; |
| 30 | 30 |
| 31 // Some time that is known to during the setValueCurveTime interval. | 31 // Some time that is known to during the setValueCurveTime interval. |
| 32 var automationTime = curveStartTime + duration / 2; | 32 var automationTime = curveStartTime + duration / 2; |
| 33 | 33 |
| 34 success = Should("setValueCurveAtTime(curve, " + curveStartTime + ", " +
duration + ")", function() { | 34 should(() => { |
| 35 g.gain.setValueCurveAtTime(curve, curveStartTime, duration); | 35 g.gain.setValueCurveAtTime(curve, curveStartTime, duration); |
| 36 }).notThrow() && success; | 36 }, |
| 37 "setValueCurveAtTime(curve, " + curveStartTime + ", " + duration + |
| 38 ")") |
| 39 .notThrow(); |
| 37 | 40 |
| 38 success = Should("setValueAtTime(1, " + automationTime + ")", function()
{ | 41 should(function() { |
| 39 g.gain.setValueAtTime(1, automationTime); | 42 g.gain.setValueAtTime(1, automationTime); |
| 40 }).throw("NotSupportedError") && success; | 43 }, "setValueAtTime(1, " + automationTime + ")") |
| 44 .throw("NotSupportedError"); |
| 41 | 45 |
| 42 success = Should("linearRampToValueAtTime(1, " + automationTime + ")", f
unction() { | 46 should(function() { |
| 43 g.gain.linearRampToValueAtTime(1, automationTime); | 47 g.gain.linearRampToValueAtTime(1, automationTime); |
| 44 }).throw("NotSupportedError") && success; | 48 }, "linearRampToValueAtTime(1, " + automationTime + ")") |
| 49 .throw("NotSupportedError"); |
| 45 | 50 |
| 46 success = Should("exponentialRampToValueAtTime(1, " + automationTime + "
)", function() { | 51 should(function() { |
| 47 g.gain.exponentialRampToValueAtTime(1, automationTime); | 52 g.gain.exponentialRampToValueAtTime(1, automationTime); |
| 48 }).throw("NotSupportedError") && success; | 53 }, "exponentialRampToValueAtTime(1, " + automationTime + ")") |
| 54 .throw("NotSupportedError"); |
| 49 | 55 |
| 50 success = Should("setTargetAtTime(1, " + automationTime + ", 1)", functi
on() { | 56 should(function() { |
| 51 g.gain.setTargetAtTime(1, automationTime, 1); | 57 g.gain.setTargetAtTime(1, automationTime, 1); |
| 52 }).throw("NotSupportedError") && success; | 58 }, "setTargetAtTime(1, " + automationTime + ", 1)") |
| 59 .throw("NotSupportedError"); |
| 53 | 60 |
| 54 success = Should("setValueAtTime(1, " + (curveStartTime + 1.1 * duration
) + ")", function() { | 61 should(function() { |
| 55 g.gain.setValueAtTime(1, curveStartTime + 1.1 * duration); | 62 g.gain.setValueAtTime(1, curveStartTime + 1.1 * duration); |
| 56 }).notThrow() && success; | 63 }, "setValueAtTime(1, " + (curveStartTime + 1.1 * duration) + ")") |
| 64 .notThrow(); |
| 57 | 65 |
| 58 var prefix = "Automation functions overlapping an existing setValueCurve
AtTime"; | 66 task.done(); |
| 59 Should(prefix, success) | |
| 60 .summarize(" correctly signaled errors", | |
| 61 " failed to signal errors"); | |
| 62 | |
| 63 done(); | |
| 64 }); | 67 }); |
| 65 | 68 |
| 66 audit.defineTask("automations", function (done) { | 69 audit.define("automations", (task, should) => { |
| 67 var success = true; | |
| 68 var context = new OfflineAudioContext(1, testDurationFrames, sampleRate)
; | 70 var context = new OfflineAudioContext(1, testDurationFrames, sampleRate)
; |
| 69 var g = context.createGain(); | 71 var g = context.createGain(); |
| 70 | 72 |
| 71 var curve = new Float32Array(2); | 73 var curve = new Float32Array(2); |
| 72 // Start time and duration for setValueCurveAtTime | 74 // Start time and duration for setValueCurveAtTime |
| 73 var startTime = 0; | 75 var startTime = 0; |
| 74 var timeInterval = testDurationSec / 10; | 76 var timeInterval = testDurationSec / 10; |
| 75 | 77 |
| 76 startTime += timeInterval; | 78 startTime += timeInterval; |
| 77 success = Should("linearRampToValueAtTime(1, " + startTime + ")", functi
on () { | 79 should(() => { |
| 78 g.gain.linearRampToValueAtTime(1, startTime); | 80 g.gain.linearRampToValueAtTime(1, startTime); |
| 79 }).notThrow() && success; | 81 }, "linearRampToValueAtTime(1, " + startTime + ")").notThrow(); |
| 80 | 82 |
| 81 startTime += timeInterval; | 83 startTime += timeInterval; |
| 82 success = Should("exponentialRampToValueAtTime(1, " + startTime + ")", f
unction () { | 84 should(() => { |
| 83 g.gain.exponentialRampToValueAtTime(1, startTime); | 85 g.gain.exponentialRampToValueAtTime(1, startTime); |
| 84 }).notThrow() && success; | 86 }, "exponentialRampToValueAtTime(1, " + startTime + ")").notThrow(); |
| 85 | 87 |
| 86 startTime += timeInterval; | 88 startTime += timeInterval; |
| 87 success = Should("setTargetAtTime(1, " + startTime + ", 0.1)", function
() { | 89 should(() => { |
| 88 g.gain.setTargetAtTime(1, startTime, 0.1); | 90 g.gain.setTargetAtTime(1, startTime, 0.1); |
| 89 }).notThrow() && success; | 91 }, "setTargetAtTime(1, " + startTime + ", 0.1)").notThrow(); |
| 90 | 92 |
| 91 startTime += timeInterval; | 93 startTime += timeInterval; |
| 92 success = Should("setValueCurveAtTime(curve, " + startTime + ", 0.1)", f
unction () { | 94 should(() => { |
| 93 g.gain.setValueCurveAtTime(curve, startTime, 0.1); | 95 g.gain.setValueCurveAtTime(curve, startTime, 0.1); |
| 94 }).notThrow() && success; | 96 }, "setValueCurveAtTime(curve, " + startTime + ", 0.1)").notThrow(); |
| 95 | 97 |
| 96 // Now try to setValueCurve that overlaps each of the above automations | 98 // Now try to setValueCurve that overlaps each of the above automations |
| 97 startTime = timeInterval / 2; | 99 startTime = timeInterval / 2; |
| 98 | 100 |
| 99 for (var k = 0; k < 4; ++k) { | 101 for (var k = 0; k < 4; ++k) { |
| 100 var time = startTime + timeInterval * k; | 102 var time = startTime + timeInterval * k; |
| 101 success = Should("setValueCurveAtTime(curve, " + time + ", 0.01)", fun
ction () { | 103 should(() => { |
| 102 g.gain.setValueCurveAtTime(curve, time, 0.01); | 104 g.gain.setValueCurveAtTime(curve, time, 0.01); |
| 103 }).throw("NotSupportedError") && success; | 105 }, |
| 106 "setValueCurveAtTime(curve, " + time + ", 0.01)") |
| 107 .throw("NotSupportedError"); |
| 104 } | 108 } |
| 105 | 109 |
| 106 // Elements of setValueCurve should be finite. | 110 // Elements of setValueCurve should be finite. |
| 107 success = Should("setValueCurveAtTime([NaN, NaN], " + time + ", 0.01)",
function () { | 111 should(() => { |
| 108 g.gain.setValueCurveAtTime(Float32Array.from([NaN, NaN]), time, 0.01); | 112 g.gain.setValueCurveAtTime(Float32Array.from([NaN, NaN]), time, |
| 109 }).throw("TypeError") && success; | 113 0.01); |
| 114 }, |
| 115 "setValueCurveAtTime([NaN, NaN], " + time + ", 0.01)") |
| 116 .throw("TypeError"); |
| 110 | 117 |
| 111 success = Should("setValueCurveAtTime([1, Infinity], " + time + ", 0.01)
", function () { | 118 should(() => { |
| 112 g.gain.setValueCurveAtTime(Float32Array.from([1, Infinity]), time, 0.0
1); | 119 g.gain.setValueCurveAtTime(Float32Array.from([1, Infinity]), time, |
| 113 }).throw("TypeError") && success; | 120 0.01); |
| 121 }, |
| 122 "setValueCurveAtTime([1, Infinity], " + time + ", 0.01)") |
| 123 .throw("TypeError"); |
| 114 | 124 |
| 115 var d = context.createDelay(); | 125 var d = context.createDelay(); |
| 116 // Check that we get warnings for out-of-range values and also throw for | 126 // Check that we get warnings for out-of-range values and also throw for |
| 117 // non-finite values. | 127 // non-finite values. |
| 118 success = Should("delayTime.setValueCurveAtTime([1, 5], " + time + ", 0.
01)", function() { | 128 should(() => { |
| 119 d.delayTime.setValueCurveAtTime(Float32Array.from([1, 5]), time, 0.01)
; | 129 d.delayTime.setValueCurveAtTime(Float32Array.from([1, 5]), time, |
| 120 }).notThrow() && success; | 130 0.01); |
| 131 }, |
| 132 "delayTime.setValueCurveAtTime([1, 5], " + time + ", 0.01)") |
| 133 .notThrow(); |
| 121 | 134 |
| 122 success = Should("delayTime.setValueCurveAtTime([1, 5, Infinity], " + ti
me + ", 0.01)", | 135 should(() => { |
| 123 function() { | 136 d.delayTime.setValueCurveAtTime(Float32Array.from([1, 5, Infinity]
), |
| 124 d.delayTime.setValueCurveAtTime(Float32Array.from([1, 5, Infinity]),
time, 0.01); | 137 time, 0.01); |
| 125 }).throw("TypeError") && success; | 138 }, |
| 139 "delayTime.setValueCurveAtTime([1, 5, Infinity], " + time + |
| 140 ", 0.01)") |
| 141 .throw("TypeError"); |
| 126 | 142 |
| 127 // One last test that prints out lots of digits for the time. | 143 // One last test that prints out lots of digits for the time. |
| 128 var time = Math.PI / 100; | 144 var time = Math.PI / 100; |
| 129 success = Should("setValueCurveAtTime(curve, " + time + ", 0.01)", funct
ion () { | 145 should(() => { |
| 130 g.gain.setValueCurveAtTime(curve, time, 0.01); | 146 g.gain.setValueCurveAtTime(curve, time, 0.01); |
| 131 }).throw("NotSupportedError") && success; | 147 }, "setValueCurveAtTime(curve, " + time + ", 0.01)").throw("NotSupported
Error"); |
| 132 | 148 |
| 133 var prefix = "setValueCurve overlapping existing automation functions"; | 149 task.done(); |
| 134 Should(prefix, success) | |
| 135 .summarize(" correctly signaled errors", | |
| 136 " failed to signal errors"); | |
| 137 | |
| 138 done(); | |
| 139 }); | 150 }); |
| 140 | 151 |
| 141 audit.defineTask("catch-exception", function (done) { | 152 audit.define("catch-exception", (task, should) => { |
| 142 // Verify that the curve isn't inserted into the time line even if we ca
tch the exception. | 153 // Verify that the curve isn't inserted into the time line even if we ca
tch the exception. |
| 143 var success = true; | 154 var success = true; |
| 144 var context = new OfflineAudioContext(1, testDurationFrames, sampleRate)
; | 155 var context = new OfflineAudioContext(1, testDurationFrames, sampleRate)
; |
| 145 var gain = context.createGain(); | 156 var gain = context.createGain(); |
| 146 var source = context.createBufferSource(); | 157 var source = context.createBufferSource(); |
| 147 var buffer = context.createBuffer(1, 1, context.sampleRate); | 158 var buffer = context.createBuffer(1, 1, context.sampleRate); |
| 148 buffer.getChannelData(0)[0] = 1; | 159 buffer.getChannelData(0)[0] = 1; |
| 149 source.buffer = buffer; | 160 source.buffer = buffer; |
| 150 source.loop = true; | 161 source.loop = true; |
| 151 | 162 |
| 152 source.connect(gain); | 163 source.connect(gain); |
| 153 gain.connect(context.destination); | 164 gain.connect(context.destination); |
| 154 | 165 |
| 155 gain.gain.setValueAtTime(1, 0); | 166 gain.gain.setValueAtTime(1, 0); |
| 156 try { | 167 try { |
| 157 // The value curve has an invalid element. This automation shouldn't b
e inserted into the | 168 // The value curve has an invalid element. This automation shouldn't b
e inserted into the |
| 158 // timeline at all. | 169 // timeline at all. |
| 159 gain.gain.setValueCurveAtTime(Float32Array.from([0, NaN]), 128 / conte
xt.sampleRate, .5); | 170 gain.gain.setValueCurveAtTime(Float32Array.from([0, NaN]), 128 / conte
xt.sampleRate, .5); |
| 160 } catch (e) { | 171 } catch (e) { |
| 161 }; | 172 }; |
| 162 source.start(); | 173 source.start(); |
| 163 | 174 |
| 164 context.startRendering().then(function (resultBuffer) { | 175 context.startRendering().then(function (resultBuffer) { |
| 165 // Since the setValueCurve wasn't inserted, the output should be exact
ly 1 for the entire | 176 // Since the setValueCurve wasn't inserted, the output should be exact
ly 1 for the entire |
| 166 // duration. | 177 // duration. |
| 167 var success = Should("Handled setValueCurve exception so output", resu
ltBuffer.getChannelData(0)) | 178 should(resultBuffer.getChannelData(0), |
| 179 "Handled setValueCurve exception so output") |
| 168 .beConstantValueOf(1); | 180 .beConstantValueOf(1); |
| 169 | 181 |
| 170 Should("setValueCurveAtTime", success) | 182 }).then(() => task.done()); |
| 171 .summarize("correctly not inserted into timeline", | |
| 172 "incorrectly still inserted into timeline"); | |
| 173 }).then(done); | |
| 174 }); | 183 }); |
| 175 | 184 |
| 176 audit.defineTask("start-end", function (done) { | 185 audit.define("start-end", (task, should) => { |
| 177 var success = true; | |
| 178 var context = new OfflineAudioContext(1, testDurationFrames, sampleRate)
; | 186 var context = new OfflineAudioContext(1, testDurationFrames, sampleRate)
; |
| 179 var g = context.createGain(); | 187 var g = context.createGain(); |
| 180 var curve = new Float32Array(2); | 188 var curve = new Float32Array(2); |
| 181 | 189 |
| 182 // Verify that a setValueCurve can start at the end of an automation. | 190 // Verify that a setValueCurve can start at the end of an automation. |
| 183 var time = 0; | 191 var time = 0; |
| 184 var timeInterval = testDurationSec / 50; | 192 var timeInterval = testDurationSec / 50; |
| 185 success = Should("setValueAtTime(1, " + time + ")", function () { | 193 should(() => { |
| 186 g.gain.setValueAtTime(1, time); | 194 g.gain.setValueAtTime(1, time); |
| 187 }).notThrow(); | 195 }, "setValueAtTime(1, " + time + ")").notThrow(); |
| 188 | 196 |
| 189 time += timeInterval; | 197 time += timeInterval; |
| 190 success = Should("linearRampToValueAtTime(0, " + time + ")", function ()
{ | 198 should(() => { |
| 191 g.gain.linearRampToValueAtTime(0, time); | 199 g.gain.linearRampToValueAtTime(0, time); |
| 192 }).notThrow() && success; | 200 }, "linearRampToValueAtTime(0, " + time + ")").notThrow(); |
| 193 | 201 |
| 194 // setValueCurve starts at the end of the linear ramp. This should be fi
ne. | 202 // setValueCurve starts at the end of the linear ramp. This should be fi
ne. |
| 195 success = Should("setValueCurveAtTime(..., " + time + ", " + timeInterva
l + ")", function () { | 203 should(() => { |
| 196 g.gain.setValueCurveAtTime(curve, time, timeInterval); | 204 g.gain.setValueCurveAtTime(curve, time, timeInterval); |
| 197 }).notThrow() && success; | 205 }, |
| 206 "setValueCurveAtTime(..., " + time + ", " + timeInterval + ")") |
| 207 .notThrow(); |
| 198 | 208 |
| 199 // exponentialRamp ending one interval past the setValueCurve should be
fine. | 209 // exponentialRamp ending one interval past the setValueCurve should be
fine. |
| 200 time += 2*timeInterval; | 210 time += 2*timeInterval; |
| 201 success = Should("exponentialRampToValueAtTime(1, " + time + ")", functi
on () { | 211 should(() => { |
| 202 g.gain.exponentialRampToValueAtTime(1, time); | 212 g.gain.exponentialRampToValueAtTime(1, time); |
| 203 }).notThrow() && success; | 213 }, "exponentialRampToValueAtTime(1, " + time + ")").notThrow(); |
| 204 | 214 |
| 205 // setValueCurve starts at the end of the exponential ramp. This should
be fine. | 215 // setValueCurve starts at the end of the exponential ramp. This should
be fine. |
| 206 success = Should("setValueCurveAtTime(..., " + time + ", " + timeInterva
l + ")", function () { | 216 should(() => { |
| 207 g.gain.setValueCurveAtTime(curve, time, timeInterval); | 217 g.gain.setValueCurveAtTime(curve, time, timeInterval); |
| 208 }).notThrow() && success; | 218 }, |
| 219 "setValueCurveAtTime(..., " + time + ", " + timeInterval + ")") |
| 220 .notThrow(); |
| 209 | 221 |
| 210 // setValueCurve at the end of the setValueCurve should be fine. | 222 // setValueCurve at the end of the setValueCurve should be fine. |
| 211 time += timeInterval; | 223 time += timeInterval; |
| 212 success = Should("setValueCurveAtTime(..., " + time + ", " + timeInterva
l + ")", function () { | 224 should(() => { |
| 213 g.gain.setValueCurveAtTime(curve, time, timeInterval); | 225 g.gain.setValueCurveAtTime(curve, time, timeInterval); |
| 214 }).notThrow() && success; | 226 }, |
| 227 "setValueCurveAtTime(..., " + time + ", " + timeInterval + ")") |
| 228 .notThrow(); |
| 215 | 229 |
| 216 // setValueAtTime at the end of setValueCurve should be fine. | 230 // setValueAtTime at the end of setValueCurve should be fine. |
| 217 time += timeInterval; | 231 time += timeInterval; |
| 218 success = Should("setValueAtTime(0, " + time + ")", function () { | 232 should(() => { |
| 219 g.gain.setValueAtTime(0, time); | 233 g.gain.setValueAtTime(0, time); |
| 220 }).notThrow() && success; | 234 }, "setValueAtTime(0, " + time + ")").notThrow(); |
| 221 | 235 |
| 222 // setValueCurve at the end of setValueAtTime should be fine. | 236 // setValueCurve at the end of setValueAtTime should be fine. |
| 223 success = Should("setValueCurveAtTime(..., " + time + ", " + timeInterva
l + ")", function () { | 237 should(() => { |
| 224 g.gain.setValueCurveAtTime(curve, time, timeInterval); | 238 g.gain.setValueCurveAtTime(curve, time, timeInterval); |
| 225 }).notThrow() && success; | 239 }, |
| 240 "setValueCurveAtTime(..., " + time + ", " + timeInterval + ")") |
| 241 .notThrow(); |
| 226 | 242 |
| 227 // setTarget starting at the end of setValueCurve should be fine. | 243 // setTarget starting at the end of setValueCurve should be fine. |
| 228 time += timeInterval; | 244 time += timeInterval; |
| 229 success = Should("setTargetAtTime(1, " + time + ", 1)", function () { | 245 should(() => { |
| 230 g.gain.setTargetAtTime(1, time, 1); | 246 g.gain.setTargetAtTime(1, time, 1); |
| 231 }).notThrow() && success; | 247 }, "setTargetAtTime(1, " + time + ", 1)").notThrow(); |
| 232 | 248 |
| 233 var prefix = "setValueCurve with adjoining automation functions"; | 249 task.done(); |
| 234 Should(prefix, success) | |
| 235 .summarize("allowed as expected", | |
| 236 "unexpectedly signaled errors"); | |
| 237 | |
| 238 done(); | |
| 239 }); | 250 }); |
| 240 | 251 |
| 241 audit.defineTask("curve lengths", function (done) { | 252 audit.define("curve lengths", (task, should) => { |
| 242 var success = true; | |
| 243 var context = new OfflineAudioContext(1, testDurationFrames, sampleRate)
; | 253 var context = new OfflineAudioContext(1, testDurationFrames, sampleRate)
; |
| 244 var g = context.createGain(); | 254 var g = context.createGain(); |
| 245 var time = 0; | 255 var time = 0; |
| 246 | 256 |
| 247 // Check for invalid curve lengths | 257 // Check for invalid curve lengths |
| 248 success = Should("setValueCurveAtTime([], " + time + ", 0.01)", function
() { | 258 should(() => { |
| 249 g.gain.setValueCurveAtTime(Float32Array.from([]), time, 0.01); | 259 g.gain.setValueCurveAtTime(Float32Array.from([]), time, 0.01); |
| 250 }).throw("InvalidStateError") && success; | 260 }, |
| 261 "setValueCurveAtTime([], " + time + ", 0.01)") |
| 262 .throw("InvalidStateError"); |
| 251 | 263 |
| 252 success = Should("setValueCurveAtTime([1], " + time + ", 0.01)", functio
n () { | 264 should(() => { |
| 253 g.gain.setValueCurveAtTime(Float32Array.from([1]), time, 0.01); | 265 g.gain.setValueCurveAtTime(Float32Array.from([1]), time, 0.01); |
| 254 }).throw("InvalidStateError") && success; | 266 }, |
| 267 "setValueCurveAtTime([1], " + time + ", 0.01)") |
| 268 .throw("InvalidStateError"); |
| 255 | 269 |
| 256 success = Should("setValueCurveAtTime([1,2], " + time + ", 0.01)", funct
ion () { | 270 should(() => { |
| 257 g.gain.setValueCurveAtTime(Float32Array.from([1,2]), time, 0.01); | 271 g.gain.setValueCurveAtTime(Float32Array.from([1,2]), time, 0.01); |
| 258 }).notThrow() && success; | 272 }, "setValueCurveAtTime([1,2], " + time + ", 0.01)").notThrow(); |
| 259 | 273 |
| 260 Should("Exceptions for curve length", success) | 274 task.done(); |
| 261 .summarize("correctly handled", | |
| 262 "not correctly handled"); | |
| 263 | |
| 264 done(); | |
| 265 }); | 275 }); |
| 266 | 276 |
| 267 audit.defineTask("finish", function (done) { | 277 audit.run(); |
| 268 done(); | |
| 269 }); | |
| 270 | |
| 271 audit.runTasks(); | |
| 272 successfullyParsed = true; | |
| 273 </script> | 278 </script> |
| 274 </body> | 279 </body> |
| 275 </html> | 280 </html> |
| 276 | 281 |
| 277 | 282 |
| 278 | 283 |
| 279 | 284 |
| 280 | 285 |
| 281 | 286 |
| 282 | 287 |
| 283 | 288 |
| 284 | 289 |
| OLD | NEW |