]> git.ipfire.org Git - thirdparty/vuejs/router.git/commitdiff
feat(parser): add regexp options
authorEduardo San Martin Morote <posva13@gmail.com>
Thu, 12 Dec 2019 09:38:55 +0000 (10:38 +0100)
committerEduardo San Martin Morote <posva13@gmail.com>
Wed, 18 Dec 2019 09:26:15 +0000 (10:26 +0100)
__tests__/matcher/path-parser.spec.ts
src/matcher/tokenizer.ts

index 28f7c8c468e6d18bb5d512bbaa5aeeba32c83e28..ed4eabccaca1370119c0ad6209c9ee640650a8dc 100644 (file)
@@ -328,7 +328,7 @@ describe('Path parser', () => {
       expect(expectedRe).toBe(
         pathParser.re
           .toString()
-          .replace(/(:?^\/|\/$)/g, '')
+          .replace(/(:?^\/|\/\w*$)/g, '')
           .replace(/\\\//g, '/')
       )
     }
@@ -430,9 +430,10 @@ describe('Path parser', () => {
     function matchParams(
       path: string,
       pathToTest: string,
-      params: ReturnType<ReturnType<typeof tokensToParser>['parse']>
+      params: ReturnType<ReturnType<typeof tokensToParser>['parse']>,
+      options?: Parameters<typeof tokensToParser>[1]
     ) {
-      const pathParser = tokensToParser(tokenizePath(path))
+      const pathParser = tokensToParser(tokenizePath(path), options)
 
       expect(pathParser.parse(pathToTest)).toEqual(params)
     }
@@ -441,6 +442,25 @@ describe('Path parser', () => {
       matchParams('/home', '/', null)
     })
 
+    it('is insensitive by default', () => {
+      matchParams('/home', '/HOMe', {})
+    })
+
+    it('can be sensitive', () => {
+      matchParams('/home', '/HOMe', null, { sensitive: true })
+      matchParams('/home', '/home', {}, { sensitive: true })
+    })
+
+    it('can not match the beginning', () => {
+      matchParams('/home', '/other/home', null, { start: true })
+      matchParams('/home', '/other/home', {}, { start: false })
+    })
+
+    it('can not match the end', () => {
+      matchParams('/home', '/home/other', null, { end: true })
+      matchParams('/home', '/home/other', {}, { end: false })
+    })
+
     it('returns an empty object with no keys', () => {
       matchParams('/home', '/home', {})
     })
index c6dc129114afa0bd04b6fafd6badc75c8ed5efc2..3030b264d9bfaed74c1c761951141d6f0c65c2fa 100644 (file)
@@ -192,15 +192,60 @@ interface PathParser {
   stringify(params: Params): string
 }
 
+interface PathParserOptions {
+  /**
+   * Makes the RegExp case sensitive. Defaults to false
+   */
+  sensitive?: boolean
+  /**
+   * Should we allow a trailing slash. Defaults to true
+   */
+  strict?: boolean
+  /**
+   * Should the RegExp match from the beginning by prepending a ^. Defaults to true
+   */
+  start?: boolean
+  /**
+   * Should the RegExp match until the end by appending a $. Defaults to true
+   */
+  end?: boolean
+  /**
+   * Encodes a static value. This is used to encode params for them to be valid on the URL
+   */
+  encode?: (value: string) => string
+  /**
+   * Decodes a static value. This allows to produce decoded params when parsing an URL
+   */
+  decode?: (value: string) => string
+}
+
 const BASE_PARAM_PATTERN = '[^/]+?'
 
+const BASE_PATH_PARSER_OPTIONS: Required<PathParserOptions> = {
+  sensitive: false,
+  strict: false,
+  start: true,
+  end: true,
+  // TODO: implement real ones
+  encode: v => v,
+  decode: v => v,
+}
+
 /**
  * TODO: add options strict, sensitive, encode, decode
  */
 
-export function tokensToParser(segments: Array<Token[]>): PathParser {
+export function tokensToParser(
+  segments: Array<Token[]>,
+  extraOptions?: PathParserOptions
+): PathParser {
+  const options = {
+    ...BASE_PATH_PARSER_OPTIONS,
+    ...extraOptions,
+  }
+
   let score = 0
-  let pattern = '^'
+  let pattern = options.start ? '^' : ''
   const keys: ParamKey[] = []
 
   for (const segment of segments) {
@@ -231,9 +276,9 @@ export function tokensToParser(segments: Array<Token[]>): PathParser {
     }
   }
 
-  pattern += '$'
+  pattern += options.end ? '$' : ''
 
-  const re = new RegExp(pattern)
+  const re = new RegExp(pattern, options.sensitive ? '' : 'i')
 
   function parse(path: string): Params | null {
     const match = path.match(re)