LCOV - code coverage report
Current view: top level - src - beam_guard.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 14 14 100.0 %
Date: 2021-06-08 01:09:24 Functions: 0 0 -

          Line data    Source code
       1             : import 'package:beamer/src/utils.dart';
       2             : import 'package:flutter/widgets.dart';
       3             : 
       4             : import './beam_location.dart';
       5             : import './beam_page.dart';
       6             : 
       7             : /// Checks whether current [BeamLocation] is allowed to be beamed to
       8             : /// and provides steps to be executed following a failed check.
       9             : ///
      10             : /// If neither [beamTo], [beamToNamed] nor [showPage] is specified,
      11             : /// the guard will just block navigation, i.e. nothing will happen.
      12             : class BeamGuard {
      13           1 :   BeamGuard({
      14             :     required this.pathBlueprints,
      15             :     required this.check,
      16             :     this.onCheckFailed,
      17             :     this.beamTo,
      18             :     this.beamToNamed,
      19             :     this.showPage,
      20             :     this.guardNonMatching = false,
      21             :     this.replaceCurrentStack = true,
      22             :   });
      23             : 
      24             :   /// A list of path strings or regular expressions (using dart's RegExp class) that are to be guarded.
      25             :   ///
      26             :   /// For strings:
      27             :   /// Asterisk wildcard is supported to denote "anything".
      28             :   ///
      29             :   /// For example, '/books/*' will match '/books/1', '/books/2/genres', etc.
      30             :   /// but will not match '/books'. To match '/books' and everything after it,
      31             :   /// use '/books*'.
      32             :   ///
      33             :   /// See [_hasMatch] for more details.
      34             :   ///
      35             :   /// For RegExp:
      36             :   /// You can use RegExp instances and the delegate will check for a match using [RegExp.hasMatch]
      37             :   ///
      38             :   /// For example, `RegExp('/books/')` will match '/books/1', '/books/2/genres', etc.
      39             :   /// but will not match '/books'. To match '/books' and everything after it,
      40             :   /// use `RegExp('/books')`
      41             :   List<dynamic> pathBlueprints;
      42             : 
      43             :   /// What check should be performed on a given [location],
      44             :   /// the one to which beaming has been requested.
      45             :   ///
      46             :   /// [context] is also injected to fetch data up the tree if necessary.
      47             :   bool Function(BuildContext context, BeamLocation location) check;
      48             : 
      49             :   /// Arbitrary closure to execute when [check] fails.
      50             :   ///
      51             :   /// This will run before and regardless of [beamTo], [beamToNamed], [showPage].
      52             :   void Function(BuildContext context, BeamLocation location)? onCheckFailed;
      53             : 
      54             :   /// If guard [check] returns `false`, build a [BeamLocation] to be beamed to.
      55             :   ///
      56             :   /// [showPage] has precedence over this attribute.
      57             :   BeamLocation Function(BuildContext context)? beamTo;
      58             : 
      59             :   /// If guard [check] returns `false`, beam to this URI string.
      60             :   ///
      61             :   /// [showPage] has precedence over this attribute.
      62             :   String? beamToNamed;
      63             : 
      64             :   /// If guard [check] returns `false`, put this page onto navigation stack.
      65             :   ///
      66             :   /// This has precedence over [beamTo] and [beamToNamed].
      67             :   BeamPage? showPage;
      68             : 
      69             :   /// Whether to [check] all the path blueprints defined in [pathBlueprints]
      70             :   /// or [check] all the paths that **are not** in [pathBlueprints].
      71             :   ///
      72             :   /// `false` meaning former and `true` meaning latter.
      73             :   bool guardNonMatching;
      74             : 
      75             :   /// Whether or not to replace the current [BeamLocation]'s stack of pages.
      76             :   final bool replaceCurrentStack;
      77             : 
      78             :   /// Matches [location]'s pathBlueprint to [pathBlueprints].
      79             :   ///
      80             :   /// If asterisk is present, it is enough that the pre-asterisk substring is
      81             :   /// contained within location's pathBlueprint.
      82             :   /// Else, the path (i.e. the pre-query substring) of the location's uri
      83             :   /// must be equal to the pathBlueprint.
      84           1 :   bool _hasMatch(BeamLocation location) {
      85           2 :     for (var pathBlueprint in pathBlueprints) {
      86           1 :       if (pathBlueprint is String) {
      87           1 :         final asteriskIndex = pathBlueprint.indexOf('*');
      88           2 :         if (asteriskIndex != -1) {
      89           2 :           if (location.state.uri
      90           1 :               .toString()
      91           2 :               .contains(pathBlueprint.substring(0, asteriskIndex))) {
      92             :             return true;
      93             :           }
      94             :         } else {
      95           4 :           if (pathBlueprint == location.state.uri.path) {
      96             :             return true;
      97             :           }
      98             :         }
      99             :       } else {
     100           1 :         final regexp = Utils.tryCastToRegExp(pathBlueprint);
     101           4 :         return regexp.hasMatch(location.state.uri.path);
     102             :       }
     103             :     }
     104             :     return false;
     105             :   }
     106             : 
     107             :   /// Whether or not the guard should [check] the [location].
     108           1 :   bool shouldGuard(BeamLocation location) {
     109           3 :     return guardNonMatching ? !_hasMatch(location) : _hasMatch(location);
     110             :   }
     111             : }

Generated by: LCOV version 1.14