An independent Gemini 3.8 Flash audit of this repo found real problems. Each was reproduced before being fixed. Confirmed defects: - tool/adjudicate.py crashed with KeyError once R001 started grouping variants under 'variants' instead of 'variant'. Fixing that exposed a second bug of my own: it then divided verified VARIANTS by FINDINGS and reported 216% precision. Counts are now coherent (findings vs variant-level checks) and a clean repo reports 0/0 rather than a fake 100%. - GuideCommand called _readPolicy but never registered --policy, so exited 64 despite the README documenting it. - loading-flag-not-reset treated a constructor-invoked method as inheriting the loading flag without checking flag.defaultsTrue, so a default-FALSE flag was reported as in flight. - Finding.fingerprint embedded the line number for rules whose only identity was , so moving code broke baseline entries. is now a discriminating key; only loading-not-reset, which can emit two findings from one method, carries an explicit catchLine. - suggest grouped unrelated provider-read-in-build findings by file; the group key, label and target list now use valueType/call. Recall defect found while checking the auditor's own claim: UI variant mentions were collected project-wide by unqualified name, so ExportSuccess - which appears in FOUR unions on nuwayze - was cross-credited. Mentions are now scoped per union to files that also name the state type or its owner, which surfaced ArtistStoreManagementState[ExportSuccess] as a real finding. Five negative controls could not fail (an event that is never handled can never be reported as unhandled; a union with no render sites can never be reported as rendered-not-emitted). Added fixture cases that make each one bite: HandledTap (handled AND dispatched), PatternState render sites, GuardedCubit (guarded loading path), QuietCubit._warmUp (constructor-invoked await on a default-false flag). Root cause of a recurring mystery: this repo EXCLUDED test/fixtures/** from analysis, which made any analyzer running in the repo context parse the fixture without resolving its imports and report phantom undefined-class errors. I had dismissed these as stale cache several times; they were my own exclusion. The exclude is gone and the fixture governs itself. A new test asserts the fixture has zero analyzer errors, not merely that it resolves, so IR distortion cannot hide. 84 tests (was 81).
80 lines
2.1 KiB
Dart
80 lines
2.1 KiB
Dart
import 'bloc.dart';
|
|
|
|
// --- state: one variant is declared but never emitted ---------------------
|
|
|
|
abstract class GapState {
|
|
const GapState();
|
|
}
|
|
|
|
class GapIdle extends GapState {
|
|
const GapIdle();
|
|
}
|
|
|
|
/// Declared and rendered, but [GapBloc] never emits it: dead UI.
|
|
class GapGhost extends GapState {
|
|
const GapGhost();
|
|
}
|
|
|
|
// --- events: one unhandled, one never dispatched -------------------------
|
|
|
|
abstract class HandlerGapEvent {
|
|
const HandlerGapEvent();
|
|
}
|
|
|
|
/// Dispatched, but no `on<UnhandledTap>` exists: the tap does nothing.
|
|
class UnhandledTap extends HandlerGapEvent {
|
|
const UnhandledTap();
|
|
}
|
|
|
|
/// Handled, but nothing ever dispatches it: dead handler.
|
|
class NeverDispatched extends HandlerGapEvent {
|
|
const NeverDispatched();
|
|
}
|
|
|
|
/// Handled AND dispatched: the negative control for both event rules. Without a
|
|
/// case like this, asserting "HandledTap is never reported as unhandled" proves
|
|
/// nothing, because an event that is never handled could never be reported.
|
|
class HandledTap extends HandlerGapEvent {
|
|
const HandledTap();
|
|
}
|
|
|
|
// --- a variant name shared with another union ---------------------------
|
|
//
|
|
// UI matching is by UNQUALIFIED name, so a project-wide mention set would
|
|
// cross-credit: matching DuplicatedName for AlphaState would silently mark
|
|
// BetaState's identically named variant as rendered too. This pair is the
|
|
// regression guard for scoping mentions per union.
|
|
|
|
class AlphaEvent {}
|
|
|
|
sealed class AlphaState {
|
|
const AlphaState();
|
|
}
|
|
|
|
class DuplicatedName extends AlphaState {
|
|
const DuplicatedName();
|
|
}
|
|
|
|
class AlphaBloc extends Bloc<AlphaEvent, AlphaState> {
|
|
AlphaBloc() : super(const DuplicatedName());
|
|
|
|
void go() => emit(const DuplicatedName());
|
|
}
|
|
|
|
class GapBloc extends Bloc<HandlerGapEvent, GapState> {
|
|
GapBloc() : super(const GapIdle());
|
|
|
|
void register() {
|
|
on<NeverDispatched>((event, emit) => emit(const GapIdle()));
|
|
on<HandledTap>((event, emit) => emit(const GapIdle()));
|
|
}
|
|
|
|
void tap() {
|
|
// No on<UnhandledTap> is registered anywhere.
|
|
add(const UnhandledTap());
|
|
}
|
|
|
|
void tapHandled() {
|
|
add(const HandledTap());
|
|
}
|
|
}
|