import 'dart:io'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; /// Every file under `assets/content/` must be loadable through `rootBundle`, /// which is the only thing that proves it is DECLARED in pubspec.yaml and /// therefore actually ships. /// /// Found by reading the installed APK: it contained ZERO entries under /// `assets/content/`, while `assets/icons/alarmas/*` was present. pubspec /// declared `assets/content/` — and Flutter does NOT recurse: naming a /// directory includes the files sitting directly in it, never its /// subdirectories. All of this content lives in subdirectories /// (`onboarding/`, `updates//`), so the entire onboarding and /// release-notes feature had never shipped in any build. On the device it /// surfaced on every launch as: /// /// Unable to load asset: "assets/content/onboarding/en.md" /// /// with the file plainly present on disk. /// /// Same family as the drawables the resource shrinker deleted: a reference by /// NAME that nothing validates at compile time, so it fails only on a device. /// A test that merely checked `File(...).existsSync()` would have stayed green /// throughout — the files were never missing. Loading through `rootBundle` is /// what makes it a real guard, because that is the path the app itself takes. void main() { TestWidgetsFlutterBinding.ensureInitialized(); final directorio = Directory('assets/content'); final ficheros = directorio .listSync(recursive: true) .whereType() .map((f) => f.path.replaceAll(r'\', '/')) .toList() ..sort(); test('hay contenido que comprobar (si no, este test sería vacuo)', () { expect(ficheros, isNotEmpty); }); for (final ruta in ficheros) { test('$ruta está declarado y se puede cargar', () async { await expectLater( rootBundle.loadString(ruta), completes, reason: 'existe en disco pero rootBundle no lo encuentra: falta declarar ' 'su directorio en pubspec.yaml, y no viajará en el APK', ); }); } }