fix: Lade-Race in BoolPref/StringSetPref (Review-Befund)
StringSetPref.add/remove machten Read-Modify-Write auf möglicherweise noch ungeladenem State: ein add() direkt nach Erstellung persistierte nur den neuen Eintrag und LÖSCHTE alle bereits gespeicherten (per neuem Test am alten Code bewiesen). Jetzt warten add/remove auf _loaded. BoolPref bekommt einen _userSet-Guard, damit ein spät landender persistierter Wert nie eine schon getätigte Nutzeraktion zurücküberschreibt (Reihenfolge ist plattform- abhängig). In der Praxis kaum treffbar (Provider laden beim App-Start), aber die Fassade wird beim M2-Storage-Umbau Pflicht-Schnittstelle für neue, ggf. früh laufende Aufrufer. 2 neue Regressionstests, alle 24 grün. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -23,6 +23,21 @@ void main() {
|
||||
expect(pref.state, false, reason: 'persistierter Wert muss gewinnen');
|
||||
});
|
||||
|
||||
test(
|
||||
'set() sofort nach Erstellung gewinnt gegen den später ladenden '
|
||||
'persistierten Wert (Lade-Race)', () async {
|
||||
SharedPreferences.setMockInitialValues({'notif_sound': false});
|
||||
final pref = BoolPref('notif_sound', false);
|
||||
final done = pref.set(true); // bevor _load fertig ist
|
||||
await pumpEventQueue();
|
||||
await done;
|
||||
expect(pref.state, true,
|
||||
reason: 'die Nutzeraktion darf nicht vom Lade-Ergebnis '
|
||||
'zurücküberschrieben werden');
|
||||
final p = await SharedPreferences.getInstance();
|
||||
expect(p.getBool('notif_sound'), true);
|
||||
});
|
||||
|
||||
test('set/toggle ändern Zustand und persistieren', () async {
|
||||
final pref = BoolPref('notif_desktop', true);
|
||||
await pumpEventQueue();
|
||||
@@ -49,6 +64,23 @@ void main() {
|
||||
expect(p.getStringList('muted_rooms')!.toSet(), {'!b:hs', '!c:hs'});
|
||||
});
|
||||
|
||||
test(
|
||||
'add() sofort nach Erstellung verliert keine bereits persistierten '
|
||||
'Einträge (Lade-Race)', () async {
|
||||
SharedPreferences.setMockInitialValues({
|
||||
'muted_rooms': ['!a:hs'],
|
||||
});
|
||||
final pref = StringSetPref('muted_rooms');
|
||||
final done = pref.add('!b:hs'); // bevor _load fertig ist
|
||||
await pumpEventQueue();
|
||||
await done;
|
||||
expect(pref.state, {'!a:hs', '!b:hs'});
|
||||
final p = await SharedPreferences.getInstance();
|
||||
expect(p.getStringList('muted_rooms')!.toSet(), {'!a:hs', '!b:hs'},
|
||||
reason: 'Read-Modify-Write auf ungeladenem State darf keine '
|
||||
'persistierten Einträge verlieren');
|
||||
});
|
||||
|
||||
test('doppeltes add und remove von Fehlendem sind No-Ops', () async {
|
||||
final pref = StringSetPref('muted_rooms');
|
||||
await pumpEventQueue();
|
||||
|
||||
Reference in New Issue
Block a user