8fb6b4fbb3
Both fixes paired with the ci-flutter:3.44 rebuild that adds libsqlite3-dev to the runner image (CI-runner push #2: libsqlite3-0 → -dev because dart:ffi opens the unversioned .so symlink that only the dev package ships). widgets_smoke_test (TrackRow): TrackRow contains CachedIndicator which reaches audioCacheManagerProvider → appDbProvider → drift_flutter's `driftDatabase()`. That schedules a deferred-init Timer that outlives the test widget tree and trips the "A Timer is still pending after dispose" invariant. Override appDbProvider in the test to use AppDb(NativeDatabase.memory()) directly — bypasses drift_flutter's Timer-using init path, still exercises real SQLite via FFI. like_button_test (tap toggles + rollback): LikeButton was migrated to LucideHeart (SVG widget with `filled` bool) in the Lucide sweep; the test's `find.byIcon(Icons.favorite)` is stale. Replace with a small heartFilled() helper that reads the LucideHeart's `filled` prop straight off the widget tree. Same assertion semantics, just against the post-migration shape. The four sync_controller failures need no code change — they're the same root cause as the drift-tagged cohort (libsqlite3.so missing → try/catch returns null → `result?.upserts` is null instead of the expected 0). The image fix should clear them. Fable #399 / local #62. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
69 lines
2.2 KiB
Dart
69 lines
2.2 KiB
Dart
import 'package:drift/native.dart' show NativeDatabase;
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
|
|
import 'package:minstrel/cache/audio_cache_manager.dart' show appDbProvider;
|
|
import 'package:minstrel/cache/db.dart';
|
|
import 'package:minstrel/library/widgets/album_card.dart';
|
|
import 'package:minstrel/library/widgets/track_row.dart';
|
|
import 'package:minstrel/models/album.dart';
|
|
import 'package:minstrel/models/track.dart';
|
|
import 'package:minstrel/theme/theme_data.dart';
|
|
|
|
void main() {
|
|
testWidgets('AlbumCard renders title and artist', (tester) async {
|
|
await tester.pumpWidget(MaterialApp(
|
|
theme: buildThemeData(),
|
|
home: Scaffold(
|
|
body: AlbumCard(
|
|
album: const AlbumRef(
|
|
id: 'a',
|
|
title: 'Geogaddi',
|
|
artistId: 'x',
|
|
artistName: 'Boards of Canada',
|
|
),
|
|
onTap: () {},
|
|
),
|
|
),
|
|
));
|
|
expect(find.text('Geogaddi'), findsOneWidget);
|
|
expect(find.text('Boards of Canada'), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('TrackRow shows mm:ss duration', (tester) async {
|
|
// TrackRow contains CachedIndicator (ConsumerWidget) which reaches
|
|
// audioCacheManagerProvider → appDbProvider. Override appDbProvider
|
|
// with an explicit NativeDatabase.memory() executor — drift_flutter's
|
|
// default `driftDatabase()` schedules a deferred-init Timer that
|
|
// outlives the test widget tree and trips
|
|
// _verifyInvariants("A Timer is still pending after dispose").
|
|
await tester.pumpWidget(ProviderScope(
|
|
overrides: [
|
|
appDbProvider.overrideWith((ref) {
|
|
final db = AppDb(NativeDatabase.memory());
|
|
ref.onDispose(db.close);
|
|
return db;
|
|
}),
|
|
],
|
|
child: MaterialApp(
|
|
theme: buildThemeData(),
|
|
home: Scaffold(
|
|
body: TrackRow(
|
|
track: const TrackRef(
|
|
id: 't',
|
|
title: 'Roygbiv',
|
|
albumId: 'a',
|
|
artistId: 'x',
|
|
durationSec: 137,
|
|
trackNumber: 4,
|
|
),
|
|
onTap: () {},
|
|
),
|
|
),
|
|
),
|
|
));
|
|
expect(find.text('02:17'), findsOneWidget);
|
|
});
|
|
}
|