<!DOCTYPE html>
<html>
  <head>
    <title>
      Test AudioParam Nominal Range Values
    </title>
    <script src="../../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">
      // Some arbitrary sample rate for the offline context.
      let sampleRate = 48000;

      // The actual offline context
      let context;

      // The set of all methods that we've tested for verifying that we tested
      // all of the necessary objects.
      let testedMethods = new Set();

      // The most positive single float value (the value just before infinity).
      // Be careful when changing this value!  Javascript only uses double
      // floats, so the value here should be the max single-float value,
      // converted directly to a double-float value.  This also depends on
      // Javascript reading this value and producing the desired double-float
      // value correctly.
      let mostPositiveFloat = 3.4028234663852886e38;

      let audit = Audit.createTaskRunner();

      // Array describing the tests that should be run.
      let testConfigs = [
        {
          // The name of the method to create the particular node to be tested.
          creator: 'createGain',

          // Any args to pass to the creator function.
          args: [],

          // The min/max limits for each AudioParam of the node.  This is a
          // dictionary whose keys are
          // the names of each AudioParam in the node.  Don't define this if the
          // node doesn't have any
          // AudioParam attributes.
          limits: {
            gain: {
              // The expected min and max values for this AudioParam.
              minValue: -mostPositiveFloat,
              maxValue: mostPositiveFloat
            }
          }
        },
        {
          creator: 'createDelay',
          // Just specify a non-default value for the maximum delay so we can
          // make sure the limits are
          // set correctly.
          args: [1.5],
          limits: {delayTime: {minValue: 0, maxValue: 1.5}}
        },
        {
          creator: 'createBufferSource',
          args: [],
          limits: {
            playbackRate:
                {minValue: -mostPositiveFloat, maxValue: mostPositiveFloat},
            detune:
                {minValue: -mostPositiveFloat, maxValue: mostPositiveFloat}
          }
        },
        {
          creator: 'createStereoPanner',
          args: [],
          limits: {pan: {minValue: -1, maxValue: 1}}
        },
        {
          creator: 'createDynamicsCompressor',
          args: [],
          // Do not set limits for reduction;  it's currently an AudioParam but
          // should be a float.
          // So let the test fail for reduction.  When reduction is changed,
          // this test will then
          // correctly pass.
          limits: {
            threshold: {minValue: -100, maxValue: 0},
            knee: {minValue: 0, maxValue: 40},
            ratio: {minValue: 1, maxValue: 20},
            attack: {minValue: 0, maxValue: 1},
            release: {minValue: 0, maxValue: 1}
          }
        },
        {
          creator: 'createBiquadFilter',
          args: [],
          limits: {
            gain: {minValue: -mostPositiveFloat, maxValue: mostPositiveFloat},
            Q: {minValue: -mostPositiveFloat, maxValue: mostPositiveFloat},
            frequency: {minValue: 0, maxValue: sampleRate / 2},
            detune:
                {minValue: -mostPositiveFloat, maxValue: mostPositiveFloat}
          }
        },
        {
          creator: 'createOscillator',
          args: [],
          limits: {
            frequency: {minValue: -sampleRate / 2, maxValue: sampleRate / 2},
            detune:
                {minValue: -mostPositiveFloat, maxValue: mostPositiveFloat}
          }
        },
        {
          creator: 'createPanner',
          args: [],
          limits: {
            positionX: {
              minValue: -mostPositiveFloat,
              maxValue: mostPositiveFloat,
            },
            positionY: {
              minValue: -mostPositiveFloat,
              maxValue: mostPositiveFloat,
            },
            positionZ: {
              minValue: -mostPositiveFloat,
              maxValue: mostPositiveFloat,
            },
            orientationX: {
              minValue: -mostPositiveFloat,
              maxValue: mostPositiveFloat,
            },
            orientationY: {
              minValue: -mostPositiveFloat,
              maxValue: mostPositiveFloat,
            },
            orientationZ: {
              minValue: -mostPositiveFloat,
              maxValue: mostPositiveFloat,
            }
          },
        },
        {
          creator: 'createConstantSource',
          args: [],
          limits: {
            offset:
                {minValue: -mostPositiveFloat, maxValue: mostPositiveFloat}
          }
        },
        // These nodes don't have AudioParams, but we want to test them anyway.
        // Any arguments for the
        // constructor are pretty much arbitrary; they just need to be valid.
        {
          creator: 'createBuffer',
          args: [1, 1, sampleRate],
        },
        {creator: 'createIIRFilter', args: [[1, 2], [1, .9]]},
        {
          creator: 'createWaveShaper',
          args: [],
        },
        {
          creator: 'createConvolver',
          args: [],
        },
        {
          creator: 'createAnalyser',
          args: [],
        },
        {
          creator: 'createScriptProcessor',
          args: [0],
        },
        {
          creator: 'createPeriodicWave',
          args: [Float32Array.from([0, 0]), Float32Array.from([1, 0])],
        },
        {
          creator: 'createChannelSplitter',
          args: [],
        },
        {
          creator: 'createChannelMerger',
          args: [],
        },
        {creator: 'createMediaElementSource', args: [new Audio()]},
        {creator: 'createMediaStreamDestination', args: []}
        // Can't currently test MediaStreamSource because we're using an offline
        // context.
      ];

      // Create the context so we can use it in the following test.
      audit.define('initialize', (task, should) => {
        // Just any context so that we can create the nodes.
        should(() => {
          context = new OfflineAudioContext(1, 1, sampleRate);
        }, 'Create context for tests').notThrow();
        task.done();
      });

      // Create a task for each entry in testConfigs
      for (let test in testConfigs) {
        let config = testConfigs[test]
        audit.define(config.creator, (function(c) {
                       return (task, should) => {
                         let node = context[c.creator](...c.args);
                         testLimits(should, c.creator, node, c.limits);
                         task.done();
                       };
                     })(config));
      }

      // Test the AudioListener params that were added for the automated Panner
      audit.define('AudioListener', (task, should) => {
        testLimits(should, '', context.listener, {
          positionX: {
            minValue: -mostPositiveFloat,
            maxValue: mostPositiveFloat,
          },
          positionY: {
            minValue: -mostPositiveFloat,
            maxValue: mostPositiveFloat,
          },
          positionZ: {
            minValue: -mostPositiveFloat,
            maxValue: mostPositiveFloat,
          },
          forwardX: {
            minValue: -mostPositiveFloat,
            maxValue: mostPositiveFloat,
          },
          forwardY: {
            minValue: -mostPositiveFloat,
            maxValue: mostPositiveFloat,
          },
          forwardZ: {
            minValue: -mostPositiveFloat,
            maxValue: mostPositiveFloat,
          },
          upX: {
            minValue: -mostPositiveFloat,
            maxValue: mostPositiveFloat,
          },
          upY: {
            minValue: -mostPositiveFloat,
            maxValue: mostPositiveFloat,
          },
          upZ: {
            minValue: -mostPositiveFloat,
            maxValue: mostPositiveFloat,
          }
        });
        task.done();
      });

      // Verify that we have tested all the create methods available on the
      // context.
      audit.define('verifyTests', (task, should) => {
        let allNodes = new Set();
        // Create the set of all "create" methods from the context.
        for (let method in context) {
          if (typeof context[method] === 'function' &&
              method.substring(0, 6) === 'create') {
            allNodes.add(method);
          }
        }

        // Compute the difference between the set of all create methods on the
        // context and the set of tests that we've run.
        let diff = new Set([...allNodes].filter(x => !testedMethods.has(x)));

        // Can't currently test a MediaStreamSourceNode, so remove it from the
        // diff set.
        diff.delete('createMediaStreamSource');

        // It's a test failure if we didn't test all of the create methods in
        // the context (except createMediaStreamSource, of course).
        let output = [];
        if (diff.size) {
          for (let item of diff)
            output.push(' ' + item.substring(6));
        }

        should(output.length === 0, 'Number of nodes not tested')
            .message(': 0', ': ' + output);

        task.done();
      });

      // Simple test of a few automation methods to verify we get warnings.
      audit.define('automation', (task, should) => {
        // Just use a DelayNode for testing because the audio param has finite
        // limits.
        should(() => {
          let d = context.createDelay();

          // The console output should have the warnings that we're interested
          // in.
          d.delayTime.setValueAtTime(-1, 0);
          d.delayTime.linearRampToValueAtTime(2, 1);
          d.delayTime.exponentialRampToValueAtTime(3, 2);
          d.delayTime.setTargetAtTime(-1, 3, .1);
          d.delayTime.setValueCurveAtTime(
              Float32Array.from([.1, .2, 1.5, -1]), 4, .1);
        }, 'Test automations (check console logs)').notThrow();
        task.done();
      });

      audit.run();

      // Is |object| an AudioParam?  We determine this by checking the
      // constructor name.
      function isAudioParam(object) {
        return object && object.constructor.name === 'AudioParam';
      }

      // Does |limitOptions| exist and does it have valid values for the
      // expected min and max values?
      function hasValidLimits(limitOptions) {
        return limitOptions && (typeof limitOptions.minValue === 'number') &&
            (typeof limitOptions.maxValue === 'number');
      }

      // Check the min and max values for the AudioParam attribute named
      // |paramName| for the |node|. The expected limits is given by the
      // dictionary |limits|.  If some test fails, add the name of the failed
      function validateAudioParamLimits(should, node, paramName, limits) {
        let nodeName = node.constructor.name;
        let parameter = node[paramName];
        let prefix = nodeName + '.' + paramName;

        let success = true;
        if (hasValidLimits(limits[paramName])) {
          // Verify that the min and max values for the parameter are correct.
          let isCorrect = should(parameter.minValue, prefix + '.minValue')
                              .beEqualTo(limits[paramName].minValue);
          isCorrect = should(parameter.maxValue, prefix + '.maxValue')
                          .beEqualTo(limits[paramName].maxValue) &&
              isCorrect;

          // Verify that the min and max attributes are read-only
          parameter.minValue = Math.PI;
          let isReadOnly;
          isReadOnly =
              should(parameter.minValue, prefix + '.minValue = Math.PI')
                  .notBeEqualTo(Math.PI);

          should(isReadOnly, prefix + '.minValue is read-only').beEqualTo(true);

          isCorrect = isReadOnly && isCorrect;

          parameter.maxValue = Math.PI;
          isReadOnly =
              should(parameter.maxValue, prefix + '.maxValue = Math.PI')
                  .notBeEqualTo(Math.PI);
          should(isReadOnly, prefix + '.maxValue is read-only').beEqualTo(true);

          isCorrect = isReadOnly && isCorrect;

          // Now try to set the parameter outside the nominal range.
          let newValue = 2 * limits[paramName].minValue - 1;

          let isClipped = true;
          let clippingTested = false;
          // If the new value is beyond float the largest single-precision
          // float, skip the test because Chrome throws an error.
          if (newValue >= -mostPositiveFloat) {
            parameter.value = newValue;
            clippingTested = true;
            isClipped =
                should(
                    parameter.value, 'Set ' + prefix + '.value = ' + newValue)
                    .beEqualTo(parameter.minValue) &&
                isClipped;
          }

          newValue = 2 * limits[paramName].maxValue + 1;

          if (newValue <= mostPositiveFloat) {
            parameter.value = newValue;
            clippingTested = true;
            isClipped =
                should(
                    parameter.value, 'Set ' + prefix + '.value = ' + newValue)
                    .beEqualTo(parameter.maxValue) &&
                isClipped;
          }

          if (clippingTested) {
            should(
                isClipped,
                prefix + 'was clipped to lie within the nominal range')
                .beEqualTo(true);
          }

          isCorrect = isCorrect && isClipped;

          success = isCorrect && success;
        } else {
          // Test config didn't specify valid limits.  Fail this test!
          should(
              clippingTested,
              'Limits for ' + nodeName + '.' + paramName +
                  ' were correctly defined')
              .beEqualTo(false);

          success = false;
        }

        return success;
      }

      // Test all of the AudioParams for |node| using the expected values in
      // |limits|. |creatorName| is the name of the method to create the node,
      // and is used to keep trakc of which tests we've run.
      function testLimits(should, creatorName, node, limits) {
        let nodeName = node.constructor.name;
        testedMethods.add(creatorName);

        let success = true;

        // List of all of the AudioParams that were tested.
        let audioParams = [];

        // List of AudioParams that failed the test.
        let incorrectParams = [];

        // Look through all of the keys for the node and extract just the
        // AudioParams
        Object.keys(node.__proto__).forEach(function(paramName) {
          if (isAudioParam(node[paramName])) {
            audioParams.push(paramName);
            let isValid = validateAudioParamLimits(
                should, node, paramName, limits, incorrectParams);
            if (!isValid)
              incorrectParams.push(paramName);

            success = isValid && success;
          }
        });

        // Print an appropriate message depending on whether there were
        // AudioParams defined or not.
        if (audioParams.length) {
          let message =
              'Nominal ranges for AudioParam(s) of ' + node.constructor.name;
          should(success, message)
              .message('are correct', 'are incorrect for: ' + +incorrectParams);
          return success;
        } else {
          should(!limits, nodeName)
              .message(
                  'has no AudioParams as expected',
                  'has no AudioParams but test expected ' + limits);
        }
      }
    </script>
  </body>
</html>
