// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. import 'dart:async'; import 'dart:html'; import 'dart:typed_data'; import 'dart:web_audio'; import 'package:expect/async_helper.dart'; import 'package:expect/legacy/minitest.dart'; // ignore: deprecated_member_use_from_same_package main() { var isAudioContext = predicate( (x) => x is AudioContext, 'is an AudioContext', ); group('supported', () { test('supported', () { expect(AudioContext.supported, true); }); }); group('functional', () { var context; if (AudioContext.supported) { context = new AudioContext(); } test('constructorTest', () { if (AudioContext.supported) { expect(context, isNotNull); expect(context, isAudioContext); } }); test('audioRenames', () { if (AudioContext.supported) { GainNode gainNode = context.createGain(); gainNode.connectNode(context.destination); expect(gainNode is GainNode, isTrue); expect(context.createAnalyser() is AnalyserNode, isTrue); expect(context.createChannelMerger() is AudioNode, isTrue); expect(context.createChannelSplitter() is AudioNode, isTrue); expect(context.createOscillator() is OscillatorNode, isTrue); expect(context.createPanner() is PannerNode, isTrue); expect( context.createScriptProcessor(4096) is ScriptProcessorNode, isTrue, ); } }); // TODO(9322): This test times out. /* test('onAudioProcess', () { if(AudioContext.supported) { var completer = new Completer(); var context = new AudioContext(); var scriptProcessor = context.createScriptProcessor(1024, 1, 2); scriptProcessor.connectNode(context.destination); bool alreadyCalled = false; scriptProcessor.onAudioProcess.listen((event) { if (!alreadyCalled) { completer.complete(true); } alreadyCalled = true; }); return completer.future; } }); */ test('oscillatorTypes', () { if (AudioContext.supported) { OscillatorNode oscillator = context.createOscillator(); oscillator.connectNode(context.destination); oscillator.type = 'sawtooth'; expect(oscillator.type, equals('sawtooth')); oscillator.type = 'sine'; expect(oscillator.type, equals('sine')); oscillator.type = 'square'; expect(oscillator.type, equals('square')); oscillator.type = 'triangle'; expect(oscillator.type, equals('triangle')); //expect(() => oscillator.type = 7, throws); Firefox does not throw, it //simply ignores this value. expect(oscillator.type, equals('triangle')); // Firefox does not throw when it receives invalid values; it simply // ignores them. //expect(() => oscillator.type = ['heap object not a string'], throws); expect(oscillator.type, equals('triangle')); } }); asyncTest(() async { if (AudioContext.supported) { final audioSourceUrl = "/root_dart/tests/lib/html/small.mp3"; Future requestAudioDecode({ bool triggerDecodeError = false, DecodeSuccessCallback? successCallback, DecodeErrorCallback? errorCallback, }) async { HttpRequest audioRequest = HttpRequest(); audioRequest.open("GET", audioSourceUrl, async: true); audioRequest.responseType = "arraybuffer"; var completer = new Completer(); audioRequest.onLoad.listen((_) { ByteBuffer audioData = audioRequest.response; if (triggerDecodeError) audioData = Uint8List.fromList([]).buffer; context .decodeAudioData(audioData, successCallback, errorCallback) .then((_) { completer.complete(); }) .catchError((e) { completer.completeError(e); }); }); audioRequest.send(); return completer.future; } // Decode successfully without callback. await requestAudioDecode(); // Decode successfully with callback. Use counter to make sure it's only // called once. var successCallbackCalled = 0; await requestAudioDecode( successCallback: (_) { successCallbackCalled += 1; }, errorCallback: (_) {}, ); expect(successCallbackCalled, 1); // Fail decode without callback. try { await requestAudioDecode(triggerDecodeError: true); fail('Expected decode failure.'); } catch (_) {} // Fail decode with callback. var errorCallbackCalled = 0; try { await requestAudioDecode( triggerDecodeError: true, successCallback: (_) {}, errorCallback: (_) { errorCallbackCalled += 1; }, ); fail('Expected decode failure.'); } catch (e) { // Safari may return a null error. Assuming Safari is version >= 14.1, // the Future should complete with a string error if the error // callback never gets called. if (errorCallbackCalled == 0) { expect(e is String, true); } else { expect(errorCallbackCalled, 1); } } } }); }); }