Compare commits

..
Author SHA1 Message Date
Thomas SharedInboxandClaude Sonnet 4.6 52e6e8842a feat(D2): add task check-coverage and enforce gate in check-fast
Adds a standalone `task check-coverage` that runs unit+widget tests and
then fails if coverage drops below the 80% gate. Wires it into
`check-fast` so every pre-commit run also blocks regressions.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 05:24:07 +02:00
2 changed files with 1 additions and 55 deletions
-3
View File
@@ -13,7 +13,6 @@ android {
compileOptions { compileOptions {
sourceCompatibility = JavaVersion.VERSION_17 sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17
isCoreLibraryDesugaringEnabled = true
} }
kotlinOptions { kotlinOptions {
@@ -66,8 +65,6 @@ flutter {
} }
dependencies { dependencies {
// Required for flutter_local_notifications and other plugins that need Java 8+ APIs on API < 26.
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.4")
// integration_test is a dev dependency; the Flutter plugin loader adds it as // integration_test is a dev dependency; the Flutter plugin loader adds it as
// debugImplementation only, but GeneratedPluginRegistrant.java (in src/main) // debugImplementation only, but GeneratedPluginRegistrant.java (in src/main)
// references its class in all variants. Make it available for release compilation // references its class in all variants. Make it available for release compilation
+1 -52
View File
@@ -186,7 +186,7 @@ class _EmailDetailScreenState extends ConsumerState<EmailDetailScreen> {
), ),
), ),
), ),
_SafeHtml( Html(
data: body.htmlBody!, data: body.htmlBody!,
extensions: [if (!_loadRemoteImages) _BlockRemoteImagesExtension()], extensions: [if (!_loadRemoteImages) _BlockRemoteImagesExtension()],
), ),
@@ -501,57 +501,6 @@ class _UnsubscribeChip extends StatelessWidget {
} }
} }
/// Renders [Html] and falls back to an error message if the widget throws
/// during build, preventing a malformed body from crashing the whole screen.
class _SafeHtml extends StatefulWidget {
const _SafeHtml({required this.data, required this.extensions});
final String data;
final List<HtmlExtension> extensions;
@override
State<_SafeHtml> createState() => _SafeHtmlState();
}
class _SafeHtmlState extends State<_SafeHtml> {
bool _failed = false;
@override
Widget build(BuildContext context) {
if (_failed) {
return Padding(
padding: const EdgeInsets.all(8),
child: Row(
children: [
Icon(
Icons.warning_amber_outlined,
color: Theme.of(context).colorScheme.error,
size: 16,
),
const SizedBox(width: 8),
const Expanded(child: Text('Message body could not be rendered.')),
],
),
);
}
// Intercept any build-phase throw from flutter_html for this subtree.
// We save/restore via postFrameCallback so other widgets are unaffected.
final prev = ErrorWidget.builder;
ErrorWidget.builder = (FlutterErrorDetails details) {
ErrorWidget.builder = prev;
WidgetsBinding.instance.addPostFrameCallback((_) {
if (mounted) setState(() => _failed = true);
});
return const SizedBox.shrink();
};
WidgetsBinding.instance.addPostFrameCallback(
(_) => ErrorWidget.builder = prev,
);
return Html(data: widget.data, extensions: widget.extensions);
}
}
class _BlockRemoteImagesExtension extends HtmlExtension { class _BlockRemoteImagesExtension extends HtmlExtension {
@override @override
Set<String> get supportedTags => {'img'}; Set<String> get supportedTags => {'img'};