Files
wolf_dart/packages/wolf_3d_flutter/test/app_managers_test.dart
T

196 lines
5.4 KiB
Dart

import 'package:file_selector/file_selector.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:wolf_3d_dart/wolf_3d_data_types.dart';
import 'package:wolf_3d_dart/wolf_3d_engine.dart';
import 'package:wolf_3d_flutter/wolf_3d_flutter.dart';
class _NoopAudio implements EngineAudio {
@override
WolfensteinData? activeGame;
int stopAllAudioCallCount = 0;
int disposeCallCount = 0;
@override
Future<void> debugSoundTest() async {}
@override
Future<void> init() async {}
@override
void playLevelMusic(Music music) {}
@override
void playMenuMusic() {}
@override
void playSoundEffect(SoundEffect effect) {}
@override
void playSoundEffectId(int sfxId) {}
@override
Future<void> stopAllAudio() async {
stopAllAudioCallCount++;
}
@override
void stopMusic() {}
@override
void dispose() {
disposeCallCount++;
}
}
class _RecordingEngine extends Wolf3dFlutterEngine {
_RecordingEngine({required _NoopAudio audio}) : super(audioBackend: audio);
int initCallCount = 0;
String? lastDirectory;
List<String> lastAdditionalDirectories = <String>[];
@override
Future<Wolf3dFlutterEngine> init({
String? directory,
Iterable<String>? additionalDirectories,
}) async {
initCallCount++;
lastDirectory = directory;
lastAdditionalDirectories =
additionalDirectories?.toList(growable: false) ?? <String>[];
return this;
}
}
void main() {
group('GameDataPickerManager', () {
test('pickGameDataDirectory reloads selected directory', () async {
final engine = _RecordingEngine(audio: _NoopAudio());
int notifyCount = 0;
final manager = GameDataPickerManager(
engine: engine,
pickDirectory: ({String? confirmButtonText}) async => ' /tmp/wolf ',
);
await manager.pickGameDataDirectory(
notifyChanged: () => notifyCount++,
);
expect(notifyCount, 2);
expect(manager.isLoadingGameData, isFalse);
expect(manager.pickerError, isNull);
expect(engine.initCallCount, 1);
expect(engine.lastDirectory, '/tmp/wolf');
expect(engine.lastAdditionalDirectories, isEmpty);
});
test('pickGameDataDirectory ignores empty selection', () async {
final engine = _RecordingEngine(audio: _NoopAudio());
final manager = GameDataPickerManager(
engine: engine,
pickDirectory: ({String? confirmButtonText}) async => ' ',
);
await manager.pickGameDataDirectory(notifyChanged: () {});
expect(engine.initCallCount, 0);
expect(manager.pickerError, isNull);
});
test(
'pickGameDataFiles deduplicates directories and forwards extras',
() async {
final engine = _RecordingEngine(audio: _NoopAudio());
final manager = GameDataPickerManager(
engine: engine,
pickFiles: () async => <XFile>[
XFile('/a/one/VSWAP.WL6'),
XFile('/a/one/MAPHEAD.WL6'),
XFile('/a/two/VSWAP.WL1'),
],
);
await manager.pickGameDataFiles(notifyChanged: () {});
expect(engine.initCallCount, 1);
expect(engine.lastDirectory, '/a/one');
expect(engine.lastAdditionalDirectories, <String>['/a/two']);
expect(manager.pickerError, isNull);
},
);
test('pickGameDataFiles reports missing directory paths', () async {
final engine = _RecordingEngine(audio: _NoopAudio());
final manager = GameDataPickerManager(
engine: engine,
pickFiles: () async => <XFile>[
XFile('VSWAP.WL6'),
XFile('MAPHEAD.WL6'),
],
);
await manager.pickGameDataFiles(notifyChanged: () {});
expect(engine.initCallCount, 0);
expect(
manager.pickerError,
'Selected files do not expose local filesystem paths.',
);
});
test('pickGameDataDirectory captures thrown picker error', () async {
final engine = _RecordingEngine(audio: _NoopAudio());
final manager = GameDataPickerManager(
engine: engine,
pickDirectory: ({String? confirmButtonText}) async {
throw StateError('picker failed');
},
);
await manager.pickGameDataDirectory(notifyChanged: () {});
expect(engine.initCallCount, 0);
expect(
manager.pickerError,
contains('Unable to load selected directory'),
);
expect(manager.isLoadingGameData, isFalse);
});
});
group('Wolf3dAppManager', () {
test('ensureAudioShutdown only executes once', () async {
final audio = _NoopAudio();
final engine = _RecordingEngine(audio: audio);
final manager = Wolf3dAppManager(engine: engine);
await Future.wait<void>(<Future<void>>[
manager.ensureAudioShutdown(),
manager.ensureAudioShutdown(),
]);
expect(audio.stopAllAudioCallCount, 1);
expect(audio.disposeCallCount, 1);
});
test('forwards picker state from injected picker manager', () async {
final engine = _RecordingEngine(audio: _NoopAudio());
final pickerManager = GameDataPickerManager(
engine: engine,
pickDirectory: ({String? confirmButtonText}) async => '/tmp/wolf',
);
final manager = Wolf3dAppManager(
engine: engine,
pickerManager: pickerManager,
);
await manager.pickGameDataDirectory(notifyChanged: () {});
expect(manager.isLoadingGameData, isFalse);
expect(manager.pickerError, isNull);
expect(engine.lastDirectory, '/tmp/wolf');
});
});
}