summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/webaudio/the-audio-api/the-audiocontext-interface/audiocontext-suspend-resume.html
blob: ff3daebf39635a0a62951b387195bb463619202d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
<!DOCTYPE html>
<html>
  <head>
    <title>
      Test AudioContext.suspend() and AudioContext.resume()
    </title>
    <script src="/resources/testharness.js"></script>
    <script src="/resources/testharnessreport.js"></script>
    <script src="/webaudio/resources/audit-util.js"></script>
    <script src="/webaudio/resources/audit.js"></script>
  </head>
  <body>
    <script id="layout-test-code">
      let offlineContext;
      let osc;
      let p1;
      let p2;
      let p3;

      let sampleRate = 44100;
      let durationInSeconds = 1;

      let audit = Audit.createTaskRunner();

      // Task: test suspend().
      audit.define(
          {
            label: 'test-suspend',
            description: 'Test suspend() for offline context'
          },
          function(task, should) {
            // Test suspend/resume.  Ideally this test is best with a online
            // AudioContext, but content shell doesn't really have a working
            // online AudioContext. Hence, use an OfflineAudioContext. Not all
            // possible scenarios can be easily checked with an offline context
            // instead of an online context.

            // Create an audio context with an oscillator.
            should(
                () => {
                  offlineContext = new OfflineAudioContext(
                      1, durationInSeconds * sampleRate, sampleRate);
                },
                'offlineContext = new OfflineAudioContext(1, ' +
                    (durationInSeconds * sampleRate) + ', ' + sampleRate + ')')
                .notThrow();
            osc = offlineContext.createOscillator();
            osc.connect(offlineContext.destination);

            // Verify the state.
            should(offlineContext.state, 'offlineContext.state')
                .beEqualTo('suspended');

            // Multiple calls to suspend() should not be a problem. But we can't
            // test that on an offline context.  Thus, check that suspend() on
            // an OfflineAudioContext rejects the promise.
            should(
                () => p1 = offlineContext.suspend(),
                'p1 = offlineContext.suspend()')
                .notThrow();
            should(p1 instanceof Promise, 'p1 instanceof Promise').beTrue();

            should(p1, 'p1').beRejected().then(task.done.bind(task));
          });


      // Task: test resume().
      audit.define(
          {
            label: 'test-resume',
            description: 'Test resume() for offline context'
          },
          function(task, should) {
            // Multiple calls to resume should not be a problem. But we can't
            // test that on an offline context. Thus, check that resume() on an
            // OfflineAudioContext rejects the promise.
            should(
                () => p2 = offlineContext.resume(),
                'p2 = offlineContext.resume()')
                .notThrow();
            should(p2 instanceof Promise, 'p2 instanceof Promise').beTrue();

            // Resume doesn't actually resume an offline context
            should(offlineContext.state, 'After resume, offlineContext.state')
                .beEqualTo('suspended');
            should(p2, 'p2').beRejected().then(task.done.bind(task));
          });

      // Task: test the state after context closed.
      audit.define(
          {
            label: 'test-after-close',
            description: 'Test state after context closed'
          },
          function(task, should) {
            // Render the offline context.
            osc.start();

            // Test suspend/resume in tested promise pattern. We don't care
            // about the actual result of the offline rendering.
            should(
                () => p3 = offlineContext.startRendering(),
                'p3 = offlineContext.startRendering()')
                .notThrow();

            p3.then(() => {
              should(offlineContext.state, 'After close, offlineContext.state')
                  .beEqualTo('closed');

              // suspend() should be rejected on a closed context.
              should(offlineContext.suspend(), 'offlineContext.suspend()')
                  .beRejected()
                  .then(() => {
                    // resume() should be rejected on closed context.
                    should(offlineContext.resume(), 'offlineContext.resume()')
                        .beRejected()
                        .then(task.done.bind(task));
                  })
            });
          });

      audit.define(
          {
            label: 'resume-running-context',
            description: 'Test resuming a running context'
          },
          (task, should) => {
            let context;
            should(() => context = new AudioContext(), 'Create online context')
                .notThrow();

            should(context.state, 'context.state').beEqualTo('suspended');
            should(context.resume(), 'context.resume')
                .beResolved()
                .then(() => {
                  should(context.state, 'context.state after resume')
                      .beEqualTo('running');
                })
                .then(() => task.done());
          });

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