All files / src StateUtils.js

48.65% Statements 18/37
58.62% Branches 17/29
80% Functions 4/5
53.13% Lines 17/32

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114              2x             32x         32x 8x   30x 24x 24x 24x 24x 24x               24x   38x 48x           38x 38x 38x 38x                                                                                                                                    
/* @flow */
 
import { matchPath, type Location } from 'react-router'
import RouteUtils from './RouteUtils'
import StackUtils from './StackUtils'
import type { NavigationState, RouteProps, Route } from './TypeDefinitions'
 
const StateUtils = {
  initialize(
    stack: Array<RouteProps>,
    location: Location,
    entries: Array<Location>,
    buildFrom: 'entries' | 'stack',
  ): NavigationState<> {
    const historyEntries = StackUtils.getHistoryEntries(
      stack,
      entries,
      location,
    )
    if (buildFrom === 'stack') {
      return stack.reduce(
        (state, item) => {
          const entry = historyEntries.find(({ pathname }) => matchPath(pathname, item))
          const match = entry ? matchPath(entry.pathname, item) : null
          const route = RouteUtils.create(item, match && entry)
          Iif (!route) return state
          const isCurrentLocation = entry && entry.pathname === location.pathname
          return {
            index: isCurrentLocation ? state.routes.length : state.index,
            routes: [...state.routes, route],
          }
        },
        { index: -1, routes: [] },
      )
    }
    return historyEntries.reduce(
      (state, entry) => {
        const item = stack.find(({ path, exact, strict }) => {
          return matchPath(entry.pathname, {
            path,
            exact,
            strict,
          })
        })
        Iif (!item || !item.path) return state
        const route = RouteUtils.create(item, entry)
        Iif (!route) return state
        return {
          index: matchPath(location.pathname, item) ? state.routes.length : state.index,
          routes: [...state.routes, route],
        }
      },
      { index: -1, routes: [] },
    )
  },
 
  push(state: NavigationState<>, route: Route): NavigationState<> {
    const newRoutes = [...state.routes, route]
    return {
      ...state,
      index: newRoutes.length - 1,
      routes: newRoutes,
    }
  },
 
  pop(state: NavigationState<>, n: number = 1): NavigationState<> {
    if (state.index <= 0) return state
    const newRoutes = state.routes.slice(0, -n)
    return {
      ...state,
      index: newRoutes.length - 1,
      routes: newRoutes,
    }
  },
 
  replace(
    state: NavigationState<>,
    index: number,
    route: Route,
  ): NavigationState<> {
    if (state.routes[index] === route || index > state.routes.length) {
      return state
    }
    const newRoutes = [
      ...state.routes.slice(0, index),
      route,
      ...state.routes.slice(index + 1),
    ]
    return {
      ...state,
      index,
      routes: newRoutes,
    }
  },
 
  changeIndex(state: NavigationState<>, arg: number | Route) {
    if (typeof arg === 'number') {
      return { ...state, index: arg }
    }
    const index = state.routes.findIndex(
    // $FlowFixMe
      route => route.routeName === arg.routeName,
    )
    const routes = [
      ...state.routes.slice(0, index),
      arg,
      ...state.routes.slice(index + 1),
    ]
    return { ...state, routes, index }
  },
}
 
export default StateUtils