- detectSystemMessages() erkennt jetzt auch den Uebergang zu einem GPS-Fix (flankengetriggert wie Battery/Failsafe), Meldung "GPS fix acquired (N satellites)". - Die automatisch erkannten Verbindungsmeldungen heissen jetzt "Drone connected"/"Drone disconnected" statt "Connected"/"Connection lost" - praeziser an die tatsaechliche Bedeutung angelehnt (Eintreffen/Ausbleiben echter Telemetrie-Frames, nicht nur des rohen Socket-Zustands). - DroneProfile: feste Pack-Alarmspannung (batteryVoltageGreenMinV/RedMinV) ersetzt durch batteryCellCount + Pro-Zelle-Schwellwerte (batteryVoltageGreenMinPerCellV/RedMinPerCellV, LiPo-Standardwerte 3.4/3.2 V als Default). Die alten Feldnamen bleiben als berechnete Getter (Zellenzahl * Pro-Zelle-Wert) erhalten, damit telemetry_field_status.dart unveraendert bleibt. T1-Ranger-Standardprofil auf 4S gesetzt. - DB-Schema v8 -> v9 (additiv, alte Pack-Spannungs-Spalten bleiben als tote Spalten stehen), Repository und Share-Codec-Im-/Export entsprechend angepasst; alte Exportdateien ohne die neuen Felder fallen auf die DroneProfile-Defaults zurueck statt eine unbekannte Zellenzahl zu raten. - DroneProfileEditor: "Battery voltage alarm"-Gruppe um ein Zellenzahl-Feld erweitert und auf V/Zelle umbenannt. - Tests ergaenzt/angepasst: GPS-Fix-Erkennung (Unit + Provider-Integration), neuer v8->v9-Migrationstest analog zum bestehenden v7->v8-Test, Connected/Disconnected-Umbenennung in Provider- und Widget-Tests, Cell-Count-Roundtrip in Repository- und Share-Codec-Tests. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
69 lines
2.0 KiB
Dart
69 lines
2.0 KiB
Dart
import 'package:drift/native.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
|
|
import 'package:dmc_app/domain/mission/drone_profile.dart';
|
|
import 'package:dmc_app/services/database/app_database.dart' hide DroneProfile;
|
|
import 'package:dmc_app/services/database/drone_profile_repository.dart';
|
|
|
|
void main() {
|
|
late AppDatabase db;
|
|
late DroneProfileRepository repository;
|
|
|
|
setUp(() {
|
|
db = AppDatabase.forTesting(NativeDatabase.memory());
|
|
repository = DroneProfileRepository(db);
|
|
});
|
|
|
|
tearDown(() => db.close());
|
|
|
|
test('ensureSeeded legt beim ersten Aufruf T1 Ranger an', () async {
|
|
final id = await repository.ensureSeeded();
|
|
|
|
final all = await repository.loadAll();
|
|
expect(all, hasLength(1));
|
|
expect(all.single.id, id);
|
|
expect(all.single.name, 'T1 Ranger');
|
|
expect(all.single.cruiseSpeed, 15);
|
|
expect(all.single.batteryCellCount, 4);
|
|
});
|
|
|
|
test('ensureSeeded ist ein no-op, wenn bereits Profile existieren', () async {
|
|
await repository.insert(DroneProfile.t1Ranger().copyWith(name: 'Custom'));
|
|
|
|
await repository.ensureSeeded();
|
|
|
|
final all = await repository.loadAll();
|
|
expect(all, hasLength(1));
|
|
expect(all.single.name, 'Custom');
|
|
});
|
|
|
|
test('insert/update/delete rundtrip', () async {
|
|
final id = await repository.insert(
|
|
DroneProfile.t1Ranger().copyWith(name: 'Racer', maxSpeed: 40),
|
|
);
|
|
|
|
var all = await repository.loadAll();
|
|
expect(all.single.maxSpeed, 40);
|
|
|
|
await repository.update(all.single.copyWith(maxSpeed: 45));
|
|
all = await repository.loadAll();
|
|
expect(all.single.maxSpeed, 45);
|
|
expect(all.single.id, id);
|
|
|
|
await repository.delete(id);
|
|
expect(await repository.loadAll(), isEmpty);
|
|
});
|
|
|
|
test('watchAll gibt Aenderungen reaktiv weiter', () async {
|
|
final stream = repository.watchAll();
|
|
final emissions = <int>[];
|
|
final sub = stream.listen((profiles) => emissions.add(profiles.length));
|
|
addTearDown(sub.cancel);
|
|
|
|
await repository.insert(DroneProfile.t1Ranger());
|
|
await pumpEventQueue();
|
|
|
|
expect(emissions, contains(1));
|
|
});
|
|
}
|