LCOV - code coverage report
Current view: top level - src - bloc_provider.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 22 22 100.0 %
Date: 2021-10-05 22:30:28 Functions: 0 0 -

          Line data    Source code
       1             : import 'package:bloc/bloc.dart';
       2             : import 'package:flutter/widgets.dart';
       3             : import 'package:provider/provider.dart';
       4             : import 'package:provider/single_child_widget.dart';
       5             : 
       6             : /// Mixin which allows `MultiBlocProvider` to infer the types
       7             : /// of multiple [BlocProvider]s.
       8             : mixin BlocProviderSingleChildWidget on SingleChildWidget {}
       9             : 
      10             : /// {@template bloc_provider}
      11             : /// Takes a [Create] function that is responsible for
      12             : /// creating the [Bloc] or [Cubit] and a [child] which will have access
      13             : /// to the instance via `BlocProvider.of(context)`.
      14             : /// It is used as a dependency injection (DI) widget so that a single instance
      15             : /// of a [Bloc] or [Cubit] can be provided to multiple widgets within a subtree.
      16             : ///
      17             : /// ```dart
      18             : /// BlocProvider(
      19             : ///   create: (BuildContext context) => BlocA(),
      20             : ///   child: ChildA(),
      21             : /// );
      22             : /// ```
      23             : ///
      24             : /// It automatically handles closing the instance when used with [Create].
      25             : /// By default, [Create] is called only when the instance is accessed.
      26             : /// To override this behavior, set [lazy] to `false`.
      27             : ///
      28             : /// ```dart
      29             : /// BlocProvider(
      30             : ///   lazy: false,
      31             : ///   create: (BuildContext context) => BlocA(),
      32             : ///   child: ChildA(),
      33             : /// );
      34             : /// ```
      35             : ///
      36             : /// {@endtemplate}
      37             : class BlocProvider<T extends BlocBase<Object?>>
      38             :     extends SingleChildStatelessWidget with BlocProviderSingleChildWidget {
      39             :   /// {@macro bloc_provider}
      40           2 :   BlocProvider({
      41             :     Key? key,
      42             :     required Create<T> create,
      43             :     this.child,
      44             :     this.lazy,
      45             :   })  : _create = create,
      46             :         _value = null,
      47           2 :         super(key: key, child: child);
      48             : 
      49             :   /// Takes a [value] and a [child] which will have access to the [value] via
      50             :   /// `BlocProvider.of(context)`.
      51             :   /// When `BlocProvider.value` is used, the [Bloc] or [Cubit]
      52             :   /// will not be automatically closed.
      53             :   /// As a result, `BlocProvider.value` should only be used for providing
      54             :   /// existing instances to new subtrees.
      55             :   ///
      56             :   /// A new [Bloc] or [Cubit] should not be created in `BlocProvider.value`.
      57             :   /// New instances should always be created using the
      58             :   /// default constructor within the [Create] function.
      59             :   ///
      60             :   /// ```dart
      61             :   /// BlocProvider.value(
      62             :   ///   value: BlocProvider.of<BlocA>(context),
      63             :   ///   child: ScreenA(),
      64             :   /// );
      65             :   /// ```
      66           6 :   BlocProvider.value({
      67             :     Key? key,
      68             :     required T value,
      69             :     this.child,
      70             :   })  : _value = value,
      71             :         _create = null,
      72             :         lazy = null,
      73           6 :         super(key: key, child: child);
      74             : 
      75             :   /// Widget which will have access to the [Bloc] or [Cubit].
      76             :   final Widget? child;
      77             : 
      78             :   /// Whether the [Bloc] or [Cubit] should be created lazily.
      79             :   /// Defaults to `true`.
      80             :   final bool? lazy;
      81             : 
      82             :   final Create<T>? _create;
      83             : 
      84             :   final T? _value;
      85             : 
      86             :   /// Method that allows widgets to access a [Bloc] or [Cubit] instance
      87             :   /// as long as their `BuildContext` contains a [BlocProvider] instance.
      88             :   ///
      89             :   /// If we want to access an instance of `BlocA` which was provided higher up
      90             :   /// in the widget tree we can do so via:
      91             :   ///
      92             :   /// ```dart
      93             :   /// BlocProvider.of<BlocA>(context);
      94             :   /// ```
      95           2 :   static T of<T extends BlocBase<Object?>>(
      96             :     BuildContext context, {
      97             :     bool listen = false,
      98             :   }) {
      99             :     try {
     100           2 :       return Provider.of<T>(context, listen: listen);
     101           1 :     } on ProviderNotFoundException catch (e) {
     102           2 :       if (e.valueType != T) rethrow;
     103           1 :       throw FlutterError(
     104             :         '''
     105             :         BlocProvider.of() called with a context that does not contain a $T.
     106             :         No ancestor could be found starting from the context that was passed to BlocProvider.of<$T>().
     107             : 
     108             :         This can happen if the context you used comes from a widget above the BlocProvider.
     109             : 
     110             :         The context used was: $context
     111           1 :         ''',
     112             :       );
     113             :     }
     114             :   }
     115             : 
     116           6 :   @override
     117             :   Widget buildWithChild(BuildContext context, Widget? child) {
     118           6 :     final value = _value;
     119             :     return value != null
     120           6 :         ? InheritedProvider<T>.value(
     121             :             value: value,
     122             :             startListening: _startListening,
     123           6 :             lazy: lazy,
     124             :             child: child,
     125             :           )
     126           2 :         : InheritedProvider<T>(
     127           2 :             create: _create,
     128           4 :             dispose: (_, bloc) => bloc.close(),
     129             :             startListening: _startListening,
     130             :             child: child,
     131           2 :             lazy: lazy,
     132             :           );
     133             :   }
     134             : 
     135           6 :   static VoidCallback _startListening(
     136             :     InheritedContext<BlocBase?> e,
     137             :     BlocBase value,
     138             :   ) {
     139          12 :     final subscription = value.stream.listen(
     140          12 :       (dynamic _) => e.markNeedsNotifyDependents(),
     141             :     );
     142           6 :     return subscription.cancel;
     143             :   }
     144             : }

Generated by: LCOV version 1.15