dispose-safe teardown for KeymapService + ClaudeConfig; cover the
claude extension lifecycle make test-integration failed at widget-tree finalization: the palette's dispose() clears its scope flag, which during app teardown runs AFTER KernelServices.dispose() has disposed the KeymapService — notifyListeners asserted. Scope-flag mutations now use the same fire-and-forget guard SettingsStore established. Same family in ClaudeConfig: activation's unawaited load() could notify (and start watchers on) a disposed notifier when a teardown raced it. The claude extension's activation lifecycle and command success paths are now exercised end-to-end through the kernel fixture — the file entered the coverage denominator with the T-391 failure-path tests, so per the ratchet discipline the rest of it gets covered too. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -167,20 +167,37 @@ class KeymapService extends ChangeNotifier {
|
||||
return km.match(sequence, _scope).exact;
|
||||
}
|
||||
|
||||
/// Scope-flag producers clear their flags from widget dispose() — which
|
||||
/// during app teardown runs AFTER KernelServices.dispose() has disposed
|
||||
/// this notifier. Tolerate that ordering instead of asserting (the same
|
||||
/// fire-and-forget pattern SettingsStore uses).
|
||||
bool _disposed = false;
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_disposed = true;
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _safeNotify() {
|
||||
if (_disposed) return;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
/// Set a named scope flag. Producers should call this when their
|
||||
/// state changes so when-clauses re-evaluate correctly. Notifies
|
||||
/// listeners when the value actually changes.
|
||||
void setScopeFlag(String name, bool value) {
|
||||
if (_scope[name] == value) return;
|
||||
_scope[name] = value;
|
||||
notifyListeners();
|
||||
_safeNotify();
|
||||
}
|
||||
|
||||
/// Clear a named scope flag.
|
||||
void clearScopeFlag(String name) {
|
||||
if (!_scope.containsKey(name)) return;
|
||||
_scope.remove(name);
|
||||
notifyListeners();
|
||||
_safeNotify();
|
||||
}
|
||||
|
||||
/// Switch presets. Persists the new preset name to settings and
|
||||
|
||||
Reference in New Issue
Block a user