<!DOCTYPE html>
<html>
  <head>
    <title>
      offlineaudiocontext-suspend-resume-basic.html
    </title>
    <script src="../../imported/w3c/web-platform-tests/resources/testharness.js"></script>
    <script src="../../resources/testharnessreport.js"></script>
    <script src="../resources/audit-util.js"></script>
    <script src="../resources/audit.js"></script>
  </head>
  <body>
    <script id="layout-test-code">
      let sampleRate = 44100;
      let renderDuration = 1;
      let renderQuantum = 128;

      let audit = Audit.createTaskRunner();

      // Task: Calling suspend with no argument, negative time or the time
      // beyond the maximum render duration reject the promise.
      audit.define('suspend-invalid-argument', (task, should) => {
        let context =
            new OfflineAudioContext(1, sampleRate * renderDuration, sampleRate);

        should(context.suspend(), 'context.suspend()').beRejected();
        should(context.suspend(-1.0), 'context.suspend(-1.0)').beRejected();
        should(context.suspend(2.0), 'context.suspend(2.0)').beRejected();

        context.startRendering().then(() => task.done());
      });

      // Task: Scheduling a suspend in the past should be rejected.
      audit.define('suspend-in-the-past', (task, should) => {
        let context =
            new OfflineAudioContext(1, sampleRate * renderDuration, sampleRate);

        context.suspend(0.5).then(function() {
          should(
              context.suspend(context.currentTime - 0.1),
              'Scheduling a suspend in the past')
              .beRejected();

          should(context
                     .suspend(
                         context.currentTime + 0.1,
                         'Scheduling a suspend in the future')
                     .then(function() {
                       context.resume();
                     }))
              .beResolved();

          context.resume();
        });

        context.startRendering().then(() => task.done());
      });

      // Task: suspending after rendering is finished must be rejected with the
      // properly clamped frame/time information.
      audit.define('suspend-after-render-completion', (task, should) => {
        let context =
            new OfflineAudioContext(1, sampleRate * renderDuration, sampleRate);
        context.startRendering()
            .then(function() {
              should(
                  context.suspend(renderDuration),
                  'Scheduling a suspend after the render completion')
                  .beRejected();
            })
            .then(() => task.done());
      });

      // Task: Calling multiple suspends at the same rendering quantum should
      // reject the promise.
      audit.define('identical-suspend-time', (task, should) => {
        let context =
            new OfflineAudioContext(1, sampleRate * renderDuration, sampleRate);

        // |suspendTime1| and |suspendTime2| are identical when quantized to the
        // render quantum size.  The factors are arbitrary except they should be
        // between 1 (exclusive) and 2 (inclusive).  Using a factor of 2 also
        // tests that times are rounded up.
        let suspendTime1 = 1.25 * renderQuantum / sampleRate;
        let suspendTime2 = 2 * renderQuantum / sampleRate;

        should(
            () => context.suspend(suspendTime1).then(() => context.resume()),
            'Scheduling a suspend at frame ' + suspendTime1 * sampleRate)
            .notThrow();

        should(
            context.suspend(suspendTime2).then(() => context.resume()),
            'Scheduling another suspend at the same rendering quantum')
            .beRejected();

        context.startRendering().then(() => task.done());
      });

      // Task: Resuming a running context should be resolved.
      audit.define('resume-before-suspend', (task, should) => {
        // Make the render length 5 times longer to minimize the flakiness.
        let longRenderDuration = renderDuration * 5;
        let context = new OfflineAudioContext(
            1, sampleRate * longRenderDuration, sampleRate);

        // Create dummy audio graph to slow the rendering.
        let osc = context.createOscillator();
        let lpf = context.createBiquadFilter();
        osc.type = 'sawtooth';
        osc.frequency.setValueAtTime(0.1, 0.0);
        osc.frequency.linearRampToValueAtTime(1000, longRenderDuration * 0.5);
        osc.frequency.linearRampToValueAtTime(0.1, longRenderDuration);
        lpf.frequency.setValueAtTime(0.1, 0.0);
        lpf.frequency.linearRampToValueAtTime(1000, longRenderDuration * 0.5);
        lpf.frequency.linearRampToValueAtTime(0.1, longRenderDuration);
        osc.connect(lpf);
        lpf.connect(context.destination);
        osc.start();

        // A suspend is scheduled at the 90% of the render duration.
        should(
            () => {
              // Test is finished when this suspend resolves.
              context.suspend(longRenderDuration * 0.9).then(() => task.done());
            },
            'Scheduling a suspend at ' + longRenderDuration * 0.9 + ' seconds')
            .notThrow();

        // We have to start rendering to get the time running.
        context.startRendering();

        // Then call resume() immediately after the rendering starts. Resuming
        // a context that is already running should be resolved.
        should(context.resume(), 'Resuming a running context').beResolved();
      });

      // Task: Calling resume on a context that is not started should reject the
      // promise.
      audit.define('resume-without-suspend', (task, should) => {
        let context =
            new OfflineAudioContext(1, sampleRate * renderDuration, sampleRate);

        should(context.resume(), 'Resuming a context without starting it')
            .beRejected()
            .then(() => task.done());
      });

      audit.run();
    </script>
  </body>
</html>
