Skip to content

Commit

Permalink
chore: better tests
Browse files Browse the repository at this point in the history
  • Loading branch information
lishaduck committed Apr 30, 2024
1 parent 175682c commit f28d8b2
Show file tree
Hide file tree
Showing 6 changed files with 19 additions and 56 deletions.
10 changes: 0 additions & 10 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -246,16 +246,6 @@ jobs:
with:
path: coverage/lcov.info
min_coverage: 90 # 100
exclude: >-
lib/src/gen/*.gen.dart
lib/src/features/**/*.g.dart
lib/src/features/**/*.freezed.dart
lib/src/utils/*.g.dart
lib/src/utils/*.freezed.dart
lib/src/app/*.gr.dart
lib/src/app/*.gm.dart
lib/src/l10n/app_localizations.dart
lib/src/l10n/app_localizations_*.dart

format:
name: Formatting
Expand Down
4 changes: 2 additions & 2 deletions lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import 'package:flutter/widgets.dart';
import 'package:shared_preferences/shared_preferences.dart';

import 'src/app/app.dart';
import 'src/app/bootstrap.dart';

Future<void> main() async {
await const MyApp().bootstrap(
const RunApp(),
runApp,
SharedPreferences.getInstance,
);
}
37 changes: 9 additions & 28 deletions lib/src/app/bootstrap.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// ignore_for_file: scoped_providers_should_specify_dependencies
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart' as flutter;
import 'package:flutter/widgets.dart';
import 'package:flutter_web_plugins/url_strategy.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
Expand All @@ -17,9 +17,9 @@ mixin Bootstrap on Widget {
/// - calling [usePathUrlStrategy] to use path-style URLs,
/// - setting up the [SettingsService] and loading the user's preferences,
/// - initializing riverpod's [ProviderScope], and
/// - running the app with [RunApp].
/// - running the app with [runApp].
Future<void> bootstrap(
RunApp runApp,
void Function(Widget app) runApp,
Future<SharedPreferences> Function() getSharedPreferences,
) async {
// Don't use hash style routes.
Expand All @@ -37,34 +37,15 @@ mixin Bootstrap on Widget {
final initialSettings = await loadSettings(prefs);

// Run the app.
runApp.runApp(
this,
overrides: [
sharedPreferencesProvider.overrideWithValue(prefs),
initialSettingsProvider.overrideWithValue(initialSettings),
],
);
}
}

/// {@template RunApp}
/// Allow mocking runApp in tests.
/// {@endtemplate}
class RunApp {
/// {@macro RunApp}
const RunApp();

/// See [flutter.runApp]
void runApp(
Widget app, {
List<Override> overrides = const [],
}) {
flutter.runApp(
runApp(
ProviderScope(
overrides: overrides,
overrides: [
sharedPreferencesProvider.overrideWithValue(prefs),
initialSettingsProvider.overrideWithValue(initialSettings),
],
child: RestorationScope(
restorationId: 'root',
child: app,
child: this,
),
),
);
Expand Down
3 changes: 0 additions & 3 deletions test/helpers/mocks.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import 'package:duly_noted/src/app/bootstrap.dart';
import 'package:mocktail/mocktail.dart';
import 'package:shared_preferences/shared_preferences.dart';

class MockSharedPreferences extends Mock implements SharedPreferences {}

class MockRunApp extends Mock implements RunApp {}
7 changes: 1 addition & 6 deletions test/src/app/bootstrap_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,14 @@ void main() {
});

test('main does not throw', () async {
final mockRunApp = MockRunApp();
const app = MyApp();

await expectLater(
app.bootstrap(
mockRunApp,
(_) {},
getSharedPreferences,
),
completes,
);

// Verify that runApp was called with an instance of MyApp.
verify(() => mockRunApp.runApp(app, overrides: any(named: 'overrides')))
.called(1);
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,17 @@ void main() {
});
});

group('initialPreferences', () {
test('should throw an error if initialPreferences is not provided', () {
group('initialSettings', () {
test('should throw an error if initialSettings are not provided', () {
// Arrange
final container = ProviderContainer();

// Act
PreferencesRepository call() =>
container.read(preferencesRepositoryProvider);

// Assert
expect(call, throwsA(isA<UnimplementedError>()));
expect(
// Act
() => container.read(initialSettingsProvider),
throwsA(isA<UnimplementedError>()),
);
});
});
}

0 comments on commit f28d8b2

Please sign in to comment.