import 'dart:async'; import 'dart:io'; import 'package:flutter_test/flutter_test.dart'; import 'package:spotiflac_android/services/sqlite_helpers.dart'; void main() { group('SingleFlightInitializer', () { test('coalesces concurrent initialization and caches the result', () async { final initializer = SingleFlightInitializer(); final gate = Completer(); var calls = 0; Future create() async { calls++; await gate.future; return 42; } final first = initializer.getOrCreate(create); final second = initializer.getOrCreate(create); expect(identical(first, second), isTrue); expect(calls, 1); gate.complete(); expect(await Future.wait([first, second]), [42, 42]); expect(await initializer.getOrCreate(create), 42); expect(calls, 1); }); test('allows retry after initialization fails', () async { final initializer = SingleFlightInitializer(); var calls = 0; Future create() { calls++; if (calls == 1) throw StateError('first attempt failed'); return Future.value(7); } await expectLater(initializer.getOrCreate(create), throwsStateError); expect(await initializer.getOrCreate(create), 7); expect(calls, 2); }); test('reset permits a fresh initialization', () async { final initializer = SingleFlightInitializer(); var value = 1; expect(await initializer.getOrCreate(() async => value), 1); value = 2; expect(await initializer.getOrCreate(() async => value), 1); initializer.reset(); expect(await initializer.getOrCreate(() async => value), 2); }); }); group('SQLite startup configuration', () { final source = File('lib/services/sqlite_helpers.dart').readAsStringSync(); test('waits for transient locks before configuring the connection', () { final configureIndex = source.indexOf('onConfigure:'); final busyTimeoutIndex = source.indexOf('PRAGMA busy_timeout'); final journalModeIndex = source.indexOf('PRAGMA journal_mode'); expect(configureIndex, greaterThanOrEqualTo(0)); expect(busyTimeoutIndex, greaterThan(configureIndex)); expect(busyTimeoutIndex, lessThan(journalModeIndex)); }); test('sets incremental auto-vacuum only before app tables exist', () { final schemaCheckIndex = source.indexOf('FROM sqlite_master'); final emptySchemaGuardIndex = source.indexOf('if (tables.isEmpty)'); final autoVacuumMatches = RegExp( r"PRAGMA auto_vacuum = INCREMENTAL", ).allMatches(source).toList(); final onCreateIndex = source.indexOf('onCreate:'); expect(autoVacuumMatches, hasLength(1)); expect(schemaCheckIndex, greaterThanOrEqualTo(0)); expect(emptySchemaGuardIndex, greaterThan(schemaCheckIndex)); expect( autoVacuumMatches.single.start, greaterThan(emptySchemaGuardIndex), ); expect(autoVacuumMatches.single.start, lessThan(onCreateIndex)); }); }); }