LCOV - code coverage report
Current view: top level - src - beam_state.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 52 52 100.0 %
Date: 2021-12-03 10:03:44 Functions: 0 0 -

          Line data    Source code
       1             : import 'dart:convert';
       2             : 
       3             : import 'package:flutter/widgets.dart';
       4             : 
       5             : import './utils.dart';
       6             : import './beam_location.dart';
       7             : 
       8             : /// A class to mix with when defining a custom state for [BeamLocation].
       9             : ///
      10             : /// [fromRouteInformation] and [toRouteInformation] need to be implemented in
      11             : /// order to notify the platform of current [RouteInformation] that corresponds
      12             : /// to the state.
      13             : mixin RouteInformationSerializable<T> {
      14             :   /// Create a state of type `T` from [RouteInformation].
      15             :   T fromRouteInformation(RouteInformation routeInformation);
      16             : 
      17             :   /// Creates a [RouteInformation] fro the state of type `T`.
      18             :   RouteInformation toRouteInformation();
      19             : 
      20             :   /// A convenience method to get [RouteInformation] from this.
      21             :   ///
      22             :   /// Basically returns [toRouteInformation].
      23          22 :   RouteInformation get routeInformation => toRouteInformation();
      24             : }
      25             : 
      26             : /// Beamer's opinionated state for [BeamLocation]s.
      27             : ///
      28             : /// This can be used when one does not desire to define its own state.
      29             : class BeamState with RouteInformationSerializable<BeamState> {
      30             :   /// Creates a [BeamState] with specified properties.
      31             :   ///
      32             :   /// All of the properties have empty or `null` default values.
      33           9 :   BeamState({
      34             :     this.pathPatternSegments = const <String>[],
      35             :     this.pathParameters = const <String, String>{},
      36             :     this.queryParameters = const <String, String>{},
      37             :     this.routeState,
      38           9 :   }) : assert(() {
      39           9 :           json.encode(routeState);
      40             :           return true;
      41             :         }()) {
      42           9 :     configure();
      43             :   }
      44             : 
      45             :   /// Creates a [BeamState] from given [uri] and optional [data].
      46             :   ///
      47             :   /// If [beamLocation] is given, then it will take into consideration
      48             :   /// its `pathPatterns` to populate the [pathParameters] attribute.
      49             :   ///
      50             :   /// See [Utils.createBeamState].
      51           9 :   factory BeamState.fromUri(
      52             :     Uri uri, {
      53             :     BeamLocation? beamLocation,
      54             :     Object? routeState,
      55             :   }) {
      56           9 :     return Utils.createBeamState(
      57             :       uri,
      58             :       beamLocation: beamLocation,
      59             :       routeState: routeState,
      60             :     );
      61             :   }
      62             : 
      63             :   /// Creates a [BeamState] from given [uriString] and optional [data].
      64             :   ///
      65             :   /// If [beamLocation] is given, then it will take into consideration
      66             :   /// its path blueprints to populate the [pathParameters] attribute.
      67             :   ///
      68             :   /// See [BeamState.fromUri].
      69           1 :   factory BeamState.fromUriString(
      70             :     String uriString, {
      71             :     BeamLocation? beamLocation,
      72             :     Object? routeState,
      73             :   }) {
      74           1 :     uriString = Utils.trimmed(uriString);
      75           1 :     final uri = Uri.parse(uriString);
      76           1 :     return BeamState.fromUri(
      77             :       uri,
      78             :       beamLocation: beamLocation,
      79             :       routeState: routeState,
      80             :     );
      81             :   }
      82             : 
      83             :   /// Creates a [BeamState] from given [routeInformation].
      84             :   ///
      85             :   /// If [beamLocation] is given, then it will take into consideration
      86             :   /// its path blueprints to populate the [pathParameters] attribute.
      87             :   ///
      88             :   /// See [BeamState.fromUri].
      89           9 :   factory BeamState.fromRouteInformation(
      90             :     RouteInformation routeInformation, {
      91             :     BeamLocation? beamLocation,
      92             :   }) {
      93           9 :     return BeamState.fromUri(
      94          18 :       Uri.parse(routeInformation.location ?? '/'),
      95             :       beamLocation: beamLocation,
      96           9 :       routeState: routeInformation.state,
      97             :     );
      98             :   }
      99             : 
     100             :   /// Path segments of the current URI,
     101             :   /// in the form as it's defined in [BeamLocation.pathPatterns].
     102             :   ///
     103             :   /// If current URI is '/books/1', this will be `['books', ':bookId']`.
     104             :   final List<String> pathPatternSegments;
     105             : 
     106             :   /// Path parameters from the URI,
     107             :   /// in the form as it's defined in [BeamLocation.pathPatterns].
     108             :   ///
     109             :   /// If current URI is '/books/1', this will be `{'bookId': '1'}`.
     110             :   final Map<String, String> pathParameters;
     111             : 
     112             :   /// Query parameters of the current URI.
     113             :   ///
     114             :   /// If current URI is '/books?title=str', this will be `{'title': 'str'}`.
     115             :   final Map<String, String> queryParameters;
     116             : 
     117             :   /// An object that will be passed to [RouteInformation.state]
     118             :   /// that is stored as a part of browser history entry.
     119             :   ///
     120             :   /// This needs to be serializable.
     121             :   final Object? routeState;
     122             : 
     123             :   late Uri _uriBlueprint;
     124             : 
     125             :   /// Current URI object in the "blueprint form",
     126             :   /// as it's defined in [BeamLocation.pathPatterns].
     127             :   ///
     128             :   /// This is constructed from [pathPatternSegments] and [queryParameters].
     129             :   /// See more at [configure].
     130           4 :   Uri get uriBlueprint => _uriBlueprint;
     131             : 
     132             :   late Uri _uri;
     133             : 
     134             :   /// Current URI object in the "real form",
     135             :   /// as it should be shown in browser's URL bar.
     136             :   ///
     137             :   /// This is constructed from [pathPatternSegments] and [queryParameters],
     138             :   /// with the addition of replacing each pathPatternSegment of the form ':*'
     139             :   /// with a coresponding value from [pathParameters].
     140             :   ///
     141             :   /// See more at [configure].
     142          18 :   Uri get uri => _uri;
     143             : 
     144             :   /// Copies this with configuration for specific [BeamLocation].
     145           1 :   BeamState copyForLocation(BeamLocation beamLocation, Object? routeState) {
     146           1 :     return Utils.createBeamState(
     147           1 :       uri,
     148             :       beamLocation: beamLocation,
     149             :       routeState: routeState,
     150             :     );
     151             :   }
     152             : 
     153             :   /// Returns a configured copy of this.
     154           3 :   BeamState copyWith({
     155             :     List<String>? pathPatternSegments,
     156             :     Map<String, String>? pathParameters,
     157             :     Map<String, String>? queryParameters,
     158             :     Object? routeState,
     159             :   }) =>
     160           3 :       BeamState(
     161           2 :         pathPatternSegments: pathPatternSegments ?? this.pathPatternSegments,
     162           1 :         pathParameters: pathParameters ?? this.pathParameters,
     163           2 :         queryParameters: queryParameters ?? this.queryParameters,
     164           3 :         routeState: routeState ?? this.routeState,
     165           3 :       )..configure();
     166             : 
     167             :   /// Constructs [uriBlueprint] and [uri].
     168           9 :   void configure() {
     169          18 :     _uriBlueprint = Uri(
     170          27 :       path: '/' + pathPatternSegments.join('/'),
     171          24 :       queryParameters: queryParameters.isEmpty ? null : queryParameters,
     172             :     );
     173          18 :     final pathSegments = pathPatternSegments.toList();
     174          27 :     for (int i = 0; i < pathSegments.length; i++) {
     175          45 :       if (pathSegments[i].isNotEmpty && pathSegments[i][0] == ':') {
     176          12 :         final key = pathSegments[i].substring(1);
     177          12 :         if (pathParameters.containsKey(key)) {
     178          18 :           pathSegments[i] = pathParameters[key]!;
     179             :         }
     180             :       }
     181             :     }
     182          18 :     _uri = Uri(
     183          18 :       path: '/' + pathSegments.join('/'),
     184          24 :       queryParameters: queryParameters.isEmpty ? null : queryParameters,
     185             :     );
     186             :   }
     187             : 
     188           1 :   @override
     189             :   BeamState fromRouteInformation(RouteInformation routeInformation) =>
     190           1 :       BeamState.fromRouteInformation(routeInformation);
     191             : 
     192           9 :   @override
     193           9 :   RouteInformation toRouteInformation() => RouteInformation(
     194          18 :         location: uri.toString(),
     195           9 :         state: routeState,
     196             :       );
     197             : 
     198           1 :   @override
     199           4 :   int get hashCode => hashValues(uri, json.encode(routeState));
     200             : 
     201           1 :   @override
     202             :   bool operator ==(Object other) {
     203           1 :     return other is BeamState &&
     204           3 :         other.uri == uri &&
     205           5 :         json.encode(other.routeState) == json.encode(routeState);
     206             :   }
     207             : }

Generated by: LCOV version 1.14