import 'package:fake_async/fake_async.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:speech_to_text/speech_to_text.dart'; import 'package:speech_to_text/speech_to_text_provider.dart'; import 'test_speech_channel_handler.dart'; import 'test_speech_listener.dart'; void main() { SpeechToTextProvider provider; SpeechToText speechToText; TestSpeechChannelHandler speechHandler; TestSpeechListener speechListener; TestWidgetsFlutterBinding.ensureInitialized(); setUp(() { speechToText = SpeechToText.withMethodChannel(SpeechToText.speechChannel); speechHandler = TestSpeechChannelHandler(speechToText); speechToText.channel .setMockMethodCallHandler(speechHandler.methodCallHandler); provider = SpeechToTextProvider(speechToText); speechListener = TestSpeechListener(provider); provider.addListener(speechListener.onNotify); }); tearDown(() { speechToText.channel.setMockMethodCallHandler(null); }); group('delegates', () { test('isListening matches delegate defaults', () { expect(provider.isListening, speechToText.isListening); expect(provider.isNotListening, speechToText.isNotListening); }); test('isAvailable matches delegate defaults', () { expect(provider.isAvailable, speechToText.isAvailable); expect(provider.isNotAvailable, !speechToText.isAvailable); }); test('isAvailable matches delegate after init', () async { expect(await provider.initialize(), isTrue); expect(provider.isAvailable, speechToText.isAvailable); expect(provider.isNotAvailable, !speechToText.isAvailable); }); test('hasError matches delegate after error', () async { expect(await provider.initialize(), isTrue); expect(provider.hasError, speechToText.hasError); }); }); group('listening', () { test('notifies on initialize', () async { fakeAsync((fa) { provider.initialize(); fa.flushMicrotasks(); expect(speechListener.notified, isTrue); expect(speechListener.isAvailable, isTrue); }); }); test('notifies on listening', () async { fakeAsync((fa) { setupForListen(provider, fa, speechListener); expect(speechListener.notified, isTrue); expect(speechListener.isListening, isTrue); expect(provider.hasResults, isFalse); }); }); test('notifies on final words', () async { fakeAsync((fa) { setupForListen(provider, fa, speechListener); speechListener.reset(); speechHandler.notifyFinalWords(); fa.flushMicrotasks(); expect(speechListener.notified, isTrue); expect(provider.hasResults, isTrue); var result = speechListener.recognitionResult; expect(result.recognizedWords, TestSpeechChannelHandler.secondRecognizedWords); expect(result.finalResult, isTrue); }); }); test('hasResult false after listening before new results', () async { fakeAsync((fa) { setupForListen(provider, fa, speechListener); speechHandler.notifyFinalWords(); provider.stop(); setupForListen(provider, fa, speechListener); fa.flushMicrotasks(); expect(provider.hasResults, isFalse); }); }); test('notifies on partial words', () async { fakeAsync((fa) { setupForListen(provider, fa, speechListener, partialResults: true); speechListener.reset(); speechHandler.notifyPartialWords(); fa.flushMicrotasks(); expect(speechListener.notified, isTrue); expect(provider.hasResults, isTrue); var result = speechListener.recognitionResult; expect(result.recognizedWords, TestSpeechChannelHandler.firstRecognizedWords); expect(result.finalResult, isFalse); }); }); }); group('soundLevel', () { test('notifies when requested', () async { fakeAsync((fa) { setupForListen(provider, fa, speechListener, partialResults: true, soundLevel: true); speechListener.reset(); speechHandler.notifySoundLevel(); fa.flushMicrotasks(); expect(speechListener.notified, isTrue); expect(speechListener.soundLevel, TestSpeechChannelHandler.level2); }); }); test('no notification by default', () async { fakeAsync((fa) { setupForListen(provider, fa, speechListener, partialResults: true, soundLevel: false); speechListener.reset(); speechHandler.notifySoundLevel(); fa.flushMicrotasks(); expect(speechListener.notified, isFalse); expect(speechListener.soundLevel, 0); }); }); }); group('stop/cancel', () { test('notifies on stop', () async { fakeAsync((fa) { provider.initialize(); setupForListen(provider, fa, speechListener); speechListener.reset(); provider.stop(); fa.flushMicrotasks(); expect(speechListener.notified, isTrue); expect(speechListener.isListening, isFalse); }); }); test('notifies on cancel', () async { fakeAsync((fa) { provider.initialize(); setupForListen(provider, fa, speechListener); speechListener.reset(); provider.cancel(); fa.flushMicrotasks(); expect(speechListener.notified, isTrue); expect(speechListener.isListening, isFalse); }); }); }); group('error handling', () { test('hasError matches delegate default', () async { expect(await provider.initialize(), isTrue); expect(provider.hasError, speechToText.hasError); }); test('notifies on error', () async { fakeAsync((fa) { provider.initialize(); setupForListen(provider, fa, speechListener); speechListener.reset(); speechHandler.notifyPermanentError(); expect(speechListener.notified, isTrue); expect(speechListener.hasError, isTrue); }); }); }); group('locale', () { test('locales empty before init', () async { expect(provider.systemLocale, isNull); expect(provider.locales, isEmpty); }); test('set from SpeechToText after init', () async { fakeAsync((fa) { speechHandler.setupLocales(); provider.initialize(); fa.flushMicrotasks(); expect( provider.systemLocale.localeId, TestSpeechChannelHandler.localeId1); expect(provider.locales, hasLength(speechHandler.locales.length)); }); }); }); } void setupForListen(SpeechToTextProvider provider, FakeAsync fa, TestSpeechListener speechListener, {bool partialResults = false, bool soundLevel = false}) { provider.initialize(); fa.flushMicrotasks(); speechListener.reset(); provider.listen(partialResults: partialResults, soundLevel: soundLevel); fa.flushMicrotasks(); }