Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test and Doc improvements for Dependencies #367

Merged
merged 2 commits into from
Aug 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
"recommendations": [
"Dart-Code.dart-code",
"Dart-Code.flutter",
"FelixAngelov.bloc",
"redhat.vscode-yaml"
],
"unwantedRecommendations": []
"unwantedRecommendations": [

]
}
1 change: 0 additions & 1 deletion lib/src/feature/app/widget/app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import 'package:flutter/material.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
import 'package:sizzle_starter/src/feature/app/widget/material_context.dart';
import 'package:sizzle_starter/src/feature/initialization/logic/composition_root.dart';
import 'package:sizzle_starter/src/feature/initialization/model/dependencies.dart';
import 'package:sizzle_starter/src/feature/initialization/widget/dependencies_scope.dart';
import 'package:sizzle_starter/src/feature/settings/widget/settings_scope.dart';

Expand Down
35 changes: 31 additions & 4 deletions lib/src/feature/initialization/logic/composition_root.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import 'package:shared_preferences/shared_preferences.dart';
import 'package:sizzle_starter/src/core/constant/config.dart';
import 'package:sizzle_starter/src/core/utils/refined_logger.dart';
import 'package:sizzle_starter/src/feature/app/logic/tracking_manager.dart';
import 'package:sizzle_starter/src/feature/initialization/model/dependencies.dart';
import 'package:sizzle_starter/src/feature/initialization/model/dependencies_container.dart';
import 'package:sizzle_starter/src/feature/settings/bloc/settings_bloc.dart';
import 'package:sizzle_starter/src/feature/settings/data/locale_datasource.dart';
import 'package:sizzle_starter/src/feature/settings/data/locale_repository.dart';
Expand Down Expand Up @@ -47,15 +47,17 @@ final class CompositionRoot {
dependencies: dependencies,
msSpent: stopwatch.elapsedMilliseconds,
);

return result;
}

Future<Dependencies> _initDependencies() async {
final errorTrackingManager = await _initErrorTrackingManager();
Future<DependenciesContainer> _initDependencies() async {
final sharedPreferences = SharedPreferencesAsync();

final errorTrackingManager = await _initErrorTrackingManager();
final settingsBloc = await _initSettingsBloc(sharedPreferences);

return Dependencies(
return DependenciesContainer(
settingsBloc: settingsBloc,
errorTrackingManager: errorTrackingManager,
);
Expand Down Expand Up @@ -111,3 +113,28 @@ final class CompositionRoot {
return settingsBloc;
}
}

/// {@template composition_result}
/// Result of composition
///
/// {@macro composition_process}
/// {@endtemplate}
final class CompositionResult {
/// {@macro composition_result}
const CompositionResult({
required this.dependencies,
required this.msSpent,
});

/// The dependencies container
final DependenciesContainer dependencies;

/// The number of milliseconds spent
final int msSpent;

@override
String toString() => '$CompositionResult('
'dependencies: $dependencies, '
'msSpent: $msSpent'
')';
}
49 changes: 0 additions & 49 deletions lib/src/feature/initialization/model/dependencies.dart

This file was deleted.

42 changes: 42 additions & 0 deletions lib/src/feature/initialization/model/dependencies_container.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import 'package:sizzle_starter/src/feature/app/logic/tracking_manager.dart';
import 'package:sizzle_starter/src/feature/initialization/logic/composition_root.dart';
import 'package:sizzle_starter/src/feature/settings/bloc/settings_bloc.dart';

/// {@template dependencies_container}
/// Composed dependencies from the [CompositionRoot].
///
/// This class contains all the dependencies that are required for the application
/// to work.
///
/// {@macro composition_process}
/// {@endtemplate}
base class DependenciesContainer {
/// {@macro dependencies_container}
const DependenciesContainer({
required this.settingsBloc,
required this.errorTrackingManager,
});

/// [SettingsBloc] instance, used to manage theme and locale.
final SettingsBloc settingsBloc;

/// [ErrorTrackingManager] instance, used to report errors.
final ErrorTrackingManager errorTrackingManager;
}

/// {@template testing_dependencies_container}
/// A special version of [DependenciesContainer] that is used in tests.
///
/// In order to use [DependenciesContainer] in tests, it is needed to
/// extend this class and provide the dependencies that are needed for the test.
/// {@endtemplate}
base class TestDependenciesContainer implements DependenciesContainer {
@override
Object? noSuchMethod(Invocation invocation) {
throw UnimplementedError(
'The test tries to access ${invocation.memberName} dependency, but '
'it was not provided. Please provide the dependency in the test. '
'You can do it by extending this class and providing the dependency.',
);
}
}
29 changes: 19 additions & 10 deletions lib/src/feature/initialization/widget/dependencies_scope.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,25 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:sizzle_starter/src/core/utils/extensions/context_extension.dart';
import 'package:sizzle_starter/src/feature/initialization/model/dependencies.dart';
import 'package:sizzle_starter/src/feature/initialization/model/dependencies_container.dart';

/// {@template dependencies_scope}
/// A scope that provides application dependencies.
/// A scope that provides composed [DependenciesContainer].
///
/// In order to use this in widget tests, you need to wrap your widget with
/// this widget and provide the dependencies. However, you should not
/// always provide the full pack of dependencies, only the ones that are
/// needed for the test. It is possible by creating a new class that extends
/// [Dependencies] and overrides the dependencies that are needed for the test.
/// **Testing**:
///
/// To use [DependenciesScope] in tests, it is needed to wrap the widget with
/// [DependenciesScope], extend [TestDependenciesContainer] and provide the
/// dependencies that are needed for the test.
///
/// ```dart
/// class AuthDependenciesContainer extends TestDependenciesContainer {
/// // for example, use mocks created by mockito, or pass fake/real implementations
/// // via constructor.
/// @override
/// final MockAuthRepository authRepository = MockAuthRepository();
/// }
/// ```
/// {@endtemplate}
class DependenciesScope extends InheritedWidget {
/// {@macro dependencies_scope}
Expand All @@ -22,17 +31,17 @@ class DependenciesScope extends InheritedWidget {
});

/// Container with dependencies.
final Dependencies dependencies;
final DependenciesContainer dependencies;

/// Get the dependencies from the [context].
static Dependencies of(BuildContext context) =>
static DependenciesContainer of(BuildContext context) =>
context.inhOf<DependenciesScope>(listen: false).dependencies;

@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(
DiagnosticsProperty<Dependencies>('dependencies', dependencies),
DiagnosticsProperty<DependenciesContainer>('dependencies', dependencies),
);
}

Expand Down