]> git.ipfire.org Git - thirdparty/vuejs/router.git/commitdiff
test: add tests for parseURL
authorEduardo San Martin Morote <posva13@gmail.com>
Thu, 11 Apr 2019 15:45:03 +0000 (17:45 +0200)
committerEduardo San Martin Morote <posva13@gmail.com>
Thu, 11 Apr 2019 15:45:03 +0000 (17:45 +0200)
__tests__/url.spec.ts [new file with mode: 0644]
src/history/abstract.ts
src/history/base.ts
src/history/html5.ts

diff --git a/__tests__/url.spec.ts b/__tests__/url.spec.ts
new file mode 100644 (file)
index 0000000..18ae805
--- /dev/null
@@ -0,0 +1,40 @@
+import { BaseHistory } from '../src/history/base'
+
+const parseURL = BaseHistory.prototype.parseURL
+
+describe('URL parsing', () => {
+  it('works with no query no hash', () => {
+    expect(parseURL('/foo')).toEqual({
+      path: '/foo',
+      hash: '',
+      query: {},
+    })
+  })
+
+  it('extracts the query', () => {
+    expect(parseURL('/foo?a=one&b=two')).toEqual({
+      path: '/foo',
+      hash: '',
+      query: {
+        a: 'one',
+        b: 'two',
+      },
+    })
+  })
+
+  it('extracts the hash', () => {
+    expect(parseURL('/foo#bar')).toEqual({
+      path: '/foo',
+      hash: '#bar',
+      query: {},
+    })
+  })
+
+  it('extracts query and hash', () => {
+    expect(parseURL('/foo?a=one#bar')).toEqual({
+      path: '/foo',
+      hash: '#bar',
+      query: { a: 'one' },
+    })
+  })
+})
index d21ee4c9d0d372ff8c43efdde457a8cbb2e2a247..93e8460a8c0c2b8b4b81963fc24980d0183ad2e4 100644 (file)
@@ -1,21 +1,11 @@
 import consola from 'consola'
 import { BaseHistory } from './base'
-import {
-  HistoryLocation,
-  NavigationCallback,
-  HistoryState,
-  NavigationType,
-  HistoryURL,
-} from './base'
+import { HistoryLocation, NavigationCallback, HistoryState } from './base'
 
-const cs = consola.withTag('html5')
-
-type PopStateListener = (this: Window, ev: PopStateEvent) => any
+const cs = consola.withTag('abstract')
 
 export class AbstractHistory extends BaseHistory {
-  private history = window.history
-  private _popStateListeners: PopStateListener[] = []
-  private _listeners: NavigationCallback[] = []
+  // private _listeners: NavigationCallback[] = []
   private _teardowns: Array<() => void> = []
 
   constructor() {
@@ -23,137 +13,14 @@ export class AbstractHistory extends BaseHistory {
   }
 
   // TODO: is this necessary
-  ensureLocation() {
-    const to = buildFullPath()
-    cs.log('ensureLocation', to)
-    this.history.replaceState(
-      {
-        _back: null,
-        _current: to,
-        _forward: null,
-      },
-      '',
-      to
-    )
-    this.location = to
-  }
+  ensureLocation() {}
 
-  replace(to: HistoryLocation) {
-    if (to === this.location) return
-    cs.info('replace', this.location, to)
-    this.history.replaceState(
-      {
-        // TODO: this should be user's responsibility
-        // _replacedState: this.history.state || null,
-        _back: this.location,
-        _current: to,
-        _forward: null,
-        _replaced: true,
-      },
-      '',
-      to
-    )
-    this.location = to
-  }
+  replace(to: HistoryLocation) {}
 
-  push(to: HistoryLocation, data?: HistoryState) {
-    // replace current entry state to add the forward value
-    this.history.replaceState(
-      {
-        ...this.history.state,
-        _forward: to,
-      },
-      ''
-    )
-    // TODO: compare current location to prevent navigation
-    // NEW NOTE: I think it shouldn't be history responsibility to check that
-    // if (to === this.location) return
-    const state = {
-      _back: this.location,
-      _current: to,
-      _forward: null,
-      ...data,
-    }
-    cs.info('push', this.location, '->', to, 'with state', state)
-    this.history.pushState(state, '', to)
-    this.location = to
-  }
+  push(to: HistoryLocation, data?: HistoryState) {}
 
   listen(callback: NavigationCallback) {
-    // state is the same as history.state
-    const handler: PopStateListener = ({ state }) => {
-      cs.log(this)
-      cs.info('popstate fired', {
-        state,
-        location: this.location,
-      })
-      const from = this.location
-      // we have the state from the old entry, not the current one being removed
-      // TODO: correctly parse pathname
-      this.location = state ? state._current : buildFullPath
-      callback(this.location, from, {
-        type:
-          from === state._forward
-            ? NavigationType.back
-            : NavigationType.forward,
-      })
-    }
-
-    // settup the listener and prepare teardown callbacks
-    this._popStateListeners.push(handler)
-    this._listeners.push(callback)
-    window.addEventListener('popstate', handler)
-
-    const teardown = () => {
-      this._popStateListeners.splice(
-        this._popStateListeners.indexOf(handler),
-        1
-      )
-      this._listeners.splice(this._listeners.indexOf(callback), 1)
-      window.removeEventListener('popstate', handler)
-    }
-
-    this._teardowns.push(teardown)
-    return teardown
-  }
-
-  parseURL(location: string): HistoryURL {
-    let path = '',
-      search: HistoryURL['search'] = {},
-      searchString = '',
-      hash = ''
-
-    // Could use URL and URLSearchParams but IE 11 doesn't support it
-    const searchPos = location.indexOf('?')
-    const hashPos = location.indexOf(location, searchPos > -1 ? searchPos : 0)
-    if (searchPos > -1) {
-      path = location.slice(0, searchPos)
-      searchString = location.slice(
-        searchPos + 1,
-        hashPos > -1 ? hashPos : location.length - 1
-      )
-
-      // TODO: properly do this in a util function
-      search = searchString.split('&').reduce((search, entry) => {
-        const [key, value] = entry.split('=')
-        search[key] = value
-        return search
-      }, search)
-    }
-
-    if (hashPos > -1) {
-      path = path || location.slice(0, hashPos)
-      hash = location.slice(hashPos, location.length - 1)
-    }
-
-    path = path || location
-
-    return {
-      path,
-      // TODO: transform searchString
-      search,
-      hash,
-    }
+    return () => {}
   }
 
   destroy() {
@@ -161,6 +28,3 @@ export class AbstractHistory extends BaseHistory {
     this._teardowns = []
   }
 }
-
-const buildFullPath = () =>
-  window.location.pathname + window.location.search + window.location.hash
index 2001c3686036043fac8243801863752abea5c8fe..767ffffca4bb7307897722158fbac914d38825ec 100644 (file)
@@ -1,7 +1,7 @@
 export type HistoryLocation = string
 export interface HistoryURL {
   path: string
-  search: Record<string, string>
+  query: Record<string, string> // TODO: handle arrays
   hash: string
 }
 
@@ -72,7 +72,45 @@ export abstract class BaseHistory {
    * @param location location to normalize
    * @param currentLocation current location, to reuse params and location
    */
-  abstract parseURL(location: HistoryLocation): HistoryURL
+  parseURL(location: string): HistoryURL {
+    let path = '',
+      query: HistoryURL['query'] = {},
+      searchString = '',
+      hash = ''
+
+    // Could use URL and URLSearchParams but IE 11 doesn't support it
+    // TODO: move this utility to base.ts so it can be used by any history implementation
+    const searchPos = location.indexOf('?')
+    const hashPos = location.indexOf('#', searchPos > -1 ? searchPos : 0)
+    if (searchPos > -1) {
+      path = location.slice(0, searchPos)
+      searchString = location.slice(
+        searchPos + 1,
+        hashPos > -1 ? hashPos : location.length
+      )
+
+      // TODO: properly do this in a util function
+      query = searchString.split('&').reduce((query, entry) => {
+        const [key, value] = entry.split('=')
+        query[key] = value
+        return query
+      }, query)
+    }
+
+    if (hashPos > -1) {
+      path = path || location.slice(0, hashPos)
+      hash = location.slice(hashPos, location.length)
+    }
+
+    path = path || location
+
+    return {
+      path,
+      // TODO: transform searchString
+      query,
+      hash,
+    }
+  }
 
   /**
    * ensure the current location matches the external source
index bac509b5243f37890ff792b34eea6c092956dbb1..209d5eb1bbc648d0cc01d8097c727e7e71356ae8 100644 (file)
@@ -5,7 +5,6 @@ import {
   NavigationCallback,
   HistoryState,
   NavigationType,
-  HistoryURL,
 } from './base'
 
 const cs = consola.withTag('html5')
@@ -101,45 +100,6 @@ export class HTML5History extends BaseHistory {
     return teardown
   }
 
-  parseURL(location: string): HistoryURL {
-    let path = '',
-      search: HistoryURL['search'] = {},
-      searchString = '',
-      hash = ''
-
-    // Could use URL and URLSearchParams but IE 11 doesn't support it
-    const searchPos = location.indexOf('?')
-    const hashPos = location.indexOf(location, searchPos > -1 ? searchPos : 0)
-    if (searchPos > -1) {
-      path = location.slice(0, searchPos)
-      searchString = location.slice(
-        searchPos + 1,
-        hashPos > -1 ? hashPos : location.length - 1
-      )
-
-      // TODO: properly do this in a util function
-      search = searchString.split('&').reduce((search, entry) => {
-        const [key, value] = entry.split('=')
-        search[key] = value
-        return search
-      }, search)
-    }
-
-    if (hashPos > -1) {
-      path = path || location.slice(0, hashPos)
-      hash = location.slice(hashPos, location.length - 1)
-    }
-
-    path = path || location
-
-    return {
-      path,
-      // TODO: transform searchString
-      search,
-      hash,
-    }
-  }
-
   /**
    * Remove all listeners attached to the history and cleanups the history
    * instance