halkyon/packages/halkyon_app/test/speech/voice_input_app_test.dart

98 lines
3.3 KiB
Dart
Raw Normal View History

2026-11-07 23:45:20 +01:00
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:halkyon_app/halkyon_app.dart';
/// The device's voice input app through Android's `RECOGNIZE_SPEECH`
/// intent (Halkyon Meditate's ADR 0038, D18), asked through each app's
/// `VoiceInput.kt` on `app.halkyon/voice_input`, its channel answering as
/// the activity does.
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
late List<MethodCall> calls;
void answer(Object? Function(MethodCall call) answers) {
calls = [];
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
.setMockMethodCallHandler(ChannelVoiceInputApp.channel, (call) async {
calls.add(call);
return answers(call);
});
}
tearDown(() {
debugDefaultTargetPlatformOverride = null;
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
.setMockMethodCallHandler(ChannelVoiceInputApp.channel, null);
});
const app = ChannelVoiceInputApp();
group('installed', () {
test('where Android has an app for the intent', () async {
answer((call) => call.method == 'installed');
expect(await app.installed(), isTrue);
});
test('not where it has none', () async {
answer((call) => false);
expect(await app.installed(), isFalse);
});
test('not where the activity fails or knows no such channel', () async {
answer((call) => throw PlatformException(code: 'failed'));
expect(await app.installed(), isFalse);
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
.setMockMethodCallHandler(ChannelVoiceInputApp.channel, null);
expect(await app.installed(), isFalse);
});
test('never off Android, without asking', () async {
answer((call) => true);
for (final platform in [
TargetPlatform.iOS,
TargetPlatform.linux,
TargetPlatform.macOS,
TargetPlatform.windows,
]) {
debugDefaultTargetPlatformOverride = platform;
expect(await app.installed(), isFalse, reason: '$platform');
}
expect(calls, isEmpty);
});
});
group('listening', () {
test('asks in the language given, with the prompt, and hands back the '
'words', () async {
answer((call) => 'a house by the sea');
expect(
await app.listen(language: 'de-DE', prompt: 'Was hast du geträumt?'),
'a house by the sea',
);
final listen = calls.single;
expect(listen.method, 'listen');
expect(listen.arguments, {
'language': 'de-DE',
'prompt': 'Was hast du geträumt?',
});
});
test('cancelled, hands back nothing', () async {
answer((call) => '');
expect(await app.listen(language: null), '');
expect(calls.single.arguments, {'language': null, 'prompt': null});
});
test(
'where the app could not be opened, says so without throwing',
() async {
answer((call) => throw PlatformException(code: 'noApp'));
expect(await app.listen(language: 'en'), isNull);
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
.setMockMethodCallHandler(ChannelVoiceInputApp.channel, null);
expect(await app.listen(language: 'en'), isNull);
},
);
});
}